From 656acceb789b40738c965c421d39577de78ae893 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp Date: Mon, 3 Jun 2019 13:23:31 -0700 Subject: [PATCH 01/71] basic format --- .../audits/byte-efficiency/unminified-css.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index cfccdb861228..644539ecf999 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -16,6 +16,21 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Minifying CSS files can reduce network payload sizes. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', + titleObj: { + message: 'Minifying CSS files can reduce network payload sizes.' + + ' $LINK_START$Learn More$LINK_END$', + description: 'Description of a Lighthouse audit that tells the user *why* they should ' + + 'minify (remove whitespace) the page\'s CSS code. This is displayed after a user expands ' + + 'the section to see more. No character length limits.', + placeholders: { + link_start: { + content: '[', + }, + link_end: { + content: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', + }, + }, + }, }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); From fc762a5d5fe6c83831b5e3edfe141ec7d2dca964 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp Date: Mon, 3 Jun 2019 17:25:55 -0700 Subject: [PATCH 02/71] Basic placeholder syntax. --- .../audits/accessibility/document-title.js | 11 +++- .../audits/byte-efficiency/unminified-css.js | 6 +-- lighthouse-core/lib/i18n/en-US.json | 21 ++++++-- lighthouse-core/lib/i18n/i18n.js | 54 ++++++++++++++++++- .../scripts/i18n/collect-strings.js | 16 ++++-- 5 files changed, 93 insertions(+), 15 deletions(-) diff --git a/lighthouse-core/audits/accessibility/document-title.js b/lighthouse-core/audits/accessibility/document-title.js index 8dc37370a1d5..2c8bf99341e9 100644 --- a/lighthouse-core/audits/accessibility/document-title.js +++ b/lighthouse-core/audits/accessibility/document-title.js @@ -14,8 +14,15 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if the page has a element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required. */ - title: 'Document has a `<title>` element', + title: { + message: 'Document has a $html_title$ element', + description: 'Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.', + placeholders: { + html_title: { + content: '`<title-x>`', + }, + }, + }, /** Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: 'Document doesn\'t have a `<title>` element', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 644539ecf999..f3d0e48f0b58 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -14,11 +14,9 @@ const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ title: 'Minify CSS', /** Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: 'Minifying CSS files can reduce network payload sizes. ' + - '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', - titleObj: { + description: { message: 'Minifying CSS files can reduce network payload sizes.' + - ' $LINK_START$Learn More$LINK_END$', + ' $link_start$Learn More$link_end$', description: 'Description of a Lighthouse audit that tells the user *why* they should ' + 'minify (remove whitespace) the page\'s CSS code. This is displayed after a user expands ' + 'the section to see more. No character length limits.', diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index adfc34c8fa21..96122eeb68b9 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -180,8 +180,13 @@ "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "Document has a `<title>` element", - "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Document has a $html_title$ element", + "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "html_title": { + "content": "`<title-x>`" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse).", @@ -508,8 +513,16 @@ "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).", - "description": "Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More$link_end$", + "description": "Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits.", + "placeholders": { + "link_start": { + "content": "[" + }, + "link_end": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { "message": "Minify CSS", diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index b93423b4a83f..a0097bc455fe 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -164,6 +164,8 @@ function _preprocessMessageValues(icuMessage, values) { /** @type {Map<string, IcuMessageInstance[]>} */ const _icuMessageInstanceMap = new Map(); +const _icuMessageInstanceMap2 = new Map(); + /** * * @param {LH.Locale} locale @@ -174,7 +176,23 @@ const _icuMessageInstanceMap = new Map(); */ function _formatIcuMessage(locale, icuMessageId, icuMessage, values) { const localeMessages = LOCALES[locale]; - const localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; + let localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; + // lets try to replace some things :o + const placeholders = localeMessages[icuMessageId] && localeMessages[icuMessageId].placeholders; + if (placeholders) { + console.log('placeholders!'); + // do some regex + Object.entries(placeholders).forEach(entry => { + const key = entry[0]; + const value = entry[1]; + //use key and value here + let regexStr = `\$${key}\$`; + console.log(key, value, regexStr); + localeMessage = localeMessage.replace(regexStr, value.content); + console.log(localeMessage); + }); + } + // fallback to the original english message if we couldn't find a message in the specified locale // better to have an english message than no message at all, in some number cases it won't even matter const messageForMessageFormat = localeMessage || icuMessage; @@ -254,6 +272,40 @@ function createMessageInstanceIdFn(filename, fileStrings) { return getMessageInstanceIdFn; } +/** + * @param {string} filename + * @param {Record<string, string>} fileStrings + */ +function createMessageInstanceIdFn2(filename, fileStrings) { + + + /** @type {Record<string, string>} */ + const mergedStrings = {...UIStrings, ...fileStrings}; + + /** @param {string} icuMessage @param {*} [values] */ + const getMessageInstanceIdFn = (icuMessage, values) => { + const keyname = Object.keys(mergedStrings).find(key => mergedStrings[key] === icuMessage); + if (!keyname) throw new Error(`Could not locate: ${icuMessage}`); + + const filenameToLookup = keyname in fileStrings ? filename : __filename; + const unixStyleFilename = path.relative(LH_ROOT, filenameToLookup).replace(/\\/g, '/'); + const icuMessageId = `${unixStyleFilename} | ${keyname}`; + const icuMessageInstances = _icuMessageInstanceMap.get(icuMessageId) || []; + + let indexOfInstance = icuMessageInstances.findIndex(inst => isDeepEqual(inst.values, values)); + if (indexOfInstance === -1) { + icuMessageInstances.push({icuMessageId, icuMessage, values}); + indexOfInstance = icuMessageInstances.length - 1; + } + + _icuMessageInstanceMap.set(icuMessageId, icuMessageInstances); + + return `${icuMessageId} # ${indexOfInstance}`; + }; + + return getMessageInstanceIdFn; +} + /** * Returns true if string is an ICUMessage reference. * @param {string} icuMessageIdOrRawString diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index d266c8c72a21..a3ac4606f574 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -84,10 +84,18 @@ function collectAllStringsInDir(dir, strings = {}) { let lastPropertyEndIndex = 0; for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; - const message = exportVars.UIStrings[key]; - const description = computeDescription(ast, property, lastPropertyEndIndex); - strings[`${relativePath} | ${key}`] = {message, description}; - lastPropertyEndIndex = property.range[1]; + const val = exportVars.UIStrings[key]; + if (typeof val === 'string') { + const description = computeDescription(ast, property, lastPropertyEndIndex); + strings[`${relativePath} | ${key}`] = {message: val, description}; + lastPropertyEndIndex = property.range[1]; + } else { + const message = val.message; + const description = val.description; + const placeholders = val.placeholders; + strings[`${relativePath} | ${key}`] = {message, description, placeholders}; + lastPropertyEndIndex = property.range[1]; + } } } } From d1cdeabaea62c3de0bc5e4ec8096dd0aa8fb1dc6 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 3 Jun 2019 17:34:13 -0700 Subject: [PATCH 03/71] minor corrections --- .../audits/accessibility/document-title.js | 2 +- lighthouse-core/lib/i18n/en-US.json | 2 +- lighthouse-core/lib/i18n/i18n.js | 36 ------------------- 3 files changed, 2 insertions(+), 38 deletions(-) diff --git a/lighthouse-core/audits/accessibility/document-title.js b/lighthouse-core/audits/accessibility/document-title.js index 2c8bf99341e9..585b0581064a 100644 --- a/lighthouse-core/audits/accessibility/document-title.js +++ b/lighthouse-core/audits/accessibility/document-title.js @@ -19,7 +19,7 @@ const UIStrings = { description: 'Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.', placeholders: { html_title: { - content: '`<title-x>`', + content: '`<title>`', }, }, }, diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 96122eeb68b9..04ef7f47d9a7 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -184,7 +184,7 @@ "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.", "placeholders": { "html_title": { - "content": "`<title-x>`" + "content": "`<title>`" } } }, diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index a0097bc455fe..9b8e59f9ac7e 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -164,8 +164,6 @@ function _preprocessMessageValues(icuMessage, values) { /** @type {Map<string, IcuMessageInstance[]>} */ const _icuMessageInstanceMap = new Map(); -const _icuMessageInstanceMap2 = new Map(); - /** * * @param {LH.Locale} locale @@ -272,40 +270,6 @@ function createMessageInstanceIdFn(filename, fileStrings) { return getMessageInstanceIdFn; } -/** - * @param {string} filename - * @param {Record<string, string>} fileStrings - */ -function createMessageInstanceIdFn2(filename, fileStrings) { - - - /** @type {Record<string, string>} */ - const mergedStrings = {...UIStrings, ...fileStrings}; - - /** @param {string} icuMessage @param {*} [values] */ - const getMessageInstanceIdFn = (icuMessage, values) => { - const keyname = Object.keys(mergedStrings).find(key => mergedStrings[key] === icuMessage); - if (!keyname) throw new Error(`Could not locate: ${icuMessage}`); - - const filenameToLookup = keyname in fileStrings ? filename : __filename; - const unixStyleFilename = path.relative(LH_ROOT, filenameToLookup).replace(/\\/g, '/'); - const icuMessageId = `${unixStyleFilename} | ${keyname}`; - const icuMessageInstances = _icuMessageInstanceMap.get(icuMessageId) || []; - - let indexOfInstance = icuMessageInstances.findIndex(inst => isDeepEqual(inst.values, values)); - if (indexOfInstance === -1) { - icuMessageInstances.push({icuMessageId, icuMessage, values}); - indexOfInstance = icuMessageInstances.length - 1; - } - - _icuMessageInstanceMap.set(icuMessageId, icuMessageInstances); - - return `${icuMessageId} # ${indexOfInstance}`; - }; - - return getMessageInstanceIdFn; -} - /** * Returns true if string is an ICUMessage reference. * @param {string} icuMessageIdOrRawString From 74e11c15bf7c7149a5863ae85b0e3a8b1dcebea8 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 4 Jun 2019 11:41:51 -0700 Subject: [PATCH 04/71] iterating --- .../audits/accessibility/document-title.js | 19 ++++---- .../audits/byte-efficiency/unminified-css.js | 27 +++++------ lighthouse-core/lib/i18n/en-US.json | 30 +++++++----- lighthouse-core/lib/i18n/i18n.js | 8 ++-- lighthouse-core/lib/i18n/locales/de.json | 21 +++++++- .../scripts/i18n/collect-strings.js | 48 +++++++++++++++++-- 6 files changed, 108 insertions(+), 45 deletions(-) diff --git a/lighthouse-core/audits/accessibility/document-title.js b/lighthouse-core/audits/accessibility/document-title.js index 585b0581064a..c3ffce722fc6 100644 --- a/lighthouse-core/audits/accessibility/document-title.js +++ b/lighthouse-core/audits/accessibility/document-title.js @@ -14,15 +14,16 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - title: { - message: 'Document has a $html_title$ element', - description: 'Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.', - placeholders: { - html_title: { - content: '`<title>`', - }, - }, - }, + title: 'placeholder', + // title: { + // message: 'Document has a $html_title$ element', + // description: 'Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.', + // placeholders: { + // html_title: { + // content: '`<title>`', + // }, + // }, + // }, /** Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: 'Document doesn\'t have a `<title>` element', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index f3d0e48f0b58..280b85ad55aa 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -12,21 +12,20 @@ const computeTokenLength = require('../../lib/minification-estimator.js').comput const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ - title: 'Minify CSS', - /** Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + title: { + message: 'Minify CSS like {css}', + placeholders: { + css: '`<link rel=stylesheet>`', + }, + }, + /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: { - message: 'Minifying CSS files can reduce network payload sizes.' + - ' $link_start$Learn More$link_end$', - description: 'Description of a Lighthouse audit that tells the user *why* they should ' + - 'minify (remove whitespace) the page\'s CSS code. This is displayed after a user expands ' + - 'the section to see more. No character length limits.', + message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', placeholders: { - link_start: { - content: '[', - }, - link_end: { - content: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', - }, + link_start: '[->', + link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', + /** 520 (Placeholder examples go here) */ + milliseconds: '{timeInMs, number, milliseconds}', }, }, }; @@ -47,7 +46,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { return { id: 'unminified-css', title: str_(UIStrings.title), - description: str_(UIStrings.description), + description: str_(UIStrings.description, {timeInMs: 10}), scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL'], }; diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 04ef7f47d9a7..7c38a2406ae1 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -177,16 +177,11 @@ }, "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { "message": "Document doesn't have a `<title>` element", - "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "description": "title: {" }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "Document has a $html_title$ element", - "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "html_title": { - "content": "`<title>`" - } - } + "message": "placeholder", + "description": "" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse).", @@ -513,20 +508,29 @@ "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More$link_end$", - "description": "Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits.", + "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms.", + "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { "link_start": { - "content": "[" + "content": "[->" }, "link_end": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" + }, + "milliseconds": { + "content": "{timeInMs, number, milliseconds}", + "example": "520 (Placeholder examples go here)" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "Minify CSS", - "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates." + "message": "Minify CSS like $css$", + "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates.", + "placeholders": { + "css": { + "content": "`<link rel=stylesheet>`" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).", diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 9b8e59f9ac7e..107c0d4f4941 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -121,7 +121,7 @@ function lookupLocale(locale) { */ function _preprocessMessageValues(icuMessage, values) { if (!values) return; - + // console.log(icuMessage, values); const clonedValues = JSON.parse(JSON.stringify(values)); const parsed = MessageParser.parse(icuMessage); // Throw an error if a message's value isn't provided @@ -178,17 +178,17 @@ function _formatIcuMessage(locale, icuMessageId, icuMessage, values) { // lets try to replace some things :o const placeholders = localeMessages[icuMessageId] && localeMessages[icuMessageId].placeholders; if (placeholders) { - console.log('placeholders!'); // do some regex Object.entries(placeholders).forEach(entry => { const key = entry[0]; const value = entry[1]; //use key and value here let regexStr = `\$${key}\$`; - console.log(key, value, regexStr); + // console.log(key, value, regexStr); localeMessage = localeMessage.replace(regexStr, value.content); - console.log(localeMessage); + // console.log(localeMessage); }); + icuMessage = localeMessage; } // fallback to the original english message if we couldn't find a message in the specified locale diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index 47731ac6e12c..f5b2b38f02cf 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -369,10 +369,27 @@ "message": "Vermeidet sehr große Netzwerknutzlasten" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Durch die Komprimierung von CSS-Dateien kann die Größe von Netzwerknutzlasten reduziert werden. [Weitere Informationen](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." + "message": "Durch die Komprimierung von CSS-Dateien kann die Größe von Netzwerknutzlasten reduziert werden. $link_start$Weitere Informationen$link_end$. This audit took $milliseconds$ ms.", + "placeholders": { + "link_start": { + "content": "[->" + }, + "link_end": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" + }, + "milliseconds": { + "content": "{timeInMs, number, milliseconds}", + "example": "520" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "CSS komprimieren" + "message": "CSS komprimieren $css$", + "placeholders": { + "css": { + "content": "`<link rel=stylesheet>`" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Durch die Komprimierung von JavaScript-Dateien können Nutzlastgrößen und die Zeit zum Parsen von Skripts reduziert werden. [Weitere Informationen](https://developers.google.com/speed/docs/insights/MinifyResources)." diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index a3ac4606f574..10fe7437f529 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -90,9 +90,51 @@ function collectAllStringsInDir(dir, strings = {}) { strings[`${relativePath} | ${key}`] = {message: val, description}; lastPropertyEndIndex = property.range[1]; } else { - const message = val.message; - const description = val.description; - const placeholders = val.placeholders; + // console.log(property.value.properties[0].range[1]); + // console.log(property.value.properties[1].value.properties); + let message = val.message; + // const prevProp = property.value.properties[1].value.properties[1]; + // const thisProp = property.value.properties[1].value.properties[2]; + + const description = computeDescription(ast, property, lastPropertyEndIndex); + /** + * Transform: + * placeholders: { + * /** example val *\/ + * key: value, + * ... + * }, + * Into: + * placeholders: { + * key: { + * content: value, + * example: example val, + * }, + * ... + * } + */ + // init last prop to the 'messages' end range + let lastPropEndIndex = property.value.properties[0].range[1]; + let idx = 0; + const placeholdersMini = val.placeholders; + const placeholders = {}; + Object.entries(placeholdersMini).forEach(entry => { + const key = entry[0]; + const value = entry[1]; + const thisProp = property.value.properties[1].value.properties[idx]; + const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); + placeholders[key] = { + content: value, + }; + if (thisDesc) { + placeholders[key].example = thisDesc; + } + + // replace {.*} with $.*$ + message = message.replace(`{${key}}`, `\$${key}\$`); + idx++; + lastPropEndIndex = thisProp.range[1]; + }); strings[`${relativePath} | ${key}`] = {message, description, placeholders}; lastPropertyEndIndex = property.range[1]; } From 981e02857b5d13af62380c0164690bb0806fa1fe Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 4 Jun 2019 11:59:42 -0700 Subject: [PATCH 05/71] Added ICU plural and ICU select examples. --- .../audits/byte-efficiency/unminified-css.js | 11 ++++++++++- lighthouse-core/lib/i18n/en-US.json | 8 ++++++++ lighthouse-core/lib/i18n/locales/de.json | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 280b85ad55aa..12d935ee4946 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -28,6 +28,15 @@ const UIStrings = { milliseconds: '{timeInMs, number, milliseconds}', }, }, + /** [ICU Syntax] Some plural warning... */ + warningPlural: '{itemCount, plural, ' + + '=1 {# error found}' + + 'other {# errors found}}', + /** [ICU Syntax] Some gendered (ICU select) explanation... */ + explanationGender: '{person, select, ' + + 'female {She minified this CSS.} ' + + 'male {He minified this CSS.} ' + + 'other {They minified this CSS.}}', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -121,7 +130,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)}, ]; - return {items, headings}; + return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; } } diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 7c38a2406ae1..83f5966f7d3e 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -523,6 +523,10 @@ } } }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { + "message": "{person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "description": "[ICU Syntax] Some gendered (ICU select) explanation..." + }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { "message": "Minify CSS like $css$", "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates.", @@ -532,6 +536,10 @@ } } }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { + "message": "{itemCount, plural, =1 {# error found}other {# errors found}}", + "description": "[ICU Syntax] Some plural warning..." + }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).", "description": "Description of a Lighthouse audit that tells the user *why* they should minify the page’s JS code to reduce file size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index f5b2b38f02cf..ff09d64b681a 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -391,6 +391,14 @@ } } }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { + "message": "{person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", + "description": "" + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { + "message": "{itemCount, plural, =1 {<GERMAN> # error found}other {<GERMAN> # errors found}}", + "description": "" + }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Durch die Komprimierung von JavaScript-Dateien können Nutzlastgrößen und die Zeit zum Parsen von Skripts reduziert werden. [Weitere Informationen](https://developers.google.com/speed/docs/insights/MinifyResources)." }, From 6d2dd5d3fa4f66fed4d3d5d05283790d0c938fc4 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 4 Jun 2019 12:09:27 -0700 Subject: [PATCH 06/71] Gender example has replacement AND ICU. --- .../audits/byte-efficiency/unminified-css.js | 10 ++++++++-- lighthouse-core/lib/i18n/en-US.json | 10 ++++++++-- lighthouse-core/lib/i18n/locales/de.json | 9 +++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 12d935ee4946..2dec63ff0a43 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -33,10 +33,16 @@ const UIStrings = { '=1 {# error found}' + 'other {# errors found}}', /** [ICU Syntax] Some gendered (ICU select) explanation... */ - explanationGender: '{person, select, ' + + explanationGender: { + message: 'Someone minified this, {name}. {person, select, ' + 'female {She minified this CSS.} ' + 'male {He minified this CSS.} ' + 'other {They minified this CSS.}}', + placeholders: { + /** Ouch this syntax kind of sucks, {name} then {name} stutters. But example: Karen. */ + name: '{name}', + }, + } }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -130,7 +136,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)}, ]; - return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; + return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female', name: 'Kim'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; } } diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 83f5966f7d3e..977eb05e12fd 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -524,8 +524,14 @@ } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "{person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", - "description": "[ICU Syntax] Some gendered (ICU select) explanation..." + "message": "Someone minified this, $name$. {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "description": "[ICU Syntax] Some gendered (ICU select) explanation...", + "placeholders": { + "name": { + "content": "{name}", + "example": "Ouch this syntax kind of sucks. But example: Karen." + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { "message": "Minify CSS like $css$", diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index ff09d64b681a..fd7d6118638a 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -392,8 +392,13 @@ } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "{person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", - "description": "" + "message": "<GERMAN> Someone minified this, $name$. {person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", + "description": "", + "placeholders": { + "name": { + "content": "{name}" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { "message": "{itemCount, plural, =1 {<GERMAN> # error found}other {<GERMAN> # errors found}}", From f22ee1bbdc89b921065b41bfd9e37e825473e202 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 4 Jun 2019 12:17:54 -0700 Subject: [PATCH 07/71] less stutter syntax --- .../audits/byte-efficiency/unminified-css.js | 21 ++++++++++++++---- lighthouse-core/lib/i18n/en-US.json | 18 +++++++++++++-- lighthouse-core/lib/i18n/locales/de.json | 22 ++++++++++++++----- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 2dec63ff0a43..52ad2b6bbcba 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -34,15 +34,28 @@ const UIStrings = { 'other {# errors found}}', /** [ICU Syntax] Some gendered (ICU select) explanation... */ explanationGender: { - message: 'Someone minified this, {name}. {person, select, ' + + message: 'Someone minified this, {direct_replace_name}. {static_replacement} {person, select, ' + 'female {She minified this CSS.} ' + 'male {He minified this CSS.} ' + 'other {They minified this CSS.}}', placeholders: { - /** Ouch this syntax kind of sucks, {name} then {name} stutters. But example: Karen. */ + /** Some static replacement. */ + static_replacement: '`<link rel=>`', + }, + }, + /** [ICU Syntax] Some gendered (ICU select) explanation... */ + explanationGender2: { + message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + + 'female {She minified this CSS.} ' + + 'male {He minified this CSS.} ' + + 'other {They minified this CSS.}}', + placeholders: { + /** Some static replacement. */ + static_replacement: '`<link rel=>`', + /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ name: '{name}', }, - } + }, }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -136,7 +149,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)}, ]; - return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female', name: 'Kim'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; + return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female', direct_replace_name: 'Kim'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; } } diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 977eb05e12fd..a0e7e8215279 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -524,12 +524,26 @@ } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Someone minified this, $name$. {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "message": "Someone minified this, {direct_replace_name}. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", "description": "[ICU Syntax] Some gendered (ICU select) explanation...", "placeholders": { + "static_replacement": { + "content": "`<link rel=>`", + "example": "Some static replacement." + } + } + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { + "message": "Someone minified this, $name$. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "description": "[ICU Syntax] Some gendered (ICU select) explanation...", + "placeholders": { + "static_replacement": { + "content": "`<link rel=>`", + "example": "Some static replacement." + }, "name": { "content": "{name}", - "example": "Ouch this syntax kind of sucks. But example: Karen." + "example": "This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen." } } }, diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index fd7d6118638a..af886f9bb1fc 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -392,17 +392,29 @@ } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "<GERMAN> Someone minified this, $name$. {person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", - "description": "", + "message": "<GERMAN> Someone minified this, {direct_replace_name}. $static_replacement$ {person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", "placeholders": { + "static_replacement": { + "content": "`<link rel=>`", + "example": "Some static replacement." + } + } + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { + "message": "Someone minified this, $name$. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "placeholders": { + "static_replacement": { + "content": "`<link rel=>`", + "example": "Some static replacement." + }, "name": { - "content": "{name}" + "content": "{name}", + "example": "This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen." } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {<GERMAN> # error found}other {<GERMAN> # errors found}}", - "description": "" + "message": "{itemCount, plural, =1 {<GERMAN> # error found}other {<GERMAN> # errors found}}" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Durch die Komprimierung von JavaScript-Dateien können Nutzlastgrößen und die Zeit zum Parsen von Skripts reduziert werden. [Weitere Informationen](https://developers.google.com/speed/docs/insights/MinifyResources)." From c66c0c6453559d98f40b1f2016e8f03a9e8b12ec Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 4 Jun 2019 13:41:41 -0700 Subject: [PATCH 08/71] docs --- lighthouse-core/lib/i18n/README.md | 122 +++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lighthouse-core/lib/i18n/README.md diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md new file mode 100644 index 000000000000..b5a0ba8ddf46 --- /dev/null +++ b/lighthouse-core/lib/i18n/README.md @@ -0,0 +1,122 @@ +# UIStrings Syntax + +## ICU Syntax + +### Ordinals + +### Selects (Gender) + +### Primitive Formatting + +This include number formatting like `{timeInMs, number, milliseconds}` and string replacements like `{some_name}`. + +## message.json Syntax + +### Why we use message.json + +It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for i18n messages. + +### Parts of a message.json message + +(From the Chrome Docs) + +```json +{ + "name": { + "message": "Message text, with optional placeholders.", + "description": "Translator-aimed description of the message.", + "placeholders": { + "placeholder_name": { + "content": "A string to be placed within the message.", + "example": "Translator-aimed example of the placeholder string." + }, + ... + } + }, + ... +} +``` + +## Our message system + +We use UIStrings & i18n.js to extract strings from individual js files into locale.json files. This allows us to keep strings close +to the code in which they are used so that developers can easily understand their context. It also comes with its own syntax. + +UIStrings can be defined in 1 of 2 ways: +* simple strings (no placeholders): + ```Javascript + /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ + title: 'Minify CSS', + ``` +* nested objects (needs placeholders): + ```Javascript + /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ + title: { + message: 'Minify CSS like {css}', + placeholders: { + css: '`<link rel=stylesheet>`', + }, + }, + ``` +TODO(exterkamp): explain all the comments and where they go/what they become. + +TODO(exterkamp): explain why we can't use some ICU like number formatting. + +### The pipeline + +file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> $placeholder$'s replaced -> {ICU} syntax replaced => final string + +TODO(exterkamp): Simple example + +Complex example: + +1. string in `file_with_UIStrings.js` + ```Javascript + /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + description: { + message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', + placeholders: { + link_start: '[->', + link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', + /** 520 (Placeholder examples go here) */ + milliseconds: '{timeInMs, number, milliseconds}', + }, + }, + ``` + +2. string when exported to locale.json file (en-US) + ```json + "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { + "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms.", + "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "link_start": { + "content": "[->" + }, + "link_end": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" + }, + "milliseconds": { + "content": "{timeInMs, number, milliseconds}", + "example": "520 (Placeholder examples go here)" + } + } + }, + ``` + +3. string when read by i18n.js (initially) + ```Javascript + message = "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms." + sent_values = {timeInMs: 10} + ``` + +4. string when placeholders replaced (with the static content) + ```Javascript + message = "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." + sent_values = {timeInMs: 10} + ``` + +5. string when ICU syntax has been replaced (with the sent_values) + ```Javascript + message = "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took 10 ms." + ``` From 70a5a070995e84ec14a0d4622bcd953b09591e13 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 12 Jun 2019 16:18:29 -0400 Subject: [PATCH 09/71] Updated README. --- lighthouse-core/lib/i18n/README.md | 45 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index b5a0ba8ddf46..f799a5d9aeb8 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -30,10 +30,8 @@ It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-message "content": "A string to be placed within the message.", "example": "Translator-aimed example of the placeholder string." }, - ... } - }, - ... + } } ``` @@ -74,12 +72,12 @@ Complex example: ```Javascript /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: { - message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', + message: 'Minifying CSS files can reduce network payload sizes. {LINK_START}Learn More!!!{LINK_START}. This audit took {MILLISECONDS} ms.', placeholders: { - link_start: '[->', - link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', + LINK_START: '[', + LINK_START: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', /** 520 (Placeholder examples go here) */ - milliseconds: '{timeInMs, number, milliseconds}', + MILLISECONDS: '{timeInMs, number, milliseconds}', }, }, ``` @@ -87,36 +85,53 @@ Complex example: 2. string when exported to locale.json file (en-US) ```json "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms.", + "message": "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_START$. This audit took $MILLISECONDS$ ms.", "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { - "link_start": { - "content": "[->" + "LINK_START": { + "content": "[" }, - "link_end": { + "LINK_START": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" }, - "milliseconds": { + "MILLISECONDS": { "content": "{timeInMs, number, milliseconds}", "example": "520 (Placeholder examples go here)" } } }, ``` + 1. string when exported back from translators locale.json file (everything but en-US) + ```json + "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { + "message": "La réduction des fichiers CSS peut réduire la taille des charges utiles de réseau. $LINK_START$En savoir plus$LINK_START$. Cet audit a pris $MILLISECONDS ms", + "placeholders": { + "LINK_START": { + "content": "[" + }, + "LINK_START": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" + }, + "MILLISECONDS": { + "content": "{timeInMs, number, milliseconds}", + } + } + }, + ``` 3. string when read by i18n.js (initially) ```Javascript - message = "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms." + message = "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_END$. This audit took $MILLISECONDS$ ms." sent_values = {timeInMs: 10} ``` 4. string when placeholders replaced (with the static content) ```Javascript - message = "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." + message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." sent_values = {timeInMs: 10} ``` 5. string when ICU syntax has been replaced (with the sent_values) ```Javascript - message = "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took 10 ms." + message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took 10 ms." ``` From a7fc83a5e2450d914810d0a95798e764e53dd97c Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 2 Jul 2019 23:59:56 -0700 Subject: [PATCH 10/71] correct-strings --- lighthouse-core/lib/i18n/locales/en-US.json | 1139 +++++++++++++++++ .../lib/i18n/{ => pre-locale}/en-US.json | 0 .../scripts/i18n/collect-strings.js | 2 +- .../scripts/i18n/correct-strings.js | 202 +++ package.json | 1 + 5 files changed, 1343 insertions(+), 1 deletion(-) create mode 100644 lighthouse-core/lib/i18n/locales/en-US.json rename lighthouse-core/lib/i18n/{ => pre-locale}/en-US.json (100%) create mode 100644 lighthouse-core/scripts/i18n/correct-strings.js diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json new file mode 100644 index 000000000000..c16bdf398b3d --- /dev/null +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -0,0 +1,1139 @@ +{ + "lighthouse-core/audits/accessibility/accesskeys.js | description": { + "message": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { + "message": "`[accesskey]` values are not unique" + }, + "lighthouse-core/audits/accessibility/accesskeys.js | title": { + "message": "`[accesskey]` values are unique" + }, + "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { + "message": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { + "message": "`[aria-*]` attributes do not match their roles" + }, + "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { + "message": "`[aria-*]` attributes match their roles" + }, + "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { + "message": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { + "message": "`[role]`s do not have all required `[aria-*]` attributes" + }, + "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { + "message": "`[role]`s have all required `[aria-*]` attributes" + }, + "lighthouse-core/audits/accessibility/aria-required-children.js | description": { + "message": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { + "message": "Elements with `[role]` that require specific children `[role]`s, are missing." + }, + "lighthouse-core/audits/accessibility/aria-required-children.js | title": { + "message": "Elements with `[role]` that require specific children `[role]`s, are present" + }, + "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { + "message": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { + "message": "`[role]`s are not contained by their required parent element" + }, + "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { + "message": "`[role]`s are contained by their required parent element" + }, + "lighthouse-core/audits/accessibility/aria-roles.js | description": { + "message": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { + "message": "`[role]` values are not valid" + }, + "lighthouse-core/audits/accessibility/aria-roles.js | title": { + "message": "`[role]` values are valid" + }, + "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { + "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { + "message": "`[aria-*]` attributes do not have valid values" + }, + "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { + "message": "`[aria-*]` attributes have valid values" + }, + "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { + "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { + "message": "`[aria-*]` attributes are not valid or misspelled" + }, + "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { + "message": "`[aria-*]` attributes are valid and not misspelled" + }, + "lighthouse-core/audits/accessibility/audio-caption.js | description": { + "message": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. [Learn more](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { + "message": "`<audio>` elements are missing a `<track>` element with `[kind=\"captions\"]`." + }, + "lighthouse-core/audits/accessibility/audio-caption.js | title": { + "message": "`<audio>` elements contain a `<track>` element with `[kind=\"captions\"]`" + }, + "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { + "message": "Failing Elements" + }, + "lighthouse-core/audits/accessibility/button-name.js | description": { + "message": "When a button doesn't have an accessible name, screen readers announce it as \"button\", making it unusable for users who rely on screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { + "message": "Buttons do not have an accessible name" + }, + "lighthouse-core/audits/accessibility/button-name.js | title": { + "message": "Buttons have an accessible name" + }, + "lighthouse-core/audits/accessibility/bypass.js | description": { + "message": "Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. [Learn more](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { + "message": "The page does not contain a heading, skip link, or landmark region" + }, + "lighthouse-core/audits/accessibility/bypass.js | title": { + "message": "The page contains a heading, skip link, or landmark region" + }, + "lighthouse-core/audits/accessibility/color-contrast.js | description": { + "message": "Low-contrast text is difficult or impossible for many users to read. [Learn more](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { + "message": "Background and foreground colors do not have a sufficient contrast ratio." + }, + "lighthouse-core/audits/accessibility/color-contrast.js | title": { + "message": "Background and foreground colors have a sufficient contrast ratio" + }, + "lighthouse-core/audits/accessibility/definition-list.js | description": { + "message": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. [Learn more](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { + "message": "`<dl>`'s do not contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements." + }, + "lighthouse-core/audits/accessibility/definition-list.js | title": { + "message": "`<dl>`'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements." + }, + "lighthouse-core/audits/accessibility/dlitem.js | description": { + "message": "Definition list items (`<dt>` and `<dd>`) must be wrapped in a parent `<dl>` element to ensure that screen readers can properly announce them. [Learn more](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { + "message": "Definition list items are not wrapped in `<dl>` elements" + }, + "lighthouse-core/audits/accessibility/dlitem.js | title": { + "message": "Definition list items are wrapped in `<dl>` elements" + }, + "lighthouse-core/audits/accessibility/document-title.js | description": { + "message": "The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/title)." + }, + "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { + "message": "Document doesn't have a `<title>` element" + }, + "lighthouse-core/audits/accessibility/document-title.js | title": { + "message": "placeholder" + }, + "lighthouse-core/audits/accessibility/duplicate-id.js | description": { + "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { + "message": "`[id]` attributes on the page are not unique" + }, + "lighthouse-core/audits/accessibility/duplicate-id.js | title": { + "message": "`[id]` attributes on the page are unique" + }, + "lighthouse-core/audits/accessibility/frame-title.js | description": { + "message": "Screen reader users rely on frame titles to describe the contents of frames. [Learn more](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { + "message": "`<frame>` or `<iframe>` elements do not have a title" + }, + "lighthouse-core/audits/accessibility/frame-title.js | title": { + "message": "`<frame>` or `<iframe>` elements have a title" + }, + "lighthouse-core/audits/accessibility/html-has-lang.js | description": { + "message": "If a page doesn't specify a lang attribute, a screen reader assumes that the page is in the default language that the user chose when setting up the screen reader. If the page isn't actually in the default language, then the screen reader might not announce the page's text correctly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { + "message": "`<html>` element does not have a `[lang]` attribute" + }, + "lighthouse-core/audits/accessibility/html-has-lang.js | title": { + "message": "`<html>` element has a `[lang]` attribute" + }, + "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { + "message": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) helps screen readers announce text properly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { + "message": "`<html>` element does not have a valid value for its `[lang]` attribute." + }, + "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { + "message": "`<html>` element has a valid value for its `[lang]` attribute" + }, + "lighthouse-core/audits/accessibility/image-alt.js | description": { + "message": "Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. [Learn more](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { + "message": "Image elements do not have `[alt]` attributes" + }, + "lighthouse-core/audits/accessibility/image-alt.js | title": { + "message": "Image elements have `[alt]` attributes" + }, + "lighthouse-core/audits/accessibility/input-image-alt.js | description": { + "message": "When an image is being used as an `<input>` button, providing alternative text can help screen reader users understand the purpose of the button. [Learn more](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { + "message": "`<input type=\"image\">` elements do not have `[alt]` text" + }, + "lighthouse-core/audits/accessibility/input-image-alt.js | title": { + "message": "`<input type=\"image\">` elements have `[alt]` text" + }, + "lighthouse-core/audits/accessibility/label.js | description": { + "message": "Labels ensure that form controls are announced properly by assistive technologies, like screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/label.js | failureTitle": { + "message": "Form elements do not have associated labels" + }, + "lighthouse-core/audits/accessibility/label.js | title": { + "message": "Form elements have associated labels" + }, + "lighthouse-core/audits/accessibility/layout-table.js | description": { + "message": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { + "message": "Presentational `<table>` elements do not avoid using `<th>`, `<caption>` or the `[summary]` attribute." + }, + "lighthouse-core/audits/accessibility/layout-table.js | title": { + "message": "Presentational `<table>` elements avoid using `<th>`, `<caption>` or the `[summary]` attribute." + }, + "lighthouse-core/audits/accessibility/link-name.js | description": { + "message": "Link text (and alternate text for images, when used as links) that is discernible, unique, and focusable improves the navigation experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { + "message": "Links do not have a discernible name" + }, + "lighthouse-core/audits/accessibility/link-name.js | title": { + "message": "Links have a discernible name" + }, + "lighthouse-core/audits/accessibility/list.js | description": { + "message": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. [Learn more](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/list.js | failureTitle": { + "message": "Lists do not contain only `<li>` elements and script supporting elements (`<script>` and `<template>`)." + }, + "lighthouse-core/audits/accessibility/list.js | title": { + "message": "Lists contain only `<li>` elements and script supporting elements (`<script>` and `<template>`)." + }, + "lighthouse-core/audits/accessibility/listitem.js | description": { + "message": "Screen readers require list items (`<li>`) to be contained within a parent `<ul>` or `<ol>` to be announced properly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { + "message": "List items (`<li>`) are not contained within `<ul>` or `<ol>` parent elements." + }, + "lighthouse-core/audits/accessibility/listitem.js | title": { + "message": "List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements" + }, + "lighthouse-core/audits/accessibility/meta-refresh.js | description": { + "message": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. [Learn more](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { + "message": "The document uses `<meta http-equiv=\"refresh\">`" + }, + "lighthouse-core/audits/accessibility/meta-refresh.js | title": { + "message": "The document does not use `<meta http-equiv=\"refresh\">`" + }, + "lighthouse-core/audits/accessibility/meta-viewport.js | description": { + "message": "Disabling zooming is problematic for users with low vision who rely on screen magnification to properly see the contents of a web page. [Learn more](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { + "message": "`[user-scalable=\"no\"]` is used in the `<meta name=\"viewport\">` element or the `[maximum-scale]` attribute is less than 5." + }, + "lighthouse-core/audits/accessibility/meta-viewport.js | title": { + "message": "`[user-scalable=\"no\"]` is not used in the `<meta name=\"viewport\">` element and the `[maximum-scale]` attribute is not less than 5." + }, + "lighthouse-core/audits/accessibility/object-alt.js | description": { + "message": "Screen readers cannot translate non-text content. Adding alt text to `<object>` elements helps screen readers convey meaning to users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { + "message": "`<object>` elements do not have `[alt]` text" + }, + "lighthouse-core/audits/accessibility/object-alt.js | title": { + "message": "`<object>` elements have `[alt]` text" + }, + "lighthouse-core/audits/accessibility/tabindex.js | description": { + "message": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { + "message": "Some elements have a `[tabindex]` value greater than 0" + }, + "lighthouse-core/audits/accessibility/tabindex.js | title": { + "message": "No element has a `[tabindex]` value greater than 0" + }, + "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { + "message": "Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { + "message": "Cells in a `<table>` element that use the `[headers]` attribute refers to other cells of that same table." + }, + "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { + "message": "Cells in a `<table>` element that use the `[headers]` attribute only refer to other cells of that same table." + }, + "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { + "message": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { + "message": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` do not have data cells they describe." + }, + "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { + "message": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` have data cells they describe." + }, + "lighthouse-core/audits/accessibility/valid-lang.js | description": { + "message": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) on elements helps ensure that text is pronounced correctly by a screen reader. [Learn more](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { + "message": "`[lang]` attributes do not have a valid value" + }, + "lighthouse-core/audits/accessibility/valid-lang.js | title": { + "message": "`[lang]` attributes have a valid value" + }, + "lighthouse-core/audits/accessibility/video-caption.js | description": { + "message": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. [Learn more](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { + "message": "`<video>` elements do not contain a `<track>` element with `[kind=\"captions\"]`." + }, + "lighthouse-core/audits/accessibility/video-caption.js | title": { + "message": "`<video>` elements contain a `<track>` element with `[kind=\"captions\"]`" + }, + "lighthouse-core/audits/accessibility/video-description.js | description": { + "message": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. [Learn more](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)." + }, + "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { + "message": "`<video>` elements do not contain a `<track>` element with `[kind=\"description\"]`." + }, + "lighthouse-core/audits/accessibility/video-description.js | title": { + "message": "`<video>` elements contain a `<track>` element with `[kind=\"description\"]`" + }, + "lighthouse-core/audits/apple-touch-icon.js | description": { + "message": "For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG. [Learn More](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)." + }, + "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { + "message": "Does not provide a valid `apple-touch-icon`" + }, + "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { + "message": "`apple-touch-icon-precomposed` is out of date; `apple-touch-icon` is preferred." + }, + "lighthouse-core/audits/apple-touch-icon.js | title": { + "message": "Provides a valid `apple-touch-icon`" + }, + "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { + "message": "Chrome extensions negatively affected this page's load performance. Try auditing the page in incognito mode or from a Chrome profile without extensions." + }, + "lighthouse-core/audits/bootup-time.js | columnScriptEval": { + "message": "Script Evaluation" + }, + "lighthouse-core/audits/bootup-time.js | columnScriptParse": { + "message": "Script Parse" + }, + "lighthouse-core/audits/bootup-time.js | columnTotal": { + "message": "Total CPU Time" + }, + "lighthouse-core/audits/bootup-time.js | description": { + "message": "Consider reducing the time spent parsing, compiling, and executing JS. You may find delivering smaller JS payloads helps with this. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/bootup)." + }, + "lighthouse-core/audits/bootup-time.js | failureTitle": { + "message": "Reduce JavaScript execution time" + }, + "lighthouse-core/audits/bootup-time.js | title": { + "message": "JavaScript execution time" + }, + "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { + "message": "Large GIFs are inefficient for delivering animated content. Consider using MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save network bytes. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" + }, + "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { + "message": "Use video formats for animated content" + }, + "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { + "message": "Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)." + }, + "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { + "message": "Defer offscreen images" + }, + "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { + "message": "Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)." + }, + "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { + "message": "Eliminate render-blocking resources" + }, + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { + "message": "Large network payloads cost users real money and are highly correlated with long load times. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)." + }, + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { + "message": "Total size was {totalBytes, number, bytes} KB" + }, + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | failureTitle": { + "message": "Avoid enormous network payloads" + }, + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | title": { + "message": "Avoids enormous network payloads" + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { + "message": "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { + "message": "Someone minified this, {direct_replace_name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { + "message": "Someone minified this, {name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { + "message": "Minify CSS like `<link rel=stylesheet>`" + }, + "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { + "message": "{itemCount, plural, =1 {# error found}other {# errors found}}" + }, + "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { + "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources)." + }, + "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { + "message": "Minify JavaScript" + }, + "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { + "message": "Remove dead rules from stylesheets and defer the loading of CSS not used for above-the-fold content to reduce unnecessary bytes consumed by network activity. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/unused-css)." + }, + "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { + "message": "Remove unused CSS" + }, + "lighthouse-core/audits/byte-efficiency/unused-javascript.js | description": { + "message": "Remove unused JavaScript to reduce bytes consumed by network activity." + }, + "lighthouse-core/audits/byte-efficiency/unused-javascript.js | title": { + "message": "Remove unused JavaScript" + }, + "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { + "message": "A long cache lifetime can speed up repeat visits to your page. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)." + }, + "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { + "message": "{itemCount, plural,\n =1 {1 resource found}\n other {# resources found}\n }" + }, + "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | failureTitle": { + "message": "Serve static assets with an efficient cache policy" + }, + "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | title": { + "message": "Uses efficient cache policy on static assets" + }, + "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { + "message": "Optimized images load faster and consume less cellular data. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)." + }, + "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { + "message": "Efficiently encode images" + }, + "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { + "message": "Serve images that are appropriately-sized to save cellular data and improve load time. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)." + }, + "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { + "message": "Properly size images" + }, + "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { + "message": "Text-based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/text-compression)." + }, + "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { + "message": "Enable text compression" + }, + "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { + "message": "Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/webp)." + }, + "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { + "message": "Serve images in next-gen formats" + }, + "lighthouse-core/audits/critical-request-chains.js | description": { + "message": "The Critical Request Chains below show you what resources are loaded with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)." + }, + "lighthouse-core/audits/critical-request-chains.js | displayValue": { + "message": "{itemCount, plural,\n =1 {1 chain found}\n other {# chains found}\n }" + }, + "lighthouse-core/audits/critical-request-chains.js | title": { + "message": "Minimize Critical Requests Depth" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | columnElement": { + "message": "Element" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | columnStatistic": { + "message": "Statistic" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | columnValue": { + "message": "Value" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | description": { + "message": "Browser engineers recommend pages contain fewer than ~1,500 DOM elements. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer [style calculations](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations), and produce costly [layout reflows](https://developers.google.com/speed/articles/reflow). [Learn more](https://developers.google.com/web/tools/lighthouse/audits/dom-size)." + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { + "message": "{itemCount, plural,\n =1 {1 element}\n other {# elements}\n }" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | failureTitle": { + "message": "Avoid an excessive DOM size" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMDepth": { + "message": "Maximum DOM Depth" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMElements": { + "message": "Total DOM Elements" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMWidth": { + "message": "Maximum Child Elements" + }, + "lighthouse-core/audits/dobetterweb/dom-size.js | title": { + "message": "Avoids an excessive DOM size" + }, + "lighthouse-core/audits/font-display.js | description": { + "message": "Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading. [Learn more](https://developers.google.com/web/updates/2016/02/font-display)." + }, + "lighthouse-core/audits/font-display.js | failureTitle": { + "message": "Ensure text remains visible during webfont load" + }, + "lighthouse-core/audits/font-display.js | title": { + "message": "All text remains visible during webfont loads" + }, + "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { + "message": "A fast page load over a cellular network ensures a good mobile user experience. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)." + }, + "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { + "message": "Interactive at {timeInMs, number, seconds} s" + }, + "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueTextWithOverride": { + "message": "Interactive on simulated mobile network at {timeInMs, number, seconds} s" + }, + "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": { + "message": "Page load is not fast enough on mobile networks" + }, + "lighthouse-core/audits/load-fast-enough-for-pwa.js | title": { + "message": "Page load is fast enough on mobile networks" + }, + "lighthouse-core/audits/mainthread-work-breakdown.js | columnCategory": { + "message": "Category" + }, + "lighthouse-core/audits/mainthread-work-breakdown.js | description": { + "message": "Consider reducing the time spent parsing, compiling and executing JS. You may find delivering smaller JS payloads helps with this." + }, + "lighthouse-core/audits/mainthread-work-breakdown.js | failureTitle": { + "message": "Minimize main-thread work" + }, + "lighthouse-core/audits/mainthread-work-breakdown.js | title": { + "message": "Minimizes main-thread work" + }, + "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { + "message": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)." + }, + "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { + "message": "Estimated Input Latency" + }, + "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { + "message": "First Contentful Paint marks the time at which the first text or image is painted. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)." + }, + "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { + "message": "First Contentful Paint" + }, + "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { + "message": "First CPU Idle marks the first time at which the page's main thread is quiet enough to handle input. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)." + }, + "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { + "message": "First CPU Idle" + }, + "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { + "message": "First Meaningful Paint measures when the primary content of a page is visible. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)." + }, + "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { + "message": "First Meaningful Paint" + }, + "lighthouse-core/audits/metrics/interactive.js | description": { + "message": "Time to interactive is the amount of time it takes for the page to become fully interactive. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)." + }, + "lighthouse-core/audits/metrics/interactive.js | title": { + "message": "Time to Interactive" + }, + "lighthouse-core/audits/metrics/max-potential-fid.js | description": { + "message": "The maximum potential First Input Delay that your users could experience is the duration, in milliseconds, of the longest task. [Learn more](https://developers.google.com/web/updates/2018/05/first-input-delay)." + }, + "lighthouse-core/audits/metrics/max-potential-fid.js | title": { + "message": "Max Potential First Input Delay" + }, + "lighthouse-core/audits/metrics/speed-index.js | description": { + "message": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/speed-index)." + }, + "lighthouse-core/audits/metrics/speed-index.js | title": { + "message": "Speed Index" + }, + "lighthouse-core/audits/network-rtt.js | description": { + "message": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. [Learn more](https://hpbn.co/primer-on-latency-and-bandwidth/)." + }, + "lighthouse-core/audits/network-rtt.js | title": { + "message": "Network Round Trip Times" + }, + "lighthouse-core/audits/network-server-latency.js | description": { + "message": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. [Learn more](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)." + }, + "lighthouse-core/audits/network-server-latency.js | title": { + "message": "Server Backend Latencies" + }, + "lighthouse-core/audits/performance-budget.js | description": { + "message": "Keep the quantity and size of network requests under the targets set by the provided performance budget. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets)." + }, + "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { + "message": "{count, plural,\n =1 {1 request}\n other {# requests}\n }" + }, + "lighthouse-core/audits/performance-budget.js | title": { + "message": "Performance budget" + }, + "lighthouse-core/audits/redirects.js | description": { + "message": "Redirects introduce additional delays before the page can be loaded. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/redirects)." + }, + "lighthouse-core/audits/redirects.js | title": { + "message": "Avoid multiple page redirects" + }, + "lighthouse-core/audits/resource-summary.js | description": { + "message": "To set budgets for the quantity and size of page resources, add a budget.json file. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets)." + }, + "lighthouse-core/audits/resource-summary.js | displayValue": { + "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB" + }, + "lighthouse-core/audits/resource-summary.js | title": { + "message": "Keep request counts low and transfer sizes small" + }, + "lighthouse-core/audits/seo/canonical.js | description": { + "message": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical)." + }, + "lighthouse-core/audits/seo/canonical.js | explanationConflict": { + "message": "Multiple conflicting URLs ({urlList})" + }, + "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain": { + "message": "Points to a different domain ({url})" + }, + "lighthouse-core/audits/seo/canonical.js | explanationInvalid": { + "message": "Invalid URL ({url})" + }, + "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { + "message": "Points to another `hreflang` location ({url})" + }, + "lighthouse-core/audits/seo/canonical.js | explanationRelative": { + "message": "Relative URL ({url})" + }, + "lighthouse-core/audits/seo/canonical.js | explanationRoot": { + "message": "Points to the domain's root URL (the homepage), instead of an equivalent page of content" + }, + "lighthouse-core/audits/seo/canonical.js | failureTitle": { + "message": "Document does not have a valid `rel=canonical`" + }, + "lighthouse-core/audits/seo/canonical.js | title": { + "message": "Document has a valid `rel=canonical`" + }, + "lighthouse-core/audits/seo/font-size.js | description": { + "message": "Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)." + }, + "lighthouse-core/audits/seo/font-size.js | displayValue": { + "message": "{decimalProportion, number, extendedPercent} legible text" + }, + "lighthouse-core/audits/seo/font-size.js | explanation": { + "message": "{decimalProportion, number, extendedPercent} of text is too small." + }, + "lighthouse-core/audits/seo/font-size.js | explanationViewport": { + "message": "Text is illegible because there's no viewport meta tag optimized for mobile screens." + }, + "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": { + "message": "{decimalProportion, number, extendedPercent} of text is too small (based on {decimalProportionVisited, number, extendedPercent} sample)." + }, + "lighthouse-core/audits/seo/font-size.js | failureTitle": { + "message": "Document doesn't use legible font sizes" + }, + "lighthouse-core/audits/seo/font-size.js | title": { + "message": "Document uses legible font sizes" + }, + "lighthouse-core/audits/seo/hreflang.js | description": { + "message": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/hreflang)." + }, + "lighthouse-core/audits/seo/hreflang.js | failureTitle": { + "message": "Document doesn't have a valid `hreflang`" + }, + "lighthouse-core/audits/seo/hreflang.js | title": { + "message": "Document has a valid `hreflang`" + }, + "lighthouse-core/audits/seo/http-status-code.js | description": { + "message": "Pages with unsuccessful HTTP status codes may not be indexed properly. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)." + }, + "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { + "message": "Page has unsuccessful HTTP status code" + }, + "lighthouse-core/audits/seo/http-status-code.js | title": { + "message": "Page has successful HTTP status code" + }, + "lighthouse-core/audits/seo/is-crawlable.js | description": { + "message": "Search engines are unable to include your pages in search results if they don't have permission to crawl them. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/indexing)." + }, + "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { + "message": "Page is blocked from indexing" + }, + "lighthouse-core/audits/seo/is-crawlable.js | title": { + "message": "Page isn’t blocked from indexing" + }, + "lighthouse-core/audits/seo/link-text.js | description": { + "message": "Descriptive link text helps search engines understand your content. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)." + }, + "lighthouse-core/audits/seo/link-text.js | displayValue": { + "message": "{itemCount, plural,\n =1 {1 link found}\n other {# links found}\n }" + }, + "lighthouse-core/audits/seo/link-text.js | failureTitle": { + "message": "Links do not have descriptive text" + }, + "lighthouse-core/audits/seo/link-text.js | title": { + "message": "Links have descriptive text" + }, + "lighthouse-core/audits/seo/manual/structured-data.js | description": { + "message": "Run the [Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool/) and the [Structured Data Linter](http://linter.structured-data.org/) to validate structured data. [Learn more](https://developers.google.com/search/docs/guides/mark-up-content)." + }, + "lighthouse-core/audits/seo/manual/structured-data.js | title": { + "message": "Structured data is valid" + }, + "lighthouse-core/audits/seo/meta-description.js | description": { + "message": "Meta descriptions may be included in search results to concisely summarize page content. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/description)." + }, + "lighthouse-core/audits/seo/meta-description.js | explanation": { + "message": "Description text is empty." + }, + "lighthouse-core/audits/seo/meta-description.js | failureTitle": { + "message": "Document does not have a meta description" + }, + "lighthouse-core/audits/seo/meta-description.js | title": { + "message": "Document has a meta description" + }, + "lighthouse-core/audits/seo/plugins.js | description": { + "message": "Search engines can't index plugin content, and many devices restrict plugins or don't support them. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/plugins)." + }, + "lighthouse-core/audits/seo/plugins.js | failureTitle": { + "message": "Document uses plugins" + }, + "lighthouse-core/audits/seo/plugins.js | title": { + "message": "Document avoids plugins" + }, + "lighthouse-core/audits/seo/robots-txt.js | description": { + "message": "If your robots.txt file is malformed, crawlers may not be able to understand how you want your website to be crawled or indexed." + }, + "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": { + "message": "request for robots.txt returned HTTP status: {statusCode}" + }, + "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": { + "message": "{itemCount, plural,\n =1 {1 error found}\n other {# errors found}\n }" + }, + "lighthouse-core/audits/seo/robots-txt.js | explanation": { + "message": "Lighthouse was unable to download a robots.txt file" + }, + "lighthouse-core/audits/seo/robots-txt.js | failureTitle": { + "message": "robots.txt is not valid" + }, + "lighthouse-core/audits/seo/robots-txt.js | title": { + "message": "robots.txt is valid" + }, + "lighthouse-core/audits/seo/tap-targets.js | description": { + "message": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. [Learn more](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)." + }, + "lighthouse-core/audits/seo/tap-targets.js | displayValue": { + "message": "{decimalProportion, number, percent} appropriately sized tap targets" + }, + "lighthouse-core/audits/seo/tap-targets.js | explanationViewportMetaNotOptimized": { + "message": "Tap targets are too small because there's no viewport meta tag optimized for mobile screens" + }, + "lighthouse-core/audits/seo/tap-targets.js | failureTitle": { + "message": "Tap targets are not sized appropriately" + }, + "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": { + "message": "Overlapping Target" + }, + "lighthouse-core/audits/seo/tap-targets.js | sizeHeader": { + "message": "Size" + }, + "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": { + "message": "Tap Target" + }, + "lighthouse-core/audits/seo/tap-targets.js | title": { + "message": "Tap targets are sized appropriately" + }, + "lighthouse-core/audits/time-to-first-byte.js | description": { + "message": "Time To First Byte identifies the time at which your server sends a response. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/ttfb)." + }, + "lighthouse-core/audits/time-to-first-byte.js | displayValue": { + "message": "Root document took {timeInMs, number, milliseconds} ms" + }, + "lighthouse-core/audits/time-to-first-byte.js | failureTitle": { + "message": "Reduce server response times (TTFB)" + }, + "lighthouse-core/audits/time-to-first-byte.js | title": { + "message": "Server response times are low (TTFB)" + }, + "lighthouse-core/audits/user-timings.js | columnDuration": { + "message": "Duration" + }, + "lighthouse-core/audits/user-timings.js | columnName": { + "message": "Name" + }, + "lighthouse-core/audits/user-timings.js | columnStartTime": { + "message": "Start Time" + }, + "lighthouse-core/audits/user-timings.js | columnType": { + "message": "Type" + }, + "lighthouse-core/audits/user-timings.js | description": { + "message": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing)." + }, + "lighthouse-core/audits/user-timings.js | displayValue": { + "message": "{itemCount, plural,\n =1 {1 user timing}\n other {# user timings}\n }" + }, + "lighthouse-core/audits/user-timings.js | title": { + "message": "User Timing marks and measures" + }, + "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { + "message": "A preconnect <link> was found for \"{securityOrigin}\" but was not used by the browser. Check that you are using the `crossorigin` attribute properly." + }, + "lighthouse-core/audits/uses-rel-preconnect.js | description": { + "message": "Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)." + }, + "lighthouse-core/audits/uses-rel-preconnect.js | title": { + "message": "Preconnect to required origins" + }, + "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { + "message": "A preload <link> was found for \"{preloadURL}\" but was not used by the browser. Check that you are using the `crossorigin` attribute properly." + }, + "lighthouse-core/audits/uses-rel-preload.js | description": { + "message": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload)." + }, + "lighthouse-core/audits/uses-rel-preload.js | title": { + "message": "Preload key requests" + }, + "lighthouse-core/config/default-config.js | a11yAriaGroupDescription": { + "message": "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader." + }, + "lighthouse-core/config/default-config.js | a11yAriaGroupTitle": { + "message": "ARIA" + }, + "lighthouse-core/config/default-config.js | a11yAudioVideoGroupDescription": { + "message": "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments." + }, + "lighthouse-core/config/default-config.js | a11yAudioVideoGroupTitle": { + "message": "Audio and video" + }, + "lighthouse-core/config/default-config.js | a11yBestPracticesGroupDescription": { + "message": "These items highlight common accessibility best practices." + }, + "lighthouse-core/config/default-config.js | a11yBestPracticesGroupTitle": { + "message": "Best practices" + }, + "lighthouse-core/config/default-config.js | a11yCategoryDescription": { + "message": "These checks highlight opportunities to [improve the accessibility of your web app](https://developers.google.com/web/fundamentals/accessibility). Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged." + }, + "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { + "message": "These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://developers.google.com/web/fundamentals/accessibility/how-to-review)." + }, + "lighthouse-core/config/default-config.js | a11yCategoryTitle": { + "message": "Accessibility" + }, + "lighthouse-core/config/default-config.js | a11yColorContrastGroupDescription": { + "message": "These are opportunities to improve the legibility of your content." + }, + "lighthouse-core/config/default-config.js | a11yColorContrastGroupTitle": { + "message": "Contrast" + }, + "lighthouse-core/config/default-config.js | a11yLanguageGroupDescription": { + "message": "These are opportunities to improve the interpretation of your content by users in different locales." + }, + "lighthouse-core/config/default-config.js | a11yLanguageGroupTitle": { + "message": "Internationalization and localization" + }, + "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupDescription": { + "message": "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader." + }, + "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupTitle": { + "message": "Names and labels" + }, + "lighthouse-core/config/default-config.js | a11yNavigationGroupDescription": { + "message": "These are opportunities to improve keyboard navigation in your application." + }, + "lighthouse-core/config/default-config.js | a11yNavigationGroupTitle": { + "message": "Navigation" + }, + "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupDescription": { + "message": "These are opportunities to to improve the experience of reading tabular or list data using assistive technology, like a screen reader." + }, + "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupTitle": { + "message": "Tables and lists" + }, + "lighthouse-core/config/default-config.js | budgetsGroupDescription": { + "message": "Performance budgets set standards for the performance of your site." + }, + "lighthouse-core/config/default-config.js | budgetsGroupTitle": { + "message": "Budgets" + }, + "lighthouse-core/config/default-config.js | diagnosticsGroupDescription": { + "message": "More information about the performance of your application." + }, + "lighthouse-core/config/default-config.js | diagnosticsGroupTitle": { + "message": "Diagnostics" + }, + "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupDescription": { + "message": "The most critical aspect of performance is how quickly pixels are rendered onscreen. Key metrics: First Contentful Paint, First Meaningful Paint" + }, + "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupTitle": { + "message": "First Paint Improvements" + }, + "lighthouse-core/config/default-config.js | loadOpportunitiesGroupDescription": { + "message": "These optimizations can speed up your page load." + }, + "lighthouse-core/config/default-config.js | loadOpportunitiesGroupTitle": { + "message": "Opportunities" + }, + "lighthouse-core/config/default-config.js | metricGroupTitle": { + "message": "Metrics" + }, + "lighthouse-core/config/default-config.js | overallImprovementsGroupDescription": { + "message": "Enhance the overall loading experience, so the page is responsive and ready to use as soon as possible. Key metrics: Time to Interactive, Speed Index" + }, + "lighthouse-core/config/default-config.js | overallImprovementsGroupTitle": { + "message": "Overall Improvements" + }, + "lighthouse-core/config/default-config.js | performanceCategoryTitle": { + "message": "Performance" + }, + "lighthouse-core/config/default-config.js | pwaFastReliableGroupTitle": { + "message": "Fast and reliable" + }, + "lighthouse-core/config/default-config.js | pwaInstallableGroupTitle": { + "message": "Installable" + }, + "lighthouse-core/config/default-config.js | pwaOptimizedGroupTitle": { + "message": "PWA Optimized" + }, + "lighthouse-core/config/default-config.js | seoCategoryDescription": { + "message": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. [Learn more](https://support.google.com/webmasters/answer/35769)." + }, + "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { + "message": "Run these additional validators on your site to check additional SEO best practices." + }, + "lighthouse-core/config/default-config.js | seoCategoryTitle": { + "message": "SEO" + }, + "lighthouse-core/config/default-config.js | seoContentGroupDescription": { + "message": "Format your HTML in a way that enables crawlers to better understand your app’s content." + }, + "lighthouse-core/config/default-config.js | seoContentGroupTitle": { + "message": "Content Best Practices" + }, + "lighthouse-core/config/default-config.js | seoCrawlingGroupDescription": { + "message": "To appear in search results, crawlers need access to your app." + }, + "lighthouse-core/config/default-config.js | seoCrawlingGroupTitle": { + "message": "Crawling and Indexing" + }, + "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { + "message": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn more](https://developers.google.com/search/mobile-sites/)." + }, + "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { + "message": "Mobile Friendly" + }, + "lighthouse-core/lib/i18n/i18n.js | columnCacheTTL": { + "message": "Cache TTL" + }, + "lighthouse-core/lib/i18n/i18n.js | columnSize": { + "message": "Size" + }, + "lighthouse-core/lib/i18n/i18n.js | columnTimeSpent": { + "message": "Time Spent" + }, + "lighthouse-core/lib/i18n/i18n.js | columnURL": { + "message": "URL" + }, + "lighthouse-core/lib/i18n/i18n.js | columnWastedBytes": { + "message": "Potential Savings" + }, + "lighthouse-core/lib/i18n/i18n.js | columnWastedMs": { + "message": "Potential Savings" + }, + "lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings": { + "message": "Potential savings of {wastedBytes, number, bytes} KB" + }, + "lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings": { + "message": "Potential savings of {wastedMs, number, milliseconds} ms" + }, + "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { + "message": "Document" + }, + "lighthouse-core/lib/i18n/i18n.js | fontResourceType": { + "message": "Font" + }, + "lighthouse-core/lib/i18n/i18n.js | imageResourceType": { + "message": "Image" + }, + "lighthouse-core/lib/i18n/i18n.js | mediaResourceType": { + "message": "Media" + }, + "lighthouse-core/lib/i18n/i18n.js | ms": { + "message": "{timeInMs, number, milliseconds} ms" + }, + "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { + "message": "Other" + }, + "lighthouse-core/lib/i18n/i18n.js | scriptResourceType": { + "message": "Script" + }, + "lighthouse-core/lib/i18n/i18n.js | seconds": { + "message": "{timeInMs, number, seconds} s" + }, + "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { + "message": "Stylesheet" + }, + "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": { + "message": "Third-party" + }, + "lighthouse-core/lib/i18n/i18n.js | totalResourceType": { + "message": "Total" + }, + "lighthouse-core/lib/lh-error.js | badTraceRecording": { + "message": "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})" + }, + "lighthouse-core/lib/lh-error.js | criTimeout": { + "message": "Timeout waiting for initial Debugger Protocol connection." + }, + "lighthouse-core/lib/lh-error.js | didntCollectScreenshots": { + "message": "Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})" + }, + "lighthouse-core/lib/lh-error.js | dnsFailure": { + "message": "DNS servers could not resolve the provided domain." + }, + "lighthouse-core/lib/lh-error.js | internalChromeError": { + "message": "An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse." + }, + "lighthouse-core/lib/lh-error.js | pageLoadFailed": { + "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests." + }, + "lighthouse-core/lib/lh-error.js | pageLoadFailedHung": { + "message": "Lighthouse was unable to reliably load the URL you requested because the page stopped responding." + }, + "lighthouse-core/lib/lh-error.js | pageLoadFailedInsecure": { + "message": "The URL you have provided does not have a valid security certificate. {securityMessages}" + }, + "lighthouse-core/lib/lh-error.js | pageLoadFailedWithDetails": { + "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})" + }, + "lighthouse-core/lib/lh-error.js | pageLoadFailedWithStatusCode": { + "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: {statusCode})" + }, + "lighthouse-core/lib/lh-error.js | pageLoadTookTooLong": { + "message": "Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ({errorCode})" + }, + "lighthouse-core/lib/lh-error.js | protocolTimeout": { + "message": "Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})" + }, + "lighthouse-core/lib/lh-error.js | requestContentTimeout": { + "message": "Fetching resource content has exceeded the allotted time" + }, + "lighthouse-core/lib/lh-error.js | urlInvalid": { + "message": "The URL you have provided appears to be invalid." + }, + "lighthouse-core/report/html/renderer/util.js | auditGroupExpandTooltip": { + "message": "Show audits" + }, + "lighthouse-core/report/html/renderer/util.js | crcInitialNavigation": { + "message": "Initial Navigation" + }, + "lighthouse-core/report/html/renderer/util.js | crcLongestDurationLabel": { + "message": "Maximum critical path latency:" + }, + "lighthouse-core/report/html/renderer/util.js | errorLabel": { + "message": "Error!" + }, + "lighthouse-core/report/html/renderer/util.js | errorMissingAuditInfo": { + "message": "Report error: no audit information" + }, + "lighthouse-core/report/html/renderer/util.js | labDataTitle": { + "message": "Lab Data" + }, + "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { + "message": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary." + }, + "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { + "message": "Additional items to manually check" + }, + "lighthouse-core/report/html/renderer/util.js | notApplicableAuditsGroupTitle": { + "message": "Not applicable" + }, + "lighthouse-core/report/html/renderer/util.js | opportunityResourceColumnLabel": { + "message": "Opportunity" + }, + "lighthouse-core/report/html/renderer/util.js | opportunitySavingsColumnLabel": { + "message": "Estimated Savings" + }, + "lighthouse-core/report/html/renderer/util.js | passedAuditsGroupTitle": { + "message": "Passed audits" + }, + "lighthouse-core/report/html/renderer/util.js | snippetCollapseButtonLabel": { + "message": "Collapse snippet" + }, + "lighthouse-core/report/html/renderer/util.js | snippetExpandButtonLabel": { + "message": "Expand snippet" + }, + "lighthouse-core/report/html/renderer/util.js | thirdPartyResourcesLabel": { + "message": "Show 3rd-party resources" + }, + "lighthouse-core/report/html/renderer/util.js | toplevelWarningsMessage": { + "message": "There were issues affecting this run of Lighthouse:" + }, + "lighthouse-core/report/html/renderer/util.js | varianceDisclaimer": { + "message": "Values are estimated and may vary." + }, + "lighthouse-core/report/html/renderer/util.js | warningAuditsGroupTitle": { + "message": "Passed audits but with warnings" + }, + "lighthouse-core/report/html/renderer/util.js | warningHeader": { + "message": "Warnings: " + }, + "stack-packs/packs/wordpress.js | efficient_animated_content": { + "message": "Consider uploading your GIF to a service which will make it available to embed as an HTML5 video." + }, + "stack-packs/packs/wordpress.js | offscreen_images": { + "message": "Install a [lazy-load WordPress plugin](https://wordpress.org/plugins/search/lazy+load/) that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using [the AMP plugin](https://wordpress.org/plugins/amp/)." + }, + "stack-packs/packs/wordpress.js | render_blocking_resources": { + "message": "There are a number of WordPress plugins that can help you [inline critical assets](https://wordpress.org/plugins/search/critical+css/) or [defer less important resources](https://wordpress.org/plugins/search/defer+css+javascript/). Beware that optimizations provided by these plugins may break features of your theme or plugins, so you will likely need to make code changes." + }, + "stack-packs/packs/wordpress.js | time_to_first_byte": { + "message": "Themes, plugins, and server specifications all contribute to server response time. Consider finding a more optimized theme, carefully selecting an optimization plugin, and/or upgrading your server." + }, + "stack-packs/packs/wordpress.js | total_byte_weight": { + "message": "Consider showing excerpts in your post lists (e.g. via the more tag), reducing the number of posts shown on a given page, breaking your long posts into multiple pages, or using a plugin to lazy-load comments." + }, + "stack-packs/packs/wordpress.js | unminified_css": { + "message": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+css/) can speed up your site by concatenating, minifying, and compressing your styles. You may also want to use a build process to do this minification up-front if possible." + }, + "stack-packs/packs/wordpress.js | unminified_javascript": { + "message": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+javascript/) can speed up your site by concatenating, minifying, and compressing your scripts. You may also want to use a build process to do this minification up front if possible." + }, + "stack-packs/packs/wordpress.js | unused_css_rules": { + "message": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused CSS in your page. To identify plugins that are adding extraneous CSS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page." + }, + "stack-packs/packs/wordpress.js | unused_javascript": { + "message": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the script. Look out for plugins that have many scripts in the list which have a lot of red in code coverage. A plugin should only enqueue a script if it is actually used on the page." + }, + "stack-packs/packs/wordpress.js | uses_long_cache_ttl": { + "message": "Read about [Browser Caching in WordPress](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching)." + }, + "stack-packs/packs/wordpress.js | uses_optimized_images": { + "message": "Consider using an [image optimization WordPress plugin](https://wordpress.org/plugins/search/optimize+images/) that compresses your images while retaining quality." + }, + "stack-packs/packs/wordpress.js | uses_responsive_images": { + "message": "Upload images directly through the [media library](https://codex.wordpress.org/Media_Library_Screen) to ensure that the required image sizes are available, and then insert them from the media library or use the image widget to ensure the optimal image sizes are used (including those for the responsive breakpoints). Avoid using `Full Size` images unless the dimensions are adequate for their usage. [Learn More](https://codex.wordpress.org/Inserting_Images_into_Posts_and_Pages#Image_Size)." + }, + "stack-packs/packs/wordpress.js | uses_text_compression": { + "message": "You can enable text compression in your web server configuration." + }, + "stack-packs/packs/wordpress.js | uses_webp_images": { + "message": "Consider using a [plugin](https://wordpress.org/plugins/search/convert+webp/) or service that will automatically convert your uploaded images to the optimal formats." + } +} diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json similarity index 100% rename from lighthouse-core/lib/i18n/en-US.json rename to lighthouse-core/lib/i18n/pre-locale/en-US.json diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 10fe7437f529..2a52b02b3d4b 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -151,7 +151,7 @@ function collectAllStringsInDir(dir, strings = {}) { * @param {Record<string, ICUMessageDefn>} strings */ function writeEnStringsToLocaleFormat(strings) { - const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/en-US.json`); + const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/pre-locale/en-US.json`); /** @type {Record<string, ICUMessageDefn>} */ const output = {}; const sortedEntries = Object.entries(strings).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js new file mode 100644 index 000000000000..7070e7716753 --- /dev/null +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -0,0 +1,202 @@ +#!/usr/bin/env node +/** + * @license Copyright 2018 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +/* eslint-disable no-console, max-len */ + +const fs = require('fs'); +const path = require('path'); +const esprima = require('esprima'); + +const LH_ROOT = path.join(__dirname, '../../../'); +const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; + +/** + * @typedef ICUMessageDefn + * @property {string} message + * @property {string} [description] + */ + +const ignoredPathComponents = [ + '/.git', + '/scripts', + '/node_modules', + '/test/', + '-test.js', + '-renderer.js', +]; + +// @ts-ignore - @types/esprima lacks all of these +function computeDescription(ast, property, startRange) { + const endRange = property.range[0]; + for (const comment of ast.comments || []) { + if (comment.range[0] < startRange) continue; + if (comment.range[0] > endRange) continue; + return comment.value.replace('*', '').trim(); + } + + return ''; +} + +/** + * @param {string} dir + * @param {Record<string, ICUMessageDefn>} strings + */ +function collectAllStringsInDir(dir, strings = {}) { + for (const name of fs.readdirSync(dir)) { + const fullPath = path.join(dir, name); + const relativePath = path.relative(LH_ROOT, fullPath); + if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; + + if (fs.statSync(fullPath).isDirectory()) { + collectAllStringsInDir(fullPath, strings); + } else { + if (name.endsWith('.js')) { + if (!process.env.CI) console.log('Collecting from', relativePath); + const content = fs.readFileSync(fullPath, 'utf8'); + const exportVars = require(fullPath); + const regexMatches = !!UISTRINGS_REGEX.test(content); + const exportsUIStrings = !!exportVars.UIStrings; + if (!regexMatches && !exportsUIStrings) continue; + + if (regexMatches && !exportsUIStrings) { + throw new Error('UIStrings defined but not exported'); + } + + if (exportsUIStrings && !regexMatches) { + throw new Error('UIStrings exported but no definition found'); + } + + // @ts-ignore regex just matched + const justUIStrings = 'const ' + content.match(UISTRINGS_REGEX)[0]; + // just parse the UIStrings substring to avoid ES version issues, save time, etc + // @ts-ignore - esprima's type definition is supremely lacking + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + for (const stmt of ast.body) { + if (stmt.type !== 'VariableDeclaration') continue; + if (stmt.declarations[0].id.name !== 'UIStrings') continue; + + let lastPropertyEndIndex = 0; + for (const property of stmt.declarations[0].init.properties) { + const key = property.key.name; + const val = exportVars.UIStrings[key]; + if (typeof val === 'string') { + const description = computeDescription(ast, property, lastPropertyEndIndex); + strings[`${relativePath} | ${key}`] = {message: val, description}; + lastPropertyEndIndex = property.range[1]; + } else { + // console.log(property.value.properties[0].range[1]); + // console.log(property.value.properties[1].value.properties); + let message = val.message; + // const prevProp = property.value.properties[1].value.properties[1]; + // const thisProp = property.value.properties[1].value.properties[2]; + + const description = computeDescription(ast, property, lastPropertyEndIndex); + /** + * Transform: + * placeholders: { + * /** example val *\/ + * key: value, + * ... + * }, + * Into: + * placeholders: { + * key: { + * content: value, + * example: example val, + * }, + * ... + * } + */ + // init last prop to the 'messages' end range + let lastPropEndIndex = property.value.properties[0].range[1]; + let idx = 0; + const placeholdersMini = val.placeholders; + const placeholders = {}; + Object.entries(placeholdersMini).forEach(entry => { + const key = entry[0]; + const value = entry[1]; + const thisProp = property.value.properties[1].value.properties[idx]; + const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); + placeholders[key] = { + content: value, + }; + if (thisDesc) { + placeholders[key].example = thisDesc; + } + + // replace {.*} with $.*$ + message = message.replace(`{${key}}`, `\$${key}\$`); + idx++; + lastPropEndIndex = thisProp.range[1]; + }); + strings[`${relativePath} | ${key}`] = {message, description, placeholders}; + lastPropertyEndIndex = property.range[1]; + } + } + } + } + } + } + + return strings; +} + +/** + * @param {Record<string, ICUMessageDefn>} strings + */ +function writeEnStringsToLocaleFormat(strings) { + const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/pre-locale/en-US.json`); + /** @type {Record<string, ICUMessageDefn>} */ + const output = {}; + const sortedEntries = Object.entries(strings).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); + for (const [key, defn] of sortedEntries) { + output[key] = defn; + } + + fs.writeFileSync(fullPath, JSON.stringify(output, null, 2) + '\n'); +} + +function collectPreLocaleStrings(file) { + const rawdata = fs.readFileSync(file, 'utf8'); + const messages = JSON.parse(rawdata); + return messages; +} + +function bakePlaceholders(messages) { + for (const key in messages) { + if (!Object.prototype.hasOwnProperty.call(messages, key)) continue; + + delete messages[key]['description']; + + let message = messages[key]['message']; + const placeholders = messages[key]['placeholders']; + + for (const placeholder in placeholders) { + if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; + + const content = placeholders[placeholder]['content']; + const re = new RegExp('\\$' + placeholder + '\\$'); + message = message.replace(re, content); + } + messages[key]['message'] = message; + + delete messages[key]['placeholders']; + } + return messages; +} + +function saveLocaleStrings(path, output) { + fs.writeFileSync(path, JSON.stringify(output, null, 2) + '\n'); +} + +const preLocaleStrings = collectPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/en-US.json')); + +const strings = bakePlaceholders(preLocaleStrings); + +saveLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/en-US.json'), strings); diff --git a/package.json b/package.json index 2af0149e182d..723219f2aa5e 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "type-check": "tsc -p . && tsc -p lighthouse-viewer/", "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", "i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js", + "i18n:correct-strings": "node lighthouse-core/scripts/i18n/correct-strings.js", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", From 0de54856d0b12dac3a75f8a86615418cb02664d7 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 3 Jul 2019 11:05:53 -0700 Subject: [PATCH 11/71] updated i18n.js --- lighthouse-core/lib/i18n/i18n.js | 44 +++++++++++++---------------- lighthouse-core/lib/i18n/locales.js | 4 +-- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 107c0d4f4941..251ca9baa1c3 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -157,10 +157,12 @@ function _preprocessMessageValues(icuMessage, values) { /** * @typedef IcuMessageInstance * @prop {string} icuMessageId - * @prop {string} icuMessage * @prop {*} [values] */ +// Only used for value lookups, default mapping to en is done with a lookup to the en file, +// not this pre-baked msg map. + /** @type {Map<string, IcuMessageInstance[]>} */ const _icuMessageInstanceMap = new Map(); @@ -168,41 +170,33 @@ const _icuMessageInstanceMap = new Map(); * * @param {LH.Locale} locale * @param {string} icuMessageId - * @param {string} icuMessage * @param {*} [values] * @return {{formattedString: string, icuMessage: string}} */ -function _formatIcuMessage(locale, icuMessageId, icuMessage, values) { +function _formatIcuMessage(locale, icuMessageId, values) { const localeMessages = LOCALES[locale]; let localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; - // lets try to replace some things :o - const placeholders = localeMessages[icuMessageId] && localeMessages[icuMessageId].placeholders; - if (placeholders) { - // do some regex - Object.entries(placeholders).forEach(entry => { - const key = entry[0]; - const value = entry[1]; - //use key and value here - let regexStr = `\$${key}\$`; - // console.log(key, value, regexStr); - localeMessage = localeMessage.replace(regexStr, value.content); - // console.log(localeMessage); - }); - icuMessage = localeMessage; - } // fallback to the original english message if we couldn't find a message in the specified locale // better to have an english message than no message at all, in some number cases it won't even matter - const messageForMessageFormat = localeMessage || icuMessage; + if (!localeMessage) { + // Backup message + localeMessage = LOCALES['en'][icuMessageId] && LOCALES['en'][icuMessageId].message; + if (!localeMessage) { + // panic + throw Error('ICU replacement message not found in locale, or en.'); + } + } + // when using accented english, force the use of a different locale for number formatting const localeForMessageFormat = locale === 'en-XA' ? 'de-DE' : locale; // pre-process values for the message format like KB and milliseconds - const valuesForMessageFormat = _preprocessMessageValues(icuMessage, values); + const valuesForMessageFormat = _preprocessMessageValues(localeMessage, values); - const formatter = new MessageFormat(messageForMessageFormat, localeForMessageFormat, formats); + const formatter = new MessageFormat(localeMessage, localeForMessageFormat, formats); const formattedString = formatter.format(valuesForMessageFormat); - return {formattedString, icuMessage: messageForMessageFormat}; + return {formattedString, icuMessage: localeMessage}; } /** @param {string[]} pathInLHR */ @@ -258,7 +252,7 @@ function createMessageInstanceIdFn(filename, fileStrings) { let indexOfInstance = icuMessageInstances.findIndex(inst => isDeepEqual(inst.values, values)); if (indexOfInstance === -1) { - icuMessageInstances.push({icuMessageId, icuMessage, values}); + icuMessageInstances.push({icuMessageId, values}); indexOfInstance = icuMessageInstances.length - 1; } @@ -305,9 +299,9 @@ function _resolveIcuMessageInstanceId(icuMessageInstanceId, locale) { const [_, icuMessageId, icuMessageInstanceIndex] = matches; const icuMessageInstances = _icuMessageInstanceMap.get(icuMessageId) || []; const icuMessageInstance = icuMessageInstances[Number(icuMessageInstanceIndex)]; - + // console.log(locale, "-->", icuMessageInstance.icuMessage); const {formattedString} = _formatIcuMessage(locale, icuMessageId, - icuMessageInstance.icuMessage, icuMessageInstance.values); + icuMessageInstance.values); return {icuMessageInstance, formattedString}; } diff --git a/lighthouse-core/lib/i18n/locales.js b/lighthouse-core/lib/i18n/locales.js index 273f778b72e6..ad619ed4e03d 100644 --- a/lighthouse-core/lib/i18n/locales.js +++ b/lighthouse-core/lib/i18n/locales.js @@ -17,8 +17,8 @@ // The keys within this const must exactly match the LH.Locale type in externs.d.ts /** @type {Record<LH.Locale, LocaleMessages>} */ const locales = { - 'en-US': require('./en-US.json'), // The 'source' strings, with descriptions - 'en': require('./en-US.json'), // According to CLDR/ICU, 'en' == 'en-US' dates/numbers (Why?!) + 'en-US': require('./locales/en-US.json'), // The 'source' strings, with descriptions + 'en': require('./locales/en-US.json'), // According to CLDR/ICU, 'en' == 'en-US' dates/numbers (Why?!) // TODO: en-GB has just ~10 messages that are different from en-US. We should only ship those. 'en-AU': require('./locales/en-GB.json'), // Alias of 'en-GB' From 37dc2ae9966a303383bb352d57d0b93a717ba546 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 3 Jul 2019 11:55:40 -0700 Subject: [PATCH 12/71] remove unused from correct-strings --- .../scripts/i18n/correct-strings.js | 134 ------------------ 1 file changed, 134 deletions(-) diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js index 6721b5851132..6a07fa73fac5 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -10,10 +10,8 @@ const fs = require('fs'); const path = require('path'); -const esprima = require('esprima'); const LH_ROOT = path.join(__dirname, '../../../'); -const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; /** * @typedef ICUMessageDefn @@ -30,138 +28,6 @@ const ignoredPathComponents = [ '-renderer.js', ]; -// @ts-ignore - @types/esprima lacks all of these -function computeDescription(ast, property, startRange) { - const endRange = property.range[0]; - for (const comment of ast.comments || []) { - if (comment.range[0] < startRange) continue; - if (comment.range[0] > endRange) continue; - return comment.value.replace('*', '').trim(); - } - - return ''; -} - -/** - * @param {string} dir - * @param {Record<string, ICUMessageDefn>} strings - */ -function collectAllStringsInDir(dir, strings = {}) { - for (const name of fs.readdirSync(dir)) { - const fullPath = path.join(dir, name); - const relativePath = path.relative(LH_ROOT, fullPath); - if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; - - if (fs.statSync(fullPath).isDirectory()) { - collectAllStringsInDir(fullPath, strings); - } else { - if (name.endsWith('.js')) { - if (!process.env.CI) console.log('Collecting from', relativePath); - const content = fs.readFileSync(fullPath, 'utf8'); - const exportVars = require(fullPath); - const regexMatches = !!UISTRINGS_REGEX.test(content); - const exportsUIStrings = !!exportVars.UIStrings; - if (!regexMatches && !exportsUIStrings) continue; - - if (regexMatches && !exportsUIStrings) { - throw new Error('UIStrings defined but not exported'); - } - - if (exportsUIStrings && !regexMatches) { - throw new Error('UIStrings exported but no definition found'); - } - - // @ts-ignore regex just matched - const justUIStrings = 'const ' + content.match(UISTRINGS_REGEX)[0]; - // just parse the UIStrings substring to avoid ES version issues, save time, etc - // @ts-ignore - esprima's type definition is supremely lacking - const ast = esprima.parse(justUIStrings, {comment: true, range: true}); - - for (const stmt of ast.body) { - if (stmt.type !== 'VariableDeclaration') continue; - if (stmt.declarations[0].id.name !== 'UIStrings') continue; - - let lastPropertyEndIndex = 0; - for (const property of stmt.declarations[0].init.properties) { - const key = property.key.name; - const val = exportVars.UIStrings[key]; - if (typeof val === 'string') { - const description = computeDescription(ast, property, lastPropertyEndIndex); - strings[`${relativePath} | ${key}`] = {message: val, description}; - lastPropertyEndIndex = property.range[1]; - } else { - // console.log(property.value.properties[0].range[1]); - // console.log(property.value.properties[1].value.properties); - let message = val.message; - // const prevProp = property.value.properties[1].value.properties[1]; - // const thisProp = property.value.properties[1].value.properties[2]; - - const description = computeDescription(ast, property, lastPropertyEndIndex); - /** - * Transform: - * placeholders: { - * /** example val *\/ - * key: value, - * ... - * }, - * Into: - * placeholders: { - * key: { - * content: value, - * example: example val, - * }, - * ... - * } - */ - // init last prop to the 'messages' end range - let lastPropEndIndex = property.value.properties[0].range[1]; - let idx = 0; - const placeholdersMini = val.placeholders; - const placeholders = {}; - Object.entries(placeholdersMini).forEach(entry => { - const key = entry[0]; - const value = entry[1]; - const thisProp = property.value.properties[1].value.properties[idx]; - const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); - placeholders[key] = { - content: value, - }; - if (thisDesc) { - placeholders[key].example = thisDesc; - } - - // replace {.*} with $.*$ - message = message.replace(`{${key}}`, `\$${key}\$`); - idx++; - lastPropEndIndex = thisProp.range[1]; - }); - strings[`${relativePath} | ${key}`] = {message, description, placeholders}; - lastPropertyEndIndex = property.range[1]; - } - } - } - } - } - } - - return strings; -} - -/** - * @param {Record<string, ICUMessageDefn>} strings - */ -function writeEnStringsToLocaleFormat(strings) { - const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/pre-locale/en-US.json`); - /** @type {Record<string, ICUMessageDefn>} */ - const output = {}; - const sortedEntries = Object.entries(strings).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); - for (const [key, defn] of sortedEntries) { - output[key] = defn; - } - - fs.writeFileSync(fullPath, JSON.stringify(output, null, 2) + '\n'); -} - function collectPreLocaleStrings(file) { const rawdata = fs.readFileSync(file, 'utf8'); const messages = JSON.parse(rawdata); From 58c7dedb70234fd3886e726104dab1fefacd7282 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 3 Jul 2019 13:06:59 -0700 Subject: [PATCH 13/71] exported correct-strings to be reused to import. ts first pass on collect & correct. --- lighthouse-core/lib/i18n/i18n.js | 2 +- .../scripts/i18n/collect-strings.js | 16 +++++++++-- .../scripts/i18n/correct-strings.js | 28 +++++++++++++------ .../scripts/i18n/pseudolocalize.js | 15 ++++++++++ package.json | 2 +- 5 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 lighthouse-core/scripts/i18n/pseudolocalize.js diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index c85722ad9b8a..ca81ac4fbb34 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -309,7 +309,7 @@ function getFormattedFromIdAndValues(locale, icuMessageId, values) { const icuMessageIdRegex = /(.* \| .*)$/; if (!icuMessageIdRegex.test(icuMessageId)) throw new Error('This is not an ICU message ID'); - const {formattedString} = _formatIcuMessage(locale, icuMessageId, undefined, values); + const {formattedString} = _formatIcuMessage(locale, icuMessageId, values); return formattedString; } diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 041b3f877000..654a7bbe7f8d 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -19,7 +19,13 @@ const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; * @typedef ICUMessageDefn * @property {string} message * @property {string} [description] - * @property {*} placeholders + * @property {*} [placeholders] + */ + +/** + * @typedef ICUPlaceholderDefn + * @property {string} content + * @property {string} [example] */ const ignoredPathComponents = [ @@ -96,10 +102,10 @@ function collectAllStringsInDir(dir, strings = {}) { let message = val.message; // const prevProp = property.value.properties[1].value.properties[1]; // const thisProp = property.value.properties[1].value.properties[2]; - + const description = computeDescription(ast, property, lastPropertyEndIndex); /** - * Transform: + * Transform: * placeholders: { * /** example val *\/ * key: value, @@ -118,12 +124,14 @@ function collectAllStringsInDir(dir, strings = {}) { let lastPropEndIndex = property.value.properties[0].range[1]; let idx = 0; const placeholdersMini = val.placeholders; + /** @type {*} */ const placeholders = {}; Object.entries(placeholdersMini).forEach(entry => { const key = entry[0]; const value = entry[1]; const thisProp = property.value.properties[1].value.properties[idx]; const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); + placeholders[key] = { content: value, }; @@ -132,6 +140,7 @@ function collectAllStringsInDir(dir, strings = {}) { } // replace {.*} with $.*$ + // eslint-disable-next-line no-useless-escape message = message.replace(`{${key}}`, `\$${key}\$`); idx++; lastPropEndIndex = thisProp.range[1]; @@ -223,5 +232,6 @@ collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); console.log('Collected from Stack Packs!'); writeStringsToLocaleFormat('pre-locale/en-US', strings); +// Generate local pseudolocalized files for debugging while translating writeStringsToLocaleFormat('pre-locale/en-XL', psuedoLocalizedStrings); console.log('Written to disk!'); diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js index 6a07fa73fac5..8ed230570183 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -11,8 +11,6 @@ const fs = require('fs'); const path = require('path'); -const LH_ROOT = path.join(__dirname, '../../../'); - /** * @typedef ICUMessageDefn * @property {string} message @@ -28,12 +26,18 @@ const ignoredPathComponents = [ '-renderer.js', ]; +/** + * @param {*} file + */ function collectPreLocaleStrings(file) { const rawdata = fs.readFileSync(file, 'utf8'); const messages = JSON.parse(rawdata); return messages; } +/** + * @param {*} messages + */ function bakePlaceholders(messages) { for (const key in messages) { if (!Object.prototype.hasOwnProperty.call(messages, key)) continue; @@ -57,29 +61,35 @@ function bakePlaceholders(messages) { return messages; } +/** + * @param {*} path + * @param {*} output + */ function saveLocaleStrings(path, output) { fs.writeFileSync(path, JSON.stringify(output, null, 2) + '\n'); } /** * @param {string} dir - * @param {Map<string, Record<string, ICUMessageDefn>>} strings + * @param {string} output */ -function collectAllPreLocaleStrings(dir, strings = new Map()) { +function collectAllPreLocaleStrings(dir, output) { for (const name of fs.readdirSync(dir)) { const fullPath = path.join(dir, name); - const relativePath = path.relative(LH_ROOT, fullPath); + const relativePath = fullPath;// path.relative(LH_ROOT, fullPath); if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; if (name.endsWith('.json')) { if (!process.env.CI) console.log('Correcting from', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); const strings = bakePlaceholders(preLocaleStrings); - saveLocaleStrings(path.join(LH_ROOT, `lighthouse-core/lib/i18n/locales/${path.basename(name)}`), strings); + saveLocaleStrings(output + path.basename(name), strings); } } - - return strings; } -collectAllPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/')); +// collectAllPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/')); + +module.exports = { + collectAllPreLocaleStrings, +}; diff --git a/lighthouse-core/scripts/i18n/pseudolocalize.js b/lighthouse-core/scripts/i18n/pseudolocalize.js new file mode 100644 index 000000000000..44229d38b5ec --- /dev/null +++ b/lighthouse-core/scripts/i18n/pseudolocalize.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node +/** + * @license Copyright 2019 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const cs = require('./correct-strings.js'); +const path = require('path'); + +const LH_ROOT = path.join(__dirname, '../../../'); + +cs.collectAllPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/'), + path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/')); diff --git a/package.json b/package.json index 057434ae11e7..60e32f08e940 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "type-check": "tsc -p . && tsc -p lighthouse-viewer/", "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", "i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js", - "i18n:correct-strings": "node lighthouse-core/scripts/i18n/correct-strings.js", + "i18n:correct-strings": "node lighthouse-core/scripts/i18n/pseudolocalize.js", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", From ad01bddd5c934c1749c27d0334a97911193ddff7 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 3 Jul 2019 14:52:06 -0700 Subject: [PATCH 14/71] first pass at new UIStrings format. --- .../audits/byte-efficiency/unminified-css.js | 107 +- lighthouse-core/lib/i18n/locales/en-US.json | 5 +- lighthouse-core/lib/i18n/locales/en-XL.json | 343 ++- .../lib/i18n/pre-locale/en-US.json | 2535 ++++++++++++++--- .../lib/i18n/pre-locale/en-XL.json | 2018 +++++++++++-- .../scripts/i18n/collect-strings.js | 156 +- 6 files changed, 4307 insertions(+), 857 deletions(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 52ad2b6bbcba..31aeba7b9c5f 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -12,52 +12,79 @@ const computeTokenLength = require('../../lib/minification-estimator.js').comput const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ - title: { - message: 'Minify CSS like {css}', - placeholders: { - css: '`<link rel=stylesheet>`', - }, - }, + title: 'Minify CSS like `<link rel=stylesheet>`', /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: { - message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', - placeholders: { - link_start: '[->', - link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', - /** 520 (Placeholder examples go here) */ - milliseconds: '{timeInMs, number, milliseconds}', - }, - }, + description: 'Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms.', /** [ICU Syntax] Some plural warning... */ - warningPlural: '{itemCount, plural, ' + - '=1 {# error found}' + - 'other {# errors found}}', + warningPlural: '{itemCount, plural, =1 {# error found} other {# errors found}}', /** [ICU Syntax] Some gendered (ICU select) explanation... */ - explanationGender: { - message: 'Someone minified this, {direct_replace_name}. {static_replacement} {person, select, ' + - 'female {She minified this CSS.} ' + + explanationGender: 'Someone minified this, {direct_replace_name}. `<link rel=>` ' + + '{person, select, female {She minified this CSS.} ' + 'male {He minified this CSS.} ' + 'other {They minified this CSS.}}', - placeholders: { - /** Some static replacement. */ - static_replacement: '`<link rel=>`', - }, - }, /** [ICU Syntax] Some gendered (ICU select) explanation... */ - explanationGender2: { - message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + - 'female {She minified this CSS.} ' + - 'male {He minified this CSS.} ' + - 'other {They minified this CSS.}}', - placeholders: { - /** Some static replacement. */ - static_replacement: '`<link rel=>`', - /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ - name: '{name}', - }, - }, + // explanationGender2: { + // message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + + // 'female {She minified this CSS.} ' + + // 'male {He minified this CSS.} ' + + // 'other {They minified this CSS.}}', + // placeholders: { + // /** Some static replacement. */ + // static_replacement: '`<link rel=>`', + // /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ + // name: '{name}', + // }, + // }, }; +// const UIStrings = { +// /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ +// title: { +// message: 'Minify CSS like {css}', +// placeholders: { +// css: '`<link rel=stylesheet>`', +// }, +// }, +// /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ +// description: { +// message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', +// placeholders: { +// link_start: '[->', +// link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', +// /** 520 (Placeholder examples go here) */ +// milliseconds: '{timeInMs, number, milliseconds}', +// }, +// }, +// /** [ICU Syntax] Some plural warning... */ +// warningPlural: '{itemCount, plural, ' + +// '=1 {# error found}' + +// 'other {# errors found}}', +// /** [ICU Syntax] Some gendered (ICU select) explanation... */ +// explanationGender: { +// message: 'Someone minified this, {direct_replace_name}. {static_replacement} {person, select, ' + +// 'female {She minified this CSS.} ' + +// 'male {He minified this CSS.} ' + +// 'other {They minified this CSS.}}', +// placeholders: { +// /** Some static replacement. */ +// static_replacement: '`<link rel=>`', +// }, +// }, +// /** [ICU Syntax] Some gendered (ICU select) explanation... */ +// explanationGender2: { +// message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + +// 'female {She minified this CSS.} ' + +// 'male {He minified this CSS.} ' + +// 'other {They minified this CSS.}}', +// placeholders: { +// /** Some static replacement. */ +// static_replacement: '`<link rel=>`', +// /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ +// name: '{name}', +// }, +// }, +// }; + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); const IGNORE_THRESHOLD_IN_PERCENT = 5; @@ -149,7 +176,9 @@ class UnminifiedCSS extends ByteEfficiencyAudit { {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)}, ]; - return {items, headings, explanation: str_(UIStrings.explanationGender, {person: 'female', direct_replace_name: 'Kim'}), warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; + return {items, headings, explanation: str_(UIStrings.explanationGender, + {person: 'female', direct_replace_name: 'Kim'}), + warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; } } diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 02de6c1b0798..86d31d3e1353 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -386,14 +386,11 @@ "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { "message": "Someone minified this, {direct_replace_name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { - "message": "Someone minified this, {name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" - }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { "message": "Minify CSS like `<link rel=stylesheet>`" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# error found}other {# errors found}}" + "message": "{itemCount, plural, =1 {# error found} other {# errors found}}" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources)." diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index c4cb5bde9b4c..dde4b1eac1fe 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -1,90 +1,90 @@ { "lighthouse-core/audits/accessibility/accesskeys.js | description": { - "message": "Âćĉéŝś k̂éŷś l̂ét̂ úŝér̂ś q̂úîćk̂ĺŷ f́ôćûś â ṕâŕt̂ óf̂ t́ĥé p̂áĝé. F̂ór̂ ṕr̂óp̂ér̂ ńâv́îǵât́îón̂, éâćĥ áĉćêśŝ ḱêý m̂úŝt́ b̂é ûńîq́ûé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âćĉéŝśk̂éŷś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âćĉéŝś k̂éŷś l̂ét̂ úŝér̂ś q̂úîćk̂ĺŷ f́ôćûś â ṕâŕt̂ óf̂ t́ĥé p̂áĝé. F̂ór̂ ṕr̂óp̂ér̂ ńâv́îǵât́îón̂, éâćĥ áĉćêśŝ ḱêý m̂úŝt́ b̂é ûńîq́ûé. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)." }, "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { - "message": "`[âćĉéŝśk̂éŷ]` v́âĺûéŝ ár̂é n̂ót̂ ún̂íq̂úê" + "message": "`[accesskey]` v̂ál̂úêś âŕê ńôt́ ûńîq́ûé" }, "lighthouse-core/audits/accessibility/accesskeys.js | title": { - "message": "`[âćĉéŝśk̂éŷ]` v́âĺûéŝ ár̂é ûńîq́ûé" + "message": "`[accesskey]` v̂ál̂úêś âŕê ún̂íq̂úê" }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { - "message": "Êáĉh́ ÂŔÎÁ `r̂ól̂é` ŝúp̂ṕôŕt̂ś â śp̂éĉíf̂íĉ śûb́ŝét̂ óf̂ `ár̂íâ-*` át̂t́r̂íb̂út̂éŝ. Ḿîśm̂át̂ćĥín̂ǵ t̂h́êśê ín̂v́âĺîd́ât́êś t̂h́ê `ár̂íâ-*` át̂t́r̂íb̂út̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-ál̂ĺôẃêd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Êáĉh́ ÂŔÎÁ `role` ŝúp̂ṕôŕt̂ś â śp̂éĉíf̂íĉ śûb́ŝét̂ óf̂ `aria-*` át̂t́r̂íb̂út̂éŝ. Ḿîśm̂át̂ćĥín̂ǵ t̂h́êśê ín̂v́âĺîd́ât́êś t̂h́ê `aria-*` át̂t́r̂íb̂út̂éŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ ḿât́ĉh́ t̂h́êír̂ ŕôĺêś" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ ḿât́ĉh́ t̂h́êír̂ ŕôĺêś" }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś m̂át̂ćĥ t́ĥéîŕ r̂ól̂éŝ" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś m̂át̂ćĥ t́ĥéîŕ r̂ól̂éŝ" }, "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ r̂ól̂éŝ h́âv́ê ŕêq́ûír̂éd̂ át̂t́r̂íb̂út̂éŝ t́ĥát̂ d́êśĉŕîb́ê t́ĥé ŝt́ât́ê óf̂ t́ĥé êĺêḿêńt̂ t́ô śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ r̂ól̂éŝ h́âv́ê ŕêq́ûír̂éd̂ át̂t́r̂íb̂út̂éŝ t́ĥát̂ d́êśĉŕîb́ê t́ĥé ŝt́ât́ê óf̂ t́ĥé êĺêḿêńt̂ t́ô śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { - "message": "`[r̂ól̂é]`ŝ d́ô ńôt́ ĥáv̂é âĺl̂ ŕêq́ûír̂éd̂ `[ár̂íâ-*]` át̂t́r̂íb̂út̂éŝ" + "message": "`[role]`ŝ d́ô ńôt́ ĥáv̂é âĺl̂ ŕêq́ûír̂éd̂ `[aria-*]` át̂t́r̂íb̂út̂éŝ" }, "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { - "message": "`[r̂ól̂é]`ŝ h́âv́ê ál̂ĺ r̂éq̂úîŕêd́ `[âŕîá-*]` ât́t̂ŕîb́ût́êś" + "message": "`[role]`ŝ h́âv́ê ál̂ĺ r̂éq̂úîŕêd́ `[aria-*]` ât́t̂ŕîb́ût́êś" }, "lighthouse-core/audits/accessibility/aria-required-children.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ p̂ár̂én̂t́ r̂ól̂éŝ ḿûśt̂ ćôńt̂áîń ŝṕêćîf́îć ĉh́îĺd̂ ŕôĺêś t̂ó p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-ĉh́îĺd̂ŕêń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ p̂ár̂én̂t́ r̂ól̂éŝ ḿûśt̂ ćôńt̂áîń ŝṕêćîf́îć ĉh́îĺd̂ ŕôĺêś t̂ó p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ `[r̂ól̂é]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[ŕôĺê]`ś, âŕê ḿîśŝín̂ǵ." + "message": "Êĺêḿêńt̂ś ŵít̂h́ `[role]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[role]`ś, âŕê ḿîśŝín̂ǵ." }, "lighthouse-core/audits/accessibility/aria-required-children.js | title": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ `[r̂ól̂é]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[ŕôĺê]`ś, âŕê ṕr̂éŝén̂t́" + "message": "Êĺêḿêńt̂ś ŵít̂h́ `[role]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[role]`ś, âŕê ṕr̂éŝén̂t́" }, "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ ĉh́îĺd̂ ŕôĺêś m̂úŝt́ b̂é ĉón̂t́âín̂éd̂ b́ŷ śp̂éĉíf̂íĉ ṕâŕêńt̂ ŕôĺêś t̂ó p̂ŕôṕêŕl̂ý p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-p̂ár̂én̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ ĉh́îĺd̂ ŕôĺêś m̂úŝt́ b̂é ĉón̂t́âín̂éd̂ b́ŷ śp̂éĉíf̂íĉ ṕâŕêńt̂ ŕôĺêś t̂ó p̂ŕôṕêŕl̂ý p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { - "message": "`[r̂ól̂é]`ŝ ár̂é n̂ót̂ ćôńt̂áîńêd́ b̂ý t̂h́êír̂ ŕêq́ûír̂éd̂ ṕâŕêńt̂ él̂ém̂én̂t́" + "message": "`[role]`ŝ ár̂é n̂ót̂ ćôńt̂áîńêd́ b̂ý t̂h́êír̂ ŕêq́ûír̂éd̂ ṕâŕêńt̂ él̂ém̂én̂t́" }, "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { - "message": "`[r̂ól̂é]`ŝ ár̂é ĉón̂t́âín̂éd̂ b́ŷ t́ĥéîŕ r̂éq̂úîŕêd́ p̂ár̂én̂t́ êĺêḿêńt̂" + "message": "`[role]`ŝ ár̂é ĉón̂t́âín̂éd̂ b́ŷ t́ĥéîŕ r̂éq̂úîŕêd́ p̂ár̂én̂t́ êĺêḿêńt̂" }, "lighthouse-core/audits/accessibility/aria-roles.js | description": { - "message": "ÂŔÎÁ r̂ól̂éŝ ḿûśt̂ h́âv́ê v́âĺîd́ v̂ál̂úêś îń ôŕd̂ér̂ t́ô ṕêŕf̂ór̂ḿ t̂h́êír̂ ín̂t́êńd̂éd̂ áĉćêśŝíb̂íl̂ít̂ý f̂ún̂ćt̂íôńŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-ŕôĺêś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "ÂŔÎÁ r̂ól̂éŝ ḿûśt̂ h́âv́ê v́âĺîd́ v̂ál̂úêś îń ôŕd̂ér̂ t́ô ṕêŕf̂ór̂ḿ t̂h́êír̂ ín̂t́êńd̂éd̂ áĉćêśŝíb̂íl̂ít̂ý f̂ún̂ćt̂íôńŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { - "message": "`[r̂ól̂é]` v̂ál̂úêś âŕê ńôt́ v̂ál̂íd̂" + "message": "`[role]` v̂ál̂úêś âŕê ńôt́ v̂ál̂íd̂" }, "lighthouse-core/audits/accessibility/aria-roles.js | title": { - "message": "`[r̂ól̂é]` v̂ál̂úêś âŕê v́âĺîd́" + "message": "`[role]` v̂ál̂úêś âŕê v́âĺîd́" }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ v̂ál̂úêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-v̂ál̂íd̂-át̂t́r̂-v́âĺûé?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ v̂ál̂úêś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê v́âĺîd́ v̂ál̂úêś" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê v́âĺîd́ v̂ál̂úêś" }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś ĥáv̂é v̂ál̂íd̂ v́âĺûéŝ" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś ĥáv̂é v̂ál̂íd̂ v́âĺûéŝ" }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ n̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-v́âĺîd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ n̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)." }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś âŕê ńôt́ v̂ál̂íd̂ ór̂ ḿîśŝṕêĺl̂éd̂" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś âŕê ńôt́ v̂ál̂íd̂ ór̂ ḿîśŝṕêĺl̂éd̂" }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś âŕê v́âĺîd́ âńd̂ ńôt́ m̂íŝśp̂él̂ĺêd́" + "message": "`[aria-*]` ât́t̂ŕîb́ût́êś âŕê v́âĺîd́ âńd̂ ńôt́ m̂íŝśp̂él̂ĺêd́" }, "lighthouse-core/audits/accessibility/audio-caption.js | description": { - "message": "Ĉáp̂t́îón̂ś m̂ák̂é âúd̂íô él̂ém̂én̂t́ŝ úŝáb̂ĺê f́ôŕ d̂éâf́ ôŕ ĥéâŕîńĝ-ím̂ṕâír̂éd̂ úŝér̂ś, p̂ŕôv́îd́îńĝ ćr̂ít̂íĉál̂ ín̂f́ôŕm̂át̂íôń ŝúĉh́ âś ŵh́ô íŝ t́âĺk̂ín̂ǵ, ŵh́ât́ t̂h́êý'r̂é ŝáŷín̂ǵ, âńd̂ ót̂h́êŕ n̂ón̂-śp̂éêćĥ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âúd̂íô-ćâṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ĉáp̂t́îón̂ś m̂ák̂é âúd̂íô él̂ém̂én̂t́ŝ úŝáb̂ĺê f́ôŕ d̂éâf́ ôŕ ĥéâŕîńĝ-ím̂ṕâír̂éd̂ úŝér̂ś, p̂ŕôv́îd́îńĝ ćr̂ít̂íĉál̂ ín̂f́ôŕm̂át̂íôń ŝúĉh́ âś ŵh́ô íŝ t́âĺk̂ín̂ǵ, ŵh́ât́ t̂h́êý'r̂é ŝáŷín̂ǵ, âńd̂ ót̂h́êŕ n̂ón̂-śp̂éêćĥ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)." }, "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { - "message": "`<âúd̂íô>` él̂ém̂én̂t́ŝ ár̂é m̂íŝśîńĝ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"ĉáp̂t́îón̂ś\"]`." + "message": "`<audio>` êĺêḿêńt̂ś âŕê ḿîśŝín̂ǵ â `<track>` él̂ém̂én̂t́ ŵít̂h́ `[kind=\"captions\"]`." }, "lighthouse-core/audits/accessibility/audio-caption.js | title": { - "message": "`<âúd̂íô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"ćâṕt̂íôńŝ\"]`" + "message": "`<audio>` êĺêḿêńt̂ś ĉón̂t́âín̂ á `<track>` êĺêḿêńt̂ ẃît́ĥ `[kind=\"captions\"]`" }, "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/accessibility/button-name.js | description": { - "message": "Ŵh́êń â b́ût́t̂ón̂ d́ôéŝń't̂ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê, śĉŕêén̂ ŕêád̂ér̂ś âńn̂óûńĉé ît́ âś \"b̂út̂t́ôń\", m̂ák̂ín̂ǵ ît́ ûńûśâb́l̂é f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/b̂út̂t́ôń-n̂ám̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŵh́êń â b́ût́t̂ón̂ d́ôéŝń't̂ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê, śĉŕêén̂ ŕêád̂ér̂ś âńn̂óûńĉé ît́ âś \"b̂út̂t́ôń\", m̂ák̂ín̂ǵ ît́ ûńûśâb́l̂é f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)." }, "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { "message": "B̂út̂t́ôńŝ d́ô ńôt́ ĥáv̂é âń âćĉéŝśîb́l̂é n̂ám̂é" @@ -93,7 +93,7 @@ "message": "B̂út̂t́ôńŝ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê" }, "lighthouse-core/audits/accessibility/bypass.js | description": { - "message": "Âd́d̂ín̂ǵ ŵáŷś t̂ó b̂ýp̂áŝś r̂ép̂ét̂ít̂ív̂é ĉón̂t́êńt̂ ĺêt́ŝ ḱêýb̂óâŕd̂ úŝér̂ś n̂áv̂íĝát̂é t̂h́ê ṕâǵê ḿôŕê éf̂f́îćîén̂t́l̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/b̂ýp̂áŝś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âd́d̂ín̂ǵ ŵáŷś t̂ó b̂ýp̂áŝś r̂ép̂ét̂ít̂ív̂é ĉón̂t́êńt̂ ĺêt́ŝ ḱêýb̂óâŕd̂ úŝér̂ś n̂áv̂íĝát̂é t̂h́ê ṕâǵê ḿôŕê éf̂f́îćîén̂t́l̂ý. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)." }, "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { "message": "T̂h́ê ṕâǵê d́ôéŝ ńôt́ ĉón̂t́âín̂ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" @@ -102,7 +102,7 @@ "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" }, "lighthouse-core/audits/accessibility/color-contrast.js | description": { - "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/ĉól̂ór̂-ćôńt̂ŕâśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)." }, "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ d́ô ńôt́ ĥáv̂é â śûf́f̂íĉíêńt̂ ćôńt̂ŕâśt̂ ŕât́îó." @@ -111,88 +111,88 @@ "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ h́âv́ê á ŝúf̂f́îćîén̂t́ ĉón̂t́r̂áŝt́ r̂át̂íô" }, "lighthouse-core/audits/accessibility/definition-list.js | description": { - "message": "Ŵh́êń d̂éf̂ín̂ít̂íôń l̂íŝt́ŝ ár̂é n̂ót̂ ṕr̂óp̂ér̂ĺŷ ḿâŕk̂éd̂ úp̂, śĉŕêén̂ ŕêád̂ér̂ś m̂áŷ ṕr̂ód̂úĉé ĉón̂f́ûśîńĝ ór̂ ín̂áĉćûŕât́ê óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/d́êf́îńît́îón̂-ĺîśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŵh́êń d̂éf̂ín̂ít̂íôń l̂íŝt́ŝ ár̂é n̂ót̂ ṕr̂óp̂ér̂ĺŷ ḿâŕk̂éd̂ úp̂, śĉŕêén̂ ŕêád̂ér̂ś m̂áŷ ṕr̂ód̂úĉé ĉón̂f́ûśîńĝ ór̂ ín̂áĉćûŕât́ê óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)." }, "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { - "message": "`<d̂ĺ>`'ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ ṕr̂óp̂ér̂ĺŷ-ór̂d́êŕêd́ `<d̂t́>` âńd̂ `<d́d̂>` ǵr̂óûṕŝ, `<śĉŕîṕt̂>` ór̂ `<t́êḿp̂ĺât́ê>` él̂ém̂én̂t́ŝ." + "message": "`<dl>`'ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ ṕr̂óp̂ér̂ĺŷ-ór̂d́êŕêd́ `<dt>` âńd̂ `<dd>` ǵr̂óûṕŝ, `<script>` ór̂ `<template>` él̂ém̂én̂t́ŝ." }, "lighthouse-core/audits/accessibility/definition-list.js | title": { - "message": "`<d̂ĺ>`'ŝ ćôńt̂áîń ôńl̂ý p̂ŕôṕêŕl̂ý-ôŕd̂ér̂éd̂ `<d́t̂>` án̂d́ `<d̂d́>` ĝŕôúp̂ś, `<ŝćr̂íp̂t́>` ôŕ `<t̂ém̂ṕl̂át̂é>` êĺêḿêńt̂ś." + "message": "`<dl>`'ŝ ćôńt̂áîń ôńl̂ý p̂ŕôṕêŕl̂ý-ôŕd̂ér̂éd̂ `<dt>` án̂d́ `<dd>` ĝŕôúp̂ś, `<script>` ôŕ `<template>` êĺêḿêńt̂ś." }, "lighthouse-core/audits/accessibility/dlitem.js | description": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ (`<d́t̂>` án̂d́ `<d̂d́>`) m̂úŝt́ b̂é ŵŕâṕp̂éd̂ ín̂ á p̂ár̂én̂t́ `<d̂ĺ>` êĺêḿêńt̂ t́ô én̂śûŕê t́ĥát̂ śĉŕêén̂ ŕêád̂ér̂ś ĉán̂ ṕr̂óp̂ér̂ĺŷ án̂ńôún̂ćê t́ĥém̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/d́l̂ít̂ém̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ (`<dt>` án̂d́ `<dd>`) m̂úŝt́ b̂é ŵŕâṕp̂éd̂ ín̂ á p̂ár̂én̂t́ `<dl>` êĺêḿêńt̂ t́ô én̂śûŕê t́ĥát̂ śĉŕêén̂ ŕêád̂ér̂ś ĉán̂ ṕr̂óp̂ér̂ĺŷ án̂ńôún̂ćê t́ĥém̂. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)." }, "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é n̂ót̂ ẃr̂áp̂ṕêd́ îń `<d̂ĺ>` êĺêḿêńt̂ś" + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é n̂ót̂ ẃr̂áp̂ṕêd́ îń `<dl>` êĺêḿêńt̂ś" }, "lighthouse-core/audits/accessibility/dlitem.js | title": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é ŵŕâṕp̂éd̂ ín̂ `<d́l̂>` él̂ém̂én̂t́ŝ" + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é ŵŕâṕp̂éd̂ ín̂ `<dl>` él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/accessibility/document-title.js | description": { - "message": "T̂h́ê t́ît́l̂é ĝív̂éŝ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś âń ôv́êŕv̂íêẃ ôf́ t̂h́ê ṕâǵê, án̂d́ ŝéâŕĉh́ êńĝín̂é ûśêŕŝ ŕêĺŷ ón̂ ít̂ h́êáv̂íl̂ý t̂ó d̂ét̂ér̂ḿîńê íf̂ á p̂áĝé îś r̂él̂év̂án̂t́ t̂ó t̂h́êír̂ śêár̂ćĥ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂ít̂ĺê)." + "message": "T̂h́ê t́ît́l̂é ĝív̂éŝ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś âń ôv́êŕv̂íêẃ ôf́ t̂h́ê ṕâǵê, án̂d́ ŝéâŕĉh́ êńĝín̂é ûśêŕŝ ŕêĺŷ ón̂ ít̂ h́êáv̂íl̂ý t̂ó d̂ét̂ér̂ḿîńê íf̂ á p̂áĝé îś r̂él̂év̂án̂t́ t̂ó t̂h́êír̂ śêár̂ćĥ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/title)." }, "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â `<t́ît́l̂é>` êĺêḿêńt̂" + "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â `<title>` él̂ém̂én̂t́" }, "lighthouse-core/audits/accessibility/document-title.js | title": { "message": "p̂ĺâćêh́ôĺd̂ér̂" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { - "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/d̂úp̂ĺîćât́ê-íd̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)." }, "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { - "message": "`[îd́]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é n̂ót̂ ún̂íq̂úê" + "message": "`[id]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é n̂ót̂ ún̂íq̂úê" }, "lighthouse-core/audits/accessibility/duplicate-id.js | title": { - "message": "`[îd́]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é ûńîq́ûé" + "message": "`[id]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é ûńîq́ûé" }, "lighthouse-core/audits/accessibility/frame-title.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ŕêĺŷ ón̂ f́r̂ám̂é t̂ít̂ĺêś t̂ó d̂éŝćr̂íb̂é t̂h́ê ćôńt̂én̂t́ŝ óf̂ f́r̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/f́r̂ám̂é-t̂ít̂ĺê?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ŕêĺŷ ón̂ f́r̂ám̂é t̂ít̂ĺêś t̂ó d̂éŝćr̂íb̂é t̂h́ê ćôńt̂én̂t́ŝ óf̂ f́r̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)." }, "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { - "message": "`<f̂ŕâḿê>` ór̂ `<íf̂ŕâḿê>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é â t́ît́l̂é" + "message": "`<frame>` ôŕ `<iframe>` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê á t̂ít̂ĺê" }, "lighthouse-core/audits/accessibility/frame-title.js | title": { - "message": "`<f̂ŕâḿê>` ór̂ `<íf̂ŕâḿê>` él̂ém̂én̂t́ŝ h́âv́ê á t̂ít̂ĺê" + "message": "`<frame>` ôŕ `<iframe>` êĺêḿêńt̂ś ĥáv̂é â t́ît́l̂é" }, "lighthouse-core/audits/accessibility/html-has-lang.js | description": { - "message": "Îf́ â ṕâǵê d́ôéŝń't̂ śp̂éĉíf̂ý â ĺâńĝ át̂t́r̂íb̂út̂é, â śĉŕêén̂ ŕêád̂ér̂ áŝśûḿêś t̂h́ât́ t̂h́ê ṕâǵê íŝ ín̂ t́ĥé d̂éf̂áûĺt̂ ĺâńĝúâǵê t́ĥát̂ t́ĥé ûśêŕ ĉh́ôśê ẃĥén̂ śêt́t̂ín̂ǵ ûṕ t̂h́ê śĉŕêén̂ ŕêád̂ér̂. Íf̂ t́ĥé p̂áĝé îśn̂'t́ âćt̂úâĺl̂ý îń t̂h́ê d́êf́âúl̂t́ l̂án̂ǵûáĝé, t̂h́êń t̂h́ê śĉŕêén̂ ŕêád̂ér̂ ḿîǵĥt́ n̂ót̂ án̂ńôún̂ćê t́ĥé p̂áĝé'ŝ t́êx́t̂ ćôŕr̂éĉt́l̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/ĥt́m̂ĺ-ĥáŝ-ĺâńĝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Îf́ â ṕâǵê d́ôéŝń't̂ śp̂éĉíf̂ý â ĺâńĝ át̂t́r̂íb̂út̂é, â śĉŕêén̂ ŕêád̂ér̂ áŝśûḿêś t̂h́ât́ t̂h́ê ṕâǵê íŝ ín̂ t́ĥé d̂éf̂áûĺt̂ ĺâńĝúâǵê t́ĥát̂ t́ĥé ûśêŕ ĉh́ôśê ẃĥén̂ śêt́t̂ín̂ǵ ûṕ t̂h́ê śĉŕêén̂ ŕêád̂ér̂. Íf̂ t́ĥé p̂áĝé îśn̂'t́ âćt̂úâĺl̂ý îń t̂h́ê d́êf́âúl̂t́ l̂án̂ǵûáĝé, t̂h́êń t̂h́ê śĉŕêén̂ ŕêád̂ér̂ ḿîǵĥt́ n̂ót̂ án̂ńôún̂ćê t́ĥé p̂áĝé'ŝ t́êx́t̂ ćôŕr̂éĉt́l̂ý. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)." }, "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "`<html>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â `[lang]` át̂t́r̂íb̂út̂é" }, "lighthouse-core/audits/accessibility/html-has-lang.js | title": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ h́âś â `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "`<html>` êĺêḿêńt̂ h́âś â `[lang]` át̂t́r̂íb̂út̂é" }, "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](h́t̂t́p̂ś://ŵẃŵ.ẃ3.ôŕĝ/Ín̂t́êŕn̂át̂íôńâĺ/q̂úêśt̂íôńŝ/q́â-ćĥóôśîńĝ-ĺâńĝúâǵê-t́âǵŝ#q́ûéŝt́îón̂) h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ án̂ńôún̂ćê t́êx́t̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/v́âĺîd́-l̂án̂ǵ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](https://www.w3.org/International/questions/qa-choosing-language-tags#question) h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ án̂ńôún̂ćê t́êx́t̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)." }, "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[ĺâńĝ]` át̂t́r̂íb̂út̂é." + "message": "`<html>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[lang]` át̂t́r̂íb̂út̂é." }, "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ h́âś â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "`<html>` êĺêḿêńt̂ h́âś â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[lang]` át̂t́r̂íb̂út̂é" }, "lighthouse-core/audits/accessibility/image-alt.js | description": { - "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ím̂áĝé-âĺt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)." }, "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é `[âĺt̂]` át̂t́r̂íb̂út̂éŝ" + "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é `[alt]` ât́t̂ŕîb́ût́êś" }, "lighthouse-core/audits/accessibility/image-alt.js | title": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê `[ál̂t́]` ât́t̂ŕîb́ût́êś" + "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê `[alt]` át̂t́r̂íb̂út̂éŝ" }, "lighthouse-core/audits/accessibility/input-image-alt.js | description": { - "message": "Ŵh́êń âń îḿâǵê íŝ b́êín̂ǵ ûśêd́ âś âń `<îńp̂út̂>` b́ût́t̂ón̂, ṕr̂óv̂íd̂ín̂ǵ âĺt̂ér̂ńât́îv́ê t́êx́t̂ ćâń ĥél̂ṕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ún̂d́êŕŝt́âńd̂ t́ĥé p̂úr̂ṕôśê óf̂ t́ĥé b̂út̂t́ôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/îńp̂út̂-ím̂áĝé-âĺt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŵh́êń âń îḿâǵê íŝ b́êín̂ǵ ûśêd́ âś âń `<input>` b̂út̂t́ôń, p̂ŕôv́îd́îńĝ ál̂t́êŕn̂át̂ív̂é t̂éx̂t́ ĉán̂ h́êĺp̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś ûńd̂ér̂śt̂án̂d́ t̂h́ê ṕûŕp̂óŝé ôf́ t̂h́ê b́ût́t̂ón̂. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)." }, "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { - "message": "`<îńp̂út̂ t́ŷṕê=\"ím̂áĝé\">` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[ál̂t́]` t̂éx̂t́" + "message": "`<input type=\"image\">` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[alt]` t́êx́t̂" }, "lighthouse-core/audits/accessibility/input-image-alt.js | title": { - "message": "`<îńp̂út̂ t́ŷṕê=\"ím̂áĝé\">` êĺêḿêńt̂ś ĥáv̂é `[âĺt̂]` t́êx́t̂" + "message": "`<input type=\"image\">` êĺêḿêńt̂ś ĥáv̂é `[alt]` t̂éx̂t́" }, "lighthouse-core/audits/accessibility/label.js | description": { - "message": "L̂áb̂él̂ś êńŝúr̂é t̂h́ât́ f̂ór̂ḿ ĉón̂t́r̂ól̂ś âŕê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý b̂ý âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂áb̂él̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "L̂áb̂él̂ś êńŝúr̂é t̂h́ât́ f̂ór̂ḿ ĉón̂t́r̂ól̂ś âŕê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý b̂ý âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)." }, "lighthouse-core/audits/accessibility/label.js | failureTitle": { "message": "F̂ór̂ḿ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê áŝśôćîát̂éd̂ ĺâb́êĺŝ" @@ -201,16 +201,16 @@ "message": "F̂ór̂ḿ êĺêḿêńt̂ś ĥáv̂é âśŝóĉíât́êd́ l̂áb̂él̂ś" }, "lighthouse-core/audits/accessibility/layout-table.js | description": { - "message": " t́âb́l̂é b̂éîńĝ úŝéd̂ f́ôŕ l̂áŷóût́ p̂úr̂ṕôśêś ŝh́ôúl̂d́ n̂ót̂ ín̂ćl̂úd̂é d̂át̂á êĺêḿêńt̂ś, ŝúĉh́ âś t̂h́ê t́ĥ ór̂ ćâṕt̂íôń êĺêḿêńt̂ś ôŕ t̂h́ê śûḿm̂ár̂ý ât́t̂ŕîb́ût́ê, b́êćâúŝé t̂h́îś ĉán̂ ćr̂éât́ê á ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ĺâýôút̂-t́âb́l̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": " t́âb́l̂é b̂éîńĝ úŝéd̂ f́ôŕ l̂áŷóût́ p̂úr̂ṕôśêś ŝh́ôúl̂d́ n̂ót̂ ín̂ćl̂úd̂é d̂át̂á êĺêḿêńt̂ś, ŝúĉh́ âś t̂h́ê t́ĥ ór̂ ćâṕt̂íôń êĺêḿêńt̂ś ôŕ t̂h́ê śûḿm̂ár̂ý ât́t̂ŕîb́ût́ê, b́êćâúŝé t̂h́îś ĉán̂ ćr̂éât́ê á ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)." }, "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ `<t̂áb̂ĺê>` él̂ém̂én̂t́ŝ d́ô ńôt́ âv́ôíd̂ úŝín̂ǵ `<t̂h́>`, `<ĉáp̂t́îón̂>` ór̂ t́ĥé `[ŝúm̂ḿâŕŷ]` át̂t́r̂íb̂út̂é." + "message": "P̂ŕêśêńt̂át̂íôńâĺ `<table>` êĺêḿêńt̂ś d̂ó n̂ót̂ áv̂óîd́ ûśîńĝ `<th>`, `<caption>` ór̂ t́ĥé `[summary]` ât́t̂ŕîb́ût́ê." }, "lighthouse-core/audits/accessibility/layout-table.js | title": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ `<t̂áb̂ĺê>` él̂ém̂én̂t́ŝ áv̂óîd́ ûśîńĝ `<t́ĥ>`, `<ćâṕt̂íôń>` ôŕ t̂h́ê `[śûḿm̂ár̂ý]` ât́t̂ŕîb́ût́ê." + "message": "P̂ŕêśêńt̂át̂íôńâĺ `<table>` êĺêḿêńt̂ś âv́ôíd̂ úŝín̂ǵ `<th>`, `<caption>` ôŕ t̂h́ê `[summary]` át̂t́r̂íb̂út̂é." }, "lighthouse-core/audits/accessibility/link-name.js | description": { - "message": "L̂ín̂ḱ t̂éx̂t́ (âńd̂ ál̂t́êŕn̂át̂é t̂éx̂t́ f̂ór̂ ím̂áĝéŝ, ẃĥén̂ úŝéd̂ áŝ ĺîńk̂ś) t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê, ún̂íq̂úê, án̂d́ f̂óĉúŝáb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé n̂áv̂íĝát̂íôń êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂ín̂ḱ-n̂ám̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "L̂ín̂ḱ t̂éx̂t́ (âńd̂ ál̂t́êŕn̂át̂é t̂éx̂t́ f̂ór̂ ím̂áĝéŝ, ẃĥén̂ úŝéd̂ áŝ ĺîńk̂ś) t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê, ún̂íq̂úê, án̂d́ f̂óĉúŝáb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé n̂áv̂íĝát̂íôń êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)." }, "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { "message": "L̂ín̂ḱŝ d́ô ńôt́ ĥáv̂é â d́îśĉér̂ńîb́l̂é n̂ám̂é" @@ -219,115 +219,115 @@ "message": "L̂ín̂ḱŝ h́âv́ê á d̂íŝćêŕn̂íb̂ĺê ńâḿê" }, "lighthouse-core/audits/accessibility/list.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê á ŝṕêćîf́îć ŵáŷ óf̂ án̂ńôún̂ćîńĝ ĺîśt̂ś. Êńŝúr̂ín̂ǵ p̂ŕôṕêŕ l̂íŝt́ ŝt́r̂úĉt́ûŕê áîd́ŝ śĉŕêén̂ ŕêád̂ér̂ óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ĺîśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê á ŝṕêćîf́îć ŵáŷ óf̂ án̂ńôún̂ćîńĝ ĺîśt̂ś. Êńŝúr̂ín̂ǵ p̂ŕôṕêŕ l̂íŝt́ ŝt́r̂úĉt́ûŕê áîd́ŝ śĉŕêén̂ ŕêád̂ér̂ óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)." }, "lighthouse-core/audits/accessibility/list.js | failureTitle": { - "message": "L̂íŝt́ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ `<ĺî>` él̂ém̂én̂t́ŝ án̂d́ ŝćr̂íp̂t́ ŝúp̂ṕôŕt̂ín̂ǵ êĺêḿêńt̂ś (`<ŝćr̂íp̂t́>` âńd̂ `<t́êḿp̂ĺât́ê>`)." + "message": "L̂íŝt́ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ `<li>` él̂ém̂én̂t́ŝ án̂d́ ŝćr̂íp̂t́ ŝúp̂ṕôŕt̂ín̂ǵ êĺêḿêńt̂ś (`<script>` âńd̂ `<template>`)." }, "lighthouse-core/audits/accessibility/list.js | title": { - "message": "L̂íŝt́ŝ ćôńt̂áîń ôńl̂ý `<l̂í>` êĺêḿêńt̂ś âńd̂ śĉŕîṕt̂ śûṕp̂ór̂t́îńĝ él̂ém̂én̂t́ŝ (`<śĉŕîṕt̂>` án̂d́ `<t̂ém̂ṕl̂át̂é>`)." + "message": "L̂íŝt́ŝ ćôńt̂áîń ôńl̂ý `<li>` êĺêḿêńt̂ś âńd̂ śĉŕîṕt̂ śûṕp̂ór̂t́îńĝ él̂ém̂én̂t́ŝ (`<script>` án̂d́ `<template>`)." }, "lighthouse-core/audits/accessibility/listitem.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ŕêq́ûír̂é l̂íŝt́ ît́êḿŝ (`<ĺî>`) t́ô b́ê ćôńt̂áîńêd́ ŵít̂h́îń â ṕâŕêńt̂ `<úl̂>` ór̂ `<ól̂>` t́ô b́ê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂íŝt́ît́êḿ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ ŕêq́ûír̂é l̂íŝt́ ît́êḿŝ (`<li>`) t́ô b́ê ćôńt̂áîńêd́ ŵít̂h́îń â ṕâŕêńt̂ `<ul>` ór̂ `<ol>` t́ô b́ê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)." }, "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { - "message": "L̂íŝt́ ît́êḿŝ (`<ĺî>`) ár̂é n̂ót̂ ćôńt̂áîńêd́ ŵít̂h́îń `<ûĺ>` ôŕ `<ôĺ>` p̂ár̂én̂t́ êĺêḿêńt̂ś." + "message": "L̂íŝt́ ît́êḿŝ (`<li>`) ár̂é n̂ót̂ ćôńt̂áîńêd́ ŵít̂h́îń `<ul>` ôŕ `<ol>` p̂ár̂én̂t́ êĺêḿêńt̂ś." }, "lighthouse-core/audits/accessibility/listitem.js | title": { - "message": "L̂íŝt́ ît́êḿŝ (`<ĺî>`) ár̂é ĉón̂t́âín̂éd̂ ẃît́ĥín̂ `<úl̂>` ór̂ `<ól̂>` ṕâŕêńt̂ él̂ém̂én̂t́ŝ" + "message": "L̂íŝt́ ît́êḿŝ (`<li>`) ár̂é ĉón̂t́âín̂éd̂ ẃît́ĥín̂ `<ul>` ór̂ `<ol>` ṕâŕêńt̂ él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/accessibility/meta-refresh.js | description": { - "message": "Ûśêŕŝ d́ô ńôt́ êx́p̂éĉt́ â ṕâǵê t́ô ŕêf́r̂éŝh́ âút̂óm̂át̂íĉál̂ĺŷ, án̂d́ d̂óîńĝ śô ẃîĺl̂ ḿôv́ê f́ôćûś b̂áĉḱ t̂ó t̂h́ê t́ôṕ ôf́ t̂h́ê ṕâǵê. T́ĥíŝ ḿâý ĉŕêát̂é â f́r̂úŝt́r̂át̂ín̂ǵ ôŕ ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ḿêt́â-ŕêf́r̂éŝh́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ûśêŕŝ d́ô ńôt́ êx́p̂éĉt́ â ṕâǵê t́ô ŕêf́r̂éŝh́ âút̂óm̂át̂íĉál̂ĺŷ, án̂d́ d̂óîńĝ śô ẃîĺl̂ ḿôv́ê f́ôćûś b̂áĉḱ t̂ó t̂h́ê t́ôṕ ôf́ t̂h́ê ṕâǵê. T́ĥíŝ ḿâý ĉŕêát̂é â f́r̂úŝt́r̂át̂ín̂ǵ ôŕ ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)." }, "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { - "message": "T̂h́ê d́ôćûḿêńt̂ úŝéŝ `<ḿêt́â h́t̂t́p̂-éq̂úîv́=\"r̂éf̂ŕêśĥ\">`" + "message": "T̂h́ê d́ôćûḿêńt̂ úŝéŝ `<meta http-equiv=\"refresh\">`" }, "lighthouse-core/audits/accessibility/meta-refresh.js | title": { - "message": "T̂h́ê d́ôćûḿêńt̂ d́ôéŝ ńôt́ ûśê `<ḿêt́â h́t̂t́p̂-éq̂úîv́=\"r̂éf̂ŕêśĥ\">`" + "message": "T̂h́ê d́ôćûḿêńt̂ d́ôéŝ ńôt́ ûśê `<meta http-equiv=\"refresh\">`" }, "lighthouse-core/audits/accessibility/meta-viewport.js | description": { - "message": "D̂íŝáb̂ĺîńĝ źôóm̂ín̂ǵ îś p̂ŕôb́l̂ém̂át̂íĉ f́ôŕ ûśêŕŝ ẃît́ĥ ĺôẃ v̂íŝíôń ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ḿâǵn̂íf̂íĉát̂íôń t̂ó p̂ŕôṕêŕl̂ý ŝéê t́ĥé ĉón̂t́êńt̂ś ôf́ â ẃêb́ p̂áĝé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/m̂ét̂á-v̂íêẃp̂ór̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "D̂íŝáb̂ĺîńĝ źôóm̂ín̂ǵ îś p̂ŕôb́l̂ém̂át̂íĉ f́ôŕ ûśêŕŝ ẃît́ĥ ĺôẃ v̂íŝíôń ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ḿâǵn̂íf̂íĉát̂íôń t̂ó p̂ŕôṕêŕl̂ý ŝéê t́ĥé ĉón̂t́êńt̂ś ôf́ â ẃêb́ p̂áĝé. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)." }, "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { - "message": "`[ûśêŕ-ŝćâĺâb́l̂é=\"n̂ó\"]` îś ûśêd́ îń t̂h́ê `<ḿêt́â ńâḿê=\"v́îéŵṕôŕt̂\">` él̂ém̂én̂t́ ôŕ t̂h́ê `[ḿâx́îḿûḿ-ŝćâĺê]` át̂t́r̂íb̂út̂é îś l̂éŝś t̂h́âń 5." + "message": "`[user-scalable=\"no\"]` îś ûśêd́ îń t̂h́ê `<meta name=\"viewport\">` él̂ém̂én̂t́ ôŕ t̂h́ê `[maximum-scale]` át̂t́r̂íb̂út̂é îś l̂éŝś t̂h́âń 5." }, "lighthouse-core/audits/accessibility/meta-viewport.js | title": { - "message": "`[ûśêŕ-ŝćâĺâb́l̂é=\"n̂ó\"]` îś n̂ót̂ úŝéd̂ ín̂ t́ĥé `<m̂ét̂á n̂ám̂é=\"v̂íêẃp̂ór̂t́\">` êĺêḿêńt̂ án̂d́ t̂h́ê `[ḿâx́îḿûḿ-ŝćâĺê]` át̂t́r̂íb̂út̂é îś n̂ót̂ ĺêśŝ t́ĥán̂ 5." + "message": "`[user-scalable=\"no\"]` îś n̂ót̂ úŝéd̂ ín̂ t́ĥé `<meta name=\"viewport\">` êĺêḿêńt̂ án̂d́ t̂h́ê `[maximum-scale]` át̂t́r̂íb̂út̂é îś n̂ót̂ ĺêśŝ t́ĥán̂ 5." }, "lighthouse-core/audits/accessibility/object-alt.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ćâńn̂ót̂ t́r̂án̂śl̂át̂é n̂ón̂-t́êx́t̂ ćôńt̂én̂t́. Âd́d̂ín̂ǵ âĺt̂ t́êx́t̂ t́ô `<ób̂j́êćt̂>` él̂ém̂én̂t́ŝ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ ćôńv̂éŷ ḿêán̂ín̂ǵ t̂ó ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ób̂j́êćt̂-ál̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ ćâńn̂ót̂ t́r̂án̂śl̂át̂é n̂ón̂-t́êx́t̂ ćôńt̂én̂t́. Âd́d̂ín̂ǵ âĺt̂ t́êx́t̂ t́ô `<object>` él̂ém̂én̂t́ŝ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ ćôńv̂éŷ ḿêán̂ín̂ǵ t̂ó ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)." }, "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { - "message": "`<ôb́ĵéĉt́>` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[ál̂t́]` t̂éx̂t́" + "message": "`<object>` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[alt]` t́êx́t̂" }, "lighthouse-core/audits/accessibility/object-alt.js | title": { - "message": "`<ôb́ĵéĉt́>` êĺêḿêńt̂ś ĥáv̂é `[âĺt̂]` t́êx́t̂" + "message": "`<object>` êĺêḿêńt̂ś ĥáv̂é `[alt]` t̂éx̂t́" }, "lighthouse-core/audits/accessibility/tabindex.js | description": { - "message": " v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0 ím̂ṕl̂íêś âń êx́p̂ĺîćît́ n̂áv̂íĝát̂íôń ôŕd̂ér̂ín̂ǵ. Âĺt̂h́ôúĝh́ t̂éĉh́n̂íĉál̂ĺŷ v́âĺîd́, t̂h́îś ôf́t̂én̂ ćr̂éât́êś f̂ŕûśt̂ŕât́îńĝ éx̂ṕêŕîén̂ćêś f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/t̂áb̂ín̂d́êx́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": " v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0 ím̂ṕl̂íêś âń êx́p̂ĺîćît́ n̂áv̂íĝát̂íôń ôŕd̂ér̂ín̂ǵ. Âĺt̂h́ôúĝh́ t̂éĉh́n̂íĉál̂ĺŷ v́âĺîd́, t̂h́îś ôf́t̂én̂ ćr̂éât́êś f̂ŕûśt̂ŕât́îńĝ éx̂ṕêŕîén̂ćêś f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)." }, "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { - "message": "Ŝóm̂é êĺêḿêńt̂ś ĥáv̂é â `[t́âb́îńd̂éx̂]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" + "message": "Ŝóm̂é êĺêḿêńt̂ś ĥáv̂é â `[tabindex]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" }, "lighthouse-core/audits/accessibility/tabindex.js | title": { - "message": "N̂ó êĺêḿêńt̂ h́âś â `[t́âb́îńd̂éx̂]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" + "message": "N̂ó êĺêḿêńt̂ h́âś â `[tabindex]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" }, "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ `<t́d̂>` ćêĺl̂ś ûśîńĝ t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ ín̂ t́ĥé ŝám̂é t̂áb̂ĺê ḿâý îḿp̂ŕôv́ê t́ĥé êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/t̂d́-ĥéâd́êŕŝ-át̂t́r̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ `<td>` ćêĺl̂ś ûśîńĝ t́ĥé `[headers]` ât́t̂ŕîb́ût́ê ón̂ĺŷ ŕêf́êŕ t̂ó ôt́ĥér̂ ćêĺl̂ś îń t̂h́ê śâḿê t́âb́l̂é m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)." }, "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { - "message": "Ĉél̂ĺŝ ín̂ á `<t̂áb̂ĺê>` él̂ém̂én̂t́ t̂h́ât́ ûśê t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é r̂éf̂ér̂ś t̂ó ôt́ĥér̂ ćêĺl̂ś ôf́ t̂h́ât́ ŝám̂é t̂áb̂ĺê." + "message": "Ĉél̂ĺŝ ín̂ á `<table>` êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê `[headers]` át̂t́r̂íb̂út̂é r̂éf̂ér̂ś t̂ó ôt́ĥér̂ ćêĺl̂ś ôf́ t̂h́ât́ ŝám̂é t̂áb̂ĺê." }, "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { - "message": "Ĉél̂ĺŝ ín̂ á `<t̂áb̂ĺê>` él̂ém̂én̂t́ t̂h́ât́ ûśê t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ óf̂ t́ĥát̂ śâḿê t́âb́l̂é." + "message": "Ĉél̂ĺŝ ín̂ á `<table>` êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê `[headers]` át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ óf̂ t́ĥát̂ śâḿê t́âb́l̂é." }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́âb́l̂é ĥéâd́êŕŝ ál̂ẃâýŝ ŕêf́êŕ t̂ó ŝóm̂é ŝét̂ óf̂ ćêĺl̂ś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/t́ĥ-h́âś-d̂át̂á-ĉél̂ĺŝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́âb́l̂é ĥéâd́êŕŝ ál̂ẃâýŝ ŕêf́êŕ t̂ó ŝóm̂é ŝét̂ óf̂ ćêĺl̂ś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)." }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { - "message": "`<t̂h́>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[ŕôĺê=\"ćôĺûḿn̂h́êád̂ér̂\"/\"ŕôẃĥéâd́êŕ\"]` d̂ó n̂ót̂ h́âv́ê d́ât́â ćêĺl̂ś t̂h́êý d̂éŝćr̂íb̂é." + "message": "`<th>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[role=\"columnheader\"/\"rowheader\"]` d́ô ńôt́ ĥáv̂é d̂át̂á ĉél̂ĺŝ t́ĥéŷ d́êśĉŕîb́ê." }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { - "message": "`<t̂h́>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[ŕôĺê=\"ćôĺûḿn̂h́êád̂ér̂\"/\"ŕôẃĥéâd́êŕ\"]` ĥáv̂é d̂át̂á ĉél̂ĺŝ t́ĥéŷ d́êśĉŕîb́ê." + "message": "`<th>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[role=\"columnheader\"/\"rowheader\"]` h́âv́ê d́ât́â ćêĺl̂ś t̂h́êý d̂éŝćr̂íb̂é." }, "lighthouse-core/audits/accessibility/valid-lang.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](h́t̂t́p̂ś://ŵẃŵ.ẃ3.ôŕĝ/Ín̂t́êŕn̂át̂íôńâĺ/q̂úêśt̂íôńŝ/q́â-ćĥóôśîńĝ-ĺâńĝúâǵê-t́âǵŝ#q́ûéŝt́îón̂) ón̂ él̂ém̂én̂t́ŝ h́êĺp̂ś êńŝúr̂é t̂h́ât́ t̂éx̂t́ îś p̂ŕôńôún̂ćêd́ ĉór̂ŕêćt̂ĺŷ b́ŷ á ŝćr̂éêń r̂éâd́êŕ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂ál̂íd̂-ĺâńĝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](https://www.w3.org/International/questions/qa-choosing-language-tags#question) ón̂ él̂ém̂én̂t́ŝ h́êĺp̂ś êńŝúr̂é t̂h́ât́ t̂éx̂t́ îś p̂ŕôńôún̂ćêd́ ĉór̂ŕêćt̂ĺŷ b́ŷ á ŝćr̂éêń r̂éâd́êŕ. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)." }, "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { - "message": "`[l̂án̂ǵ]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê á v̂ál̂íd̂ v́âĺûé" + "message": "`[lang]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê á v̂ál̂íd̂ v́âĺûé" }, "lighthouse-core/audits/accessibility/valid-lang.js | title": { - "message": "`[l̂án̂ǵ]` ât́t̂ŕîb́ût́êś ĥáv̂é â v́âĺîd́ v̂ál̂úê" + "message": "`[lang]` ât́t̂ŕîb́ût́êś ĥáv̂é â v́âĺîd́ v̂ál̂úê" }, "lighthouse-core/audits/accessibility/video-caption.js | description": { - "message": "Ŵh́êń â v́îd́êó p̂ŕôv́îd́êś â ćâṕt̂íôń ît́ îś êáŝíêŕ f̂ór̂ d́êáf̂ án̂d́ ĥéâŕîńĝ ím̂ṕâír̂éd̂ úŝér̂ś t̂ó âćĉéŝś ît́ŝ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂íd̂éô-ćâṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŵh́êń â v́îd́êó p̂ŕôv́îd́êś â ćâṕt̂íôń ît́ îś êáŝíêŕ f̂ór̂ d́êáf̂ án̂d́ ĥéâŕîńĝ ím̂ṕâír̂éd̂ úŝér̂ś t̂ó âćĉéŝś ît́ŝ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)." }, "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĉón̂t́âín̂ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"ĉáp̂t́îón̂ś\"]`." + "message": "`<video>` êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â `<track>` él̂ém̂én̂t́ ŵít̂h́ `[kind=\"captions\"]`." }, "lighthouse-core/audits/accessibility/video-caption.js | title": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"ćâṕt̂íôńŝ\"]`" + "message": "`<video>` êĺêḿêńt̂ś ĉón̂t́âín̂ á `<track>` êĺêḿêńt̂ ẃît́ĥ `[kind=\"captions\"]`" }, "lighthouse-core/audits/accessibility/video-description.js | description": { - "message": "Âúd̂íô d́êśĉŕîṕt̂íôńŝ ṕr̂óv̂íd̂é r̂él̂év̂án̂t́ îńf̂ór̂ḿât́îón̂ f́ôŕ v̂íd̂éôś t̂h́ât́ d̂íâĺôǵûé ĉán̂ńôt́, ŝúĉh́ âś f̂áĉíâĺ êx́p̂ŕêśŝíôńŝ án̂d́ ŝćêńêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂íd̂éô-d́êśĉŕîṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âúd̂íô d́êśĉŕîṕt̂íôńŝ ṕr̂óv̂íd̂é r̂él̂év̂án̂t́ îńf̂ór̂ḿât́îón̂ f́ôŕ v̂íd̂éôś t̂h́ât́ d̂íâĺôǵûé ĉán̂ńôt́, ŝúĉh́ âś f̂áĉíâĺ êx́p̂ŕêśŝíôńŝ án̂d́ ŝćêńêś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)." }, "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĉón̂t́âín̂ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"d̂éŝćr̂íp̂t́îón̂\"]`." + "message": "`<video>` êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â `<track>` él̂ém̂én̂t́ ŵít̂h́ `[kind=\"description\"]`." }, "lighthouse-core/audits/accessibility/video-description.js | title": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"d́êśĉŕîṕt̂íôń\"]`" + "message": "`<video>` êĺêḿêńt̂ś ĉón̂t́âín̂ á `<track>` êĺêḿêńt̂ ẃît́ĥ `[kind=\"description\"]`" }, "lighthouse-core/audits/apple-touch-icon.js | description": { - "message": "F̂ór̂ íd̂éâĺ âṕp̂éâŕâńĉé ôń îÓŜ ẃĥén̂ úŝér̂ś âd́d̂ t́ô t́ĥé ĥóm̂é ŝćr̂éêń, d̂éf̂ín̂é âń âṕp̂ĺê-t́ôúĉh́-îćôń. Ît́ m̂úŝt́ p̂óîńt̂ t́ô á n̂ón̂-t́r̂án̂śp̂ár̂én̂t́ 192p̂x́ (ôŕ 180p̂x́) ŝq́ûár̂é P̂ŃĜ. [Ĺêár̂ń M̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/d́êśîǵn̂-án̂d́-ûx́/b̂ŕôẃŝér̂-ćûśt̂óm̂íẑát̂íôń/)." + "message": "F̂ór̂ íd̂éâĺ âṕp̂éâŕâńĉé ôń îÓŜ ẃĥén̂ úŝér̂ś âd́d̂ t́ô t́ĥé ĥóm̂é ŝćr̂éêń, d̂éf̂ín̂é âń âṕp̂ĺê-t́ôúĉh́-îćôń. Ît́ m̂úŝt́ p̂óîńt̂ t́ô á n̂ón̂-t́r̂án̂śp̂ár̂én̂t́ 192p̂x́ (ôŕ 180p̂x́) ŝq́ûár̂é P̂ŃĜ. [Ĺêár̂ń M̂ór̂é](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)." }, "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { - "message": "D̂óêś n̂ót̂ ṕr̂óv̂íd̂é â v́âĺîd́ `âṕp̂ĺê-t́ôúĉh́-îćôń`" + "message": "D̂óêś n̂ót̂ ṕr̂óv̂íd̂é â v́âĺîd́ `apple-touch-icon`" }, "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { - "message": "`âṕp̂ĺê-t́ôúĉh́-îćôń-p̂ŕêćôḿp̂óŝéd̂` íŝ óût́ ôf́ d̂át̂é; `âṕp̂ĺê-t́ôúĉh́-îćôń` îś p̂ŕêf́êŕr̂éd̂." + "message": "`apple-touch-icon-precomposed` îś ôút̂ óf̂ d́ât́ê; `apple-touch-icon` íŝ ṕr̂éf̂ér̂ŕêd́." }, "lighthouse-core/audits/apple-touch-icon.js | title": { - "message": "P̂ŕôv́îd́êś â v́âĺîd́ `âṕp̂ĺê-t́ôúĉh́-îćôń`" + "message": "P̂ŕôv́îd́êś â v́âĺîd́ `apple-touch-icon`" }, "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { "message": "Ĉh́r̂óm̂é êx́t̂én̂śîón̂ś n̂éĝát̂ív̂él̂ý âf́f̂éĉt́êd́ t̂h́îś p̂áĝé'ŝ ĺôád̂ ṕêŕf̂ór̂ḿâńĉé. T̂ŕŷ áûd́ît́îńĝ t́ĥé p̂áĝé îń îńĉóĝńît́ô ḿôd́ê ór̂ f́r̂óm̂ á Ĉh́r̂óm̂é p̂ŕôf́îĺê ẃît́ĥóût́ êx́t̂én̂śîón̂ś." @@ -342,7 +342,7 @@ "message": "T̂ót̂ál̂ ĆP̂Ú T̂ím̂é" }, "lighthouse-core/audits/bootup-time.js | description": { - "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ, âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́ôót̂úp̂)." + "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ, âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/bootup)." }, "lighthouse-core/audits/bootup-time.js | failureTitle": { "message": "R̂éd̂úĉé Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" @@ -351,25 +351,25 @@ "message": "Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { - "message": "L̂ár̂ǵê ǴÎF́ŝ ár̂é îńêf́f̂íĉíêńt̂ f́ôŕ d̂él̂ív̂ér̂ín̂ǵ âńîḿât́êd́ ĉón̂t́êńt̂. Ćôńŝíd̂ér̂ úŝín̂ǵ M̂ṔÊǴ4/Ŵéb̂Ḿ v̂íd̂éôś f̂ór̂ án̂ím̂át̂íôńŝ án̂d́ P̂ŃĜ/Ẃêb́P̂ f́ôŕ ŝt́ât́îć îḿâǵêś îńŝt́êád̂ óf̂ ǴÎF́ t̂ó ŝáv̂é n̂ét̂ẃôŕk̂ b́ŷt́êś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/p̂ér̂f́ôŕm̂án̂ćê/óp̂t́îḿîźîńĝ-ćôńt̂én̂t́-êf́f̂íĉíêńĉý/r̂ép̂ĺâćê-án̂ím̂át̂éd̂-ǵîf́ŝ-ẃît́ĥ-v́îd́êó/)" + "message": "L̂ár̂ǵê ǴÎF́ŝ ár̂é îńêf́f̂íĉíêńt̂ f́ôŕ d̂él̂ív̂ér̂ín̂ǵ âńîḿât́êd́ ĉón̂t́êńt̂. Ćôńŝíd̂ér̂ úŝín̂ǵ M̂ṔÊǴ4/Ŵéb̂Ḿ v̂íd̂éôś f̂ór̂ án̂ím̂át̂íôńŝ án̂d́ P̂ŃĜ/Ẃêb́P̂ f́ôŕ ŝt́ât́îć îḿâǵêś îńŝt́êád̂ óf̂ ǴÎF́ t̂ó ŝáv̂é n̂ét̂ẃôŕk̂ b́ŷt́êś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { "message": "Ûśê v́îd́êó f̂ór̂ḿât́ŝ f́ôŕ âńîḿât́êd́ ĉón̂t́êńt̂" }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { - "message": "Ĉón̂śîd́êŕ l̂áẑý-l̂óâd́îńĝ óf̂f́ŝćr̂éêń âńd̂ h́îd́d̂én̂ ím̂áĝéŝ áf̂t́êŕ âĺl̂ ćr̂ít̂íĉál̂ ŕêśôúr̂ćêś ĥáv̂é f̂ín̂íŝh́êd́ l̂óâd́îńĝ t́ô ĺôẃêŕ t̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ôf́f̂śĉŕêén̂-ím̂áĝéŝ)." + "message": "Ĉón̂śîd́êŕ l̂áẑý-l̂óâd́îńĝ óf̂f́ŝćr̂éêń âńd̂ h́îd́d̂én̂ ím̂áĝéŝ áf̂t́êŕ âĺl̂ ćr̂ít̂íĉál̂ ŕêśôúr̂ćêś ĥáv̂é f̂ín̂íŝh́êd́ l̂óâd́îńĝ t́ô ĺôẃêŕ t̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)." }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { "message": "D̂éf̂ér̂ óf̂f́ŝćr̂éêń îḿâǵêś" }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { - "message": "R̂éŝóûŕĉéŝ ár̂é b̂ĺôćk̂ín̂ǵ t̂h́ê f́îŕŝt́ p̂áîńt̂ óf̂ ýôúr̂ ṕâǵê. Ćôńŝíd̂ér̂ d́êĺîv́êŕîńĝ ćr̂ít̂íĉál̂ J́Ŝ/ĆŜŚ îńl̂ín̂é âńd̂ d́êf́êŕr̂ín̂ǵ âĺl̂ ńôń-ĉŕît́îćâĺ ĴŚ/ŝt́ŷĺêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́l̂óĉḱîńĝ-ŕêśôúr̂ćêś)." + "message": "R̂éŝóûŕĉéŝ ár̂é b̂ĺôćk̂ín̂ǵ t̂h́ê f́îŕŝt́ p̂áîńt̂ óf̂ ýôúr̂ ṕâǵê. Ćôńŝíd̂ér̂ d́êĺîv́êŕîńĝ ćr̂ít̂íĉál̂ J́Ŝ/ĆŜŚ îńl̂ín̂é âńd̂ d́êf́êŕr̂ín̂ǵ âĺl̂ ńôń-ĉŕît́îćâĺ ĴŚ/ŝt́ŷĺêś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)." }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { "message": "Êĺîḿîńât́ê ŕêńd̂ér̂-b́l̂óĉḱîńĝ ŕêśôúr̂ćêś" }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { - "message": "L̂ár̂ǵê ńêt́ŵór̂ḱ p̂áŷĺôád̂ś ĉóŝt́ ûśêŕŝ ŕêál̂ ḿôńêý âńd̂ ár̂é ĥíĝh́l̂ý ĉór̂ŕêĺât́êd́ ŵít̂h́ l̂ón̂ǵ l̂óâd́ t̂ím̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/n̂ét̂ẃôŕk̂-ṕâýl̂óâd́ŝ)." + "message": "L̂ár̂ǵê ńêt́ŵór̂ḱ p̂áŷĺôád̂ś ĉóŝt́ ûśêŕŝ ŕêál̂ ḿôńêý âńd̂ ár̂é ĥíĝh́l̂ý ĉór̂ŕêĺât́êd́ ŵít̂h́ l̂ón̂ǵ l̂óâd́ t̂ím̂éŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)." }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { "message": "T̂ót̂ál̂ śîźê ẃâś {totalBytes, number, bytes} K̂B́" @@ -386,23 +386,20 @@ "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. `<link rel=>` {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}" }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { - "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {name}. `<link rel=>` {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}" - }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { "message": "M̂ín̂íf̂ý ĈŚŜ ĺîḱê `<link rel=stylesheet>`" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́}other {# êŕr̂ór̂ś f̂óûńd̂}}" + "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́} other {# êŕr̂ór̂ś f̂óûńd̂}}" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { - "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŝṕêéd̂/d́ôćŝ/ín̂śîǵĥt́ŝ/Ḿîńîf́ŷŔêśôúr̂ćêś)." + "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/speed/docs/insights/MinifyResources)." }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { "message": "M̂ín̂íf̂ý Ĵáv̂áŜćr̂íp̂t́" }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { - "message": "R̂ém̂óv̂é d̂éâd́ r̂úl̂éŝ f́r̂óm̂ śt̂ýl̂éŝh́êét̂ś âńd̂ d́êf́êŕ t̂h́ê ĺôád̂ín̂ǵ ôf́ ĈŚŜ ńôt́ ûśêd́ f̂ór̂ áb̂óv̂é-t̂h́ê-f́ôĺd̂ ćôńt̂én̂t́ t̂ó r̂éd̂úĉé ûńn̂éĉéŝśâŕŷ b́ŷt́êś ĉón̂śûḿêd́ b̂ý n̂ét̂ẃôŕk̂ áĉt́îv́ît́ŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ûńûśêd́-ĉśŝ)." + "message": "R̂ém̂óv̂é d̂éâd́ r̂úl̂éŝ f́r̂óm̂ śt̂ýl̂éŝh́êét̂ś âńd̂ d́êf́êŕ t̂h́ê ĺôád̂ín̂ǵ ôf́ ĈŚŜ ńôt́ ûśêd́ f̂ór̂ áb̂óv̂é-t̂h́ê-f́ôĺd̂ ćôńt̂én̂t́ t̂ó r̂éd̂úĉé ûńn̂éĉéŝśâŕŷ b́ŷt́êś ĉón̂śûḿêd́ b̂ý n̂ét̂ẃôŕk̂ áĉt́îv́ît́ŷ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/unused-css)." }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { "message": "R̂ém̂óv̂é ûńûśêd́ ĈŚŜ" @@ -414,7 +411,7 @@ "message": "R̂ém̂óv̂é ûńûśêd́ Ĵáv̂áŜćr̂íp̂t́" }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { - "message": " ĺôńĝ ćâćĥé l̂íf̂ét̂ím̂é ĉán̂ śp̂éêd́ ûṕ r̂ép̂éât́ v̂íŝít̂ś t̂ó ŷóûŕ p̂áĝé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ćâćĥé-p̂ól̂íĉý)." + "message": " ĺôńĝ ćâćĥé l̂íf̂ét̂ím̂é ĉán̂ śp̂éêd́ ûṕ r̂ép̂éât́ v̂íŝít̂ś t̂ó ŷóûŕ p̂áĝé. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)." }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 r̂éŝóûŕĉé f̂óûńd̂}\n other {# ŕêśôúr̂ćêś f̂óûńd̂}\n }" @@ -426,31 +423,31 @@ "message": "Ûśêś êf́f̂íĉíêńt̂ ćâćĥé p̂ól̂íĉý ôń ŝt́ât́îć âśŝét̂ś" }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { - "message": "Ôṕt̂ím̂íẑéd̂ ím̂áĝéŝ ĺôád̂ f́âśt̂ér̂ án̂d́ ĉón̂śûḿê ĺêśŝ ćêĺl̂úl̂ár̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ôṕt̂ím̂íẑé-îḿâǵêś)." + "message": "Ôṕt̂ím̂íẑéd̂ ím̂áĝéŝ ĺôád̂ f́âśt̂ér̂ án̂d́ ĉón̂śûḿê ĺêśŝ ćêĺl̂úl̂ár̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)." }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { "message": "Êf́f̂íĉíêńt̂ĺŷ én̂ćôd́ê ím̂áĝéŝ" }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { - "message": "Ŝér̂v́ê ím̂áĝéŝ t́ĥát̂ ár̂é âṕp̂ŕôṕr̂íât́êĺŷ-śîźêd́ t̂ó ŝáv̂é ĉél̂ĺûĺâŕ d̂át̂á âńd̂ ím̂ṕr̂óv̂é l̂óâd́ t̂ím̂é. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/óv̂ér̂śîźêd́-îḿâǵêś)." + "message": "Ŝér̂v́ê ím̂áĝéŝ t́ĥát̂ ár̂é âṕp̂ŕôṕr̂íât́êĺŷ-śîźêd́ t̂ó ŝáv̂é ĉél̂ĺûĺâŕ d̂át̂á âńd̂ ím̂ṕr̂óv̂é l̂óâd́ t̂ím̂é. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)." }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { "message": "P̂ŕôṕêŕl̂ý ŝíẑé îḿâǵêś" }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { - "message": "T̂éx̂t́-b̂áŝéd̂ ŕêśôúr̂ćêś ŝh́ôúl̂d́ b̂é ŝér̂v́êd́ ŵít̂h́ ĉóm̂ṕr̂éŝśîón̂ (ǵẑíp̂, d́êf́l̂át̂é ôŕ b̂ŕôt́l̂í) t̂ó m̂ín̂ím̂íẑé t̂ót̂ál̂ ńêt́ŵór̂ḱ b̂ýt̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂éx̂t́-ĉóm̂ṕr̂éŝśîón̂)." + "message": "T̂éx̂t́-b̂áŝéd̂ ŕêśôúr̂ćêś ŝh́ôúl̂d́ b̂é ŝér̂v́êd́ ŵít̂h́ ĉóm̂ṕr̂éŝśîón̂ (ǵẑíp̂, d́êf́l̂át̂é ôŕ b̂ŕôt́l̂í) t̂ó m̂ín̂ím̂íẑé t̂ót̂ál̂ ńêt́ŵór̂ḱ b̂ýt̂éŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/text-compression)." }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { "message": "Êńâb́l̂é t̂éx̂t́ ĉóm̂ṕr̂éŝśîón̂" }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { - "message": "Îḿâǵê f́ôŕm̂át̂ś l̂ík̂é ĴṔÊǴ 2000, ĴṔÊǴ X̂Ŕ, âńd̂ Ẃêb́P̂ óf̂t́êń p̂ŕôv́îd́ê b́êt́t̂ér̂ ćôḿp̂ŕêśŝíôń t̂h́âń P̂ŃĜ ór̂ J́P̂ÉĜ, ẃĥíĉh́ m̂éâńŝ f́âśt̂ér̂ d́ôẃn̂ĺôád̂ś âńd̂ ĺêśŝ d́ât́â ćôńŝúm̂ṕt̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ẃêb́p̂)." + "message": "Îḿâǵê f́ôŕm̂át̂ś l̂ík̂é ĴṔÊǴ 2000, ĴṔÊǴ X̂Ŕ, âńd̂ Ẃêb́P̂ óf̂t́êń p̂ŕôv́îd́ê b́êt́t̂ér̂ ćôḿp̂ŕêśŝíôń t̂h́âń P̂ŃĜ ór̂ J́P̂ÉĜ, ẃĥíĉh́ m̂éâńŝ f́âśt̂ér̂ d́ôẃn̂ĺôád̂ś âńd̂ ĺêśŝ d́ât́â ćôńŝúm̂ṕt̂íôń. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/webp)." }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { "message": "Ŝér̂v́ê ím̂áĝéŝ ín̂ ńêx́t̂-ǵêń f̂ór̂ḿât́ŝ" }, "lighthouse-core/audits/critical-request-chains.js | description": { - "message": "T̂h́ê Ćr̂ít̂íĉál̂ Ŕêq́ûéŝt́ Ĉh́âín̂ś b̂él̂óŵ śĥóŵ ýôú ŵh́ât́ r̂éŝóûŕĉéŝ ár̂é l̂óâd́êd́ ŵít̂h́ â h́îǵĥ ṕr̂íôŕît́ŷ. Ćôńŝíd̂ér̂ ŕêd́ûćîńĝ t́ĥé l̂én̂ǵt̂h́ ôf́ ĉh́âín̂ś, r̂éd̂úĉín̂ǵ t̂h́ê d́ôẃn̂ĺôád̂ śîźê óf̂ ŕêśôúr̂ćêś, ôŕ d̂éf̂ér̂ŕîńĝ t́ĥé d̂óŵńl̂óâd́ ôf́ ûńn̂éĉéŝśâŕŷ ŕêśôúr̂ćêś t̂ó îḿp̂ŕôv́ê ṕâǵê ĺôád̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĉŕît́îćâĺ-r̂éq̂úêśt̂-ćĥáîńŝ)." + "message": "T̂h́ê Ćr̂ít̂íĉál̂ Ŕêq́ûéŝt́ Ĉh́âín̂ś b̂él̂óŵ śĥóŵ ýôú ŵh́ât́ r̂éŝóûŕĉéŝ ár̂é l̂óâd́êd́ ŵít̂h́ â h́îǵĥ ṕr̂íôŕît́ŷ. Ćôńŝíd̂ér̂ ŕêd́ûćîńĝ t́ĥé l̂én̂ǵt̂h́ ôf́ ĉh́âín̂ś, r̂éd̂úĉín̂ǵ t̂h́ê d́ôẃn̂ĺôád̂ śîźê óf̂ ŕêśôúr̂ćêś, ôŕ d̂éf̂ér̂ŕîńĝ t́ĥé d̂óŵńl̂óâd́ ôf́ ûńn̂éĉéŝśâŕŷ ŕêśôúr̂ćêś t̂ó îḿp̂ŕôv́ê ṕâǵê ĺôád̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)." }, "lighthouse-core/audits/critical-request-chains.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ĉh́âín̂ f́ôún̂d́}\n other {# ĉh́âín̂ś f̂óûńd̂}\n }" @@ -465,7 +462,7 @@ "message": "L̂ín̂é" }, "lighthouse-core/audits/deprecations.js | description": { - "message": "D̂ép̂ŕêćât́êd́ ÂṔÎś ŵíl̂ĺ êv́êńt̂úâĺl̂ý b̂é r̂ém̂óv̂éd̂ f́r̂óm̂ t́ĥé b̂ŕôẃŝér̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://ẃŵẃ.ĉh́r̂óm̂éŝt́ât́ûś.ĉóm̂/f́êát̂úr̂éŝ#d́êṕr̂éĉát̂éd̂)." + "message": "D̂ép̂ŕêćât́êd́ ÂṔÎś ŵíl̂ĺ êv́êńt̂úâĺl̂ý b̂é r̂ém̂óv̂éd̂ f́r̂óm̂ t́ĥé b̂ŕôẃŝér̂. [Ĺêár̂ń m̂ór̂é](https://www.chromestatus.com/features#deprecated)." }, "lighthouse-core/audits/deprecations.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ŵár̂ńîńĝ f́ôún̂d́}\n other {# ŵár̂ńîńĝś f̂óûńd̂}\n }" @@ -477,7 +474,7 @@ "message": "Âv́ôíd̂ś d̂ép̂ŕêćât́êd́ ÂṔÎś" }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | description": { - "message": "Âṕp̂ĺîćât́îón̂ Ćâćĥé îś d̂ép̂ŕêćât́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/áp̂ṕĉáĉh́ê)." + "message": "Âṕp̂ĺîćât́îón̂ Ćâćĥé îś d̂ép̂ŕêćât́êd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/appcache)." }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { "message": "F̂óûńd̂ \"{AppCacheManifest}\"" @@ -489,10 +486,10 @@ "message": "Âv́ôíd̂ś Âṕp̂ĺîćât́îón̂ Ćâćĥé" }, "lighthouse-core/audits/dobetterweb/doctype.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â d́ôćt̂ýp̂é p̂ŕêv́êńt̂ś t̂h́ê b́r̂óŵśêŕ f̂ŕôḿ ŝẃît́ĉh́îńĝ t́ô q́ûír̂ḱŝ-ḿôd́ê. Ŕêád̂ ḿôŕê ón̂ t́ĥé [M̂D́N̂ Ẃêb́ D̂óĉś p̂áĝé](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕ.m̂óẑíl̂ĺâ.ór̂ǵ/êń-ÛŚ/d̂óĉś/Ĝĺôśŝár̂ý/D̂óĉt́ŷṕê)" + "message": "Ŝṕêćîf́ŷín̂ǵ â d́ôćt̂ýp̂é p̂ŕêv́êńt̂ś t̂h́ê b́r̂óŵśêŕ f̂ŕôḿ ŝẃît́ĉh́îńĝ t́ô q́ûír̂ḱŝ-ḿôd́ê. Ŕêád̂ ḿôŕê ón̂ t́ĥé [M̂D́N̂ Ẃêb́ D̂óĉś p̂áĝé](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)" }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationBadDoctype": { - "message": "D̂óĉt́ŷṕê ńâḿê ḿûśt̂ b́ê t́ĥé l̂óŵér̂ćâśê śt̂ŕîńĝ `h́t̂ḿl̂`" + "message": "D̂óĉt́ŷṕê ńâḿê ḿûśt̂ b́ê t́ĥé l̂óŵér̂ćâśê śt̂ŕîńĝ `html`" }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationNoDoctype": { "message": "D̂óĉúm̂én̂t́ m̂úŝt́ ĉón̂t́âín̂ á d̂óĉt́ŷṕê" @@ -519,7 +516,7 @@ "message": "V̂ál̂úê" }, "lighthouse-core/audits/dobetterweb/dom-size.js | description": { - "message": "B̂ŕôẃŝér̂ én̂ǵîńêér̂ś r̂éĉóm̂ḿêńd̂ ṕâǵêś ĉón̂t́âín̂ f́êẃêŕ t̂h́âń ~1,500 D̂ÓM̂ él̂ém̂én̂t́ŝ. T́ĥé ŝẃêét̂ śp̂ót̂ íŝ á t̂ŕêé d̂ép̂t́ĥ < 32 él̂ém̂én̂t́ŝ án̂d́ f̂éŵér̂ t́ĥán̂ 60 ćĥíl̂d́r̂én̂/ṕâŕêńt̂ él̂ém̂én̂t́.  ĺâŕĝé D̂ÓM̂ ćâń îńĉŕêáŝé m̂ém̂ór̂ý ûśâǵê, ćâúŝé l̂ón̂ǵêŕ [ŝt́ŷĺê ćâĺĉúl̂át̂íôńŝ](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/p̂ér̂f́ôŕm̂án̂ćê/ŕêńd̂ér̂ín̂ǵ/r̂éd̂úĉé-t̂h́ê-śĉóp̂é-âńd̂-ćôḿp̂ĺêx́ît́ŷ-óf̂-śt̂ýl̂é-ĉál̂ćûĺât́îón̂ś), âńd̂ ṕr̂ód̂úĉé ĉóŝt́l̂ý [l̂áŷóût́ r̂éf̂ĺôẃŝ](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/śp̂éêd́/âŕt̂íĉĺêś/r̂éf̂ĺôẃ). [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́ôḿ-ŝíẑé)." + "message": "B̂ŕôẃŝér̂ én̂ǵîńêér̂ś r̂éĉóm̂ḿêńd̂ ṕâǵêś ĉón̂t́âín̂ f́êẃêŕ t̂h́âń ~1,500 D̂ÓM̂ él̂ém̂én̂t́ŝ. T́ĥé ŝẃêét̂ śp̂ót̂ íŝ á t̂ŕêé d̂ép̂t́ĥ < 32 él̂ém̂én̂t́ŝ án̂d́ f̂éŵér̂ t́ĥán̂ 60 ćĥíl̂d́r̂én̂/ṕâŕêńt̂ él̂ém̂én̂t́.  ĺâŕĝé D̂ÓM̂ ćâń îńĉŕêáŝé m̂ém̂ór̂ý ûśâǵê, ćâúŝé l̂ón̂ǵêŕ [ŝt́ŷĺê ćâĺĉúl̂át̂íôńŝ](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations), án̂d́ p̂ŕôd́ûćê ćôśt̂ĺŷ [ĺâýôút̂ ŕêf́l̂óŵś](https://developers.google.com/speed/articles/reflow). [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/dom-size)." }, "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 êĺêḿêńt̂}\n other {# él̂ém̂én̂t́ŝ}\n }" @@ -546,7 +543,7 @@ "message": "T̂ár̂ǵêt́" }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description": { - "message": "Âd́d̂ `ŕêĺ=\"n̂óôṕêńêŕ\"` ôŕ `r̂él̂=\"ńôŕêf́êŕr̂ér̂\"` t́ô án̂ý êx́t̂ér̂ńâĺ l̂ín̂ḱŝ t́ô ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê án̂d́ p̂ŕêv́êńt̂ śêćûŕît́ŷ v́ûĺn̂ér̂áb̂íl̂ít̂íêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ńôóp̂én̂ér̂)." + "message": "Âd́d̂ `rel=\"noopener\"` ór̂ `rel=\"noreferrer\"` t́ô án̂ý êx́t̂ér̂ńâĺ l̂ín̂ḱŝ t́ô ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê án̂d́ p̂ŕêv́êńt̂ śêćûŕît́ŷ v́ûĺn̂ér̂áb̂íl̂ít̂íêś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/noopener)." }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle": { "message": "L̂ín̂ḱŝ t́ô ćr̂óŝś-ôŕîǵîń d̂éŝt́îńât́îón̂ś âŕê ún̂śâf́ê" @@ -558,7 +555,7 @@ "message": "Ûńâb́l̂é t̂ó d̂ét̂ér̂ḿîńê t́ĥé d̂éŝt́îńât́îón̂ f́ôŕ âńĉh́ôŕ ({anchorHTML}). Îf́ n̂ót̂ úŝéd̂ áŝ á ĥýp̂ér̂ĺîńk̂, ćôńŝíd̂ér̂ ŕêḿôv́îńĝ t́âŕĝét̂=_b́l̂án̂ḱ." }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĝéôĺôćât́îón̂-ón̂-ĺôád̂)." + "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load)." }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | failureTitle": { "message": "R̂éq̂úêśt̂ś t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" @@ -579,13 +576,13 @@ "message": "D̂ét̂éĉt́êd́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ" }, "lighthouse-core/audits/dobetterweb/no-document-write.js | description": { - "message": "F̂ór̂ úŝér̂ś ôń ŝĺôẃ ĉón̂ńêćt̂íôńŝ, éx̂t́êŕn̂ál̂ śĉŕîṕt̂ś d̂ýn̂ám̂íĉál̂ĺŷ ín̂j́êćt̂éd̂ v́îá `d̂óĉúm̂én̂t́.ŵŕît́ê()` ćâń d̂él̂áŷ ṕâǵê ĺôád̂ b́ŷ t́êńŝ óf̂ śêćôńd̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́ôćûḿêńt̂-ẃr̂ít̂é)." + "message": "F̂ór̂ úŝér̂ś ôń ŝĺôẃ ĉón̂ńêćt̂íôńŝ, éx̂t́êŕn̂ál̂ śĉŕîṕt̂ś d̂ýn̂ám̂íĉál̂ĺŷ ín̂j́êćt̂éd̂ v́îá `document.write()` ĉán̂ d́êĺâý p̂áĝé l̂óâd́ b̂ý t̂én̂ś ôf́ ŝéĉón̂d́ŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/document-write)." }, "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": { - "message": "Ûśêś `d̂óĉúm̂én̂t́.ŵŕît́ê()`" + "message": "Ûśêś `document.write()`" }, "lighthouse-core/audits/dobetterweb/no-document-write.js | title": { - "message": "Âv́ôíd̂ś `d̂óĉúm̂én̂t́.ŵŕît́ê()`" + "message": "Âv́ôíd̂ś `document.write()`" }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnSeverity": { "message": "Ĥíĝh́êśt̂ Śêv́êŕît́ŷ" @@ -597,7 +594,7 @@ "message": "V̂úl̂ńêŕâb́îĺît́ŷ Ćôún̂t́" }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description": { - "message": "Ŝóm̂é t̂h́îŕd̂-ṕâŕt̂ý ŝćr̂íp̂t́ŝ ḿâý ĉón̂t́âín̂ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ t́ĥát̂ ár̂é êáŝíl̂ý îd́êńt̂íf̂íêd́ âńd̂ éx̂ṕl̂óît́êd́ b̂ý ât́t̂áĉḱêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/v̂úl̂ńêŕâb́îĺît́îéŝ)." + "message": "Ŝóm̂é t̂h́îŕd̂-ṕâŕt̂ý ŝćr̂íp̂t́ŝ ḿâý ĉón̂t́âín̂ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ t́ĥát̂ ár̂é êáŝíl̂ý îd́êńt̂íf̂íêd́ âńd̂ éx̂ṕl̂óît́êd́ b̂ý ât́t̂áĉḱêŕŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities)." }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 v̂úl̂ńêŕâb́îĺît́ŷ d́êt́êćt̂éd̂}\n other {# v́ûĺn̂ér̂áb̂íl̂ít̂íêś d̂ét̂éĉt́êd́}\n }" @@ -618,7 +615,7 @@ "message": "Âv́ôíd̂ś f̂ŕôńt̂-én̂d́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ ẃît́ĥ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ" }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ô śêńd̂ ńôt́îf́îćât́îón̂ś ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô úŝér̂ ǵêśt̂úr̂éŝ ín̂śt̂éâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ńôt́îf́îćât́îón̂ś-ôń-l̂óâd́)." + "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ô śêńd̂ ńôt́îf́îćât́îón̂ś ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô úŝér̂ ǵêśt̂úr̂éŝ ín̂śt̂éâd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load)." }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | failureTitle": { "message": "R̂éq̂úêśt̂ś t̂h́ê ńôt́îf́îćât́îón̂ ṕêŕm̂íŝśîón̂ ón̂ ṕâǵê ĺôád̂" @@ -630,7 +627,7 @@ "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { - "message": "P̂ŕêv́êńt̂ín̂ǵ p̂áŝśŵór̂d́ p̂áŝt́îńĝ ún̂d́êŕm̂ín̂éŝ ǵôód̂ śêćûŕît́ŷ ṕôĺîćŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/p̂áŝśŵór̂d́-p̂áŝt́îńĝ)." + "message": "P̂ŕêv́êńt̂ín̂ǵ p̂áŝśŵór̂d́ p̂áŝt́îńĝ ún̂d́êŕm̂ín̂éŝ ǵôód̂ śêćûŕît́ŷ ṕôĺîćŷ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/password-pasting)." }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | failureTitle": { "message": "P̂ŕêv́êńt̂ś ûśêŕŝ t́ô ṕâśt̂é îńt̂ó p̂áŝśŵór̂d́ f̂íêĺd̂ś" @@ -642,7 +639,7 @@ "message": "P̂ŕôt́ôćôĺ" }, "lighthouse-core/audits/dobetterweb/uses-http2.js | description": { - "message": "ĤT́T̂Ṕ/2 ôf́f̂ér̂ś m̂án̂ý b̂én̂éf̂ít̂ś ôv́êŕ ĤT́T̂Ṕ/1.1, îńĉĺûd́îńĝ b́îńâŕŷ h́êád̂ér̂ś, m̂úl̂t́îṕl̂éx̂ín̂ǵ, âńd̂ śêŕv̂ér̂ ṕûśĥ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĥt́t̂ṕ2)." + "message": "ĤT́T̂Ṕ/2 ôf́f̂ér̂ś m̂án̂ý b̂én̂éf̂ít̂ś ôv́êŕ ĤT́T̂Ṕ/1.1, îńĉĺûd́îńĝ b́îńâŕŷ h́êád̂ér̂ś, m̂úl̂t́îṕl̂éx̂ín̂ǵ, âńd̂ śêŕv̂ér̂ ṕûśĥ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/http2)." }, "lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 r̂éq̂úêśt̂ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n other {# ŕêq́ûéŝt́ŝ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n }" @@ -654,7 +651,7 @@ "message": "Ûśêś ĤT́T̂Ṕ/2 f̂ór̂ ít̂ś ôẃn̂ ŕêśôúr̂ćêś" }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description": { - "message": "Ĉón̂śîd́êŕ m̂ár̂ḱîńĝ ýôúr̂ t́ôúĉh́ âńd̂ ẃĥéêĺ êv́êńt̂ ĺîśt̂én̂ér̂ś âś `p̂áŝśîv́ê` t́ô ím̂ṕr̂óv̂é ŷóûŕ p̂áĝé'ŝ śĉŕôĺl̂ ṕêŕf̂ór̂ḿâńĉé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ṕâśŝív̂é-êv́êńt̂-ĺîśt̂én̂ér̂ś)." + "message": "Ĉón̂śîd́êŕ m̂ár̂ḱîńĝ ýôúr̂ t́ôúĉh́ âńd̂ ẃĥéêĺ êv́êńt̂ ĺîśt̂én̂ér̂ś âś `passive` t̂ó îḿp̂ŕôv́ê ýôúr̂ ṕâǵê'ś ŝćr̂ól̂ĺ p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners)." }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | failureTitle": { "message": "D̂óêś n̂ót̂ úŝé p̂áŝśîv́ê ĺîśt̂én̂ér̂ś t̂ó îḿp̂ŕôv́ê śĉŕôĺl̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê" @@ -675,7 +672,7 @@ "message": "N̂ó b̂ŕôẃŝér̂ ér̂ŕôŕŝ ĺôǵĝéd̂ t́ô t́ĥé ĉón̂śôĺê" }, "lighthouse-core/audits/font-display.js | description": { - "message": "L̂év̂ér̂áĝé t̂h́ê f́ôńt̂-d́îśp̂ĺâý ĈŚŜ f́êát̂úr̂é t̂ó êńŝúr̂é t̂éx̂t́ îś ûśêŕ-v̂íŝíb̂ĺê ẃĥíl̂é ŵéb̂f́ôńt̂ś âŕê ĺôád̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/ûṕd̂át̂éŝ/2016/02/f́ôńt̂-d́îśp̂ĺâý)." + "message": "L̂év̂ér̂áĝé t̂h́ê f́ôńt̂-d́îśp̂ĺâý ĈŚŜ f́êát̂úr̂é t̂ó êńŝúr̂é t̂éx̂t́ îś ûśêŕ-v̂íŝíb̂ĺê ẃĥíl̂é ŵéb̂f́ôńt̂ś âŕê ĺôád̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/updates/2016/02/font-display)." }, "lighthouse-core/audits/font-display.js | failureTitle": { "message": "Êńŝúr̂é t̂éx̂t́ r̂ém̂áîńŝ v́îśîb́l̂é d̂úr̂ín̂ǵ ŵéb̂f́ôńt̂ ĺôád̂" @@ -693,7 +690,7 @@ "message": "Âśp̂éĉt́ R̂át̂íô (D́îśp̂ĺâýêd́)" }, "lighthouse-core/audits/image-aspect-ratio.js | description": { - "message": "Îḿâǵê d́îśp̂ĺâý d̂ím̂én̂śîón̂ś ŝh́ôúl̂d́ m̂át̂ćĥ ńât́ûŕâĺ âśp̂éĉt́ r̂át̂íô. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/âśp̂éĉt́-r̂át̂íô)." + "message": "Îḿâǵê d́îśp̂ĺâý d̂ím̂én̂śîón̂ś ŝh́ôúl̂d́ m̂át̂ćĥ ńât́ûŕâĺ âśp̂éĉt́ r̂át̂íô. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio)." }, "lighthouse-core/audits/image-aspect-ratio.js | failureTitle": { "message": "D̂íŝṕl̂áŷś îḿâǵêś ŵít̂h́ îńĉór̂ŕêćt̂ áŝṕêćt̂ ŕât́îó" @@ -708,7 +705,7 @@ "message": "Îńŝéĉúr̂é ÛŔL̂" }, "lighthouse-core/audits/is-on-https.js | description": { - "message": "Âĺl̂ śît́êś ŝh́ôúl̂d́ b̂é p̂ŕôt́êćt̂éd̂ ẃît́ĥ H́T̂T́P̂Ś, êv́êń ôńêś t̂h́ât́ d̂ón̂'t́ ĥán̂d́l̂é ŝén̂śît́îv́ê d́ât́â. H́T̂T́P̂Ś p̂ŕêv́êńt̂ś îńt̂ŕûd́êŕŝ f́r̂óm̂ t́âḿp̂ér̂ín̂ǵ ŵít̂h́ ôŕ p̂áŝśîv́êĺŷ ĺîśt̂én̂ín̂ǵ îń ôń t̂h́ê ćôḿm̂ún̂íĉát̂íôńŝ b́êt́ŵéêń ŷóûŕ âṕp̂ án̂d́ ŷóûŕ ûśêŕŝ, án̂d́ îś â ṕr̂ér̂éq̂úîśît́ê f́ôŕ ĤT́T̂Ṕ/2 âńd̂ ḿâńŷ ńêẃ ŵéb̂ ṕl̂át̂f́ôŕm̂ ÁP̂Íŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĥt́t̂ṕŝ)." + "message": "Âĺl̂ śît́êś ŝh́ôúl̂d́ b̂é p̂ŕôt́êćt̂éd̂ ẃît́ĥ H́T̂T́P̂Ś, êv́êń ôńêś t̂h́ât́ d̂ón̂'t́ ĥán̂d́l̂é ŝén̂śît́îv́ê d́ât́â. H́T̂T́P̂Ś p̂ŕêv́êńt̂ś îńt̂ŕûd́êŕŝ f́r̂óm̂ t́âḿp̂ér̂ín̂ǵ ŵít̂h́ ôŕ p̂áŝśîv́êĺŷ ĺîśt̂én̂ín̂ǵ îń ôń t̂h́ê ćôḿm̂ún̂íĉát̂íôńŝ b́êt́ŵéêń ŷóûŕ âṕp̂ án̂d́ ŷóûŕ ûśêŕŝ, án̂d́ îś â ṕr̂ér̂éq̂úîśît́ê f́ôŕ ĤT́T̂Ṕ/2 âńd̂ ḿâńŷ ńêẃ ŵéb̂ ṕl̂át̂f́ôŕm̂ ÁP̂Íŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/https)." }, "lighthouse-core/audits/is-on-https.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 îńŝéĉúr̂é r̂éq̂úêśt̂ f́ôún̂d́}\n other {# îńŝéĉúr̂é r̂éq̂úêśt̂ś f̂óûńd̂}\n }" @@ -720,7 +717,7 @@ "message": "Ûśêś ĤT́T̂ṔŜ" }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { - "message": " f́âśt̂ ṕâǵê ĺôád̂ óv̂ér̂ á ĉél̂ĺûĺâŕ n̂ét̂ẃôŕk̂ én̂śûŕêś â ǵôód̂ ḿôb́îĺê úŝér̂ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂áŝt́-3ĝ)." + "message": " f́âśt̂ ṕâǵê ĺôád̂ óv̂ér̂ á ĉél̂ĺûĺâŕ n̂ét̂ẃôŕk̂ én̂śûŕêś â ǵôód̂ ḿôb́îĺê úŝér̂ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)." }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { "message": "Îńt̂ér̂áĉt́îv́ê át̂ {timeInMs, number, seconds} ś" @@ -747,55 +744,55 @@ "message": "M̂ín̂ím̂íẑéŝ ḿâín̂-t́ĥŕêád̂ ẃôŕk̂" }, "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { - "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/éŝt́îḿât́êd́-îńp̂út̂-ĺât́êńĉý)." + "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)." }, "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ" }, "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { - "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́ m̂ár̂ḱŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ t́ĥé f̂ír̂śt̂ t́êx́t̂ ór̂ ím̂áĝé îś p̂áîńt̂éd̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ír̂śt̂-ćôńt̂én̂t́f̂úl̂-ṕâín̂t́)." + "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́ m̂ár̂ḱŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ t́ĥé f̂ír̂śt̂ t́êx́t̂ ór̂ ím̂áĝé îś p̂áîńt̂éd̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)." }, "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́" }, "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { - "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é m̂ár̂ḱŝ t́ĥé f̂ír̂śt̂ t́îḿê át̂ ẃĥíĉh́ t̂h́ê ṕâǵê'ś m̂áîń t̂h́r̂éâd́ îś q̂úîét̂ én̂óûǵĥ t́ô h́âńd̂ĺê ín̂ṕût́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/f́îŕŝt́-îńt̂ér̂áĉt́îv́ê)." + "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é m̂ár̂ḱŝ t́ĥé f̂ír̂śt̂ t́îḿê át̂ ẃĥíĉh́ t̂h́ê ṕâǵê'ś m̂áîń t̂h́r̂éâd́ îś q̂úîét̂ én̂óûǵĥ t́ô h́âńd̂ĺê ín̂ṕût́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)." }, "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é" }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { - "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́ m̂éâśûŕêś ŵh́êń t̂h́ê ṕr̂ím̂ár̂ý ĉón̂t́êńt̂ óf̂ á p̂áĝé îś v̂íŝíb̂ĺê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ír̂śt̂-ḿêán̂ín̂ǵf̂úl̂-ṕâín̂t́)." + "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́ m̂éâśûŕêś ŵh́êń t̂h́ê ṕr̂ím̂ár̂ý ĉón̂t́êńt̂ óf̂ á p̂áĝé îś v̂íŝíb̂ĺê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)." }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́" }, "lighthouse-core/audits/metrics/interactive.js | description": { - "message": "T̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê íŝ t́ĥé âḿôún̂t́ ôf́ t̂ím̂é ît́ t̂ák̂éŝ f́ôŕ t̂h́ê ṕâǵê t́ô b́êćôḿê f́ûĺl̂ý îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĉón̂śîśt̂én̂t́l̂ý-îńt̂ér̂áĉt́îv́ê)." + "message": "T̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê íŝ t́ĥé âḿôún̂t́ ôf́ t̂ím̂é ît́ t̂ák̂éŝ f́ôŕ t̂h́ê ṕâǵê t́ô b́êćôḿê f́ûĺl̂ý îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)." }, "lighthouse-core/audits/metrics/interactive.js | title": { "message": "T̂ím̂é t̂ó Îńt̂ér̂áĉt́îv́ê" }, "lighthouse-core/audits/metrics/max-potential-fid.js | description": { - "message": "T̂h́ê ḿâx́îḿûḿ p̂ót̂én̂t́îál̂ F́îŕŝt́ Îńp̂út̂ D́êĺâý t̂h́ât́ ŷóûŕ ûśêŕŝ ćôúl̂d́ êx́p̂ér̂íêńĉé îś t̂h́ê d́ûŕât́îón̂, ín̂ ḿîĺl̂íŝéĉón̂d́ŝ, óf̂ t́ĥé l̂ón̂ǵêśt̂ t́âśk̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/úp̂d́ât́êś/2018/05/f̂ír̂śt̂-ín̂ṕût́-d̂él̂áŷ)." + "message": "T̂h́ê ḿâx́îḿûḿ p̂ót̂én̂t́îál̂ F́îŕŝt́ Îńp̂út̂ D́êĺâý t̂h́ât́ ŷóûŕ ûśêŕŝ ćôúl̂d́ êx́p̂ér̂íêńĉé îś t̂h́ê d́ûŕât́îón̂, ín̂ ḿîĺl̂íŝéĉón̂d́ŝ, óf̂ t́ĥé l̂ón̂ǵêśt̂ t́âśk̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/updates/2018/05/first-input-delay)." }, "lighthouse-core/audits/metrics/max-potential-fid.js | title": { "message": "M̂áx̂ Ṕôt́êńt̂íâĺ F̂ír̂śt̂ Ín̂ṕût́ D̂él̂áŷ" }, "lighthouse-core/audits/metrics/speed-index.js | description": { - "message": "Ŝṕêéd̂ Ín̂d́êx́ ŝh́ôẃŝ h́ôẃ q̂úîćk̂ĺŷ t́ĥé ĉón̂t́êńt̂ś ôf́ â ṕâǵê ár̂é v̂íŝíb̂ĺŷ ṕôṕûĺât́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/śp̂éêd́-îńd̂éx̂)." + "message": "Ŝṕêéd̂ Ín̂d́êx́ ŝh́ôẃŝ h́ôẃ q̂úîćk̂ĺŷ t́ĥé ĉón̂t́êńt̂ś ôf́ â ṕâǵê ár̂é v̂íŝíb̂ĺŷ ṕôṕûĺât́êd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/speed-index)." }, "lighthouse-core/audits/metrics/speed-index.js | title": { "message": "Ŝṕêéd̂ Ín̂d́êx́" }, "lighthouse-core/audits/network-rtt.js | description": { - "message": "N̂ét̂ẃôŕk̂ ŕôún̂d́ t̂ŕîṕ t̂ím̂éŝ (ŔT̂T́) ĥáv̂é â ĺâŕĝé îḿp̂áĉt́ ôń p̂ér̂f́ôŕm̂án̂ćê. Íf̂ t́ĥé R̂T́T̂ t́ô án̂ ór̂íĝín̂ íŝ h́îǵĥ, ít̂'ś âń îńd̂íĉát̂íôń t̂h́ât́ ŝér̂v́êŕŝ ćl̂óŝér̂ t́ô t́ĥé ûśêŕ ĉóûĺd̂ ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://h́p̂b́n̂.ćô/ṕr̂ím̂ér̂-ón̂-ĺât́êńĉý-âńd̂-b́âńd̂ẃîd́t̂h́/)." + "message": "N̂ét̂ẃôŕk̂ ŕôún̂d́ t̂ŕîṕ t̂ím̂éŝ (ŔT̂T́) ĥáv̂é â ĺâŕĝé îḿp̂áĉt́ ôń p̂ér̂f́ôŕm̂án̂ćê. Íf̂ t́ĥé R̂T́T̂ t́ô án̂ ór̂íĝín̂ íŝ h́îǵĥ, ít̂'ś âń îńd̂íĉát̂íôń t̂h́ât́ ŝér̂v́êŕŝ ćl̂óŝér̂ t́ô t́ĥé ûśêŕ ĉóûĺd̂ ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](https://hpbn.co/primer-on-latency-and-bandwidth/)." }, "lighthouse-core/audits/network-rtt.js | title": { "message": "N̂ét̂ẃôŕk̂ Ŕôún̂d́ T̂ŕîṕ T̂ím̂éŝ" }, "lighthouse-core/audits/network-server-latency.js | description": { - "message": "Ŝér̂v́êŕ l̂át̂én̂ćîéŝ ćâń îḿp̂áĉt́ ŵéb̂ ṕêŕf̂ór̂ḿâńĉé. Îf́ t̂h́ê śêŕv̂ér̂ ĺât́êńĉý ôf́ âń ôŕîǵîń îś ĥíĝh́, ît́'ŝ án̂ ín̂d́îćât́îón̂ t́ĥé ŝér̂v́êŕ îś ôv́êŕl̂óâd́êd́ ôŕ ĥáŝ ṕôór̂ b́âćk̂én̂d́ p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://h́p̂b́n̂.ćô/ṕr̂ím̂ér̂-ón̂-ẃêb́-p̂ér̂f́ôŕm̂án̂ćê/#án̂ál̂ýẑín̂ǵ-t̂h́ê-ŕêśôúr̂ćê-ẃât́êŕf̂ál̂ĺ)." + "message": "Ŝér̂v́êŕ l̂át̂én̂ćîéŝ ćâń îḿp̂áĉt́ ŵéb̂ ṕêŕf̂ór̂ḿâńĉé. Îf́ t̂h́ê śêŕv̂ér̂ ĺât́êńĉý ôf́ âń ôŕîǵîń îś ĥíĝh́, ît́'ŝ án̂ ín̂d́îćât́îón̂ t́ĥé ŝér̂v́êŕ îś ôv́êŕl̂óâd́êd́ ôŕ ĥáŝ ṕôór̂ b́âćk̂én̂d́ p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)." }, "lighthouse-core/audits/network-server-latency.js | title": { "message": "Ŝér̂v́êŕ B̂áĉḱêńd̂ Ĺât́êńĉíêś" @@ -804,7 +801,7 @@ "message": "Ôv́êŕ B̂úd̂ǵêt́" }, "lighthouse-core/audits/performance-budget.js | description": { - "message": "K̂éêṕ t̂h́ê q́ûán̂t́ît́ŷ án̂d́ ŝíẑé ôf́ n̂ét̂ẃôŕk̂ ŕêq́ûéŝt́ŝ ún̂d́êŕ t̂h́ê t́âŕĝét̂ś ŝét̂ b́ŷ t́ĥé p̂ŕôv́îd́êd́ p̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/b̂úd̂ǵêt́ŝ)." + "message": "K̂éêṕ t̂h́ê q́ûán̂t́ît́ŷ án̂d́ ŝíẑé ôf́ n̂ét̂ẃôŕk̂ ŕêq́ûéŝt́ŝ ún̂d́êŕ t̂h́ê t́âŕĝét̂ś ŝét̂ b́ŷ t́ĥé p̂ŕôv́îd́êd́ p̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/budgets)." }, "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { "message": "{count, plural,\n =1 {1 r̂éq̂úêśt̂}\n other {# ŕêq́ûéŝt́ŝ}\n }" @@ -813,13 +810,13 @@ "message": "P̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂" }, "lighthouse-core/audits/redirects.js | description": { - "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ŕêd́îŕêćt̂ś)." + "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/redirects)." }, "lighthouse-core/audits/redirects.js | title": { "message": "Âv́ôíd̂ ḿûĺt̂íp̂ĺê ṕâǵê ŕêd́îŕêćt̂ś" }, "lighthouse-core/audits/resource-summary.js | description": { - "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́ûd́ĝét̂ś)." + "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/budgets)." }, "lighthouse-core/audits/resource-summary.js | displayValue": { "message": "{requestCount, plural, =1 {1 r̂éq̂úêśt̂} other {# ŕêq́ûéŝt́ŝ}} • { byteCount, number, bytes } ḰB̂" @@ -828,7 +825,7 @@ "message": "K̂éêṕ r̂éq̂úêśt̂ ćôún̂t́ŝ ĺôẃ âńd̂ t́r̂án̂śf̂ér̂ śîźêś ŝḿâĺl̂" }, "lighthouse-core/audits/seo/canonical.js | description": { - "message": "Ĉán̂ón̂íĉál̂ ĺîńk̂ś ŝúĝǵêśt̂ ẃĥíĉh́ ÛŔL̂ t́ô śĥóŵ ín̂ śêár̂ćĥ ŕêśûĺt̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ćâńôńîćâĺ)." + "message": "Ĉán̂ón̂íĉál̂ ĺîńk̂ś ŝúĝǵêśt̂ ẃĥíĉh́ ÛŔL̂ t́ô śĥóŵ ín̂ śêár̂ćĥ ŕêśûĺt̂ś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/canonical)." }, "lighthouse-core/audits/seo/canonical.js | explanationConflict": { "message": "M̂úl̂t́îṕl̂é ĉón̂f́l̂íĉt́îńĝ ÚR̂Ĺŝ ({urlList})" @@ -840,7 +837,7 @@ "message": "Îńv̂ál̂íd̂ ÚR̂Ĺ ({url})" }, "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ `h́r̂éf̂ĺâńĝ` ĺôćât́îón̂ ({url})" + "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ `hreflang` ĺôćât́îón̂ ({url})" }, "lighthouse-core/audits/seo/canonical.js | explanationRelative": { "message": "R̂él̂át̂ív̂é ÛŔL̂ ({url})" @@ -849,13 +846,13 @@ "message": "P̂óîńt̂ś t̂ó t̂h́ê d́ôḿâín̂'ś r̂óôt́ ÛŔL̂ (t́ĥé ĥóm̂ép̂áĝé), îńŝt́êád̂ óf̂ án̂ éq̂úîv́âĺêńt̂ ṕâǵê óf̂ ćôńt̂én̂t́" }, "lighthouse-core/audits/seo/canonical.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á v̂ál̂íd̂ `ŕêĺ=ĉán̂ón̂íĉál̂`" + "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á v̂ál̂íd̂ `rel=canonical`" }, "lighthouse-core/audits/seo/canonical.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `ŕêĺ=ĉán̂ón̂íĉál̂`" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `rel=canonical`" }, "lighthouse-core/audits/seo/font-size.js | description": { - "message": "F̂ón̂t́ ŝíẑéŝ ĺêśŝ t́ĥán̂ 12ṕx̂ ár̂é t̂óô śm̂ál̂ĺ t̂ó b̂é l̂éĝíb̂ĺê án̂d́ r̂éq̂úîŕê ḿôb́îĺê v́îśît́ôŕŝ t́ô “ṕîńĉh́ t̂ó ẑóôḿ” îń ôŕd̂ér̂ t́ô ŕêád̂. Śt̂ŕîv́ê t́ô h́âv́ê >60% óf̂ ṕâǵê t́êx́t̂ ≥12ṕx̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ón̂t́-ŝíẑéŝ)." + "message": "F̂ón̂t́ ŝíẑéŝ ĺêśŝ t́ĥán̂ 12ṕx̂ ár̂é t̂óô śm̂ál̂ĺ t̂ó b̂é l̂éĝíb̂ĺê án̂d́ r̂éq̂úîŕê ḿôb́îĺê v́îśît́ôŕŝ t́ô “ṕîńĉh́ t̂ó ẑóôḿ” îń ôŕd̂ér̂ t́ô ŕêád̂. Śt̂ŕîv́ê t́ô h́âv́ê >60% óf̂ ṕâǵê t́êx́t̂ ≥12ṕx̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)." }, "lighthouse-core/audits/seo/font-size.js | displayValue": { "message": "{decimalProportion, number, extendedPercent} l̂éĝíb̂ĺê t́êx́t̂" @@ -876,16 +873,16 @@ "message": "D̂óĉúm̂én̂t́ ûśêś l̂éĝíb̂ĺê f́ôńt̂ śîźêś" }, "lighthouse-core/audits/seo/hreflang.js | description": { - "message": "ĥŕêf́l̂án̂ǵ l̂ín̂ḱŝ t́êĺl̂ śêár̂ćĥ én̂ǵîńêś ŵh́ât́ v̂ér̂śîón̂ óf̂ á p̂áĝé t̂h́êý ŝh́ôúl̂d́ l̂íŝt́ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ f́ôŕ â ǵîv́êń l̂án̂ǵûáĝé ôŕ r̂éĝíôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/h́r̂éf̂ĺâńĝ)." + "message": "ĥŕêf́l̂án̂ǵ l̂ín̂ḱŝ t́êĺl̂ śêár̂ćĥ én̂ǵîńêś ŵh́ât́ v̂ér̂śîón̂ óf̂ á p̂áĝé t̂h́êý ŝh́ôúl̂d́ l̂íŝt́ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ f́ôŕ â ǵîv́êń l̂án̂ǵûáĝé ôŕ r̂éĝíôń. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/hreflang)." }, "lighthouse-core/audits/seo/hreflang.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â v́âĺîd́ `ĥŕêf́l̂án̂ǵ`" + "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â v́âĺîd́ `hreflang`" }, "lighthouse-core/audits/seo/hreflang.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `h́r̂éf̂ĺâńĝ`" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `hreflang`" }, "lighthouse-core/audits/seo/http-status-code.js | description": { - "message": "P̂áĝéŝ ẃît́ĥ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́êś m̂áŷ ńôt́ b̂é îńd̂éx̂éd̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ŝúĉćêśŝf́ûĺ-ĥt́t̂ṕ-ĉód̂é)." + "message": "P̂áĝéŝ ẃît́ĥ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́êś m̂áŷ ńôt́ b̂é îńd̂éx̂éd̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)." }, "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { "message": "P̂áĝé ĥáŝ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" @@ -894,7 +891,7 @@ "message": "P̂áĝé ĥáŝ śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" }, "lighthouse-core/audits/seo/is-crawlable.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ár̂é ûńâb́l̂é t̂ó îńĉĺûd́ê ýôúr̂ ṕâǵêś îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ íf̂ t́ĥéŷ d́ôń't̂ h́âv́ê ṕêŕm̂íŝśîón̂ t́ô ćr̂áŵĺ t̂h́êḿ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ín̂d́êx́îńĝ)." + "message": "Ŝéâŕĉh́ êńĝín̂éŝ ár̂é ûńâb́l̂é t̂ó îńĉĺûd́ê ýôúr̂ ṕâǵêś îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ íf̂ t́ĥéŷ d́ôń't̂ h́âv́ê ṕêŕm̂íŝśîón̂ t́ô ćr̂áŵĺ t̂h́êḿ. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/indexing)." }, "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { "message": "P̂áĝé îś b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" @@ -903,7 +900,7 @@ "message": "P̂áĝé îśn̂’t́ b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" }, "lighthouse-core/audits/seo/link-text.js | description": { - "message": "D̂éŝćr̂íp̂t́îv́ê ĺîńk̂ t́êx́t̂ h́êĺp̂ś ŝéâŕĉh́ êńĝín̂éŝ ún̂d́êŕŝt́âńd̂ ýôúr̂ ćôńt̂én̂t́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́êśĉŕîṕt̂ív̂é-l̂ín̂ḱ-t̂éx̂t́)." + "message": "D̂éŝćr̂íp̂t́îv́ê ĺîńk̂ t́êx́t̂ h́êĺp̂ś ŝéâŕĉh́ êńĝín̂éŝ ún̂d́êŕŝt́âńd̂ ýôúr̂ ćôńt̂én̂t́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)." }, "lighthouse-core/audits/seo/link-text.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 l̂ín̂ḱ f̂óûńd̂}\n other {# ĺîńk̂ś f̂óûńd̂}\n }" @@ -915,13 +912,13 @@ "message": "L̂ín̂ḱŝ h́âv́ê d́êśĉŕîṕt̂ív̂é t̂éx̂t́" }, "lighthouse-core/audits/seo/manual/structured-data.js | description": { - "message": "R̂ún̂ t́ĥé [Ŝt́r̂úĉt́ûŕêd́ D̂át̂á T̂éŝt́îńĝ T́ôól̂](h́t̂t́p̂ś://ŝéâŕĉh́.ĝóôǵl̂é.ĉóm̂/śt̂ŕûćt̂úr̂éd̂-d́ât́â/t́êśt̂ín̂ǵ-t̂óôĺ/) âńd̂ t́ĥé [Ŝt́r̂úĉt́ûŕêd́ D̂át̂á L̂ín̂t́êŕ](ĥt́t̂ṕ://l̂ín̂t́êŕ.ŝt́r̂úĉt́ûŕêd́-d̂át̂á.ôŕĝ/) t́ô v́âĺîd́ât́ê śt̂ŕûćt̂úr̂éd̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŝéâŕĉh́/d̂óĉś/ĝúîd́êś/m̂ár̂ḱ-ûṕ-ĉón̂t́êńt̂)." + "message": "R̂ún̂ t́ĥé [Ŝt́r̂úĉt́ûŕêd́ D̂át̂á T̂éŝt́îńĝ T́ôól̂](https://search.google.com/structured-data/testing-tool/) án̂d́ t̂h́ê [Śt̂ŕûćt̂úr̂éd̂ D́ât́â Ĺîńt̂ér̂](http://linter.structured-data.org/) t́ô v́âĺîd́ât́ê śt̂ŕûćt̂úr̂éd̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/search/docs/guides/mark-up-content)." }, "lighthouse-core/audits/seo/manual/structured-data.js | title": { "message": "Ŝt́r̂úĉt́ûŕêd́ d̂át̂á îś v̂ál̂íd̂" }, "lighthouse-core/audits/seo/meta-description.js | description": { - "message": "M̂ét̂á d̂éŝćr̂íp̂t́îón̂ś m̂áŷ b́ê ín̂ćl̂úd̂éd̂ ín̂ śêár̂ćĥ ŕêśûĺt̂ś t̂ó ĉón̂ćîśêĺŷ śûḿm̂ár̂íẑé p̂áĝé ĉón̂t́êńt̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/d̂éŝćr̂íp̂t́îón̂)." + "message": "M̂ét̂á d̂éŝćr̂íp̂t́îón̂ś m̂áŷ b́ê ín̂ćl̂úd̂éd̂ ín̂ śêár̂ćĥ ŕêśûĺt̂ś t̂ó ĉón̂ćîśêĺŷ śûḿm̂ár̂íẑé p̂áĝé ĉón̂t́êńt̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/description)." }, "lighthouse-core/audits/seo/meta-description.js | explanation": { "message": "D̂éŝćr̂íp̂t́îón̂ t́êx́t̂ íŝ ém̂ṕt̂ý." @@ -933,7 +930,7 @@ "message": "D̂óĉúm̂én̂t́ ĥáŝ á m̂ét̂á d̂éŝćr̂íp̂t́îón̂" }, "lighthouse-core/audits/seo/plugins.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ćâń't̂ ín̂d́êx́ p̂ĺûǵîń ĉón̂t́êńt̂, án̂d́ m̂án̂ý d̂év̂íĉéŝ ŕêśt̂ŕîćt̂ ṕl̂úĝín̂ś ôŕ d̂ón̂'t́ ŝúp̂ṕôŕt̂ t́ĥém̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/p̂ĺûǵîńŝ)." + "message": "Ŝéâŕĉh́ êńĝín̂éŝ ćâń't̂ ín̂d́êx́ p̂ĺûǵîń ĉón̂t́êńt̂, án̂d́ m̂án̂ý d̂év̂íĉéŝ ŕêśt̂ŕîćt̂ ṕl̂úĝín̂ś ôŕ d̂ón̂'t́ ŝúp̂ṕôŕt̂ t́ĥém̂. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/plugins)." }, "lighthouse-core/audits/seo/plugins.js | failureTitle": { "message": "D̂óĉúm̂én̂t́ ûśêś p̂ĺûǵîńŝ" @@ -960,7 +957,7 @@ "message": "r̂ób̂ót̂ś.t̂x́t̂ íŝ v́âĺîd́" }, "lighthouse-core/audits/seo/tap-targets.js | description": { - "message": "Îńt̂ér̂áĉt́îv́ê él̂ém̂én̂t́ŝ ĺîḱê b́ût́t̂ón̂ś âńd̂ ĺîńk̂ś ŝh́ôúl̂d́ b̂é l̂ár̂ǵê én̂óûǵĥ (48x́48p̂x́), âńd̂ h́âv́ê én̂óûǵĥ śp̂áĉé âŕôún̂d́ t̂h́êḿ, t̂ó b̂é êáŝý êńôúĝh́ t̂ó t̂áp̂ ẃît́ĥóût́ ôv́êŕl̂áp̂ṕîńĝ ón̂t́ô ót̂h́êŕ êĺêḿêńt̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/âćĉéŝśîb́îĺît́ŷ/áĉćêśŝíb̂ĺê-śt̂ýl̂éŝ#ḿûĺt̂í-d̂év̂íĉé_r̂éŝṕôńŝív̂é_d̂éŝíĝń)." + "message": "Îńt̂ér̂áĉt́îv́ê él̂ém̂én̂t́ŝ ĺîḱê b́ût́t̂ón̂ś âńd̂ ĺîńk̂ś ŝh́ôúl̂d́ b̂é l̂ár̂ǵê én̂óûǵĥ (48x́48p̂x́), âńd̂ h́âv́ê én̂óûǵĥ śp̂áĉé âŕôún̂d́ t̂h́êḿ, t̂ó b̂é êáŝý êńôúĝh́ t̂ó t̂áp̂ ẃît́ĥóût́ ôv́êŕl̂áp̂ṕîńĝ ón̂t́ô ót̂h́êŕ êĺêḿêńt̂ś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)." }, "lighthouse-core/audits/seo/tap-targets.js | displayValue": { "message": "{decimalProportion, number, percent} âṕp̂ŕôṕr̂íât́êĺŷ śîźêd́ t̂áp̂ t́âŕĝét̂ś" @@ -990,7 +987,7 @@ "message": "T̂h́îŕd̂-Ṕâŕt̂ý" }, "lighthouse-core/audits/third-party-summary.js | description": { - "message": "T̂h́îŕd̂-ṕâŕt̂ý ĉód̂é ĉán̂ śîǵn̂íf̂íĉán̂t́l̂ý îḿp̂áĉt́ l̂óâd́ p̂ér̂f́ôŕm̂án̂ćê. Ĺîḿît́ t̂h́ê ńûḿb̂ér̂ óf̂ ŕêd́ûńd̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý p̂ŕôv́îd́êŕŝ án̂d́ t̂ŕŷ t́ô ĺôád̂ t́ĥír̂d́-p̂ár̂t́ŷ ćôd́ê áf̂t́êŕ ŷóûŕ p̂áĝé ĥáŝ ṕr̂ím̂ár̂íl̂ý f̂ín̂íŝh́êd́ l̂óâd́îńĝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/ṕêŕf̂ór̂ḿâńĉé/ôṕt̂ím̂íẑín̂ǵ-ĉón̂t́êńt̂-éf̂f́îćîén̂ćŷ/ĺôád̂ín̂ǵ-t̂h́îŕd̂-ṕâŕt̂ý-ĵáv̂áŝćr̂íp̂t́/)." + "message": "T̂h́îŕd̂-ṕâŕt̂ý ĉód̂é ĉán̂ śîǵn̂íf̂íĉán̂t́l̂ý îḿp̂áĉt́ l̂óâd́ p̂ér̂f́ôŕm̂án̂ćê. Ĺîḿît́ t̂h́ê ńûḿb̂ér̂ óf̂ ŕêd́ûńd̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý p̂ŕôv́îd́êŕŝ án̂d́ t̂ŕŷ t́ô ĺôád̂ t́ĥír̂d́-p̂ár̂t́ŷ ćôd́ê áf̂t́êŕ ŷóûŕ p̂áĝé ĥáŝ ṕr̂ím̂ár̂íl̂ý f̂ín̂íŝh́êd́ l̂óâd́îńĝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)." }, "lighthouse-core/audits/third-party-summary.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 T̂h́îŕd̂-Ṕâŕt̂ý F̂óûńd̂}\n other {# T́ĥír̂d́-P̂ár̂t́îéŝ F́ôún̂d́}\n }" @@ -999,7 +996,7 @@ "message": "T̂h́îŕd̂-Ṕâŕt̂ý Ûśâǵê" }, "lighthouse-core/audits/time-to-first-byte.js | description": { - "message": "T̂ím̂é T̂ó F̂ír̂śt̂ B́ŷt́ê íd̂én̂t́îf́îéŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ ýôúr̂ śêŕv̂ér̂ śêńd̂ś â ŕêśp̂ón̂śê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂t́f̂b́)." + "message": "T̂ím̂é T̂ó F̂ír̂śt̂ B́ŷt́ê íd̂én̂t́îf́îéŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ ýôúr̂ śêŕv̂ér̂ śêńd̂ś â ŕêśp̂ón̂śê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/ttfb)." }, "lighthouse-core/audits/time-to-first-byte.js | displayValue": { "message": "R̂óôt́ d̂óĉúm̂én̂t́ t̂óôḱ {timeInMs, number, milliseconds} m̂ś" @@ -1023,7 +1020,7 @@ "message": "T̂ýp̂é" }, "lighthouse-core/audits/user-timings.js | description": { - "message": "Ĉón̂śîd́êŕ îńŝt́r̂úm̂én̂t́îńĝ ýôúr̂ áp̂ṕ ŵít̂h́ t̂h́ê Úŝér̂ T́îḿîńĝ ÁP̂Í t̂ó m̂éâśûŕê ýôúr̂ áp̂ṕ'ŝ ŕêál̂-ẃôŕl̂d́ p̂ér̂f́ôŕm̂án̂ćê d́ûŕîńĝ ḱêý ûśêŕ êx́p̂ér̂íêńĉéŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ûśêŕ-t̂ím̂ín̂ǵ)." + "message": "Ĉón̂śîd́êŕ îńŝt́r̂úm̂én̂t́îńĝ ýôúr̂ áp̂ṕ ŵít̂h́ t̂h́ê Úŝér̂ T́îḿîńĝ ÁP̂Í t̂ó m̂éâśûŕê ýôúr̂ áp̂ṕ'ŝ ŕêál̂-ẃôŕl̂d́ p̂ér̂f́ôŕm̂án̂ćê d́ûŕîńĝ ḱêý ûśêŕ êx́p̂ér̂íêńĉéŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/user-timing)." }, "lighthouse-core/audits/user-timings.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ûśêŕ t̂ím̂ín̂ǵ}\n other {# ûśêŕ t̂ím̂ín̂ǵŝ}\n }" @@ -1032,19 +1029,19 @@ "message": "Ûśêŕ T̂ím̂ín̂ǵ m̂ár̂ḱŝ án̂d́ m̂éâśûŕêś" }, "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"{securityOrigin}\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé `ĉŕôśŝór̂íĝín̂` át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý." + "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"{securityOrigin}\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé `crossorigin` ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ." }, "lighthouse-core/audits/uses-rel-preconnect.js | description": { - "message": "Ĉón̂śîd́êŕ âd́d̂ín̂ǵ p̂ŕêćôńn̂éĉt́ ôŕ d̂ńŝ-ṕr̂éf̂ét̂ćĥ ŕêśôúr̂ćê h́îńt̂ś t̂ó êśt̂áb̂ĺîśĥ éâŕl̂ý ĉón̂ńêćt̂íôńŝ t́ô ím̂ṕôŕt̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý ôŕîǵîńŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/ṕêŕf̂ór̂ḿâńĉé/r̂éŝóûŕĉé-p̂ŕîór̂ít̂íẑát̂íôń#p̂ŕêćôńn̂éĉt́)." + "message": "Ĉón̂śîd́êŕ âd́d̂ín̂ǵ p̂ŕêćôńn̂éĉt́ ôŕ d̂ńŝ-ṕr̂éf̂ét̂ćĥ ŕêśôúr̂ćê h́îńt̂ś t̂ó êśt̂áb̂ĺîśĥ éâŕl̂ý ĉón̂ńêćt̂íôńŝ t́ô ím̂ṕôŕt̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý ôŕîǵîńŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)." }, "lighthouse-core/audits/uses-rel-preconnect.js | title": { "message": "P̂ŕêćôńn̂éĉt́ t̂ó r̂éq̂úîŕêd́ ôŕîǵîńŝ" }, "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê `ćr̂óŝśôŕîǵîń` ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ." + "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê `crossorigin` át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý." }, "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ṕr̂él̂óâd́)." + "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/preload)." }, "lighthouse-core/audits/uses-rel-preload.js | title": { "message": "P̂ŕêĺôád̂ ḱêý r̂éq̂úêśt̂ś" @@ -1068,10 +1065,10 @@ "message": "B̂éŝt́ p̂ŕâćt̂íĉéŝ" }, "lighthouse-core/config/default-config.js | a11yCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ h́îǵĥĺîǵĥt́ ôṕp̂ór̂t́ûńît́îéŝ t́ô [ím̂ṕr̂óv̂é t̂h́ê áĉćêśŝíb̂íl̂ít̂ý ôf́ ŷóûŕ ŵéb̂ áp̂ṕ](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/áĉćêśŝíb̂íl̂ít̂ý). Ôńl̂ý â śûb́ŝét̂ óf̂ áĉćêśŝíb̂íl̂ít̂ý îśŝúêś ĉán̂ b́ê áût́ôḿât́îćâĺl̂ý d̂ét̂éĉt́êd́ ŝó m̂án̂úâĺ t̂éŝt́îńĝ íŝ ál̂śô én̂ćôúr̂áĝéd̂." + "message": "T̂h́êśê ćĥéĉḱŝ h́îǵĥĺîǵĥt́ ôṕp̂ór̂t́ûńît́îéŝ t́ô [ím̂ṕr̂óv̂é t̂h́ê áĉćêśŝíb̂íl̂ít̂ý ôf́ ŷóûŕ ŵéb̂ áp̂ṕ](https://developers.google.com/web/fundamentals/accessibility). Ôńl̂ý â śûb́ŝét̂ óf̂ áĉćêśŝíb̂íl̂ít̂ý îśŝúêś ĉán̂ b́ê áût́ôḿât́îćâĺl̂ý d̂ét̂éĉt́êd́ ŝó m̂án̂úâĺ t̂éŝt́îńĝ íŝ ál̂śô én̂ćôúr̂áĝéd̂." }, "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { - "message": "T̂h́êśê ít̂ém̂ś âd́d̂ŕêśŝ ár̂éâś ŵh́îćĥ án̂ áût́ôḿât́êd́ t̂éŝt́îńĝ t́ôól̂ ćâńn̂ót̂ ćôv́êŕ. L̂éâŕn̂ ḿôŕê ín̂ óûŕ ĝúîd́ê ón̂ [ćôńd̂úĉt́îńĝ án̂ áĉćêśŝíb̂íl̂ít̂ý r̂év̂íêẃ](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/áĉćêśŝíb̂íl̂ít̂ý/ĥóŵ-t́ô-ŕêv́îéŵ)." + "message": "T̂h́êśê ít̂ém̂ś âd́d̂ŕêśŝ ár̂éâś ŵh́îćĥ án̂ áût́ôḿât́êd́ t̂éŝt́îńĝ t́ôól̂ ćâńn̂ót̂ ćôv́êŕ. L̂éâŕn̂ ḿôŕê ín̂ óûŕ ĝúîd́ê ón̂ [ćôńd̂úĉt́îńĝ án̂ áĉćêśŝíb̂íl̂ít̂ý r̂év̂íêẃ](https://developers.google.com/web/fundamentals/accessibility/how-to-review)." }, "lighthouse-core/config/default-config.js | a11yCategoryTitle": { "message": "Âćĉéŝśîb́îĺît́ŷ" @@ -1155,7 +1152,7 @@ "message": "P̂Ẃ Óp̂t́îḿîźêd́" }, "lighthouse-core/config/default-config.js | seoCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ én̂śûŕê t́ĥát̂ ýôúr̂ ṕâǵê íŝ óp̂t́îḿîźêd́ f̂ór̂ śêár̂ćĥ én̂ǵîńê ŕêśûĺt̂ś r̂án̂ḱîńĝ. T́ĥér̂é âŕê ád̂d́ît́îón̂ál̂ f́âćt̂ór̂ś L̂íĝh́t̂h́ôúŝé d̂óêś n̂ót̂ ćĥéĉḱ t̂h́ât́ m̂áŷ áf̂f́êćt̂ ýôúr̂ śêár̂ćĥ ŕâńk̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://ŝúp̂ṕôŕt̂.ǵôóĝĺê.ćôḿ/ŵéb̂ḿâśt̂ér̂ś/âńŝẃêŕ/35769)." + "message": "T̂h́êśê ćĥéĉḱŝ én̂śûŕê t́ĥát̂ ýôúr̂ ṕâǵê íŝ óp̂t́îḿîźêd́ f̂ór̂ śêár̂ćĥ én̂ǵîńê ŕêśûĺt̂ś r̂án̂ḱîńĝ. T́ĥér̂é âŕê ád̂d́ît́îón̂ál̂ f́âćt̂ór̂ś L̂íĝh́t̂h́ôúŝé d̂óêś n̂ót̂ ćĥéĉḱ t̂h́ât́ m̂áŷ áf̂f́êćt̂ ýôúr̂ śêár̂ćĥ ŕâńk̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](https://support.google.com/webmasters/answer/35769)." }, "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { "message": "R̂ún̂ t́ĥéŝé âd́d̂ít̂íôńâĺ v̂ál̂íd̂át̂ór̂ś ôń ŷóûŕ ŝít̂é t̂ó ĉh́êćk̂ ád̂d́ît́îón̂ál̂ ŚÊÓ b̂éŝt́ p̂ŕâćt̂íĉéŝ." @@ -1176,7 +1173,7 @@ "message": "Ĉŕâẃl̂ín̂ǵ âńd̂ Ín̂d́êx́îńĝ" }, "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { - "message": "M̂ák̂é ŝúr̂é ŷóûŕ p̂áĝéŝ ár̂é m̂ób̂íl̂é f̂ŕîén̂d́l̂ý ŝó ûśêŕŝ d́ôń’t̂ h́âv́ê t́ô ṕîńĉh́ ôŕ ẑóôḿ îń ôŕd̂ér̂ t́ô ŕêád̂ t́ĥé ĉón̂t́êńt̂ ṕâǵêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/śêár̂ćĥ/ḿôb́îĺê-śît́êś/)." + "message": "M̂ák̂é ŝúr̂é ŷóûŕ p̂áĝéŝ ár̂é m̂ób̂íl̂é f̂ŕîén̂d́l̂ý ŝó ûśêŕŝ d́ôń’t̂ h́âv́ê t́ô ṕîńĉh́ ôŕ ẑóôḿ îń ôŕd̂ér̂ t́ô ŕêád̂ t́ĥé ĉón̂t́êńt̂ ṕâǵêś. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/search/mobile-sites/)." }, "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { "message": "M̂ób̂íl̂é F̂ŕîén̂d́l̂ý" @@ -1320,7 +1317,7 @@ "message": "L̂áb̂ D́ât́â" }, "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { - "message": "[L̂íĝh́t̂h́ôúŝé](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/) âńâĺŷśîś ôf́ t̂h́ê ćûŕr̂én̂t́ p̂áĝé ôń âń êḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂. V́âĺûéŝ ár̂é êśt̂ím̂át̂éd̂ án̂d́ m̂áŷ v́âŕŷ." + "message": "[L̂íĝh́t̂h́ôúŝé](https://developers.google.com/web/tools/lighthouse/) âńâĺŷśîś ôf́ t̂h́ê ćûŕr̂én̂t́ p̂áĝé ôń âń êḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂. V́âĺûéŝ ár̂é êśt̂ím̂át̂éd̂ án̂d́ m̂áŷ v́âŕŷ." }, "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { "message": "Âd́d̂ít̂íôńâĺ ît́êḿŝ t́ô ḿâńûál̂ĺŷ ćĥéĉḱ" diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index de0bc1a2fcb8..017d9ec5549b 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -1,119 +1,351 @@ { "lighthouse-core/audits/accessibility/accesskeys.js | description": { - "message": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { - "message": "`[accesskey]` values are not unique", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ values are not unique", + "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[accesskey]`", + "example": "[accesskey]" + } + } }, "lighthouse-core/audits/accessibility/accesskeys.js | title": { - "message": "`[accesskey]` values are unique", - "description": "Title of an accesibility audit that evaluates if the accesskey HTML attribute values are unique across all elements. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ values are unique", + "description": "Title of an accesibility audit that evaluates if the accesskey HTML attribute values are unique across all elements. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[accesskey]`", + "example": "[accesskey]" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { - "message": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Each ARIA $MARKDOWN_SNIPPET_0$ supports a specific subset of $MARKDOWN_SNIPPET_1$ attributes. Mismatching these invalidates the $MARKDOWN_SNIPPET_2$ attributes. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`role`", + "example": "role" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`aria-*`", + "example": "aria-*" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`aria-*`", + "example": "aria-*" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { - "message": "`[aria-*]` attributes do not match their roles", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ attributes do not match their roles", + "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { - "message": "`[aria-*]` attributes match their roles", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ attributes match their roles", + "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { - "message": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Some ARIA roles have required attributes that describe the state of the element to screen readers. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { - "message": "`[role]`s do not have all required `[aria-*]` attributes", - "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$s do not have all required $MARKDOWN_SNIPPET_1$ attributes", + "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { - "message": "`[role]`s have all required `[aria-*]` attributes", - "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$s have all required $MARKDOWN_SNIPPET_1$ attributes", + "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | description": { - "message": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { - "message": "Elements with `[role]` that require specific children `[role]`s, are missing.", - "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Elements with $MARKDOWN_SNIPPET_0$ that require specific children $MARKDOWN_SNIPPET_1$s, are missing.", + "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | title": { - "message": "Elements with `[role]` that require specific children `[role]`s, are present", - "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Elements with $MARKDOWN_SNIPPET_0$ that require specific children $MARKDOWN_SNIPPET_1$s, are present", + "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { - "message": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { - "message": "`[role]`s are not contained by their required parent element", - "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$s are not contained by their required parent element", + "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { - "message": "`[role]`s are contained by their required parent element", - "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$s are contained by their required parent element", + "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | description": { - "message": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "ARIA roles must have valid values in order to perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { - "message": "`[role]` values are not valid", - "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ values are not valid", + "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | title": { - "message": "`[role]` values are valid", - "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ values are valid", + "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { - "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { - "message": "`[aria-*]` attributes do not have valid values", - "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ attributes do not have valid values", + "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { - "message": "`[aria-*]` attributes have valid values", - "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ attributes have valid values", + "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { - "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { - "message": "`[aria-*]` attributes are not valid or misspelled", - "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ attributes are not valid or misspelled", + "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { - "message": "`[aria-*]` attributes are valid and not misspelled", - "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ attributes are valid and not misspelled", + "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | description": { - "message": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. [Learn more](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { - "message": "`<audio>` elements are missing a `<track>` element with `[kind=\"captions\"]`.", - "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements are missing a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", + "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<audio>`", + "example": "<audio>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | title": { - "message": "`<audio>` elements contain a `<track>` element with `[kind=\"captions\"]`", - "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", + "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<audio>`", + "example": "<audio>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { "message": "Failing Elements", "description": "Label of a table column that identifies HTML elements that have failed an audit." }, "lighthouse-core/audits/accessibility/button-name.js | description": { - "message": "When a button doesn't have an accessible name, screen readers announce it as \"button\", making it unusable for users who rely on screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "When a button doesn't have an accessible name, screen readers announce it as \"button\", making it unusable for users who rely on screen readers. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { "message": "Buttons do not have an accessible name", @@ -124,8 +356,16 @@ "description": "Title of an accesibility audit that evaluates if all button elements have names accessible to screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." }, "lighthouse-core/audits/accessibility/bypass.js | description": { - "message": "Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. [Learn more](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { "message": "The page does not contain a heading, skip link, or landmark region", @@ -136,8 +376,16 @@ "description": "Title of an accesibility audit that evaluates if the page has elements that let screen reader users skip over repetitive content. `heading`, `skip link`, and `landmark region` are technical terms for the elements that enable quick page navigation. This title is descriptive of the successful state and is shown to users when no user action is required." }, "lighthouse-core/audits/accessibility/color-contrast.js | description": { - "message": "Low-contrast text is difficult or impossible for many users to read. [Learn more](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Low-contrast text is difficult or impossible for many users to read. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { "message": "Background and foreground colors do not have a sufficient contrast ratio.", @@ -148,116 +396,384 @@ "description": "Title of an accesibility audit that evaluates if all foreground colors are distinct enough from their background colors to be legible for users. This title is descriptive of the successful state and is shown to users when no user action is required." }, "lighthouse-core/audits/accessibility/definition-list.js | description": { - "message": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. [Learn more](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { - "message": "`<dl>`'s do not contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements.", - "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$'s do not contain only properly-ordered $MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$ groups, $MARKDOWN_SNIPPET_3$ or $MARKDOWN_SNIPPET_4$ elements.", + "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_4": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/definition-list.js | title": { - "message": "`<dl>`'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements.", - "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$'s contain only properly-ordered $MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$ groups, $MARKDOWN_SNIPPET_3$ or $MARKDOWN_SNIPPET_4$ elements.", + "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_4": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | description": { - "message": "Definition list items (`<dt>` and `<dd>`) must be wrapped in a parent `<dl>` element to ensure that screen readers can properly announce them. [Learn more](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Definition list items ($MARKDOWN_SNIPPET_0$ and $MARKDOWN_SNIPPET_1$) must be wrapped in a parent $MARKDOWN_SNIPPET_2$ element to ensure that screen readers can properly announce them. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dl>`", + "example": "<dl>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { - "message": "Definition list items are not wrapped in `<dl>` elements", - "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Definition list items are not wrapped in $MARKDOWN_SNIPPET_0$ elements", + "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | title": { - "message": "Definition list items are wrapped in `<dl>` elements", - "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Definition list items are wrapped in $MARKDOWN_SNIPPET_0$ elements", + "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | description": { - "message": "The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/title).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/title)" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { - "message": "Document doesn't have a `<title>` element", - "description": "title: {" + "message": "Document doesn't have a $MARKDOWN_SNIPPET_0$ element", + "description": "title: {", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<title>`", + "example": "<title>" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | title": { "message": "placeholder", "description": "" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { - "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { - "message": "`[id]` attributes on the page are not unique", - "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ attributes on the page are not unique", + "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[id]`", + "example": "[id]" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | title": { - "message": "`[id]` attributes on the page are unique", - "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ attributes on the page are unique", + "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[id]`", + "example": "[id]" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | description": { - "message": "Screen reader users rely on frame titles to describe the contents of frames. [Learn more](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen reader users rely on frame titles to describe the contents of frames. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { - "message": "`<frame>` or `<iframe>` elements do not have a title", - "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ elements do not have a title", + "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<frame>`", + "example": "<frame>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<iframe>`", + "example": "<iframe>" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | title": { - "message": "`<frame>` or `<iframe>` elements have a title", - "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ elements have a title", + "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<frame>`", + "example": "<frame>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<iframe>`", + "example": "<iframe>" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | description": { - "message": "If a page doesn't specify a lang attribute, a screen reader assumes that the page is in the default language that the user chose when setting up the screen reader. If the page isn't actually in the default language, then the screen reader might not announce the page's text correctly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "If a page doesn't specify a lang attribute, a screen reader assumes that the page is in the default language that the user chose when setting up the screen reader. If the page isn't actually in the default language, then the screen reader might not announce the page's text correctly. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { - "message": "`<html>` element does not have a `[lang]` attribute", - "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ element does not have a $MARKDOWN_SNIPPET_1$ attribute", + "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | title": { - "message": "`<html>` element has a `[lang]` attribute", - "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ element has a $MARKDOWN_SNIPPET_1$ attribute", + "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { - "message": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) helps screen readers announce text properly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Specifying a valid $LINK_START_0$BCP 47 language$LINK_END_0$ helps screen readers announce text properly. $LINK_START_1$Learn more$LINK_END_1$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { - "message": "`<html>` element does not have a valid value for its `[lang]` attribute.", - "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ element does not have a valid value for its $MARKDOWN_SNIPPET_1$ attribute.", + "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { - "message": "`<html>` element has a valid value for its `[lang]` attribute", - "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ element has a valid value for its $MARKDOWN_SNIPPET_1$ attribute", + "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | description": { - "message": "Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. [Learn more](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { - "message": "Image elements do not have `[alt]` attributes", - "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Image elements do not have $MARKDOWN_SNIPPET_0$ attributes", + "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | title": { - "message": "Image elements have `[alt]` attributes", - "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Image elements have $MARKDOWN_SNIPPET_0$ attributes", + "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | description": { - "message": "When an image is being used as an `<input>` button, providing alternative text can help screen reader users understand the purpose of the button. [Learn more](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "When an image is being used as an $MARKDOWN_SNIPPET_0$ button, providing alternative text can help screen reader users understand the purpose of the button. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input>`", + "example": "<input>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { - "message": "`<input type=\"image\">` elements do not have `[alt]` text", - "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements do not have $MARKDOWN_SNIPPET_1$ text", + "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input type=\"image\">`", + "example": "<input type=\"image\">" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | title": { - "message": "`<input type=\"image\">` elements have `[alt]` text", - "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements have $MARKDOWN_SNIPPET_1$ text", + "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input type=\"image\">`", + "example": "<input type=\"image\">" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/label.js | description": { - "message": "Labels ensure that form controls are announced properly by assistive technologies, like screen readers. [Learn more](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Labels ensure that form controls are announced properly by assistive technologies, like screen readers. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/label.js | failureTitle": { "message": "Form elements do not have associated labels", @@ -268,20 +784,72 @@ "description": "Title of an accesibility audit that evaluates if all form elements have corresponding label elements. This title is descriptive of the successful state and is shown to users when no user action is required." }, "lighthouse-core/audits/accessibility/layout-table.js | description": { - "message": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { - "message": "Presentational `<table>` elements do not avoid using `<th>`, `<caption>` or the `[summary]` attribute.", - "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Presentational $MARKDOWN_SNIPPET_0$ elements do not avoid using $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ or the $MARKDOWN_SNIPPET_3$ attribute.", + "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<caption>`", + "example": "<caption>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`[summary]`", + "example": "[summary]" + } + } }, "lighthouse-core/audits/accessibility/layout-table.js | title": { - "message": "Presentational `<table>` elements avoid using `<th>`, `<caption>` or the `[summary]` attribute.", - "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Presentational $MARKDOWN_SNIPPET_0$ elements avoid using $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ or the $MARKDOWN_SNIPPET_3$ attribute.", + "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<caption>`", + "example": "<caption>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`[summary]`", + "example": "[summary]" + } + } }, "lighthouse-core/audits/accessibility/link-name.js | description": { - "message": "Link text (and alternate text for images, when used as links) that is discernible, unique, and focusable improves the navigation experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Link text (and alternate text for images, when used as links) that is discernible, unique, and focusable improves the navigation experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { "message": "Links do not have a discernible name", @@ -292,152 +860,536 @@ "description": "Title of an accesibility audit that evaluates if all link elements have a non-generic name to screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." }, "lighthouse-core/audits/accessibility/list.js | description": { - "message": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. [Learn more](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/list.js | failureTitle": { - "message": "Lists do not contain only `<li>` elements and script supporting elements (`<script>` and `<template>`).", - "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Lists do not contain only $MARKDOWN_SNIPPET_0$ elements and script supporting elements ($MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$).", + "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/list.js | title": { - "message": "Lists contain only `<li>` elements and script supporting elements (`<script>` and `<template>`).", - "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Lists contain only $MARKDOWN_SNIPPET_0$ elements and script supporting elements ($MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$).", + "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | description": { - "message": "Screen readers require list items (`<li>`) to be contained within a parent `<ul>` or `<ol>` to be announced properly. [Learn more](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen readers require list items ($MARKDOWN_SNIPPET_0$) to be contained within a parent $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ to be announced properly. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { - "message": "List items (`<li>`) are not contained within `<ul>` or `<ol>` parent elements.", - "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "List items ($MARKDOWN_SNIPPET_0$) are not contained within $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ parent elements.", + "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | title": { - "message": "List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements", - "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "List items ($MARKDOWN_SNIPPET_0$) are contained within $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ parent elements", + "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | description": { - "message": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. [Learn more](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { - "message": "The document uses `<meta http-equiv=\"refresh\">`", - "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "The document uses $MARKDOWN_SNIPPET_0$", + "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<meta http-equiv=\"refresh\">`", + "example": "<meta http-equiv=\"refresh\">" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | title": { - "message": "The document does not use `<meta http-equiv=\"refresh\">`", - "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "The document does not use $MARKDOWN_SNIPPET_0$", + "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<meta http-equiv=\"refresh\">`", + "example": "<meta http-equiv=\"refresh\">" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | description": { - "message": "Disabling zooming is problematic for users with low vision who rely on screen magnification to properly see the contents of a web page. [Learn more](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Disabling zooming is problematic for users with low vision who rely on screen magnification to properly see the contents of a web page. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { - "message": "`[user-scalable=\"no\"]` is used in the `<meta name=\"viewport\">` element or the `[maximum-scale]` attribute is less than 5.", - "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ is used in the $MARKDOWN_SNIPPET_1$ element or the $MARKDOWN_SNIPPET_2$ attribute is less than 5.", + "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[user-scalable=\"no\"]`", + "example": "[user-scalable=\"no\"]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<meta name=\"viewport\">`", + "example": "<meta name=\"viewport\">" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[maximum-scale]`", + "example": "[maximum-scale]" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | title": { - "message": "`[user-scalable=\"no\"]` is not used in the `<meta name=\"viewport\">` element and the `[maximum-scale]` attribute is not less than 5.", - "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ is not used in the $MARKDOWN_SNIPPET_1$ element and the $MARKDOWN_SNIPPET_2$ attribute is not less than 5.", + "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[user-scalable=\"no\"]`", + "example": "[user-scalable=\"no\"]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<meta name=\"viewport\">`", + "example": "<meta name=\"viewport\">" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[maximum-scale]`", + "example": "[maximum-scale]" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | description": { - "message": "Screen readers cannot translate non-text content. Adding alt text to `<object>` elements helps screen readers convey meaning to users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen readers cannot translate non-text content. Adding alt text to $MARKDOWN_SNIPPET_0$ elements helps screen readers convey meaning to users. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { - "message": "`<object>` elements do not have `[alt]` text", - "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements do not have $MARKDOWN_SNIPPET_1$ text", + "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | title": { - "message": "`<object>` elements have `[alt]` text", - "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements have $MARKDOWN_SNIPPET_1$ text", + "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | description": { - "message": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { - "message": "Some elements have a `[tabindex]` value greater than 0", - "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Some elements have a $MARKDOWN_SNIPPET_0$ value greater than 0", + "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[tabindex]`", + "example": "[tabindex]" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | title": { - "message": "No element has a `[tabindex]` value greater than 0", - "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "No element has a $MARKDOWN_SNIPPET_0$ value greater than 0", + "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[tabindex]`", + "example": "[tabindex]" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { - "message": "Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen readers have features to make navigating tables easier. Ensuring $MARKDOWN_SNIPPET_0$ cells using the $MARKDOWN_SNIPPET_1$ attribute only refer to other cells in the same table may improve the experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<td>`", + "example": "<td>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { - "message": "Cells in a `<table>` element that use the `[headers]` attribute refers to other cells of that same table.", - "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "Cells in a $MARKDOWN_SNIPPET_0$ element that use the $MARKDOWN_SNIPPET_1$ attribute refers to other cells of that same table.", + "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { - "message": "Cells in a `<table>` element that use the `[headers]` attribute only refer to other cells of that same table.", - "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "Cells in a $MARKDOWN_SNIPPET_0$ element that use the $MARKDOWN_SNIPPET_1$ attribute only refer to other cells of that same table.", + "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { - "message": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { - "message": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` do not have data cells they describe.", - "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements and elements with $MARKDOWN_SNIPPET_1$ do not have data cells they describe.", + "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role=\"columnheader\"/\"rowheader\"]`", + "example": "[role=\"columnheader\"/\"rowheader\"]" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { - "message": "`<th>` elements and elements with `[role=\"columnheader\"/\"rowheader\"]` have data cells they describe.", - "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements and elements with $MARKDOWN_SNIPPET_1$ have data cells they describe.", + "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role=\"columnheader\"/\"rowheader\"]`", + "example": "[role=\"columnheader\"/\"rowheader\"]" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | description": { - "message": "Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) on elements helps ensure that text is pronounced correctly by a screen reader. [Learn more](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Specifying a valid $LINK_START_0$BCP 47 language$LINK_END_0$ on elements helps ensure that text is pronounced correctly by a screen reader. $LINK_START_1$Learn more$LINK_END_1$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { - "message": "`[lang]` attributes do not have a valid value", - "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ attributes do not have a valid value", + "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | title": { - "message": "`[lang]` attributes have a valid value", - "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ attributes have a valid value", + "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | description": { - "message": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. [Learn more](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { - "message": "`<video>` elements do not contain a `<track>` element with `[kind=\"captions\"]`.", - "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements do not contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", + "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | title": { - "message": "`<video>` elements contain a `<track>` element with `[kind=\"captions\"]`", - "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", + "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | description": { - "message": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. [Learn more](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse).", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { - "message": "`<video>` elements do not contain a `<track>` element with `[kind=\"description\"]`.", - "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." + "message": "$MARKDOWN_SNIPPET_0$ elements do not contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", + "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"description\"]`", + "example": "[kind=\"description\"]" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | title": { - "message": "`<video>` elements contain a `<track>` element with `[kind=\"description\"]`", - "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required." + "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", + "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"description\"]`", + "example": "[kind=\"description\"]" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | description": { - "message": "For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG. [Learn More](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/).", - "description": "Description of a Lighthouse audit that tells the user what having a valid apple-touch-icon does. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"apple-touch-icon\" is an HTML attribute value and should not be translated." + "message": "For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG. $LINK_START_0$Learn More$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user what having a valid apple-touch-icon does. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { - "message": "Does not provide a valid `apple-touch-icon`", - "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page does not contain a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated." + "message": "Does not provide a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page does not contain a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { - "message": "`apple-touch-icon-precomposed` is out of date; `apple-touch-icon` is preferred.", - "description": "Warning that HTML attribute `apple-touch-icon-precomposed` should not be used in favor of `apple-touch-icon`. \"apple-touch-icon-precomposed\" and \"apple-touch-icon\" are HTML attribute values and should not be translated." + "message": "$MARKDOWN_SNIPPET_0$ is out of date; $MARKDOWN_SNIPPET_1$ is preferred.", + "description": "Warning that HTML attribute `apple-touch-icon-precomposed` should not be used in favor of `apple-touch-icon`. \"apple-touch-icon-precomposed\" and \"apple-touch-icon\" are HTML attribute values and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon-precomposed`", + "example": "apple-touch-icon-precomposed" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | title": { - "message": "Provides a valid `apple-touch-icon`", - "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page contains a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated." + "message": "Provides a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page contains a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { "message": "Chrome extensions negatively affected this page's load performance. Try auditing the page in incognito mode or from a Chrome profile without extensions.", @@ -456,8 +1408,16 @@ "description": "Label for the total time column in a data table; entries will be the number of milliseconds spent executing per resource loaded by the page." }, "lighthouse-core/audits/bootup-time.js | description": { - "message": "Consider reducing the time spent parsing, compiling, and executing JS. You may find delivering smaller JS payloads helps with this. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/bootup).", - "description": "Description of a Lighthouse audit that tells the user that they should reduce the amount of time spent executing javascript and one method of doing so. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Consider reducing the time spent parsing, compiling, and executing JS. You may find delivering smaller JS payloads helps with this. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user that they should reduce the amount of time spent executing javascript and one method of doing so. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/bootup)" + } + } }, "lighthouse-core/audits/bootup-time.js | failureTitle": { "message": "Reduce JavaScript execution time", @@ -468,36 +1428,74 @@ "description": "Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { - "message": "Large GIFs are inefficient for delivering animated content. Consider using MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save network bytes. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)", - "description": "Description of a Lighthouse audit that tells the user *why* they should use video instead of GIF format for delivering animated content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Large GIFs are inefficient for delivering animated content. Consider using MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save network bytes. $LINK_START_0$Learn more$LINK_END_0$", + "description": "Description of a Lighthouse audit that tells the user *why* they should use video instead of GIF format for delivering animated content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" + } + } }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { "message": "Use video formats for animated content", "description": "Imperative title of a Lighthouse audit that tells the user to use video formats rather than animated GIFs, which are wasteful. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { - "message": "Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images).", - "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { "message": "Defer offscreen images", "description": "Imperative title of a Lighthouse audit that tells the user to defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { - "message": "Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources).", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce or remove network resources that block the initial render of the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should reduce or remove network resources that block the initial render of the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)" + } + } }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { "message": "Eliminate render-blocking resources", "description": "Imperative title of a Lighthouse audit that tells the user to reduce or remove network resources that block the initial render of the page. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { - "message": "Large network payloads cost users real money and are highly correlated with long load times. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/network-payloads).", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the network resources required by the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Large network payloads cost users real money and are highly correlated with long load times. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the network resources required by the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)" + } + } }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "Total size was {totalBytes, number, bytes} KB", - "description": "Used to summarize the total byte size of the page and all its network requests. The `{totalBytes}` placeholder will be replaced with the total byte sizes, shown in kilobytes (e.g. 142 KB)" + "message": "Total size was $COMPLEX_ICU_0$ KB", + "description": "Used to summarize the total byte size of the page and all its network requests. The `{totalBytes}` placeholder will be replaced with the total byte sizes, shown in kilobytes (e.g. 142 KB)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{totalBytes, number, bytes}", + "example": "499" + } + } }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | failureTitle": { "message": "Avoid enormous network payloads", @@ -508,69 +1506,72 @@ "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $link_start$Learn More!!!$link_end$. This audit took $milliseconds$ ms.", + "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$->Learn More!!!$LINK_END_0$. This audit took $COMPLEX_ICU_0$ ms.", "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { - "link_start": { - "content": "[->" + "LINK_START_0": { + "content": "[" }, - "link_end": { + "LINK_END_0": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" }, - "milliseconds": { + "COMPLEX_ICU_0": { "content": "{timeInMs, number, milliseconds}", - "example": "520 (Placeholder examples go here)" + "example": "499" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Someone minified this, {direct_replace_name}. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", + "message": "Someone minified this, {direct_replace_name}. $MARKDOWN_SNIPPET_0$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", "description": "[ICU Syntax] Some gendered (ICU select) explanation...", "placeholders": { - "static_replacement": { + "MARKDOWN_SNIPPET_0": { "content": "`<link rel=>`", - "example": "Some static replacement." - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { - "message": "Someone minified this, $name$. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", - "description": "[ICU Syntax] Some gendered (ICU select) explanation...", - "placeholders": { - "static_replacement": { - "content": "`<link rel=>`", - "example": "Some static replacement." - }, - "name": { - "content": "{name}", - "example": "This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen." + "example": "<link rel=>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "Minify CSS like $css$", + "message": "Minify CSS like $MARKDOWN_SNIPPET_0$", "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates.", "placeholders": { - "css": { - "content": "`<link rel=stylesheet>`" + "MARKDOWN_SNIPPET_0": { + "content": "`<link rel=stylesheet>`", + "example": "<link rel=stylesheet>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# error found}other {# errors found}}", + "message": "{itemCount, plural, =1 {# error found} other {# errors found}}", "description": "[ICU Syntax] Some plural warning..." }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { - "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).", - "description": "Description of a Lighthouse audit that tells the user *why* they should minify the page’s JS code to reduce file size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Minifying JavaScript files can reduce payload sizes and script parse time. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should minify the page’s JS code to reduce file size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/speed/docs/insights/MinifyResources)" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { "message": "Minify JavaScript", "description": "Imperative title of a Lighthouse audit that tells the user to minify the page’s JS code to reduce file size. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { - "message": "Remove dead rules from stylesheets and defer the loading of CSS not used for above-the-fold content to reduce unnecessary bytes consumed by network activity. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/unused-css).", - "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading any content in CSS that isn’t needed at page load. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation." + "message": "Remove dead rules from stylesheets and defer the loading of CSS not used for above-the-fold content to reduce unnecessary bytes consumed by network activity. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading any content in CSS that isn’t needed at page load. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/unused-css)" + } + } }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { "message": "Remove unused CSS", @@ -585,8 +1586,16 @@ "description": "Imperative title of a Lighthouse audit that tells the user to remove JavaScript that is never evaluated during page load. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { - "message": "A long cache lifetime can speed up repeat visits to your page. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/cache-policy).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to adopt a long cache lifetime policy. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "A long cache lifetime can speed up repeat visits to your page. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to adopt a long cache lifetime policy. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 resource found}\n other {# resources found}\n }", @@ -601,40 +1610,80 @@ "description": "Title of a diagnostic audit that provides detail on the cache policy applies to the page's static assets. Cache refers to browser disk cache, which keeps old versions of network resources around for future use. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { - "message": "Optimized images load faster and consume less cellular data. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/optimize-images).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to efficiently encode images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Optimized images load faster and consume less cellular data. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to efficiently encode images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { "message": "Efficiently encode images", "description": "Imperative title of a Lighthouse audit that tells the user to encode images with optimization (better compression). This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { - "message": "Serve images that are appropriately-sized to save cellular data and improve load time. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/oversized-images).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to serve appropriately sized images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Serve images that are appropriately-sized to save cellular data and improve load time. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to serve appropriately sized images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { "message": "Properly size images", "description": "Imperative title of a Lighthouse audit that tells the user to resize images to match the display dimensions. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { - "message": "Text-based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/text-compression).", - "description": "Description of a Lighthouse audit that tells the user *why* their text-based resources should be served with compression (like gzip). This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Text-based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* their text-based resources should be served with compression (like gzip). This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/text-compression)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { "message": "Enable text compression", "description": "Imperative title of a Lighthouse audit that tells the user to enable text compression (like gzip) in order to enhance the performance of a page. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { - "message": "Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/webp).", - "description": "Description of a Lighthouse audit that tells the user *why* they should use newer and more efficient image formats. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should use newer and more efficient image formats. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/webp)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { "message": "Serve images in next-gen formats", "description": "Imperative title of a Lighthouse audit that tells the user to serve images in newer and more efficient image formats in order to enhance the performance of a page. A non-modern image format was designed 20+ years ago. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/critical-request-chains.js | description": { - "message": "The Critical Request Chains below show you what resources are loaded with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains).", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the depth of critical network requests to enhance initial load of a page . This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "The Critical Request Chains below show you what resources are loaded with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the depth of critical network requests to enhance initial load of a page . This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)" + } + } }, "lighthouse-core/audits/critical-request-chains.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 chain found}\n other {# chains found}\n }", @@ -653,8 +1702,16 @@ "description": "Table column header for line of code (eg. 432) that is using a deprecated API." }, "lighthouse-core/audits/deprecations.js | description": { - "message": "Deprecated APIs will eventually be removed from the browser. [Learn more](https://www.chromestatus.com/features#deprecated).", - "description": "Description of a Lighthouse audit that tells the user why they should not use deprecated APIs on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Deprecated APIs will eventually be removed from the browser. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should not use deprecated APIs on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.chromestatus.com/features#deprecated)" + } + } }, "lighthouse-core/audits/deprecations.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 warning found}\n other {# warnings found}\n }", @@ -669,8 +1726,16 @@ "description": "Title of a Lighthouse audit that provides detail on the use of deprecated APIs. This descriptive title is shown to users when the page does not use deprecated APIs." }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | description": { - "message": "Application Cache is deprecated. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).", - "description": "Description of a Lighthouse audit that tells the user why they should not use the Application Cache API. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Application Cache is deprecated. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should not use the Application Cache API. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/appcache)" + } + } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { "message": "Found \"{AppCacheManifest}\"", @@ -685,12 +1750,26 @@ "description": "Title of a Lighthouse audit that provides detail on the use of the Application Cache API. This descriptive title is shown to users when they do not use the Application Cache API." }, "lighthouse-core/audits/dobetterweb/doctype.js | description": { - "message": "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)", - "description": "Description of a Lighthouse audit that tells the user why they should define an HTML doctype. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Specifying a doctype prevents the browser from switching to quirks-mode. Read more on the $LINK_START_0$MDN Web Docs page$LINK_END_0$", + "description": "Description of a Lighthouse audit that tells the user why they should define an HTML doctype. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)" + } + } }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationBadDoctype": { - "message": "Doctype name must be the lowercase string `html`", - "description": "Explanatory message stating that the doctype is set, but is not \"html\" and is therefore invalid." + "message": "Doctype name must be the lowercase string $MARKDOWN_SNIPPET_0$", + "description": "Explanatory message stating that the doctype is set, but is not \"html\" and is therefore invalid.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`html`", + "example": "html" + } + } }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationNoDoctype": { "message": "Document must contain a doctype", @@ -725,8 +1804,28 @@ "description": "Table column header for the observed value of the DOM statistic." }, "lighthouse-core/audits/dobetterweb/dom-size.js | description": { - "message": "Browser engineers recommend pages contain fewer than ~1,500 DOM elements. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer [style calculations](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations), and produce costly [layout reflows](https://developers.google.com/speed/articles/reflow). [Learn more](https://developers.google.com/web/tools/lighthouse/audits/dom-size).", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Browser engineers recommend pages contain fewer than ~1,500 DOM elements. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer $LINK_START_0$style calculations$LINK_END_0$, and produce costly $LINK_START_1$layout reflows$LINK_END_1$. $LINK_START_2$Learn more$LINK_END_2$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://developers.google.com/speed/articles/reflow)" + }, + "LINK_START_2": { + "content": "[" + }, + "LINK_END_2": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/dom-size)" + } + } }, "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 element}\n other {# elements}\n }", @@ -761,8 +1860,24 @@ "description": "Label for a column in a data table; entries will be the target attribute of a link. Each entry is either an empty string or a string like `_blank`." }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description": { - "message": "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).", - "description": "Description of a Lighthouse audit that tells the user why and how they should secure cross-origin links. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Add $MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ to any external links to improve performance and prevent security vulnerabilities. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why and how they should secure cross-origin links. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=\"noopener\"`", + "example": "rel=\"noopener\"" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`rel=\"noreferrer\"`", + "example": "rel=\"noreferrer\"" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/noopener)" + } + } }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle": { "message": "Links to cross-origin destinations are unsafe", @@ -777,8 +1892,16 @@ "description": "Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety." }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { - "message": "Users are mistrustful of or confused by sites that request their location without context. Consider tying the request to a user action instead. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load).", - "description": "Description of a Lighthouse audit that tells the user why they should not ask for geolocation permissions on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Users are mistrustful of or confused by sites that request their location without context. Consider tying the request to a user action instead. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should not ask for geolocation permissions on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load)" + } + } }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | failureTitle": { "message": "Requests the geolocation permission on page load", @@ -805,16 +1928,40 @@ "description": "Title of a Lighthouse audit that provides detail on the Javascript libraries that are used on the page." }, "lighthouse-core/audits/dobetterweb/no-document-write.js | description": { - "message": "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).", - "description": "Description of a Lighthouse audit that tells the user why they should avoid `document.write`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "For users on slow connections, external scripts dynamically injected via $MARKDOWN_SNIPPET_0$ can delay page load by tens of seconds. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should avoid `document.write`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/document-write)" + } + } }, "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": { - "message": "Uses `document.write()`", - "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does use `document.write`." + "message": "Uses $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does use `document.write`.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + } + } }, "lighthouse-core/audits/dobetterweb/no-document-write.js | title": { - "message": "Avoids `document.write()`", - "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does not use `document.write`." + "message": "Avoids $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does not use `document.write`.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + } + } }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnSeverity": { "message": "Highest Severity", @@ -829,8 +1976,16 @@ "description": "Label for a column in a data table; entries will be the counts of JavaScript-library vulnerabilities found." }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description": { - "message": "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).", - "description": "Description of a Lighthouse audit that tells the user why they should be concerned about the third party Javascript libraries that they use. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Some third-party scripts may contain known security vulnerabilities that are easily identified and exploited by attackers. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should be concerned about the third party Javascript libraries that they use. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities)" + } + } }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 vulnerability detected}\n other {# vulnerabilities detected}\n }", @@ -857,8 +2012,16 @@ "description": "Title of a Lighthouse audit that provides detail on Javascript libraries the page uses. This descriptive title is shown to users when all Javascript libraries are free of known security vulnerabilities." }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | description": { - "message": "Users are mistrustful of or confused by sites that request to send notifications without context. Consider tying the request to user gestures instead. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load).", - "description": "Description of a Lighthouse audit that tells the user why they should not ask for notification permission on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Users are mistrustful of or confused by sites that request to send notifications without context. Consider tying the request to user gestures instead. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should not ask for notification permission on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load)" + } + } }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | failureTitle": { "message": "Requests the notification permission on page load", @@ -873,8 +2036,16 @@ "description": "Table column header for the HTML elements that do not allow pasting of content." }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { - "message": "Preventing password pasting undermines good security policy. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/password-pasting).", - "description": "Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Preventing password pasting undermines good security policy. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/password-pasting)" + } + } }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | failureTitle": { "message": "Prevents users to paste into password fields", @@ -889,8 +2060,16 @@ "description": "Label for a column in a data table; entries in the column will be the HTTP Protocol used to make a network request." }, "lighthouse-core/audits/dobetterweb/uses-http2.js | description": { - "message": "HTTP/2 offers many benefits over HTTP/1.1, including binary headers, multiplexing, and server push. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/http2).", - "description": "Description of a Lighthouse audit that tells the user why they should use HTTP/2. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "HTTP/2 offers many benefits over HTTP/1.1, including binary headers, multiplexing, and server push. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should use HTTP/2. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/http2)" + } + } }, "lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 request not served via HTTP/2}\n other {# requests not served via HTTP/2}\n }", @@ -905,8 +2084,20 @@ "description": "Title of a Lighthouse audit that provides detail on whether the webpage uses HTTP/2 for resources it requests over the network. This descriptive title is shown to users when the page uses HTTP/2 for its requests." }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description": { - "message": "Consider marking your touch and wheel event listeners as `passive` to improve your page's scroll performance. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners).", - "description": "Description of a Lighthouse audit that tells the user why they should use passive event listeners on the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Consider marking your touch and wheel event listeners as $MARKDOWN_SNIPPET_0$ to improve your page's scroll performance. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should use passive event listeners on the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`passive`", + "example": "passive" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners)" + } + } }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | failureTitle": { "message": "Does not use passive listeners to improve scrolling performance", @@ -933,8 +2124,16 @@ "description": "Title of a Lighthouse audit that provides detail on browser errors. This descriptive title is shown to users when no browser errors were logged into the devtools console." }, "lighthouse-core/audits/font-display.js | description": { - "message": "Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading. [Learn more](https://developers.google.com/web/updates/2016/02/font-display).", - "description": "Description of a Lighthouse audit that tells the user *why* they should use the font-display CSS feature. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should use the font-display CSS feature. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/updates/2016/02/font-display)" + } + } }, "lighthouse-core/audits/font-display.js | failureTitle": { "message": "Ensure text remains visible during webfont load", @@ -957,8 +2156,16 @@ "description": "Label for a column in a data table; entries in the column will be the numeric aspect ratio of an image as displayed in a web page." }, "lighthouse-core/audits/image-aspect-ratio.js | description": { - "message": "Image display dimensions should match natural aspect ratio. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio).", - "description": "Description of a Lighthouse audit that tells the user why they should maintain the correct aspect ratios for all images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Image display dimensions should match natural aspect ratio. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why they should maintain the correct aspect ratios for all images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio)" + } + } }, "lighthouse-core/audits/image-aspect-ratio.js | failureTitle": { "message": "Displays images with incorrect aspect ratio", @@ -977,8 +2184,16 @@ "description": "Label for a column in a data table; entries in the column will be the URLs of insecure (non-HTTPS) network requests." }, "lighthouse-core/audits/is-on-https.js | description": { - "message": "All sites should be protected with HTTPS, even ones that don't handle sensitive data. HTTPS prevents intruders from tampering with or passively listening in on the communications between your app and your users, and is a prerequisite for HTTP/2 and many new web platform APIs. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/https).", - "description": "Description of a Lighthouse audit that tells the user *why* HTTPS use is important. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "All sites should be protected with HTTPS, even ones that don't handle sensitive data. HTTPS prevents intruders from tampering with or passively listening in on the communications between your app and your users, and is a prerequisite for HTTP/2 and many new web platform APIs. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* HTTPS use is important. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/https)" + } + } }, "lighthouse-core/audits/is-on-https.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 insecure request found}\n other {# insecure requests found}\n }", @@ -993,16 +2208,36 @@ "description": "Title of a Lighthouse audit that provides detail on the useage of HTTPS on a page. This descriptive title is shown to users when all requests on a page are fufilled using HTTPS." }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { - "message": "A fast page load over a cellular network ensures a good mobile user experience. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/fast-3g).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to load fast enough on mobile networks. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "A fast page load over a cellular network ensures a good mobile user experience. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to load fast enough on mobile networks. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { - "message": "Interactive at {timeInMs, number, seconds} s", - "description": "Label for the audit identifying the time it took for the page to become interactive." + "message": "Interactive at $COMPLEX_ICU_0$ s", + "description": "Label for the audit identifying the time it took for the page to become interactive.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueTextWithOverride": { - "message": "Interactive on simulated mobile network at {timeInMs, number, seconds} s", - "description": "Label for the audit identifying the time it took for the page to become interactive on a mobile network." + "message": "Interactive on simulated mobile network at $COMPLEX_ICU_0$ s", + "description": "Label for the audit identifying the time it took for the page to become interactive on a mobile network.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": { "message": "Page load is not fast enough on mobile networks", @@ -1029,72 +2264,144 @@ "description": "Title of a diagnostic audit that provides detail on the main thread work the browser did to load the page. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { - "message": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency).", - "description": "Description of the Estimated Input Latency metric that estimates the amount of time, in milliseconds, that the app takes to respond to user input. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the Estimated Input Latency metric that estimates the amount of time, in milliseconds, that the app takes to respond to user input. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)" + } + } }, "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { "message": "Estimated Input Latency", "description": "The name of the metric that marks the estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { - "message": "First Contentful Paint marks the time at which the first text or image is painted. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint).", - "description": "Description of the First Contentful Paint (FCP) metric, which marks the time at which the first text or image is painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "First Contentful Paint marks the time at which the first text or image is painted. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the First Contentful Paint (FCP) metric, which marks the time at which the first text or image is painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)" + } + } }, "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { "message": "First Contentful Paint", "description": "The name of the metric that marks the time at which the first text or image is painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { - "message": "First CPU Idle marks the first time at which the page's main thread is quiet enough to handle input. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-interactive).", - "description": "Description of the First CPU Idle metric, which marks the time at which the page has displayed content and the CPU is not busy executing the page's scripts. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "First CPU Idle marks the first time at which the page's main thread is quiet enough to handle input. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the First CPU Idle metric, which marks the time at which the page has displayed content and the CPU is not busy executing the page's scripts. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)" + } + } }, "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { "message": "First CPU Idle", "description": "The name of the metric that marks when the page has displayed content and the CPU is not busy executing the page's scripts. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { - "message": "First Meaningful Paint measures when the primary content of a page is visible. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint).", - "description": "Description of the First Meaningful Paint (FMP) metric, which marks the time at which a majority of the content has been painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "First Meaningful Paint measures when the primary content of a page is visible. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the First Meaningful Paint (FMP) metric, which marks the time at which a majority of the content has been painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)" + } + } }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { "message": "First Meaningful Paint", "description": "The name of the metric that marks the time at which a majority of the content has been painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/interactive.js | description": { - "message": "Time to interactive is the amount of time it takes for the page to become fully interactive. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive).", - "description": "Description of the Time to Interactive (TTI) metric, which evaluates when a page has completed its primary network activity and main thread work. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Time to interactive is the amount of time it takes for the page to become fully interactive. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the Time to Interactive (TTI) metric, which evaluates when a page has completed its primary network activity and main thread work. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)" + } + } }, "lighthouse-core/audits/metrics/interactive.js | title": { "message": "Time to Interactive", "description": "The name of the metric that marks the time at which the page is fully loaded and is able to quickly respond to user input (clicks, taps, and keypresses feel responsive). Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/max-potential-fid.js | description": { - "message": "The maximum potential First Input Delay that your users could experience is the duration, in milliseconds, of the longest task. [Learn more](https://developers.google.com/web/updates/2018/05/first-input-delay).", - "description": "Description of the Maximum Potential First Input Delay metric that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "The maximum potential First Input Delay that your users could experience is the duration, in milliseconds, of the longest task. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the Maximum Potential First Input Delay metric that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/updates/2018/05/first-input-delay)" + } + } }, "lighthouse-core/audits/metrics/max-potential-fid.js | title": { "message": "Max Potential First Input Delay", "description": "The name of the metric \"Maximum Potential First Input Delay\" that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/metrics/speed-index.js | description": { - "message": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/speed-index).", - "description": "Description of the Speed Index metric, which summarizes how quickly the page looked visually complete. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Speed Index shows how quickly the contents of a page are visibly populated. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the Speed Index metric, which summarizes how quickly the page looked visually complete. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/speed-index)" + } + } }, "lighthouse-core/audits/metrics/speed-index.js | title": { "message": "Speed Index", "description": "The name of the metric that summarizes how quickly the page looked visually complete. The name of this metric is largely abstract and can be loosely translated. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." }, "lighthouse-core/audits/network-rtt.js | description": { - "message": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. [Learn more](https://hpbn.co/primer-on-latency-and-bandwidth/).", - "description": "Description of a Lighthouse audit that tells the user that a high network round trip time (RTT) can effect their website's performance because the server is physically far away from them thus making the RTT high. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user that a high network round trip time (RTT) can effect their website's performance because the server is physically far away from them thus making the RTT high. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://hpbn.co/primer-on-latency-and-bandwidth/)" + } + } }, "lighthouse-core/audits/network-rtt.js | title": { "message": "Network Round Trip Times", "description": "Descriptive title of a Lighthouse audit that tells the user the round trip times to each origin the page connected to. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/network-server-latency.js | description": { - "message": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. [Learn more](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall).", - "description": "Description of a Lighthouse audit that tells the user that server latency can effect their website's performance negatively. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user that server latency can effect their website's performance negatively. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)" + } + } }, "lighthouse-core/audits/network-server-latency.js | title": { "message": "Server Backend Latencies", @@ -1105,8 +2412,16 @@ "description": "Label for a column in a data table; entries will be how much the quantity or size of network requests exceeded a predetermined budget." }, "lighthouse-core/audits/performance-budget.js | description": { - "message": "Keep the quantity and size of network requests under the targets set by the provided performance budget. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets).", - "description": "Description of a Lighthouse audit where a user sets budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Keep the quantity and size of network requests under the targets set by the provided performance budget. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit where a user sets budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" + } + } }, "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { "message": "{count, plural,\n =1 {1 request}\n other {# requests}\n }", @@ -1117,16 +2432,32 @@ "description": "Title of a Lighthouse audit that compares the size and quantity of page resources against targets set by the user. These targets are thought of as \"performance budgets\" because these metrics impact page performance (i.e. how quickly a page loads)." }, "lighthouse-core/audits/redirects.js | description": { - "message": "Redirects introduce additional delays before the page can be loaded. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/redirects).", - "description": "Description of a Lighthouse audit that tells users why they should reduce the number of server-side redirects on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Redirects introduce additional delays before the page can be loaded. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells users why they should reduce the number of server-side redirects on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/redirects)" + } + } }, "lighthouse-core/audits/redirects.js | title": { "message": "Avoid multiple page redirects", "description": "Imperative title of a Lighthouse audit that tells the user to eliminate the redirects taken through multiple URLs to load the page. This is shown in a list of audits that Lighthouse generates." }, "lighthouse-core/audits/resource-summary.js | description": { - "message": "To set budgets for the quantity and size of page resources, add a budget.json file. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets).", - "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "To set budgets for the quantity and size of page resources, add a budget.json file. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" + } + } }, "lighthouse-core/audits/resource-summary.js | displayValue": { "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB", @@ -1137,8 +2468,16 @@ "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." }, "lighthouse-core/audits/seo/canonical.js | description": { - "message": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Canonical links suggest which URL to show in search results. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/canonical)" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationConflict": { "message": "Multiple conflicting URLs ({urlList})", @@ -1153,8 +2492,14 @@ "description": "Explanatory message stating that there was a failure in an audit caused by a URL being invalid. \"url\" will be replaced by the invalid URL (e.g. https://example.com)." }, "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "Points to another `hreflang` location ({url})", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. \"url\" will be replaced by the invalid URL (e.g. https://example.com). 'hreflang' is an HTML attribute and should not be translated." + "message": "Points to another $MARKDOWN_SNIPPET_0$ location ({url})", + "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. \"url\" will be replaced by the invalid URL (e.g. https://example.com). 'hreflang' is an HTML attribute and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationRelative": { "message": "Relative URL ({url})", @@ -1165,32 +2510,74 @@ "description": "Explanatory message stating that the page's canonical URL was pointing to the domain's root URL, which is a common mistake. \"points\" refers to the action of the 'rel=canonical' referencing another link. \"root\" refers to the starting/home page of the website. \"domain\" refers to the registered domain name of the website." }, "lighthouse-core/audits/seo/canonical.js | failureTitle": { - "message": "Document does not have a valid `rel=canonical`", - "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is invalid and should be fixed. \"rel=canonical\" is an HTML attribute and value and so should not be translated." + "message": "Document does not have a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is invalid and should be fixed. \"rel=canonical\" is an HTML attribute and value and so should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=canonical`", + "example": "rel=canonical" + } + } }, "lighthouse-core/audits/seo/canonical.js | title": { - "message": "Document has a valid `rel=canonical`", - "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. \"rel=canonical\" is an HTML attribute and value and so should not be translated." + "message": "Document has a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. \"rel=canonical\" is an HTML attribute and value and so should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=canonical`", + "example": "rel=canonical" + } + } }, "lighthouse-core/audits/seo/font-size.js | description": { - "message": "Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/font-sizes).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to use a larger font size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to use a larger font size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)" + } + } }, "lighthouse-core/audits/seo/font-size.js | displayValue": { - "message": "{decimalProportion, number, extendedPercent} legible text", - "description": "Label for the audit identifying font sizes that are too small." + "message": "$COMPLEX_ICU_0$ legible text", + "description": "Label for the audit identifying font sizes that are too small.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | explanation": { - "message": "{decimalProportion, number, extendedPercent} of text is too small.", - "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. \"decimalProportion\" will be replaced by a percentage between 0 and 100%." + "message": "$COMPLEX_ICU_0$ of text is too small.", + "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. \"decimalProportion\" will be replaced by a percentage between 0 and 100%.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | explanationViewport": { "message": "Text is illegible because there's no viewport meta tag optimized for mobile screens.", "description": "Explanatory message stating that there was a failure in an audit caused by a missing page viewport meta tag configuration. \"viewport\" and \"meta\" are HTML terms and should not be translated." }, "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": { - "message": "{decimalProportion, number, extendedPercent} of text is too small (based on {decimalProportionVisited, number, extendedPercent} sample).", - "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small, based on a sample size of text that was less than 100% of the text on the page. \"decimalProportion\" will be replaced by a percentage between 0 and 100%." + "message": "$COMPLEX_ICU_0$ of text is too small (based on $COMPLEX_ICU_1$ sample).", + "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small, based on a sample size of text that was less than 100% of the text on the page. \"decimalProportion\" will be replaced by a percentage between 0 and 100%.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + }, + "COMPLEX_ICU_1": { + "content": "{decimalProportionVisited, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | failureTitle": { "message": "Document doesn't use legible font sizes", @@ -1201,20 +2588,48 @@ "description": "Title of a Lighthouse audit that provides detail on the font sizes used on the page. This descriptive title is shown to users when the fonts used on the page are large enough to be considered legible." }, "lighthouse-core/audits/seo/hreflang.js | description": { - "message": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/hreflang).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"hreflang\" is an HTML attribute and should not be translated." + "message": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"hreflang\" is an HTML attribute and should not be translated.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/hreflang)" + } + } }, "lighthouse-core/audits/seo/hreflang.js | failureTitle": { - "message": "Document doesn't have a valid `hreflang`", - "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is not valid and needs to be fixed. \"hreflang\" is an HTML attribute and should not be translated." + "message": "Document doesn't have a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is not valid and needs to be fixed. \"hreflang\" is an HTML attribute and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/hreflang.js | title": { - "message": "Document has a valid `hreflang`", - "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is configured correctly. \"hreflang\" is an HTML attribute and should not be translated." + "message": "Document has a valid $MARKDOWN_SNIPPET_0$", + "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is configured correctly. \"hreflang\" is an HTML attribute and should not be translated.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/http-status-code.js | description": { - "message": "Pages with unsuccessful HTTP status codes may not be indexed properly. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to serve pages with a valid HTTP status code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Pages with unsuccessful HTTP status codes may not be indexed properly. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to serve pages with a valid HTTP status code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)" + } + } }, "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { "message": "Page has unsuccessful HTTP status code", @@ -1225,8 +2640,16 @@ "description": "Title of a Lighthouse audit that provides detail on the HTTP status code a page responds with. This descriptive title is shown when the page has responded with a valid HTTP status code." }, "lighthouse-core/audits/seo/is-crawlable.js | description": { - "message": "Search engines are unable to include your pages in search results if they don't have permission to crawl them. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/indexing).", - "description": "Description of a Lighthouse audit that tells the user *why* allowing search-engine crawling of their page is beneficial. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Search engines are unable to include your pages in search results if they don't have permission to crawl them. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* allowing search-engine crawling of their page is beneficial. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/indexing)" + } + } }, "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { "message": "Page is blocked from indexing", @@ -1237,8 +2660,16 @@ "description": "Title of a Lighthouse audit that provides detail on if search-engine crawlers are blocked from indexing the page. This title is shown when the page is not blocked from indexing and can be crawled." }, "lighthouse-core/audits/seo/link-text.js | description": { - "message": "Descriptive link text helps search engines understand your content. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have descriptive text on the links in their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Descriptive link text helps search engines understand your content. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to have descriptive text on the links in their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)" + } + } }, "lighthouse-core/audits/seo/link-text.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 link found}\n other {# links found}\n }", @@ -1253,16 +2684,44 @@ "description": "Title of a Lighthouse audit that tests if each link on a page contains a sufficient description of what a user will find when they click it. Generic, non-descriptive text like \"click here\" doesn't give an indication of what the link leads to. This descriptive title is shown when all links on the page have sufficient textual descriptions." }, "lighthouse-core/audits/seo/manual/structured-data.js | description": { - "message": "Run the [Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool/) and the [Structured Data Linter](http://linter.structured-data.org/) to validate structured data. [Learn more](https://developers.google.com/search/docs/guides/mark-up-content).", - "description": "Description of a Lighthouse audit that provides detail on the structured data in a page. \"Structured data\" is a standardized data format on a page that helps a search engine categorize and understand its contents. This description is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Run the $LINK_START_0$Structured Data Testing Tool$LINK_END_0$ and the $LINK_START_1$Structured Data Linter$LINK_END_1$ to validate structured data. $LINK_START_2$Learn more$LINK_END_2$.", + "description": "Description of a Lighthouse audit that provides detail on the structured data in a page. \"Structured data\" is a standardized data format on a page that helps a search engine categorize and understand its contents. This description is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://search.google.com/structured-data/testing-tool/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](http://linter.structured-data.org/)" + }, + "LINK_START_2": { + "content": "[" + }, + "LINK_END_2": { + "content": "](https://developers.google.com/search/docs/guides/mark-up-content)" + } + } }, "lighthouse-core/audits/seo/manual/structured-data.js | title": { "message": "Structured data is valid", "description": "Title of a Lighthouse audit that prompts users to manually check their page for valid structured data. \"Structured data\" is a standardized data format on a page that helps a search engine categorize and understand its contents." }, "lighthouse-core/audits/seo/meta-description.js | description": { - "message": "Meta descriptions may be included in search results to concisely summarize page content. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/description).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have meta descriptions on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Meta descriptions may be included in search results to concisely summarize page content. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to have meta descriptions on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/description)" + } + } }, "lighthouse-core/audits/seo/meta-description.js | explanation": { "message": "Description text is empty.", @@ -1277,8 +2736,16 @@ "description": "Title of a Lighthouse audit that provides detail on the web page's document meta description. This descriptive title is shown when the document has a meta description. \"meta\" should be left untranslated because it refers to an HTML element." }, "lighthouse-core/audits/seo/plugins.js | description": { - "message": "Search engines can't index plugin content, and many devices restrict plugins or don't support them. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/plugins).", - "description": "Description of a Lighthouse audit that tells the user *why* they need to avoid using browser plugins in their content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Search engines can't index plugin content, and many devices restrict plugins or don't support them. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they need to avoid using browser plugins in their content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/plugins)" + } + } }, "lighthouse-core/audits/seo/plugins.js | failureTitle": { "message": "Document uses plugins", @@ -1313,12 +2780,26 @@ "description": "Title of a Lighthouse audit that provides detail on the site's robots.txt file. Note: \"robots.txt\" is a canonical filename and should not be translated. This descriptive title is shown when the robots.txt file is present and configured correctly." }, "lighthouse-core/audits/seo/tap-targets.js | description": { - "message": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. [Learn more](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design).", - "description": "Description of a Lighthouse audit that tells the user why buttons and links need to be big enough and what 'big enough' means. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user why buttons and links need to be big enough and what 'big enough' means. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)" + } + } }, "lighthouse-core/audits/seo/tap-targets.js | displayValue": { - "message": "{decimalProportion, number, percent} appropriately sized tap targets", - "description": "Explanatory message stating that a certain percentage of the tap targets (like buttons and links) on the page are of an appropriately large size." + "message": "$COMPLEX_ICU_0$ appropriately sized tap targets", + "description": "Explanatory message stating that a certain percentage of the tap targets (like buttons and links) on the page are of an appropriately large size.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, percent}", + "example": "54.6%" + } + } }, "lighthouse-core/audits/seo/tap-targets.js | explanationViewportMetaNotOptimized": { "message": "Tap targets are too small because there's no viewport meta tag optimized for mobile screens", @@ -1353,8 +2834,16 @@ "description": "Label for a table column that displays the name of a third-party provider that potentially links to their website." }, "lighthouse-core/audits/third-party-summary.js | description": { - "message": "Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/).", - "description": "Description of a Lighthouse audit that identifies the code on the page that the user doesn't control. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that identifies the code on the page that the user doesn't control. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)" + } + } }, "lighthouse-core/audits/third-party-summary.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 Third-Party Found}\n other {# Third-Parties Found}\n }", @@ -1365,12 +2854,26 @@ "description": "Title of a Lighthouse audit that identifies the code on the page that the user doesn't control. This is shown in a list of audits that Lighthouse generates." }, "lighthouse-core/audits/time-to-first-byte.js | description": { - "message": "Time To First Byte identifies the time at which your server sends a response. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/ttfb).", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the amount of time it takes their server to start responding to requests. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Time To First Byte identifies the time at which your server sends a response. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the amount of time it takes their server to start responding to requests. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/ttfb)" + } + } }, "lighthouse-core/audits/time-to-first-byte.js | displayValue": { - "message": "Root document took {timeInMs, number, milliseconds} ms", - "description": "Used to summarize the total Time to First Byte duration for the primary HTML response. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 210 ms)" + "message": "Root document took $COMPLEX_ICU_0$ ms", + "description": "Used to summarize the total Time to First Byte duration for the primary HTML response. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 210 ms)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/audits/time-to-first-byte.js | failureTitle": { "message": "Reduce server response times (TTFB)", @@ -1397,8 +2900,16 @@ "description": "Label for the Type column in the User Timing event data table. User Timing API entries are added by the developer of the web page. The only possible types are 'Mark' and Measure'." }, "lighthouse-core/audits/user-timings.js | description": { - "message": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing).", - "description": "Description of a Lighthouse audit that tells the user they may want to use the User Timing API to help measure the performance of aspects of their page load and interaction. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user they may want to use the User Timing API to help measure the performance of aspects of their page load and interaction. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/user-timing)" + } + } }, "lighthouse-core/audits/user-timings.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 user timing}\n other {# user timings}\n }", @@ -1409,24 +2920,52 @@ "description": "Descriptive title of a diagnostic audit that provides details on any timestamps generated by the page. User Timing refers to the 'User Timing API', which enables a website to record specific times as 'marks', or spans of time as 'measures'." }, "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": "A preconnect <link> was found for \"{securityOrigin}\" but was not used by the browser. Check that you are using the `crossorigin` attribute properly.", - "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links." + "message": "A preconnect <link> was found for \"{securityOrigin}\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", + "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`crossorigin`", + "example": "crossorigin" + } + } }, "lighthouse-core/audits/uses-rel-preconnect.js | description": { - "message": "Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).", - "description": "Description of a Lighthouse audit that tells the user how to connect early to third-party domains that will be used to load page resources. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user how to connect early to third-party domains that will be used to load page resources. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)" + } + } }, "lighthouse-core/audits/uses-rel-preconnect.js | title": { "message": "Preconnect to required origins", "description": "Imperative title of a Lighthouse audit that tells the user to connect early to internet domains that will be used to load page resources. Origin is the correct term, however 'domain name' could be used if neccsesary. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": "A preload <link> was found for \"{preloadURL}\" but was not used by the browser. Check that you are using the `crossorigin` attribute properly.", - "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links." + "message": "A preload <link> was found for \"{preloadURL}\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", + "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`crossorigin`", + "example": "crossorigin" + } + } }, "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).", - "description": "Description of a Lighthouse audit that tells the user *why* they should preload important network requests. The associated network requests are started halfway through pageload (or later) but should be started at the beginning. This is displayed after a user expands the section to see more. No character length limits. '<link rel=preload>' is the html code the user would include in their page and shouldn't be translated. 'Learn More' becomes link text to additional documentation." + "message": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of a Lighthouse audit that tells the user *why* they should preload important network requests. The associated network requests are started halfway through pageload (or later) but should be started at the beginning. This is displayed after a user expands the section to see more. No character length limits. '<link rel=preload>' is the html code the user would include in their page and shouldn't be translated. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/preload)" + } + } }, "lighthouse-core/audits/uses-rel-preload.js | title": { "message": "Preload key requests", @@ -1457,12 +2996,28 @@ "description": "Title of the best practices section of the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices." }, "lighthouse-core/config/default-config.js | a11yCategoryDescription": { - "message": "These checks highlight opportunities to [improve the accessibility of your web app](https://developers.google.com/web/fundamentals/accessibility). Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.", - "description": "Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' becomes link text to additional documentation." + "message": "These checks highlight opportunities to $LINK_START_0$improve the accessibility of your web app$LINK_END_0$. Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.", + "description": "Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility)" + } + } }, "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { - "message": "These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://developers.google.com/web/fundamentals/accessibility/how-to-review).", - "description": "Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation." + "message": "These items address areas which an automated testing tool cannot cover. Learn more in our guide on $LINK_START_0$conducting an accessibility review$LINK_END_0$.", + "description": "Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility/how-to-review)" + } + } }, "lighthouse-core/config/default-config.js | a11yCategoryTitle": { "message": "Accessibility", @@ -1573,8 +3128,16 @@ "description": "Title of the \"PWA Optimized\" section of the web app category. Within this section are audits that check if the developer has taken advantage of features to make their web page more enjoyable and engaging for the user." }, "lighthouse-core/config/default-config.js | seoCategoryDescription": { - "message": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. [Learn more](https://support.google.com/webmasters/answer/35769).", - "description": "Description of the Search Engine Optimization (SEO) category. This is displayed at the top of a list of audits focused on optimizing a website for indexing by search engines. No character length limits. 'Learn More' becomes link text to additional documentation." + "message": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the Search Engine Optimization (SEO) category. This is displayed at the top of a list of audits focused on optimizing a website for indexing by search engines. No character length limits. 'Learn More' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://support.google.com/webmasters/answer/35769)" + } + } }, "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { "message": "Run these additional validators on your site to check additional SEO best practices.", @@ -1601,8 +3164,16 @@ "description": "Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website accessible to search engine crawlers." }, "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { - "message": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn more](https://developers.google.com/search/mobile-sites/).", - "description": "Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices." + "message": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. $LINK_START_0$Learn more$LINK_END_0$.", + "description": "Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/search/mobile-sites/)" + } + } }, "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { "message": "Mobile Friendly", @@ -1649,12 +3220,24 @@ "description": "Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions." }, "lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings": { - "message": "Potential savings of {wastedBytes, number, bytes} KB", - "description": "Label shown per-audit to show how many bytes smaller the page could be if the user implemented the suggestions. The `{wastedBytes}` placeholder will be replaced with the number of bytes, shown in kilobytes (e.g. 148 KB)" + "message": "Potential savings of $COMPLEX_ICU_0$ KB", + "description": "Label shown per-audit to show how many bytes smaller the page could be if the user implemented the suggestions. The `{wastedBytes}` placeholder will be replaced with the number of bytes, shown in kilobytes (e.g. 148 KB)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{wastedBytes, number, bytes}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings": { - "message": "Potential savings of {wastedMs, number, milliseconds} ms", - "description": "Label shown per-audit to show how many milliseconds faster the page load could be if the user implemented the suggestions. The `{wastedMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 140 ms)" + "message": "Potential savings of $COMPLEX_ICU_0$ ms", + "description": "Label shown per-audit to show how many milliseconds faster the page load could be if the user implemented the suggestions. The `{wastedMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 140 ms)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{wastedMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { "message": "Document", @@ -1673,8 +3256,14 @@ "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page. 'Media' refers to audio and video files." }, "lighthouse-core/lib/i18n/i18n.js | ms": { - "message": "{timeInMs, number, milliseconds} ms", - "description": "Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms)" + "message": "$COMPLEX_ICU_0$ ms", + "description": "Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { "message": "Other", @@ -1685,8 +3274,14 @@ "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. 'Script' refers to JavaScript or other files that are executable by a browser." }, "lighthouse-core/lib/i18n/i18n.js | seconds": { - "message": "{timeInMs, number, seconds} s", - "description": "Used to show the duration in seconds that something lasted. The {timeInMs} placeholder will be replaced with the time duration, shown in seconds (e.g. 5.2 s)" + "message": "$COMPLEX_ICU_0$ s", + "description": "Used to show the duration in seconds that something lasted. The {timeInMs} placeholder will be replaced with the time duration, shown in seconds (e.g. 5.2 s)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { "message": "Stylesheet", @@ -1793,8 +3388,16 @@ "description": "Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. \"Lab\" is an abbreviated form of \"laboratory\", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site." }, "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { - "message": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", - "description": "Explanation shown to users below performance results to inform them that the test was done with a 4G network connection and to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. 'Lighthouse' becomes link text to additional documentation." + "message": "$LINK_START_0$Lighthouse$LINK_END_0$ analysis of the current page on an emulated mobile network. Values are estimated and may vary.", + "description": "Explanation shown to users below performance results to inform them that the test was done with a 4G network connection and to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. 'Lighthouse' becomes link text to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/)" + } + } }, "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { "message": "Additional items to manually check", @@ -1849,12 +3452,40 @@ "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." }, "stack-packs/packs/wordpress.js | offscreen_images": { - "message": "Install a [lazy-load WordPress plugin](https://wordpress.org/plugins/search/lazy+load/) that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using [the AMP plugin](https://wordpress.org/plugins/amp/).", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Install a $LINK_START_0$lazy-load WordPress plugin$LINK_END_0$ that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using $LINK_START_1$the AMP plugin$LINK_END_1$.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/lazy+load/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://wordpress.org/plugins/amp/)" + } + } }, "stack-packs/packs/wordpress.js | render_blocking_resources": { - "message": "There are a number of WordPress plugins that can help you [inline critical assets](https://wordpress.org/plugins/search/critical+css/) or [defer less important resources](https://wordpress.org/plugins/search/defer+css+javascript/). Beware that optimizations provided by these plugins may break features of your theme or plugins, so you will likely need to make code changes.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "There are a number of WordPress plugins that can help you $LINK_START_0$inline critical assets$LINK_END_0$ or $LINK_START_1$defer less important resources$LINK_END_1$. Beware that optimizations provided by these plugins may break features of your theme or plugins, so you will likely need to make code changes.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/critical+css/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://wordpress.org/plugins/search/defer+css+javascript/)" + } + } }, "stack-packs/packs/wordpress.js | time_to_first_byte": { "message": "Themes, plugins, and server specifications all contribute to server response time. Consider finding a more optimized theme, carefully selecting an optimization plugin, and/or upgrading your server.", @@ -1865,39 +3496,125 @@ "description": "Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." }, "stack-packs/packs/wordpress.js | unminified_css": { - "message": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+css/) can speed up your site by concatenating, minifying, and compressing your styles. You may also want to use a build process to do this minification up-front if possible.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "A number of $LINK_START_0$WordPress plugins$LINK_END_0$ can speed up your site by concatenating, minifying, and compressing your styles. You may also want to use a build process to do this minification up-front if possible.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/minify+css/)" + } + } }, "stack-packs/packs/wordpress.js | unminified_javascript": { - "message": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+javascript/) can speed up your site by concatenating, minifying, and compressing your scripts. You may also want to use a build process to do this minification up front if possible.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "A number of $LINK_START_0$WordPress plugins$LINK_END_0$ can speed up your site by concatenating, minifying, and compressing your scripts. You may also want to use a build process to do this minification up front if possible.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/minify+javascript/)" + } + } }, "stack-packs/packs/wordpress.js | unused_css_rules": { - "message": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused CSS in your page. To identify plugins that are adding extraneous CSS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Consider reducing, or switching, the number of $LINK_START_0$WordPress plugins$LINK_END_0$ loading unused CSS in your page. To identify plugins that are adding extraneous CSS, try running $LINK_START_1$code coverage$LINK_END_1$ in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage)" + } + } }, "stack-packs/packs/wordpress.js | unused_javascript": { - "message": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the script. Look out for plugins that have many scripts in the list which have a lot of red in code coverage. A plugin should only enqueue a script if it is actually used on the page.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Consider reducing, or switching, the number of $LINK_START_0$WordPress plugins$LINK_END_0$ loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running $LINK_START_1$code coverage$LINK_END_1$ in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the script. Look out for plugins that have many scripts in the list which have a lot of red in code coverage. A plugin should only enqueue a script if it is actually used on the page.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage)" + } + } }, "stack-packs/packs/wordpress.js | uses_long_cache_ttl": { - "message": "Read about [Browser Caching in WordPress](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching).", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Read about $LINK_START_0$Browser Caching in WordPress$LINK_END_0$.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching)" + } + } }, "stack-packs/packs/wordpress.js | uses_optimized_images": { - "message": "Consider using an [image optimization WordPress plugin](https://wordpress.org/plugins/search/optimize+images/) that compresses your images while retaining quality.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Consider using an $LINK_START_0$image optimization WordPress plugin$LINK_END_0$ that compresses your images while retaining quality.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/optimize+images/)" + } + } }, "stack-packs/packs/wordpress.js | uses_responsive_images": { - "message": "Upload images directly through the [media library](https://codex.wordpress.org/Media_Library_Screen) to ensure that the required image sizes are available, and then insert them from the media library or use the image widget to ensure the optimal image sizes are used (including those for the responsive breakpoints). Avoid using `Full Size` images unless the dimensions are adequate for their usage. [Learn More](https://codex.wordpress.org/Inserting_Images_into_Posts_and_Pages#Image_Size).", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Upload images directly through the $LINK_START_0$media library$LINK_END_0$ to ensure that the required image sizes are available, and then insert them from the media library or use the image widget to ensure the optimal image sizes are used (including those for the responsive breakpoints). Avoid using $MARKDOWN_SNIPPET_0$ images unless the dimensions are adequate for their usage. $LINK_START_1$Learn More$LINK_END_1$.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`Full Size`", + "example": "Full Size" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://codex.wordpress.org/Media_Library_Screen)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://codex.wordpress.org/Inserting_Images_into_Posts_and_Pages#Image_Size)" + } + } }, "stack-packs/packs/wordpress.js | uses_text_compression": { "message": "You can enable text compression in your web server configuration.", "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance via enabling text compression in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." }, "stack-packs/packs/wordpress.js | uses_webp_images": { - "message": "Consider using a [plugin](https://wordpress.org/plugins/search/convert+webp/) or service that will automatically convert your uploaded images to the optimal formats.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." + "message": "Consider using a $LINK_START_0$plugin$LINK_END_0$ or service that will automatically convert your uploaded images to the optimal formats.", + "description": "Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://wordpress.org/plugins/search/convert+webp/)" + } + } } } diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index 2bc4bdd4a1c5..a079112d396e 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -1,90 +1,322 @@ { "lighthouse-core/audits/accessibility/accesskeys.js | description": { - "message": "Âćĉéŝś k̂éŷś l̂ét̂ úŝér̂ś q̂úîćk̂ĺŷ f́ôćûś â ṕâŕt̂ óf̂ t́ĥé p̂áĝé. F̂ór̂ ṕr̂óp̂ér̂ ńâv́îǵât́îón̂, éâćĥ áĉćêśŝ ḱêý m̂úŝt́ b̂é ûńîq́ûé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âćĉéŝśk̂éŷś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âćĉéŝś k̂éŷś l̂ét̂ úŝér̂ś q̂úîćk̂ĺŷ f́ôćûś â ṕâŕt̂ óf̂ t́ĥé p̂áĝé. F̂ór̂ ṕr̂óp̂ér̂ ńâv́îǵât́îón̂, éâćĥ áĉćêśŝ ḱêý m̂úŝt́ b̂é ûńîq́ûé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { - "message": "`[âćĉéŝśk̂éŷ]` v́âĺûéŝ ár̂é n̂ót̂ ún̂íq̂úê" + "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ńôt́ ûńîq́ûé", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[accesskey]`", + "example": "[accesskey]" + } + } }, "lighthouse-core/audits/accessibility/accesskeys.js | title": { - "message": "`[âćĉéŝśk̂éŷ]` v́âĺûéŝ ár̂é ûńîq́ûé" + "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ún̂íq̂úê", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[accesskey]`", + "example": "[accesskey]" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { - "message": "Êáĉh́ ÂŔÎÁ `r̂ól̂é` ŝúp̂ṕôŕt̂ś â śp̂éĉíf̂íĉ śûb́ŝét̂ óf̂ `ár̂íâ-*` át̂t́r̂íb̂út̂éŝ. Ḿîśm̂át̂ćĥín̂ǵ t̂h́êśê ín̂v́âĺîd́ât́êś t̂h́ê `ár̂íâ-*` át̂t́r̂íb̂út̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-ál̂ĺôẃêd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Êáĉh́ ÂŔÎÁ $MARKDOWN_SNIPPET_0$ ŝúp̂ṕôŕt̂ś â śp̂éĉíf̂íĉ śûb́ŝét̂ óf̂ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂éŝ. Ḿîśm̂át̂ćĥín̂ǵ t̂h́êśê ín̂v́âĺîd́ât́êś t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`role`", + "example": "role" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`aria-*`", + "example": "aria-*" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`aria-*`", + "example": "aria-*" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ ḿât́ĉh́ t̂h́êír̂ ŕôĺêś" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ ḿât́ĉh́ t̂h́êír̂ ŕôĺêś", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś m̂át̂ćĥ t́ĥéîŕ r̂ól̂éŝ" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś m̂át̂ćĥ t́ĥéîŕ r̂ól̂éŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ r̂ól̂éŝ h́âv́ê ŕêq́ûír̂éd̂ át̂t́r̂íb̂út̂éŝ t́ĥát̂ d́êśĉŕîb́ê t́ĥé ŝt́ât́ê óf̂ t́ĥé êĺêḿêńt̂ t́ô śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ r̂ól̂éŝ h́âv́ê ŕêq́ûír̂éd̂ át̂t́r̂íb̂út̂éŝ t́ĥát̂ d́êśĉŕîb́ê t́ĥé ŝt́ât́ê óf̂ t́ĥé êĺêḿêńt̂ t́ô śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { - "message": "`[r̂ól̂é]`ŝ d́ô ńôt́ ĥáv̂é âĺl̂ ŕêq́ûír̂éd̂ `[ár̂íâ-*]` át̂t́r̂íb̂út̂éŝ" + "message": "$MARKDOWN_SNIPPET_0$ŝ d́ô ńôt́ ĥáv̂é âĺl̂ ŕêq́ûír̂éd̂ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂éŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { - "message": "`[r̂ól̂é]`ŝ h́âv́ê ál̂ĺ r̂éq̂úîŕêd́ `[âŕîá-*]` ât́t̂ŕîb́ût́êś" + "message": "$MARKDOWN_SNIPPET_0$ŝ h́âv́ê ál̂ĺ r̂éq̂úîŕêd́ $MARKDOWN_SNIPPET_1$ ât́t̂ŕîb́ût́êś", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ p̂ár̂én̂t́ r̂ól̂éŝ ḿûśt̂ ćôńt̂áîń ŝṕêćîf́îć ĉh́îĺd̂ ŕôĺêś t̂ó p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-ĉh́îĺd̂ŕêń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ p̂ár̂én̂t́ r̂ól̂éŝ ḿûśt̂ ćôńt̂áîń ŝṕêćîf́îć ĉh́îĺd̂ ŕôĺêś t̂ó p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ `[r̂ól̂é]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[ŕôĺê]`ś, âŕê ḿîśŝín̂ǵ." + "message": "Êĺêḿêńt̂ś ŵít̂h́ $MARKDOWN_SNIPPET_0$ t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ $MARKDOWN_SNIPPET_1$ś, âŕê ḿîśŝín̂ǵ.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-children.js | title": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ `[r̂ól̂é]` t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ `[ŕôĺê]`ś, âŕê ṕr̂éŝén̂t́" + "message": "Êĺêḿêńt̂ś ŵít̂h́ $MARKDOWN_SNIPPET_0$ t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ $MARKDOWN_SNIPPET_1$ś, âŕê ṕr̂éŝén̂t́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ ĉh́îĺd̂ ŕôĺêś m̂úŝt́ b̂é ĉón̂t́âín̂éd̂ b́ŷ śp̂éĉíf̂íĉ ṕâŕêńt̂ ŕôĺêś t̂ó p̂ŕôṕêŕl̂ý p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-r̂éq̂úîŕêd́-p̂ár̂én̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝóm̂é ÂŔÎÁ ĉh́îĺd̂ ŕôĺêś m̂úŝt́ b̂é ĉón̂t́âín̂éd̂ b́ŷ śp̂éĉíf̂íĉ ṕâŕêńt̂ ŕôĺêś t̂ó p̂ŕôṕêŕl̂ý p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { - "message": "`[r̂ól̂é]`ŝ ár̂é n̂ót̂ ćôńt̂áîńêd́ b̂ý t̂h́êír̂ ŕêq́ûír̂éd̂ ṕâŕêńt̂ él̂ém̂én̂t́" + "message": "$MARKDOWN_SNIPPET_0$ŝ ár̂é n̂ót̂ ćôńt̂áîńêd́ b̂ý t̂h́êír̂ ŕêq́ûír̂éd̂ ṕâŕêńt̂ él̂ém̂én̂t́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { - "message": "`[r̂ól̂é]`ŝ ár̂é ĉón̂t́âín̂éd̂ b́ŷ t́ĥéîŕ r̂éq̂úîŕêd́ p̂ár̂én̂t́ êĺêḿêńt̂" + "message": "$MARKDOWN_SNIPPET_0$ŝ ár̂é ĉón̂t́âín̂éd̂ b́ŷ t́ĥéîŕ r̂éq̂úîŕêd́ p̂ár̂én̂t́ êĺêḿêńt̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | description": { - "message": "ÂŔÎÁ r̂ól̂éŝ ḿûśt̂ h́âv́ê v́âĺîd́ v̂ál̂úêś îń ôŕd̂ér̂ t́ô ṕêŕf̂ór̂ḿ t̂h́êír̂ ín̂t́êńd̂éd̂ áĉćêśŝíb̂íl̂ít̂ý f̂ún̂ćt̂íôńŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-ŕôĺêś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "ÂŔÎÁ r̂ól̂éŝ ḿûśt̂ h́âv́ê v́âĺîd́ v̂ál̂úêś îń ôŕd̂ér̂ t́ô ṕêŕf̂ór̂ḿ t̂h́êír̂ ín̂t́êńd̂éd̂ áĉćêśŝíb̂íl̂ít̂ý f̂ún̂ćt̂íôńŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { - "message": "`[r̂ól̂é]` v̂ál̂úêś âŕê ńôt́ v̂ál̂íd̂" + "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ńôt́ v̂ál̂íd̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-roles.js | title": { - "message": "`[r̂ól̂é]` v̂ál̂úêś âŕê v́âĺîd́" + "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê v́âĺîd́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[role]`", + "example": "[role]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ v̂ál̂úêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âŕîá-v̂ál̂íd̂-át̂t́r̂-v́âĺûé?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ v̂ál̂úêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê v́âĺîd́ v̂ál̂úêś" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê v́âĺîd́ v̂ál̂úêś", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś ĥáv̂é v̂ál̂íd̂ v́âĺûéŝ" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ĥáv̂é v̂ál̂íd̂ v́âĺûéŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ n̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ár̂íâ-v́âĺîd́-ât́t̂ŕ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ n̂ám̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś âŕê ńôt́ v̂ál̂íd̂ ór̂ ḿîśŝṕêĺl̂éd̂" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś âŕê ńôt́ v̂ál̂íd̂ ór̂ ḿîśŝṕêĺl̂éd̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { - "message": "`[âŕîá-*]` ât́t̂ŕîb́ût́êś âŕê v́âĺîd́ âńd̂ ńôt́ m̂íŝśp̂él̂ĺêd́" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś âŕê v́âĺîd́ âńd̂ ńôt́ m̂íŝśp̂él̂ĺêd́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[aria-*]`", + "example": "[aria-*]" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | description": { - "message": "Ĉáp̂t́îón̂ś m̂ák̂é âúd̂íô él̂ém̂én̂t́ŝ úŝáb̂ĺê f́ôŕ d̂éâf́ ôŕ ĥéâŕîńĝ-ím̂ṕâír̂éd̂ úŝér̂ś, p̂ŕôv́îd́îńĝ ćr̂ít̂íĉál̂ ín̂f́ôŕm̂át̂íôń ŝúĉh́ âś ŵh́ô íŝ t́âĺk̂ín̂ǵ, ŵh́ât́ t̂h́êý'r̂é ŝáŷín̂ǵ, âńd̂ ót̂h́êŕ n̂ón̂-śp̂éêćĥ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/âúd̂íô-ćâṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ĉáp̂t́îón̂ś m̂ák̂é âúd̂íô él̂ém̂én̂t́ŝ úŝáb̂ĺê f́ôŕ d̂éâf́ ôŕ ĥéâŕîńĝ-ím̂ṕâír̂éd̂ úŝér̂ś, p̂ŕôv́îd́îńĝ ćr̂ít̂íĉál̂ ín̂f́ôŕm̂át̂íôń ŝúĉh́ âś ŵh́ô íŝ t́âĺk̂ín̂ǵ, ŵh́ât́ t̂h́êý'r̂é ŝáŷín̂ǵ, âńd̂ ót̂h́êŕ n̂ón̂-śp̂éêćĥ ín̂f́ôŕm̂át̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { - "message": "`<âúd̂íô>` él̂ém̂én̂t́ŝ ár̂é m̂íŝśîńĝ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"ĉáp̂t́îón̂ś\"]`." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âŕê ḿîśŝín̂ǵ â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<audio>`", + "example": "<audio>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/audio-caption.js | title": { - "message": "`<âúd̂íô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"ćâṕt̂íôńŝ\"]`" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<audio>`", + "example": "<audio>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/accessibility/button-name.js | description": { - "message": "Ŵh́êń â b́ût́t̂ón̂ d́ôéŝń't̂ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê, śĉŕêén̂ ŕêád̂ér̂ś âńn̂óûńĉé ît́ âś \"b̂út̂t́ôń\", m̂ák̂ín̂ǵ ît́ ûńûśâb́l̂é f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/b̂út̂t́ôń-n̂ám̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŵh́êń â b́ût́t̂ón̂ d́ôéŝń't̂ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê, śĉŕêén̂ ŕêád̂ér̂ś âńn̂óûńĉé ît́ âś \"b̂út̂t́ôń\", m̂ák̂ín̂ǵ ît́ ûńûśâb́l̂é f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { "message": "B̂út̂t́ôńŝ d́ô ńôt́ ĥáv̂é âń âćĉéŝśîb́l̂é n̂ám̂é" @@ -93,7 +325,15 @@ "message": "B̂út̂t́ôńŝ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê" }, "lighthouse-core/audits/accessibility/bypass.js | description": { - "message": "Âd́d̂ín̂ǵ ŵáŷś t̂ó b̂ýp̂áŝś r̂ép̂ét̂ít̂ív̂é ĉón̂t́êńt̂ ĺêt́ŝ ḱêýb̂óâŕd̂ úŝér̂ś n̂áv̂íĝát̂é t̂h́ê ṕâǵê ḿôŕê éf̂f́îćîén̂t́l̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/b̂ýp̂áŝś?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âd́d̂ín̂ǵ ŵáŷś t̂ó b̂ýp̂áŝś r̂ép̂ét̂ít̂ív̂é ĉón̂t́êńt̂ ĺêt́ŝ ḱêýb̂óâŕd̂ úŝér̂ś n̂áv̂íĝát̂é t̂h́ê ṕâǵê ḿôŕê éf̂f́îćîén̂t́l̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { "message": "T̂h́ê ṕâǵê d́ôéŝ ńôt́ ĉón̂t́âín̂ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" @@ -102,7 +342,15 @@ "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" }, "lighthouse-core/audits/accessibility/color-contrast.js | description": { - "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/ĉól̂ór̂-ćôńt̂ŕâśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ d́ô ńôt́ ĥáv̂é â śûf́f̂íĉíêńt̂ ćôńt̂ŕâśt̂ ŕât́îó." @@ -111,88 +359,356 @@ "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ h́âv́ê á ŝúf̂f́îćîén̂t́ ĉón̂t́r̂áŝt́ r̂át̂íô" }, "lighthouse-core/audits/accessibility/definition-list.js | description": { - "message": "Ŵh́êń d̂éf̂ín̂ít̂íôń l̂íŝt́ŝ ár̂é n̂ót̂ ṕr̂óp̂ér̂ĺŷ ḿâŕk̂éd̂ úp̂, śĉŕêén̂ ŕêád̂ér̂ś m̂áŷ ṕr̂ód̂úĉé ĉón̂f́ûśîńĝ ór̂ ín̂áĉćûŕât́ê óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/d́êf́îńît́îón̂-ĺîśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŵh́êń d̂éf̂ín̂ít̂íôń l̂íŝt́ŝ ár̂é n̂ót̂ ṕr̂óp̂ér̂ĺŷ ḿâŕk̂éd̂ úp̂, śĉŕêén̂ ŕêád̂ér̂ś m̂áŷ ṕr̂ód̂úĉé ĉón̂f́ûśîńĝ ór̂ ín̂áĉćûŕât́ê óût́p̂út̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { - "message": "`<d̂ĺ>`'ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ ṕr̂óp̂ér̂ĺŷ-ór̂d́êŕêd́ `<d̂t́>` âńd̂ `<d́d̂>` ǵr̂óûṕŝ, `<śĉŕîṕt̂>` ór̂ `<t́êḿp̂ĺât́ê>` él̂ém̂én̂t́ŝ." + "message": "$MARKDOWN_SNIPPET_0$'ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ ṕr̂óp̂ér̂ĺŷ-ór̂d́êŕêd́ $MARKDOWN_SNIPPET_1$ âńd̂ $MARKDOWN_SNIPPET_2$ ǵr̂óûṕŝ, $MARKDOWN_SNIPPET_3$ ór̂ $MARKDOWN_SNIPPET_4$ él̂ém̂én̂t́ŝ.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_4": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/definition-list.js | title": { - "message": "`<d̂ĺ>`'ŝ ćôńt̂áîń ôńl̂ý p̂ŕôṕêŕl̂ý-ôŕd̂ér̂éd̂ `<d́t̂>` án̂d́ `<d̂d́>` ĝŕôúp̂ś, `<ŝćr̂íp̂t́>` ôŕ `<t̂ém̂ṕl̂át̂é>` êĺêḿêńt̂ś." + "message": "$MARKDOWN_SNIPPET_0$'ŝ ćôńt̂áîń ôńl̂ý p̂ŕôṕêŕl̂ý-ôŕd̂ér̂éd̂ $MARKDOWN_SNIPPET_1$ án̂d́ $MARKDOWN_SNIPPET_2$ ĝŕôúp̂ś, $MARKDOWN_SNIPPET_3$ ôŕ $MARKDOWN_SNIPPET_4$ êĺêḿêńt̂ś.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_4": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | description": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ (`<d́t̂>` án̂d́ `<d̂d́>`) m̂úŝt́ b̂é ŵŕâṕp̂éd̂ ín̂ á p̂ár̂én̂t́ `<d̂ĺ>` êĺêḿêńt̂ t́ô én̂śûŕê t́ĥát̂ śĉŕêén̂ ŕêád̂ér̂ś ĉán̂ ṕr̂óp̂ér̂ĺŷ án̂ńôún̂ćê t́ĥém̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/d́l̂ít̂ém̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$ án̂d́ $MARKDOWN_SNIPPET_1$) m̂úŝt́ b̂é ŵŕâṕp̂éd̂ ín̂ á p̂ár̂én̂t́ $MARKDOWN_SNIPPET_2$ êĺêḿêńt̂ t́ô én̂śûŕê t́ĥát̂ śĉŕêén̂ ŕêád̂ér̂ś ĉán̂ ṕr̂óp̂ér̂ĺŷ án̂ńôún̂ćê t́ĥém̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dt>`", + "example": "<dt>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<dd>`", + "example": "<dd>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<dl>`", + "example": "<dl>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é n̂ót̂ ẃr̂áp̂ṕêd́ îń `<d̂ĺ>` êĺêḿêńt̂ś" + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é n̂ót̂ ẃr̂áp̂ṕêd́ îń $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + } + } }, "lighthouse-core/audits/accessibility/dlitem.js | title": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é ŵŕâṕp̂éd̂ ín̂ `<d́l̂>` él̂ém̂én̂t́ŝ" + "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é ŵŕâṕp̂éd̂ ín̂ $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<dl>`", + "example": "<dl>" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | description": { - "message": "T̂h́ê t́ît́l̂é ĝív̂éŝ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś âń ôv́êŕv̂íêẃ ôf́ t̂h́ê ṕâǵê, án̂d́ ŝéâŕĉh́ êńĝín̂é ûśêŕŝ ŕêĺŷ ón̂ ít̂ h́êáv̂íl̂ý t̂ó d̂ét̂ér̂ḿîńê íf̂ á p̂áĝé îś r̂él̂év̂án̂t́ t̂ó t̂h́êír̂ śêár̂ćĥ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂ít̂ĺê)." + "message": "T̂h́ê t́ît́l̂é ĝív̂éŝ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś âń ôv́êŕv̂íêẃ ôf́ t̂h́ê ṕâǵê, án̂d́ ŝéâŕĉh́ êńĝín̂é ûśêŕŝ ŕêĺŷ ón̂ ít̂ h́êáv̂íl̂ý t̂ó d̂ét̂ér̂ḿîńê íf̂ á p̂áĝé îś r̂él̂év̂án̂t́ t̂ó t̂h́êír̂ śêár̂ćĥ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/title)" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â `<t́ît́l̂é>` êĺêḿêńt̂" + "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<title>`", + "example": "<title>" + } + } }, "lighthouse-core/audits/accessibility/document-title.js | title": { "message": "p̂ĺâćêh́ôĺd̂ér̂" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { - "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/d̂úp̂ĺîćât́ê-íd̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { - "message": "`[îd́]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é n̂ót̂ ún̂íq̂úê" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é n̂ót̂ ún̂íq̂úê", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[id]`", + "example": "[id]" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | title": { - "message": "`[îd́]` ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é ûńîq́ûé" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é ûńîq́ûé", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[id]`", + "example": "[id]" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ŕêĺŷ ón̂ f́r̂ám̂é t̂ít̂ĺêś t̂ó d̂éŝćr̂íb̂é t̂h́ê ćôńt̂én̂t́ŝ óf̂ f́r̂ám̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/f́r̂ám̂é-t̂ít̂ĺê?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ŕêĺŷ ón̂ f́r̂ám̂é t̂ít̂ĺêś t̂ó d̂éŝćr̂íb̂é t̂h́ê ćôńt̂én̂t́ŝ óf̂ f́r̂ám̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { - "message": "`<f̂ŕâḿê>` ór̂ `<íf̂ŕâḿê>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é â t́ît́l̂é" + "message": "$MARKDOWN_SNIPPET_0$ ôŕ $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê á t̂ít̂ĺê", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<frame>`", + "example": "<frame>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<iframe>`", + "example": "<iframe>" + } + } }, "lighthouse-core/audits/accessibility/frame-title.js | title": { - "message": "`<f̂ŕâḿê>` ór̂ `<íf̂ŕâḿê>` él̂ém̂én̂t́ŝ h́âv́ê á t̂ít̂ĺê" + "message": "$MARKDOWN_SNIPPET_0$ ôŕ $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ś ĥáv̂é â t́ît́l̂é", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<frame>`", + "example": "<frame>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<iframe>`", + "example": "<iframe>" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | description": { - "message": "Îf́ â ṕâǵê d́ôéŝń't̂ śp̂éĉíf̂ý â ĺâńĝ át̂t́r̂íb̂út̂é, â śĉŕêén̂ ŕêád̂ér̂ áŝśûḿêś t̂h́ât́ t̂h́ê ṕâǵê íŝ ín̂ t́ĥé d̂éf̂áûĺt̂ ĺâńĝúâǵê t́ĥát̂ t́ĥé ûśêŕ ĉh́ôśê ẃĥén̂ śêt́t̂ín̂ǵ ûṕ t̂h́ê śĉŕêén̂ ŕêád̂ér̂. Íf̂ t́ĥé p̂áĝé îśn̂'t́ âćt̂úâĺl̂ý îń t̂h́ê d́êf́âúl̂t́ l̂án̂ǵûáĝé, t̂h́êń t̂h́ê śĉŕêén̂ ŕêád̂ér̂ ḿîǵĥt́ n̂ót̂ án̂ńôún̂ćê t́ĥé p̂áĝé'ŝ t́êx́t̂ ćôŕr̂éĉt́l̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/ĥt́m̂ĺ-ĥáŝ-ĺâńĝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Îf́ â ṕâǵê d́ôéŝń't̂ śp̂éĉíf̂ý â ĺâńĝ át̂t́r̂íb̂út̂é, â śĉŕêén̂ ŕêád̂ér̂ áŝśûḿêś t̂h́ât́ t̂h́ê ṕâǵê íŝ ín̂ t́ĥé d̂éf̂áûĺt̂ ĺâńĝúâǵê t́ĥát̂ t́ĥé ûśêŕ ĉh́ôśê ẃĥén̂ śêt́t̂ín̂ǵ ûṕ t̂h́ê śĉŕêén̂ ŕêád̂ér̂. Íf̂ t́ĥé p̂áĝé îśn̂'t́ âćt̂úâĺl̂ý îń t̂h́ê d́êf́âúl̂t́ l̂án̂ǵûáĝé, t̂h́êń t̂h́ê śĉŕêén̂ ŕêád̂ér̂ ḿîǵĥt́ n̂ót̂ án̂ńôún̂ćê t́ĥé p̂áĝé'ŝ t́êx́t̂ ćôŕr̂éĉt́l̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-has-lang.js | title": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ h́âś â `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ h́âś â $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](h́t̂t́p̂ś://ŵẃŵ.ẃ3.ôŕĝ/Ín̂t́êŕn̂át̂íôńâĺ/q̂úêśt̂íôńŝ/q́â-ćĥóôśîńĝ-ĺâńĝúâǵê-t́âǵŝ#q́ûéŝt́îón̂) h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ án̂ńôún̂ćê t́êx́t̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/v́âĺîd́-l̂án̂ǵ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ $LINK_START_0$B̂ĆP̂ 47 ĺâńĝúâǵê$LINK_END_0$ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ án̂ńôún̂ćê t́êx́t̂ ṕr̂óp̂ér̂ĺŷ. $LINK_START_1$Ĺêár̂ń m̂ór̂é$LINK_END_1$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[ĺâńĝ]` át̂t́r̂íb̂út̂é." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { - "message": "`<ĥt́m̂ĺ>` êĺêḿêńt̂ h́âś â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ `[ĺâńĝ]` át̂t́r̂íb̂út̂é" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ h́âś â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<html>`", + "example": "<html>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | description": { - "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ím̂áĝé-âĺt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é `[âĺt̂]` át̂t́r̂íb̂út̂éŝ" + "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/image-alt.js | title": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê `[ál̂t́]` ât́t̂ŕîb́ût́êś" + "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂éŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | description": { - "message": "Ŵh́êń âń îḿâǵê íŝ b́êín̂ǵ ûśêd́ âś âń `<îńp̂út̂>` b́ût́t̂ón̂, ṕr̂óv̂íd̂ín̂ǵ âĺt̂ér̂ńât́îv́ê t́êx́t̂ ćâń ĥél̂ṕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ún̂d́êŕŝt́âńd̂ t́ĥé p̂úr̂ṕôśê óf̂ t́ĥé b̂út̂t́ôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/îńp̂út̂-ím̂áĝé-âĺt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŵh́êń âń îḿâǵê íŝ b́êín̂ǵ ûśêd́ âś âń $MARKDOWN_SNIPPET_0$ b̂út̂t́ôń, p̂ŕôv́îd́îńĝ ál̂t́êŕn̂át̂ív̂é t̂éx̂t́ ĉán̂ h́êĺp̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś ûńd̂ér̂śt̂án̂d́ t̂h́ê ṕûŕp̂óŝé ôf́ t̂h́ê b́ût́t̂ón̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input>`", + "example": "<input>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { - "message": "`<îńp̂út̂ t́ŷṕê=\"ím̂áĝé\">` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[ál̂t́]` t̂éx̂t́" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê $MARKDOWN_SNIPPET_1$ t́êx́t̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input type=\"image\">`", + "example": "<input type=\"image\">" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/input-image-alt.js | title": { - "message": "`<îńp̂út̂ t́ŷṕê=\"ím̂áĝé\">` êĺêḿêńt̂ś ĥáv̂é `[âĺt̂]` t́êx́t̂" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĥáv̂é $MARKDOWN_SNIPPET_1$ t̂éx̂t́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<input type=\"image\">`", + "example": "<input type=\"image\">" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/label.js | description": { - "message": "L̂áb̂él̂ś êńŝúr̂é t̂h́ât́ f̂ór̂ḿ ĉón̂t́r̂ól̂ś âŕê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý b̂ý âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂áb̂él̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "L̂áb̂él̂ś êńŝúr̂é t̂h́ât́ f̂ór̂ḿ ĉón̂t́r̂ól̂ś âŕê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý b̂ý âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/label.js | failureTitle": { "message": "F̂ór̂ḿ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê áŝśôćîát̂éd̂ ĺâb́êĺŝ" @@ -201,16 +717,68 @@ "message": "F̂ór̂ḿ êĺêḿêńt̂ś ĥáv̂é âśŝóĉíât́êd́ l̂áb̂él̂ś" }, "lighthouse-core/audits/accessibility/layout-table.js | description": { - "message": " t́âb́l̂é b̂éîńĝ úŝéd̂ f́ôŕ l̂áŷóût́ p̂úr̂ṕôśêś ŝh́ôúl̂d́ n̂ót̂ ín̂ćl̂úd̂é d̂át̂á êĺêḿêńt̂ś, ŝúĉh́ âś t̂h́ê t́ĥ ór̂ ćâṕt̂íôń êĺêḿêńt̂ś ôŕ t̂h́ê śûḿm̂ár̂ý ât́t̂ŕîb́ût́ê, b́êćâúŝé t̂h́îś ĉán̂ ćr̂éât́ê á ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ĺâýôút̂-t́âb́l̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": " t́âb́l̂é b̂éîńĝ úŝéd̂ f́ôŕ l̂áŷóût́ p̂úr̂ṕôśêś ŝh́ôúl̂d́ n̂ót̂ ín̂ćl̂úd̂é d̂át̂á êĺêḿêńt̂ś, ŝúĉh́ âś t̂h́ê t́ĥ ór̂ ćâṕt̂íôń êĺêḿêńt̂ś ôŕ t̂h́ê śûḿm̂ár̂ý ât́t̂ŕîb́ût́ê, b́êćâúŝé t̂h́îś ĉán̂ ćr̂éât́ê á ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ `<t̂áb̂ĺê>` él̂ém̂én̂t́ŝ d́ô ńôt́ âv́ôíd̂ úŝín̂ǵ `<t̂h́>`, `<ĉáp̂t́îón̂>` ór̂ t́ĥé `[ŝúm̂ḿâŕŷ]` át̂t́r̂íb̂út̂é." + "message": "P̂ŕêśêńt̂át̂íôńâĺ $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ áv̂óîd́ ûśîńĝ $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ ór̂ t́ĥé $MARKDOWN_SNIPPET_3$ ât́t̂ŕîb́ût́ê.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<caption>`", + "example": "<caption>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`[summary]`", + "example": "[summary]" + } + } }, "lighthouse-core/audits/accessibility/layout-table.js | title": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ `<t̂áb̂ĺê>` él̂ém̂én̂t́ŝ áv̂óîd́ ûśîńĝ `<t́ĥ>`, `<ćâṕt̂íôń>` ôŕ t̂h́ê `[śûḿm̂ár̂ý]` ât́t̂ŕîb́ût́ê." + "message": "P̂ŕêśêńt̂át̂íôńâĺ $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âv́ôíd̂ úŝín̂ǵ $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ ôŕ t̂h́ê $MARKDOWN_SNIPPET_3$ át̂t́r̂íb̂út̂é.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<caption>`", + "example": "<caption>" + }, + "MARKDOWN_SNIPPET_3": { + "content": "`[summary]`", + "example": "[summary]" + } + } }, "lighthouse-core/audits/accessibility/link-name.js | description": { - "message": "L̂ín̂ḱ t̂éx̂t́ (âńd̂ ál̂t́êŕn̂át̂é t̂éx̂t́ f̂ór̂ ím̂áĝéŝ, ẃĥén̂ úŝéd̂ áŝ ĺîńk̂ś) t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê, ún̂íq̂úê, án̂d́ f̂óĉúŝáb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé n̂áv̂íĝát̂íôń êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂ín̂ḱ-n̂ám̂é?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "L̂ín̂ḱ t̂éx̂t́ (âńd̂ ál̂t́êŕn̂át̂é t̂éx̂t́ f̂ór̂ ím̂áĝéŝ, ẃĥén̂ úŝéd̂ áŝ ĺîńk̂ś) t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê, ún̂íq̂úê, án̂d́ f̂óĉúŝáb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé n̂áv̂íĝát̂íôń êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { "message": "L̂ín̂ḱŝ d́ô ńôt́ ĥáv̂é â d́îśĉér̂ńîb́l̂é n̂ám̂é" @@ -219,115 +787,499 @@ "message": "L̂ín̂ḱŝ h́âv́ê á d̂íŝćêŕn̂íb̂ĺê ńâḿê" }, "lighthouse-core/audits/accessibility/list.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê á ŝṕêćîf́îć ŵáŷ óf̂ án̂ńôún̂ćîńĝ ĺîśt̂ś. Êńŝúr̂ín̂ǵ p̂ŕôṕêŕ l̂íŝt́ ŝt́r̂úĉt́ûŕê áîd́ŝ śĉŕêén̂ ŕêád̂ér̂ óût́p̂út̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ĺîśt̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê á ŝṕêćîf́îć ŵáŷ óf̂ án̂ńôún̂ćîńĝ ĺîśt̂ś. Êńŝúr̂ín̂ǵ p̂ŕôṕêŕ l̂íŝt́ ŝt́r̂úĉt́ûŕê áîd́ŝ śĉŕêén̂ ŕêád̂ér̂ óût́p̂út̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/list.js | failureTitle": { - "message": "L̂íŝt́ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ `<ĺî>` él̂ém̂én̂t́ŝ án̂d́ ŝćr̂íp̂t́ ŝúp̂ṕôŕt̂ín̂ǵ êĺêḿêńt̂ś (`<ŝćr̂íp̂t́>` âńd̂ `<t́êḿp̂ĺât́ê>`)." + "message": "L̂íŝt́ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ án̂d́ ŝćr̂íp̂t́ ŝúp̂ṕôŕt̂ín̂ǵ êĺêḿêńt̂ś ($MARKDOWN_SNIPPET_1$ âńd̂ $MARKDOWN_SNIPPET_2$).", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/list.js | title": { - "message": "L̂íŝt́ŝ ćôńt̂áîń ôńl̂ý `<l̂í>` êĺêḿêńt̂ś âńd̂ śĉŕîṕt̂ śûṕp̂ór̂t́îńĝ él̂ém̂én̂t́ŝ (`<śĉŕîṕt̂>` án̂d́ `<t̂ém̂ṕl̂át̂é>`)." + "message": "L̂íŝt́ŝ ćôńt̂áîń ôńl̂ý $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ śĉŕîṕt̂ śûṕp̂ór̂t́îńĝ él̂ém̂én̂t́ŝ ($MARKDOWN_SNIPPET_1$ án̂d́ $MARKDOWN_SNIPPET_2$).", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<script>`", + "example": "<script>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<template>`", + "example": "<template>" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ŕêq́ûír̂é l̂íŝt́ ît́êḿŝ (`<ĺî>`) t́ô b́ê ćôńt̂áîńêd́ ŵít̂h́îń â ṕâŕêńt̂ `<úl̂>` ór̂ `<ól̂>` t́ô b́ê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/l̂íŝt́ît́êḿ?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ ŕêq́ûír̂é l̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) t́ô b́ê ćôńt̂áîńêd́ ŵít̂h́îń â ṕâŕêńt̂ $MARKDOWN_SNIPPET_1$ ór̂ $MARKDOWN_SNIPPET_2$ t́ô b́ê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { - "message": "L̂íŝt́ ît́êḿŝ (`<ĺî>`) ár̂é n̂ót̂ ćôńt̂áîńêd́ ŵít̂h́îń `<ûĺ>` ôŕ `<ôĺ>` p̂ár̂én̂t́ êĺêḿêńt̂ś." + "message": "L̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) ár̂é n̂ót̂ ćôńt̂áîńêd́ ŵít̂h́îń $MARKDOWN_SNIPPET_1$ ôŕ $MARKDOWN_SNIPPET_2$ p̂ár̂én̂t́ êĺêḿêńt̂ś.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + } + } }, "lighthouse-core/audits/accessibility/listitem.js | title": { - "message": "L̂íŝt́ ît́êḿŝ (`<ĺî>`) ár̂é ĉón̂t́âín̂éd̂ ẃît́ĥín̂ `<úl̂>` ór̂ `<ól̂>` ṕâŕêńt̂ él̂ém̂én̂t́ŝ" + "message": "L̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) ár̂é ĉón̂t́âín̂éd̂ ẃît́ĥín̂ $MARKDOWN_SNIPPET_1$ ór̂ $MARKDOWN_SNIPPET_2$ ṕâŕêńt̂ él̂ém̂én̂t́ŝ", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<li>`", + "example": "<li>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<ul>`", + "example": "<ul>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`<ol>`", + "example": "<ol>" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | description": { - "message": "Ûśêŕŝ d́ô ńôt́ êx́p̂éĉt́ â ṕâǵê t́ô ŕêf́r̂éŝh́ âút̂óm̂át̂íĉál̂ĺŷ, án̂d́ d̂óîńĝ śô ẃîĺl̂ ḿôv́ê f́ôćûś b̂áĉḱ t̂ó t̂h́ê t́ôṕ ôf́ t̂h́ê ṕâǵê. T́ĥíŝ ḿâý ĉŕêát̂é â f́r̂úŝt́r̂át̂ín̂ǵ ôŕ ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ḿêt́â-ŕêf́r̂éŝh́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ûśêŕŝ d́ô ńôt́ êx́p̂éĉt́ â ṕâǵê t́ô ŕêf́r̂éŝh́ âút̂óm̂át̂íĉál̂ĺŷ, án̂d́ d̂óîńĝ śô ẃîĺl̂ ḿôv́ê f́ôćûś b̂áĉḱ t̂ó t̂h́ê t́ôṕ ôf́ t̂h́ê ṕâǵê. T́ĥíŝ ḿâý ĉŕêát̂é â f́r̂úŝt́r̂át̂ín̂ǵ ôŕ ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { - "message": "T̂h́ê d́ôćûḿêńt̂ úŝéŝ `<ḿêt́â h́t̂t́p̂-éq̂úîv́=\"r̂éf̂ŕêśĥ\">`" + "message": "T̂h́ê d́ôćûḿêńt̂ úŝéŝ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<meta http-equiv=\"refresh\">`", + "example": "<meta http-equiv=\"refresh\">" + } + } }, "lighthouse-core/audits/accessibility/meta-refresh.js | title": { - "message": "T̂h́ê d́ôćûḿêńt̂ d́ôéŝ ńôt́ ûśê `<ḿêt́â h́t̂t́p̂-éq̂úîv́=\"r̂éf̂ŕêśĥ\">`" + "message": "T̂h́ê d́ôćûḿêńt̂ d́ôéŝ ńôt́ ûśê $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<meta http-equiv=\"refresh\">`", + "example": "<meta http-equiv=\"refresh\">" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | description": { - "message": "D̂íŝáb̂ĺîńĝ źôóm̂ín̂ǵ îś p̂ŕôb́l̂ém̂át̂íĉ f́ôŕ ûśêŕŝ ẃît́ĥ ĺôẃ v̂íŝíôń ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ḿâǵn̂íf̂íĉát̂íôń t̂ó p̂ŕôṕêŕl̂ý ŝéê t́ĥé ĉón̂t́êńt̂ś ôf́ â ẃêb́ p̂áĝé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/m̂ét̂á-v̂íêẃp̂ór̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "D̂íŝáb̂ĺîńĝ źôóm̂ín̂ǵ îś p̂ŕôb́l̂ém̂át̂íĉ f́ôŕ ûśêŕŝ ẃît́ĥ ĺôẃ v̂íŝíôń ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ḿâǵn̂íf̂íĉát̂íôń t̂ó p̂ŕôṕêŕl̂ý ŝéê t́ĥé ĉón̂t́êńt̂ś ôf́ â ẃêb́ p̂áĝé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { - "message": "`[ûśêŕ-ŝćâĺâb́l̂é=\"n̂ó\"]` îś ûśêd́ îń t̂h́ê `<ḿêt́â ńâḿê=\"v́îéŵṕôŕt̂\">` él̂ém̂én̂t́ ôŕ t̂h́ê `[ḿâx́îḿûḿ-ŝćâĺê]` át̂t́r̂íb̂út̂é îś l̂éŝś t̂h́âń 5." + "message": "$MARKDOWN_SNIPPET_0$ îś ûśêd́ îń t̂h́ê $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ôŕ t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂é îś l̂éŝś t̂h́âń 5.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[user-scalable=\"no\"]`", + "example": "[user-scalable=\"no\"]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<meta name=\"viewport\">`", + "example": "<meta name=\"viewport\">" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[maximum-scale]`", + "example": "[maximum-scale]" + } + } }, "lighthouse-core/audits/accessibility/meta-viewport.js | title": { - "message": "`[ûśêŕ-ŝćâĺâb́l̂é=\"n̂ó\"]` îś n̂ót̂ úŝéd̂ ín̂ t́ĥé `<m̂ét̂á n̂ám̂é=\"v̂íêẃp̂ór̂t́\">` êĺêḿêńt̂ án̂d́ t̂h́ê `[ḿâx́îḿûḿ-ŝćâĺê]` át̂t́r̂íb̂út̂é îś n̂ót̂ ĺêśŝ t́ĥán̂ 5." + "message": "$MARKDOWN_SNIPPET_0$ îś n̂ót̂ úŝéd̂ ín̂ t́ĥé $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ án̂d́ t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂é îś n̂ót̂ ĺêśŝ t́ĥán̂ 5.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[user-scalable=\"no\"]`", + "example": "[user-scalable=\"no\"]" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<meta name=\"viewport\">`", + "example": "<meta name=\"viewport\">" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[maximum-scale]`", + "example": "[maximum-scale]" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ćâńn̂ót̂ t́r̂án̂śl̂át̂é n̂ón̂-t́êx́t̂ ćôńt̂én̂t́. Âd́d̂ín̂ǵ âĺt̂ t́êx́t̂ t́ô `<ób̂j́êćt̂>` él̂ém̂én̂t́ŝ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ ćôńv̂éŷ ḿêán̂ín̂ǵ t̂ó ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/ób̂j́êćt̂-ál̂t́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ ćâńn̂ót̂ t́r̂án̂śl̂át̂é n̂ón̂-t́êx́t̂ ćôńt̂én̂t́. Âd́d̂ín̂ǵ âĺt̂ t́êx́t̂ t́ô $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ ćôńv̂éŷ ḿêán̂ín̂ǵ t̂ó ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { - "message": "`<ôb́ĵéĉt́>` êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê `[ál̂t́]` t̂éx̂t́" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê $MARKDOWN_SNIPPET_1$ t́êx́t̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/object-alt.js | title": { - "message": "`<ôb́ĵéĉt́>` êĺêḿêńt̂ś ĥáv̂é `[âĺt̂]` t́êx́t̂" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĥáv̂é $MARKDOWN_SNIPPET_1$ t̂éx̂t́", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<object>`", + "example": "<object>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[alt]`", + "example": "[alt]" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | description": { - "message": " v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0 ím̂ṕl̂íêś âń êx́p̂ĺîćît́ n̂áv̂íĝát̂íôń ôŕd̂ér̂ín̂ǵ. Âĺt̂h́ôúĝh́ t̂éĉh́n̂íĉál̂ĺŷ v́âĺîd́, t̂h́îś ôf́t̂én̂ ćr̂éât́êś f̂ŕûśt̂ŕât́îńĝ éx̂ṕêŕîén̂ćêś f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/t̂áb̂ín̂d́êx́?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": " v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0 ím̂ṕl̂íêś âń êx́p̂ĺîćît́ n̂áv̂íĝát̂íôń ôŕd̂ér̂ín̂ǵ. Âĺt̂h́ôúĝh́ t̂éĉh́n̂íĉál̂ĺŷ v́âĺîd́, t̂h́îś ôf́t̂én̂ ćr̂éât́êś f̂ŕûśt̂ŕât́îńĝ éx̂ṕêŕîén̂ćêś f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { - "message": "Ŝóm̂é êĺêḿêńt̂ś ĥáv̂é â `[t́âb́îńd̂éx̂]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" + "message": "Ŝóm̂é êĺêḿêńt̂ś ĥáv̂é â $MARKDOWN_SNIPPET_0$ v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[tabindex]`", + "example": "[tabindex]" + } + } }, "lighthouse-core/audits/accessibility/tabindex.js | title": { - "message": "N̂ó êĺêḿêńt̂ h́âś â `[t́âb́îńd̂éx̂]` v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0" + "message": "N̂ó êĺêḿêńt̂ h́âś â $MARKDOWN_SNIPPET_0$ v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[tabindex]`", + "example": "[tabindex]" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ `<t́d̂>` ćêĺl̂ś ûśîńĝ t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ ín̂ t́ĥé ŝám̂é t̂áb̂ĺê ḿâý îḿp̂ŕôv́ê t́ĥé êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/t̂d́-ĥéâd́êŕŝ-át̂t́r̂?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ $MARKDOWN_SNIPPET_0$ ćêĺl̂ś ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_1$ ât́t̂ŕîb́ût́ê ón̂ĺŷ ŕêf́êŕ t̂ó ôt́ĥér̂ ćêĺl̂ś îń t̂h́ê śâḿê t́âb́l̂é m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<td>`", + "example": "<td>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { - "message": "Ĉél̂ĺŝ ín̂ á `<t̂áb̂ĺê>` él̂ém̂én̂t́ t̂h́ât́ ûśê t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é r̂éf̂ér̂ś t̂ó ôt́ĥér̂ ćêĺl̂ś ôf́ t̂h́ât́ ŝám̂é t̂áb̂ĺê." + "message": "Ĉél̂ĺŝ ín̂ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é r̂éf̂ér̂ś t̂ó ôt́ĥér̂ ćêĺl̂ś ôf́ t̂h́ât́ ŝám̂é t̂áb̂ĺê.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + } + } }, "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { - "message": "Ĉél̂ĺŝ ín̂ á `<t̂áb̂ĺê>` él̂ém̂én̂t́ t̂h́ât́ ûśê t́ĥé `[ĥéâd́êŕŝ]` át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ óf̂ t́ĥát̂ śâḿê t́âb́l̂é." + "message": "Ĉél̂ĺŝ ín̂ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ óf̂ t́ĥát̂ śâḿê t́âb́l̂é.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<table>`", + "example": "<table>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[headers]`", + "example": "[headers]" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́âb́l̂é ĥéâd́êŕŝ ál̂ẃâýŝ ŕêf́êŕ t̂ó ŝóm̂é ŝét̂ óf̂ ćêĺl̂ś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êq́ûéûńîv́êŕŝít̂ý.ĉóm̂/ŕûĺêś/âx́ê/3.1/t́ĥ-h́âś-d̂át̂á-ĉél̂ĺŝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́âb́l̂é ĥéâd́êŕŝ ál̂ẃâýŝ ŕêf́êŕ t̂ó ŝóm̂é ŝét̂ óf̂ ćêĺl̂ś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { - "message": "`<t̂h́>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[ŕôĺê=\"ćôĺûḿn̂h́êád̂ér̂\"/\"ŕôẃĥéâd́êŕ\"]` d̂ó n̂ót̂ h́âv́ê d́ât́â ćêĺl̂ś t̂h́êý d̂éŝćr̂íb̂é." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ $MARKDOWN_SNIPPET_1$ d́ô ńôt́ ĥáv̂é d̂át̂á ĉél̂ĺŝ t́ĥéŷ d́êśĉŕîb́ê.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role=\"columnheader\"/\"rowheader\"]`", + "example": "[role=\"columnheader\"/\"rowheader\"]" + } + } }, "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { - "message": "`<t̂h́>` êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ `[ŕôĺê=\"ćôĺûḿn̂h́êád̂ér̂\"/\"ŕôẃĥéâd́êŕ\"]` ĥáv̂é d̂át̂á ĉél̂ĺŝ t́ĥéŷ d́êśĉŕîb́ê." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ $MARKDOWN_SNIPPET_1$ h́âv́ê d́ât́â ćêĺl̂ś t̂h́êý d̂éŝćr̂íb̂é.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<th>`", + "example": "<th>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`[role=\"columnheader\"/\"rowheader\"]`", + "example": "[role=\"columnheader\"/\"rowheader\"]" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ [B̂ĆP̂ 47 ĺâńĝúâǵê](h́t̂t́p̂ś://ŵẃŵ.ẃ3.ôŕĝ/Ín̂t́êŕn̂át̂íôńâĺ/q̂úêśt̂íôńŝ/q́â-ćĥóôśîńĝ-ĺâńĝúâǵê-t́âǵŝ#q́ûéŝt́îón̂) ón̂ él̂ém̂én̂t́ŝ h́êĺp̂ś êńŝúr̂é t̂h́ât́ t̂éx̂t́ îś p̂ŕôńôún̂ćêd́ ĉór̂ŕêćt̂ĺŷ b́ŷ á ŝćr̂éêń r̂éâd́êŕ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂ál̂íd̂-ĺâńĝ?áp̂ṕl̂íĉát̂íôń=l̂íĝh́t̂h́ôúŝé)." + "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ $LINK_START_0$B̂ĆP̂ 47 ĺâńĝúâǵê$LINK_END_0$ ón̂ él̂ém̂én̂t́ŝ h́êĺp̂ś êńŝúr̂é t̂h́ât́ t̂éx̂t́ îś p̂ŕôńôún̂ćêd́ ĉór̂ŕêćt̂ĺŷ b́ŷ á ŝćr̂éêń r̂éâd́êŕ. $LINK_START_1$L̂éâŕn̂ ḿôŕê$LINK_END_1$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { - "message": "`[l̂án̂ǵ]` ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê á v̂ál̂íd̂ v́âĺûé" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê á v̂ál̂íd̂ v́âĺûé", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/valid-lang.js | title": { - "message": "`[l̂án̂ǵ]` ât́t̂ŕîb́ût́êś ĥáv̂é â v́âĺîd́ v̂ál̂úê" + "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ĥáv̂é â v́âĺîd́ v̂ál̂úê", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`[lang]`", + "example": "[lang]" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | description": { - "message": "Ŵh́êń â v́îd́êó p̂ŕôv́îd́êś â ćâṕt̂íôń ît́ îś êáŝíêŕ f̂ór̂ d́êáf̂ án̂d́ ĥéâŕîńĝ ím̂ṕâír̂éd̂ úŝér̂ś t̂ó âćĉéŝś ît́ŝ ín̂f́ôŕm̂át̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂íd̂éô-ćâṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Ŵh́êń â v́îd́êó p̂ŕôv́îd́êś â ćâṕt̂íôń ît́ îś êáŝíêŕ f̂ór̂ d́êáf̂ án̂d́ ĥéâŕîńĝ ím̂ṕâír̂éd̂ úŝér̂ś t̂ó âćĉéŝś ît́ŝ ín̂f́ôŕm̂át̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĉón̂t́âín̂ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"ĉáp̂t́îón̂ś\"]`." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/video-caption.js | title": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"ćâṕt̂íôńŝ\"]`" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"captions\"]`", + "example": "[kind=\"captions\"]" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | description": { - "message": "Âúd̂íô d́êśĉŕîṕt̂íôńŝ ṕr̂óv̂íd̂é r̂él̂év̂án̂t́ îńf̂ór̂ḿât́îón̂ f́ôŕ v̂íd̂éôś t̂h́ât́ d̂íâĺôǵûé ĉán̂ńôt́, ŝúĉh́ âś f̂áĉíâĺ êx́p̂ŕêśŝíôńŝ án̂d́ ŝćêńêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂éq̂úêún̂ív̂ér̂śît́ŷ.ćôḿ/r̂úl̂éŝ/áx̂é/3.1/v̂íd̂éô-d́êśĉŕîṕt̂íôń?âṕp̂ĺîćât́îón̂=ĺîǵĥt́ĥóûśê)." + "message": "Âúd̂íô d́êśĉŕîṕt̂íôńŝ ṕr̂óv̂íd̂é r̂él̂év̂án̂t́ îńf̂ór̂ḿât́îón̂ f́ôŕ v̂íd̂éôś t̂h́ât́ d̂íâĺôǵûé ĉán̂ńôt́, ŝúĉh́ âś f̂áĉíâĺ êx́p̂ŕêśŝíôńŝ án̂d́ ŝćêńêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ d́ô ńôt́ ĉón̂t́âín̂ á `<t̂ŕâćk̂>` él̂ém̂én̂t́ ŵít̂h́ `[k̂ín̂d́=\"d̂éŝćr̂íp̂t́îón̂\"]`." + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"description\"]`", + "example": "[kind=\"description\"]" + } + } }, "lighthouse-core/audits/accessibility/video-description.js | title": { - "message": "`<v̂íd̂éô>` él̂ém̂én̂t́ŝ ćôńt̂áîń â `<t́r̂áĉḱ>` êĺêḿêńt̂ ẃît́ĥ `[ḱîńd̂=\"d́êśĉŕîṕt̂íôń\"]`" + "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<video>`", + "example": "<video>" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`<track>`", + "example": "<track>" + }, + "MARKDOWN_SNIPPET_2": { + "content": "`[kind=\"description\"]`", + "example": "[kind=\"description\"]" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | description": { - "message": "F̂ór̂ íd̂éâĺ âṕp̂éâŕâńĉé ôń îÓŜ ẃĥén̂ úŝér̂ś âd́d̂ t́ô t́ĥé ĥóm̂é ŝćr̂éêń, d̂éf̂ín̂é âń âṕp̂ĺê-t́ôúĉh́-îćôń. Ît́ m̂úŝt́ p̂óîńt̂ t́ô á n̂ón̂-t́r̂án̂śp̂ár̂én̂t́ 192p̂x́ (ôŕ 180p̂x́) ŝq́ûár̂é P̂ŃĜ. [Ĺêár̂ń M̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/d́êśîǵn̂-án̂d́-ûx́/b̂ŕôẃŝér̂-ćûśt̂óm̂íẑát̂íôń/)." + "message": "F̂ór̂ íd̂éâĺ âṕp̂éâŕâńĉé ôń îÓŜ ẃĥén̂ úŝér̂ś âd́d̂ t́ô t́ĥé ĥóm̂é ŝćr̂éêń, d̂éf̂ín̂é âń âṕp̂ĺê-t́ôúĉh́-îćôń. Ît́ m̂úŝt́ p̂óîńt̂ t́ô á n̂ón̂-t́r̂án̂śp̂ár̂én̂t́ 192p̂x́ (ôŕ 180p̂x́) ŝq́ûár̂é P̂ŃĜ. $LINK_START_0$Ĺêár̂ń M̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { - "message": "D̂óêś n̂ót̂ ṕr̂óv̂íd̂é â v́âĺîd́ `âṕp̂ĺê-t́ôúĉh́-îćôń`" + "message": "D̂óêś n̂ót̂ ṕr̂óv̂íd̂é â v́âĺîd́ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { - "message": "`âṕp̂ĺê-t́ôúĉh́-îćôń-p̂ŕêćôḿp̂óŝéd̂` íŝ óût́ ôf́ d̂át̂é; `âṕp̂ĺê-t́ôúĉh́-îćôń` îś p̂ŕêf́êŕr̂éd̂." + "message": "$MARKDOWN_SNIPPET_0$ îś ôút̂ óf̂ d́ât́ê; $MARKDOWN_SNIPPET_1$ íŝ ṕr̂éf̂ér̂ŕêd́.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon-precomposed`", + "example": "apple-touch-icon-precomposed" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/apple-touch-icon.js | title": { - "message": "P̂ŕôv́îd́êś â v́âĺîd́ `âṕp̂ĺê-t́ôúĉh́-îćôń`" + "message": "P̂ŕôv́îd́êś â v́âĺîd́ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`apple-touch-icon`", + "example": "apple-touch-icon" + } + } }, "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { "message": "Ĉh́r̂óm̂é êx́t̂én̂śîón̂ś n̂éĝát̂ív̂él̂ý âf́f̂éĉt́êd́ t̂h́îś p̂áĝé'ŝ ĺôád̂ ṕêŕf̂ór̂ḿâńĉé. T̂ŕŷ áûd́ît́îńĝ t́ĥé p̂áĝé îń îńĉóĝńît́ô ḿôd́ê ór̂ f́r̂óm̂ á Ĉh́r̂óm̂é p̂ŕôf́îĺê ẃît́ĥóût́ êx́t̂én̂śîón̂ś." @@ -342,7 +1294,15 @@ "message": "T̂ót̂ál̂ ĆP̂Ú T̂ím̂é" }, "lighthouse-core/audits/bootup-time.js | description": { - "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ, âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́ôót̂úp̂)." + "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ, âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/bootup)" + } + } }, "lighthouse-core/audits/bootup-time.js | failureTitle": { "message": "R̂éd̂úĉé Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" @@ -351,28 +1311,66 @@ "message": "Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { - "message": "L̂ár̂ǵê ǴÎF́ŝ ár̂é îńêf́f̂íĉíêńt̂ f́ôŕ d̂él̂ív̂ér̂ín̂ǵ âńîḿât́êd́ ĉón̂t́êńt̂. Ćôńŝíd̂ér̂ úŝín̂ǵ M̂ṔÊǴ4/Ŵéb̂Ḿ v̂íd̂éôś f̂ór̂ án̂ím̂át̂íôńŝ án̂d́ P̂ŃĜ/Ẃêb́P̂ f́ôŕ ŝt́ât́îć îḿâǵêś îńŝt́êád̂ óf̂ ǴÎF́ t̂ó ŝáv̂é n̂ét̂ẃôŕk̂ b́ŷt́êś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/p̂ér̂f́ôŕm̂án̂ćê/óp̂t́îḿîźîńĝ-ćôńt̂én̂t́-êf́f̂íĉíêńĉý/r̂ép̂ĺâćê-án̂ím̂át̂éd̂-ǵîf́ŝ-ẃît́ĥ-v́îd́êó/)" + "message": "L̂ár̂ǵê ǴÎF́ŝ ár̂é îńêf́f̂íĉíêńt̂ f́ôŕ d̂él̂ív̂ér̂ín̂ǵ âńîḿât́êd́ ĉón̂t́êńt̂. Ćôńŝíd̂ér̂ úŝín̂ǵ M̂ṔÊǴ4/Ŵéb̂Ḿ v̂íd̂éôś f̂ór̂ án̂ím̂át̂íôńŝ án̂d́ P̂ŃĜ/Ẃêb́P̂ f́ôŕ ŝt́ât́îć îḿâǵêś îńŝt́êád̂ óf̂ ǴÎF́ t̂ó ŝáv̂é n̂ét̂ẃôŕk̂ b́ŷt́êś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" + } + } }, "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { "message": "Ûśê v́îd́êó f̂ór̂ḿât́ŝ f́ôŕ âńîḿât́êd́ ĉón̂t́êńt̂" }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { - "message": "Ĉón̂śîd́êŕ l̂áẑý-l̂óâd́îńĝ óf̂f́ŝćr̂éêń âńd̂ h́îd́d̂én̂ ím̂áĝéŝ áf̂t́êŕ âĺl̂ ćr̂ít̂íĉál̂ ŕêśôúr̂ćêś ĥáv̂é f̂ín̂íŝh́êd́ l̂óâd́îńĝ t́ô ĺôẃêŕ t̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ôf́f̂śĉŕêén̂-ím̂áĝéŝ)." + "message": "Ĉón̂śîd́êŕ l̂áẑý-l̂óâd́îńĝ óf̂f́ŝćr̂éêń âńd̂ h́îd́d̂én̂ ím̂áĝéŝ áf̂t́êŕ âĺl̂ ćr̂ít̂íĉál̂ ŕêśôúr̂ćêś ĥáv̂é f̂ín̂íŝh́êd́ l̂óâd́îńĝ t́ô ĺôẃêŕ t̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { "message": "D̂éf̂ér̂ óf̂f́ŝćr̂éêń îḿâǵêś" }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { - "message": "R̂éŝóûŕĉéŝ ár̂é b̂ĺôćk̂ín̂ǵ t̂h́ê f́îŕŝt́ p̂áîńt̂ óf̂ ýôúr̂ ṕâǵê. Ćôńŝíd̂ér̂ d́êĺîv́êŕîńĝ ćr̂ít̂íĉál̂ J́Ŝ/ĆŜŚ îńl̂ín̂é âńd̂ d́êf́êŕr̂ín̂ǵ âĺl̂ ńôń-ĉŕît́îćâĺ ĴŚ/ŝt́ŷĺêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́l̂óĉḱîńĝ-ŕêśôúr̂ćêś)." + "message": "R̂éŝóûŕĉéŝ ár̂é b̂ĺôćk̂ín̂ǵ t̂h́ê f́îŕŝt́ p̂áîńt̂ óf̂ ýôúr̂ ṕâǵê. Ćôńŝíd̂ér̂ d́êĺîv́êŕîńĝ ćr̂ít̂íĉál̂ J́Ŝ/ĆŜŚ îńl̂ín̂é âńd̂ d́êf́êŕr̂ín̂ǵ âĺl̂ ńôń-ĉŕît́îćâĺ ĴŚ/ŝt́ŷĺêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)" + } + } }, "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { "message": "Êĺîḿîńât́ê ŕêńd̂ér̂-b́l̂óĉḱîńĝ ŕêśôúr̂ćêś" }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { - "message": "L̂ár̂ǵê ńêt́ŵór̂ḱ p̂áŷĺôád̂ś ĉóŝt́ ûśêŕŝ ŕêál̂ ḿôńêý âńd̂ ár̂é ĥíĝh́l̂ý ĉór̂ŕêĺât́êd́ ŵít̂h́ l̂ón̂ǵ l̂óâd́ t̂ím̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/n̂ét̂ẃôŕk̂-ṕâýl̂óâd́ŝ)." + "message": "L̂ár̂ǵê ńêt́ŵór̂ḱ p̂áŷĺôád̂ś ĉóŝt́ ûśêŕŝ ŕêál̂ ḿôńêý âńd̂ ár̂é ĥíĝh́l̂ý ĉór̂ŕêĺât́êd́ ŵít̂h́ l̂ón̂ǵ l̂óâd́ t̂ím̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)" + } + } }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "T̂ót̂ál̂ śîźê ẃâś {totalBytes, number, bytes} K̂B́" + "message": "T̂ót̂ál̂ śîźê ẃâś $COMPLEX_ICU_0$ K̂B́", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{totalBytes, number, bytes}", + "example": "499" + } + } }, "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | failureTitle": { "message": "Âv́ôíd̂ én̂ór̂ḿôúŝ ńêt́ŵór̂ḱ p̂áŷĺôád̂ś" @@ -381,61 +1379,65 @@ "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $link_start$Ĺêár̂ń M̂ór̂é!!!$link_end$. T̂h́îś âúd̂ít̂ t́ôók̂ $milliseconds$ ḿŝ.", + "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$->Ĺêár̂ń M̂ór̂é!!!$LINK_END_0$. T̂h́îś âúd̂ít̂ t́ôók̂ $COMPLEX_ICU_0$ ḿŝ.", "placeholders": { - "link_start": { - "content": "[->" + "LINK_START_0": { + "content": "[" }, - "link_end": { + "LINK_END_0": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" }, - "milliseconds": { + "COMPLEX_ICU_0": { "content": "{timeInMs, number, milliseconds}", - "example": "520 (Placeholder examples go here)" + "example": "499" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. $static_replacement$ {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}", + "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. $MARKDOWN_SNIPPET_0$ {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}", "placeholders": { - "static_replacement": { + "MARKDOWN_SNIPPET_0": { "content": "`<link rel=>`", - "example": "Some static replacement." - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { - "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, $name$. $static_replacement$ {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}", - "placeholders": { - "static_replacement": { - "content": "`<link rel=>`", - "example": "Some static replacement." - }, - "name": { - "content": "{name}", - "example": "This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen." + "example": "<link rel=>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "M̂ín̂íf̂ý ĈŚŜ ĺîḱê $css$", + "message": "M̂ín̂íf̂ý ĈŚŜ ĺîḱê $MARKDOWN_SNIPPET_0$", "placeholders": { - "css": { - "content": "`<link rel=stylesheet>`" + "MARKDOWN_SNIPPET_0": { + "content": "`<link rel=stylesheet>`", + "example": "<link rel=stylesheet>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́}other {# êŕr̂ór̂ś f̂óûńd̂}}" + "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́} other {# êŕr̂ór̂ś f̂óûńd̂}}" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { - "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŝṕêéd̂/d́ôćŝ/ín̂śîǵĥt́ŝ/Ḿîńîf́ŷŔêśôúr̂ćêś)." + "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/speed/docs/insights/MinifyResources)" + } + } }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { "message": "M̂ín̂íf̂ý Ĵáv̂áŜćr̂íp̂t́" }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { - "message": "R̂ém̂óv̂é d̂éâd́ r̂úl̂éŝ f́r̂óm̂ śt̂ýl̂éŝh́êét̂ś âńd̂ d́êf́êŕ t̂h́ê ĺôád̂ín̂ǵ ôf́ ĈŚŜ ńôt́ ûśêd́ f̂ór̂ áb̂óv̂é-t̂h́ê-f́ôĺd̂ ćôńt̂én̂t́ t̂ó r̂éd̂úĉé ûńn̂éĉéŝśâŕŷ b́ŷt́êś ĉón̂śûḿêd́ b̂ý n̂ét̂ẃôŕk̂ áĉt́îv́ît́ŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ûńûśêd́-ĉśŝ)." + "message": "R̂ém̂óv̂é d̂éâd́ r̂úl̂éŝ f́r̂óm̂ śt̂ýl̂éŝh́êét̂ś âńd̂ d́êf́êŕ t̂h́ê ĺôád̂ín̂ǵ ôf́ ĈŚŜ ńôt́ ûśêd́ f̂ór̂ áb̂óv̂é-t̂h́ê-f́ôĺd̂ ćôńt̂én̂t́ t̂ó r̂éd̂úĉé ûńn̂éĉéŝśâŕŷ b́ŷt́êś ĉón̂śûḿêd́ b̂ý n̂ét̂ẃôŕk̂ áĉt́îv́ît́ŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/unused-css)" + } + } }, "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { "message": "R̂ém̂óv̂é ûńûśêd́ ĈŚŜ" @@ -447,7 +1449,15 @@ "message": "R̂ém̂óv̂é ûńûśêd́ Ĵáv̂áŜćr̂íp̂t́" }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { - "message": " ĺôńĝ ćâćĥé l̂íf̂ét̂ím̂é ĉán̂ śp̂éêd́ ûṕ r̂ép̂éât́ v̂íŝít̂ś t̂ó ŷóûŕ p̂áĝé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ćâćĥé-p̂ól̂íĉý)." + "message": " ĺôńĝ ćâćĥé l̂íf̂ét̂ím̂é ĉán̂ śp̂éêd́ ûṕ r̂ép̂éât́ v̂íŝít̂ś t̂ó ŷóûŕ p̂áĝé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 r̂éŝóûŕĉé f̂óûńd̂}\n other {# ŕêśôúr̂ćêś f̂óûńd̂}\n }" @@ -459,31 +1469,71 @@ "message": "Ûśêś êf́f̂íĉíêńt̂ ćâćĥé p̂ól̂íĉý ôń ŝt́ât́îć âśŝét̂ś" }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { - "message": "Ôṕt̂ím̂íẑéd̂ ím̂áĝéŝ ĺôád̂ f́âśt̂ér̂ án̂d́ ĉón̂śûḿê ĺêśŝ ćêĺl̂úl̂ár̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ôṕt̂ím̂íẑé-îḿâǵêś)." + "message": "Ôṕt̂ím̂íẑéd̂ ím̂áĝéŝ ĺôád̂ f́âśt̂ér̂ án̂d́ ĉón̂śûḿê ĺêśŝ ćêĺl̂úl̂ár̂ d́ât́â. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { "message": "Êf́f̂íĉíêńt̂ĺŷ én̂ćôd́ê ím̂áĝéŝ" }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { - "message": "Ŝér̂v́ê ím̂áĝéŝ t́ĥát̂ ár̂é âṕp̂ŕôṕr̂íât́êĺŷ-śîźêd́ t̂ó ŝáv̂é ĉél̂ĺûĺâŕ d̂át̂á âńd̂ ím̂ṕr̂óv̂é l̂óâd́ t̂ím̂é. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/óv̂ér̂śîźêd́-îḿâǵêś)." + "message": "Ŝér̂v́ê ím̂áĝéŝ t́ĥát̂ ár̂é âṕp̂ŕôṕr̂íât́êĺŷ-śîźêd́ t̂ó ŝáv̂é ĉél̂ĺûĺâŕ d̂át̂á âńd̂ ím̂ṕr̂óv̂é l̂óâd́ t̂ím̂é. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { "message": "P̂ŕôṕêŕl̂ý ŝíẑé îḿâǵêś" }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { - "message": "T̂éx̂t́-b̂áŝéd̂ ŕêśôúr̂ćêś ŝh́ôúl̂d́ b̂é ŝér̂v́êd́ ŵít̂h́ ĉóm̂ṕr̂éŝśîón̂ (ǵẑíp̂, d́êf́l̂át̂é ôŕ b̂ŕôt́l̂í) t̂ó m̂ín̂ím̂íẑé t̂ót̂ál̂ ńêt́ŵór̂ḱ b̂ýt̂éŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂éx̂t́-ĉóm̂ṕr̂éŝśîón̂)." + "message": "T̂éx̂t́-b̂áŝéd̂ ŕêśôúr̂ćêś ŝh́ôúl̂d́ b̂é ŝér̂v́êd́ ŵít̂h́ ĉóm̂ṕr̂éŝśîón̂ (ǵẑíp̂, d́êf́l̂át̂é ôŕ b̂ŕôt́l̂í) t̂ó m̂ín̂ím̂íẑé t̂ót̂ál̂ ńêt́ŵór̂ḱ b̂ýt̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/text-compression)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { "message": "Êńâb́l̂é t̂éx̂t́ ĉóm̂ṕr̂éŝśîón̂" }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { - "message": "Îḿâǵê f́ôŕm̂át̂ś l̂ík̂é ĴṔÊǴ 2000, ĴṔÊǴ X̂Ŕ, âńd̂ Ẃêb́P̂ óf̂t́êń p̂ŕôv́îd́ê b́êt́t̂ér̂ ćôḿp̂ŕêśŝíôń t̂h́âń P̂ŃĜ ór̂ J́P̂ÉĜ, ẃĥíĉh́ m̂éâńŝ f́âśt̂ér̂ d́ôẃn̂ĺôád̂ś âńd̂ ĺêśŝ d́ât́â ćôńŝúm̂ṕt̂íôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ẃêb́p̂)." + "message": "Îḿâǵê f́ôŕm̂át̂ś l̂ík̂é ĴṔÊǴ 2000, ĴṔÊǴ X̂Ŕ, âńd̂ Ẃêb́P̂ óf̂t́êń p̂ŕôv́îd́ê b́êt́t̂ér̂ ćôḿp̂ŕêśŝíôń t̂h́âń P̂ŃĜ ór̂ J́P̂ÉĜ, ẃĥíĉh́ m̂éâńŝ f́âśt̂ér̂ d́ôẃn̂ĺôád̂ś âńd̂ ĺêśŝ d́ât́â ćôńŝúm̂ṕt̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/webp)" + } + } }, "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { "message": "Ŝér̂v́ê ím̂áĝéŝ ín̂ ńêx́t̂-ǵêń f̂ór̂ḿât́ŝ" }, "lighthouse-core/audits/critical-request-chains.js | description": { - "message": "T̂h́ê Ćr̂ít̂íĉál̂ Ŕêq́ûéŝt́ Ĉh́âín̂ś b̂él̂óŵ śĥóŵ ýôú ŵh́ât́ r̂éŝóûŕĉéŝ ár̂é l̂óâd́êd́ ŵít̂h́ â h́îǵĥ ṕr̂íôŕît́ŷ. Ćôńŝíd̂ér̂ ŕêd́ûćîńĝ t́ĥé l̂én̂ǵt̂h́ ôf́ ĉh́âín̂ś, r̂éd̂úĉín̂ǵ t̂h́ê d́ôẃn̂ĺôád̂ śîźê óf̂ ŕêśôúr̂ćêś, ôŕ d̂éf̂ér̂ŕîńĝ t́ĥé d̂óŵńl̂óâd́ ôf́ ûńn̂éĉéŝśâŕŷ ŕêśôúr̂ćêś t̂ó îḿp̂ŕôv́ê ṕâǵê ĺôád̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĉŕît́îćâĺ-r̂éq̂úêśt̂-ćĥáîńŝ)." + "message": "T̂h́ê Ćr̂ít̂íĉál̂ Ŕêq́ûéŝt́ Ĉh́âín̂ś b̂él̂óŵ śĥóŵ ýôú ŵh́ât́ r̂éŝóûŕĉéŝ ár̂é l̂óâd́êd́ ŵít̂h́ â h́îǵĥ ṕr̂íôŕît́ŷ. Ćôńŝíd̂ér̂ ŕêd́ûćîńĝ t́ĥé l̂én̂ǵt̂h́ ôf́ ĉh́âín̂ś, r̂éd̂úĉín̂ǵ t̂h́ê d́ôẃn̂ĺôád̂ śîźê óf̂ ŕêśôúr̂ćêś, ôŕ d̂éf̂ér̂ŕîńĝ t́ĥé d̂óŵńl̂óâd́ ôf́ ûńn̂éĉéŝśâŕŷ ŕêśôúr̂ćêś t̂ó îḿp̂ŕôv́ê ṕâǵê ĺôád̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)" + } + } }, "lighthouse-core/audits/critical-request-chains.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ĉh́âín̂ f́ôún̂d́}\n other {# ĉh́âín̂ś f̂óûńd̂}\n }" @@ -498,7 +1548,15 @@ "message": "L̂ín̂é" }, "lighthouse-core/audits/deprecations.js | description": { - "message": "D̂ép̂ŕêćât́êd́ ÂṔÎś ŵíl̂ĺ êv́êńt̂úâĺl̂ý b̂é r̂ém̂óv̂éd̂ f́r̂óm̂ t́ĥé b̂ŕôẃŝér̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://ẃŵẃ.ĉh́r̂óm̂éŝt́ât́ûś.ĉóm̂/f́êát̂úr̂éŝ#d́êṕr̂éĉát̂éd̂)." + "message": "D̂ép̂ŕêćât́êd́ ÂṔÎś ŵíl̂ĺ êv́êńt̂úâĺl̂ý b̂é r̂ém̂óv̂éd̂ f́r̂óm̂ t́ĥé b̂ŕôẃŝér̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://www.chromestatus.com/features#deprecated)" + } + } }, "lighthouse-core/audits/deprecations.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ŵár̂ńîńĝ f́ôún̂d́}\n other {# ŵár̂ńîńĝś f̂óûńd̂}\n }" @@ -510,7 +1568,15 @@ "message": "Âv́ôíd̂ś d̂ép̂ŕêćât́êd́ ÂṔÎś" }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | description": { - "message": "Âṕp̂ĺîćât́îón̂ Ćâćĥé îś d̂ép̂ŕêćât́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/áp̂ṕĉáĉh́ê)." + "message": "Âṕp̂ĺîćât́îón̂ Ćâćĥé îś d̂ép̂ŕêćât́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/appcache)" + } + } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { "message": "F̂óûńd̂ \"{AppCacheManifest}\"" @@ -522,10 +1588,24 @@ "message": "Âv́ôíd̂ś Âṕp̂ĺîćât́îón̂ Ćâćĥé" }, "lighthouse-core/audits/dobetterweb/doctype.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â d́ôćt̂ýp̂é p̂ŕêv́êńt̂ś t̂h́ê b́r̂óŵśêŕ f̂ŕôḿ ŝẃît́ĉh́îńĝ t́ô q́ûír̂ḱŝ-ḿôd́ê. Ŕêád̂ ḿôŕê ón̂ t́ĥé [M̂D́N̂ Ẃêb́ D̂óĉś p̂áĝé](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕ.m̂óẑíl̂ĺâ.ór̂ǵ/êń-ÛŚ/d̂óĉś/Ĝĺôśŝár̂ý/D̂óĉt́ŷṕê)" + "message": "Ŝṕêćîf́ŷín̂ǵ â d́ôćt̂ýp̂é p̂ŕêv́êńt̂ś t̂h́ê b́r̂óŵśêŕ f̂ŕôḿ ŝẃît́ĉh́îńĝ t́ô q́ûír̂ḱŝ-ḿôd́ê. Ŕêád̂ ḿôŕê ón̂ t́ĥé $LINK_START_0$M̂D́N̂ Ẃêb́ D̂óĉś p̂áĝé$LINK_END_0$", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)" + } + } }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationBadDoctype": { - "message": "D̂óĉt́ŷṕê ńâḿê ḿûśt̂ b́ê t́ĥé l̂óŵér̂ćâśê śt̂ŕîńĝ `h́t̂ḿl̂`" + "message": "D̂óĉt́ŷṕê ńâḿê ḿûśt̂ b́ê t́ĥé l̂óŵér̂ćâśê śt̂ŕîńĝ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`html`", + "example": "html" + } + } }, "lighthouse-core/audits/dobetterweb/doctype.js | explanationNoDoctype": { "message": "D̂óĉúm̂én̂t́ m̂úŝt́ ĉón̂t́âín̂ á d̂óĉt́ŷṕê" @@ -552,7 +1632,27 @@ "message": "V̂ál̂úê" }, "lighthouse-core/audits/dobetterweb/dom-size.js | description": { - "message": "B̂ŕôẃŝér̂ én̂ǵîńêér̂ś r̂éĉóm̂ḿêńd̂ ṕâǵêś ĉón̂t́âín̂ f́êẃêŕ t̂h́âń ~1,500 D̂ÓM̂ él̂ém̂én̂t́ŝ. T́ĥé ŝẃêét̂ śp̂ót̂ íŝ á t̂ŕêé d̂ép̂t́ĥ < 32 él̂ém̂én̂t́ŝ án̂d́ f̂éŵér̂ t́ĥán̂ 60 ćĥíl̂d́r̂én̂/ṕâŕêńt̂ él̂ém̂én̂t́.  ĺâŕĝé D̂ÓM̂ ćâń îńĉŕêáŝé m̂ém̂ór̂ý ûśâǵê, ćâúŝé l̂ón̂ǵêŕ [ŝt́ŷĺê ćâĺĉúl̂át̂íôńŝ](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/p̂ér̂f́ôŕm̂án̂ćê/ŕêńd̂ér̂ín̂ǵ/r̂éd̂úĉé-t̂h́ê-śĉóp̂é-âńd̂-ćôḿp̂ĺêx́ît́ŷ-óf̂-śt̂ýl̂é-ĉál̂ćûĺât́îón̂ś), âńd̂ ṕr̂ód̂úĉé ĉóŝt́l̂ý [l̂áŷóût́ r̂éf̂ĺôẃŝ](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/śp̂éêd́/âŕt̂íĉĺêś/r̂éf̂ĺôẃ). [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́ôḿ-ŝíẑé)." + "message": "B̂ŕôẃŝér̂ én̂ǵîńêér̂ś r̂éĉóm̂ḿêńd̂ ṕâǵêś ĉón̂t́âín̂ f́êẃêŕ t̂h́âń ~1,500 D̂ÓM̂ él̂ém̂én̂t́ŝ. T́ĥé ŝẃêét̂ śp̂ót̂ íŝ á t̂ŕêé d̂ép̂t́ĥ < 32 él̂ém̂én̂t́ŝ án̂d́ f̂éŵér̂ t́ĥán̂ 60 ćĥíl̂d́r̂én̂/ṕâŕêńt̂ él̂ém̂én̂t́.  ĺâŕĝé D̂ÓM̂ ćâń îńĉŕêáŝé m̂ém̂ór̂ý ûśâǵê, ćâúŝé l̂ón̂ǵêŕ $LINK_START_0$ŝt́ŷĺê ćâĺĉúl̂át̂íôńŝ$LINK_END_0$, án̂d́ p̂ŕôd́ûćê ćôśt̂ĺŷ $LINK_START_1$ĺâýôút̂ ŕêf́l̂óŵś$LINK_END_1$. $LINK_START_2$L̂éâŕn̂ ḿôŕê$LINK_END_2$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](https://developers.google.com/speed/articles/reflow)" + }, + "LINK_START_2": { + "content": "[" + }, + "LINK_END_2": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/dom-size)" + } + } }, "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 êĺêḿêńt̂}\n other {# él̂ém̂én̂t́ŝ}\n }" @@ -579,7 +1679,23 @@ "message": "T̂ár̂ǵêt́" }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description": { - "message": "Âd́d̂ `ŕêĺ=\"n̂óôṕêńêŕ\"` ôŕ `r̂él̂=\"ńôŕêf́êŕr̂ér̂\"` t́ô án̂ý êx́t̂ér̂ńâĺ l̂ín̂ḱŝ t́ô ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê án̂d́ p̂ŕêv́êńt̂ śêćûŕît́ŷ v́ûĺn̂ér̂áb̂íl̂ít̂íêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ńôóp̂én̂ér̂)." + "message": "Âd́d̂ $MARKDOWN_SNIPPET_0$ ór̂ $MARKDOWN_SNIPPET_1$ t́ô án̂ý êx́t̂ér̂ńâĺ l̂ín̂ḱŝ t́ô ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê án̂d́ p̂ŕêv́êńt̂ śêćûŕît́ŷ v́ûĺn̂ér̂áb̂íl̂ít̂íêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=\"noopener\"`", + "example": "rel=\"noopener\"" + }, + "MARKDOWN_SNIPPET_1": { + "content": "`rel=\"noreferrer\"`", + "example": "rel=\"noreferrer\"" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/noopener)" + } + } }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle": { "message": "L̂ín̂ḱŝ t́ô ćr̂óŝś-ôŕîǵîń d̂éŝt́îńât́îón̂ś âŕê ún̂śâf́ê" @@ -591,7 +1707,15 @@ "message": "Ûńâb́l̂é t̂ó d̂ét̂ér̂ḿîńê t́ĥé d̂éŝt́îńât́îón̂ f́ôŕ âńĉh́ôŕ ({anchorHTML}). Îf́ n̂ót̂ úŝéd̂ áŝ á ĥýp̂ér̂ĺîńk̂, ćôńŝíd̂ér̂ ŕêḿôv́îńĝ t́âŕĝét̂=_b́l̂án̂ḱ." }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĝéôĺôćât́îón̂-ón̂-ĺôád̂)." + "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load)" + } + } }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | failureTitle": { "message": "R̂éq̂úêśt̂ś t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" @@ -612,13 +1736,37 @@ "message": "D̂ét̂éĉt́êd́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ" }, "lighthouse-core/audits/dobetterweb/no-document-write.js | description": { - "message": "F̂ór̂ úŝér̂ś ôń ŝĺôẃ ĉón̂ńêćt̂íôńŝ, éx̂t́êŕn̂ál̂ śĉŕîṕt̂ś d̂ýn̂ám̂íĉál̂ĺŷ ín̂j́êćt̂éd̂ v́îá `d̂óĉúm̂én̂t́.ŵŕît́ê()` ćâń d̂él̂áŷ ṕâǵê ĺôád̂ b́ŷ t́êńŝ óf̂ śêćôńd̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́ôćûḿêńt̂-ẃr̂ít̂é)." + "message": "F̂ór̂ úŝér̂ś ôń ŝĺôẃ ĉón̂ńêćt̂íôńŝ, éx̂t́êŕn̂ál̂ śĉŕîṕt̂ś d̂ýn̂ám̂íĉál̂ĺŷ ín̂j́êćt̂éd̂ v́îá $MARKDOWN_SNIPPET_0$ ĉán̂ d́êĺâý p̂áĝé l̂óâd́ b̂ý t̂én̂ś ôf́ ŝéĉón̂d́ŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/document-write)" + } + } }, "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": { - "message": "Ûśêś `d̂óĉúm̂én̂t́.ŵŕît́ê()`" + "message": "Ûśêś $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + } + } }, "lighthouse-core/audits/dobetterweb/no-document-write.js | title": { - "message": "Âv́ôíd̂ś `d̂óĉúm̂én̂t́.ŵŕît́ê()`" + "message": "Âv́ôíd̂ś $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`document.write()`", + "example": "document.write()" + } + } }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnSeverity": { "message": "Ĥíĝh́êśt̂ Śêv́êŕît́ŷ" @@ -630,7 +1778,15 @@ "message": "V̂úl̂ńêŕâb́îĺît́ŷ Ćôún̂t́" }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description": { - "message": "Ŝóm̂é t̂h́îŕd̂-ṕâŕt̂ý ŝćr̂íp̂t́ŝ ḿâý ĉón̂t́âín̂ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ t́ĥát̂ ár̂é êáŝíl̂ý îd́êńt̂íf̂íêd́ âńd̂ éx̂ṕl̂óît́êd́ b̂ý ât́t̂áĉḱêŕŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/v̂úl̂ńêŕâb́îĺît́îéŝ)." + "message": "Ŝóm̂é t̂h́îŕd̂-ṕâŕt̂ý ŝćr̂íp̂t́ŝ ḿâý ĉón̂t́âín̂ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ t́ĥát̂ ár̂é êáŝíl̂ý îd́êńt̂íf̂íêd́ âńd̂ éx̂ṕl̂óît́êd́ b̂ý ât́t̂áĉḱêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities)" + } + } }, "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 v̂úl̂ńêŕâb́îĺît́ŷ d́êt́êćt̂éd̂}\n other {# v́ûĺn̂ér̂áb̂íl̂ít̂íêś d̂ét̂éĉt́êd́}\n }" @@ -651,7 +1807,15 @@ "message": "Âv́ôíd̂ś f̂ŕôńt̂-én̂d́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ ẃît́ĥ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ" }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ô śêńd̂ ńôt́îf́îćât́îón̂ś ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô úŝér̂ ǵêśt̂úr̂éŝ ín̂śt̂éâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ńôt́îf́îćât́îón̂ś-ôń-l̂óâd́)." + "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ô śêńd̂ ńôt́îf́îćât́îón̂ś ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô úŝér̂ ǵêśt̂úr̂éŝ ín̂śt̂éâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load)" + } + } }, "lighthouse-core/audits/dobetterweb/notification-on-start.js | failureTitle": { "message": "R̂éq̂úêśt̂ś t̂h́ê ńôt́îf́îćât́îón̂ ṕêŕm̂íŝśîón̂ ón̂ ṕâǵê ĺôád̂" @@ -663,7 +1827,15 @@ "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { - "message": "P̂ŕêv́êńt̂ín̂ǵ p̂áŝśŵór̂d́ p̂áŝt́îńĝ ún̂d́êŕm̂ín̂éŝ ǵôód̂ śêćûŕît́ŷ ṕôĺîćŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/p̂áŝśŵór̂d́-p̂áŝt́îńĝ)." + "message": "P̂ŕêv́êńt̂ín̂ǵ p̂áŝśŵór̂d́ p̂áŝt́îńĝ ún̂d́êŕm̂ín̂éŝ ǵôód̂ śêćûŕît́ŷ ṕôĺîćŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/password-pasting)" + } + } }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | failureTitle": { "message": "P̂ŕêv́êńt̂ś ûśêŕŝ t́ô ṕâśt̂é îńt̂ó p̂áŝśŵór̂d́ f̂íêĺd̂ś" @@ -675,7 +1847,15 @@ "message": "P̂ŕôt́ôćôĺ" }, "lighthouse-core/audits/dobetterweb/uses-http2.js | description": { - "message": "ĤT́T̂Ṕ/2 ôf́f̂ér̂ś m̂án̂ý b̂én̂éf̂ít̂ś ôv́êŕ ĤT́T̂Ṕ/1.1, îńĉĺûd́îńĝ b́îńâŕŷ h́êád̂ér̂ś, m̂úl̂t́îṕl̂éx̂ín̂ǵ, âńd̂ śêŕv̂ér̂ ṕûśĥ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĥt́t̂ṕ2)." + "message": "ĤT́T̂Ṕ/2 ôf́f̂ér̂ś m̂án̂ý b̂én̂éf̂ít̂ś ôv́êŕ ĤT́T̂Ṕ/1.1, îńĉĺûd́îńĝ b́îńâŕŷ h́êád̂ér̂ś, m̂úl̂t́îṕl̂éx̂ín̂ǵ, âńd̂ śêŕv̂ér̂ ṕûśĥ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/http2)" + } + } }, "lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 r̂éq̂úêśt̂ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n other {# ŕêq́ûéŝt́ŝ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n }" @@ -687,7 +1867,19 @@ "message": "Ûśêś ĤT́T̂Ṕ/2 f̂ór̂ ít̂ś ôẃn̂ ŕêśôúr̂ćêś" }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description": { - "message": "Ĉón̂śîd́êŕ m̂ár̂ḱîńĝ ýôúr̂ t́ôúĉh́ âńd̂ ẃĥéêĺ êv́êńt̂ ĺîśt̂én̂ér̂ś âś `p̂áŝśîv́ê` t́ô ím̂ṕr̂óv̂é ŷóûŕ p̂áĝé'ŝ śĉŕôĺl̂ ṕêŕf̂ór̂ḿâńĉé. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ṕâśŝív̂é-êv́êńt̂-ĺîśt̂én̂ér̂ś)." + "message": "Ĉón̂śîd́êŕ m̂ár̂ḱîńĝ ýôúr̂ t́ôúĉh́ âńd̂ ẃĥéêĺ êv́êńt̂ ĺîśt̂én̂ér̂ś âś $MARKDOWN_SNIPPET_0$ t̂ó îḿp̂ŕôv́ê ýôúr̂ ṕâǵê'ś ŝćr̂ól̂ĺ p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`passive`", + "example": "passive" + }, + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners)" + } + } }, "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | failureTitle": { "message": "D̂óêś n̂ót̂ úŝé p̂áŝśîv́ê ĺîśt̂én̂ér̂ś t̂ó îḿp̂ŕôv́ê śĉŕôĺl̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê" @@ -708,7 +1900,15 @@ "message": "N̂ó b̂ŕôẃŝér̂ ér̂ŕôŕŝ ĺôǵĝéd̂ t́ô t́ĥé ĉón̂śôĺê" }, "lighthouse-core/audits/font-display.js | description": { - "message": "L̂év̂ér̂áĝé t̂h́ê f́ôńt̂-d́îśp̂ĺâý ĈŚŜ f́êát̂úr̂é t̂ó êńŝúr̂é t̂éx̂t́ îś ûśêŕ-v̂íŝíb̂ĺê ẃĥíl̂é ŵéb̂f́ôńt̂ś âŕê ĺôád̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/ûṕd̂át̂éŝ/2016/02/f́ôńt̂-d́îśp̂ĺâý)." + "message": "L̂év̂ér̂áĝé t̂h́ê f́ôńt̂-d́îśp̂ĺâý ĈŚŜ f́êát̂úr̂é t̂ó êńŝúr̂é t̂éx̂t́ îś ûśêŕ-v̂íŝíb̂ĺê ẃĥíl̂é ŵéb̂f́ôńt̂ś âŕê ĺôád̂ín̂ǵ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/updates/2016/02/font-display)" + } + } }, "lighthouse-core/audits/font-display.js | failureTitle": { "message": "Êńŝúr̂é t̂éx̂t́ r̂ém̂áîńŝ v́îśîb́l̂é d̂úr̂ín̂ǵ ŵéb̂f́ôńt̂ ĺôád̂" @@ -726,7 +1926,15 @@ "message": "Âśp̂éĉt́ R̂át̂íô (D́îśp̂ĺâýêd́)" }, "lighthouse-core/audits/image-aspect-ratio.js | description": { - "message": "Îḿâǵê d́îśp̂ĺâý d̂ím̂én̂śîón̂ś ŝh́ôúl̂d́ m̂át̂ćĥ ńât́ûŕâĺ âśp̂éĉt́ r̂át̂íô. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/âśp̂éĉt́-r̂át̂íô)." + "message": "Îḿâǵê d́îśp̂ĺâý d̂ím̂én̂śîón̂ś ŝh́ôúl̂d́ m̂át̂ćĥ ńât́ûŕâĺ âśp̂éĉt́ r̂át̂íô. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio)" + } + } }, "lighthouse-core/audits/image-aspect-ratio.js | failureTitle": { "message": "D̂íŝṕl̂áŷś îḿâǵêś ŵít̂h́ îńĉór̂ŕêćt̂ áŝṕêćt̂ ŕât́îó" @@ -741,7 +1949,15 @@ "message": "Îńŝéĉúr̂é ÛŔL̂" }, "lighthouse-core/audits/is-on-https.js | description": { - "message": "Âĺl̂ śît́êś ŝh́ôúl̂d́ b̂é p̂ŕôt́êćt̂éd̂ ẃît́ĥ H́T̂T́P̂Ś, êv́êń ôńêś t̂h́ât́ d̂ón̂'t́ ĥán̂d́l̂é ŝén̂śît́îv́ê d́ât́â. H́T̂T́P̂Ś p̂ŕêv́êńt̂ś îńt̂ŕûd́êŕŝ f́r̂óm̂ t́âḿp̂ér̂ín̂ǵ ŵít̂h́ ôŕ p̂áŝśîv́êĺŷ ĺîśt̂én̂ín̂ǵ îń ôń t̂h́ê ćôḿm̂ún̂íĉát̂íôńŝ b́êt́ŵéêń ŷóûŕ âṕp̂ án̂d́ ŷóûŕ ûśêŕŝ, án̂d́ îś â ṕr̂ér̂éq̂úîśît́ê f́ôŕ ĤT́T̂Ṕ/2 âńd̂ ḿâńŷ ńêẃ ŵéb̂ ṕl̂át̂f́ôŕm̂ ÁP̂Íŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĥt́t̂ṕŝ)." + "message": "Âĺl̂ śît́êś ŝh́ôúl̂d́ b̂é p̂ŕôt́êćt̂éd̂ ẃît́ĥ H́T̂T́P̂Ś, êv́êń ôńêś t̂h́ât́ d̂ón̂'t́ ĥán̂d́l̂é ŝén̂śît́îv́ê d́ât́â. H́T̂T́P̂Ś p̂ŕêv́êńt̂ś îńt̂ŕûd́êŕŝ f́r̂óm̂ t́âḿp̂ér̂ín̂ǵ ŵít̂h́ ôŕ p̂áŝśîv́êĺŷ ĺîśt̂én̂ín̂ǵ îń ôń t̂h́ê ćôḿm̂ún̂íĉát̂íôńŝ b́êt́ŵéêń ŷóûŕ âṕp̂ án̂d́ ŷóûŕ ûśêŕŝ, án̂d́ îś â ṕr̂ér̂éq̂úîśît́ê f́ôŕ ĤT́T̂Ṕ/2 âńd̂ ḿâńŷ ńêẃ ŵéb̂ ṕl̂át̂f́ôŕm̂ ÁP̂Íŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/https)" + } + } }, "lighthouse-core/audits/is-on-https.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 îńŝéĉúr̂é r̂éq̂úêśt̂ f́ôún̂d́}\n other {# îńŝéĉúr̂é r̂éq̂úêśt̂ś f̂óûńd̂}\n }" @@ -753,13 +1969,33 @@ "message": "Ûśêś ĤT́T̂ṔŜ" }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { - "message": " f́âśt̂ ṕâǵê ĺôád̂ óv̂ér̂ á ĉél̂ĺûĺâŕ n̂ét̂ẃôŕk̂ én̂śûŕêś â ǵôód̂ ḿôb́îĺê úŝér̂ éx̂ṕêŕîén̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂áŝt́-3ĝ)." + "message": " f́âśt̂ ṕâǵê ĺôád̂ óv̂ér̂ á ĉél̂ĺûĺâŕ n̂ét̂ẃôŕk̂ én̂śûŕêś â ǵôód̂ ḿôb́îĺê úŝér̂ éx̂ṕêŕîén̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { - "message": "Îńt̂ér̂áĉt́îv́ê át̂ {timeInMs, number, seconds} ś" + "message": "Îńt̂ér̂áĉt́îv́ê át̂ $COMPLEX_ICU_0$ ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueTextWithOverride": { - "message": "Îńt̂ér̂áĉt́îv́ê ón̂ śîḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂ át̂ {timeInMs, number, seconds} ś" + "message": "Îńt̂ér̂áĉt́îv́ê ón̂ śîḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂ át̂ $COMPLEX_ICU_0$ ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": { "message": "P̂áĝé l̂óâd́ îś n̂ót̂ f́âśt̂ én̂óûǵĥ ón̂ ḿôb́îĺê ńêt́ŵór̂ḱŝ" @@ -780,55 +2016,127 @@ "message": "M̂ín̂ím̂íẑéŝ ḿâín̂-t́ĥŕêád̂ ẃôŕk̂" }, "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { - "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/éŝt́îḿât́êd́-îńp̂út̂-ĺât́êńĉý)." + "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)" + } + } }, "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ" }, "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { - "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́ m̂ár̂ḱŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ t́ĥé f̂ír̂śt̂ t́êx́t̂ ór̂ ím̂áĝé îś p̂áîńt̂éd̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ír̂śt̂-ćôńt̂én̂t́f̂úl̂-ṕâín̂t́)." + "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́ m̂ár̂ḱŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ t́ĥé f̂ír̂śt̂ t́êx́t̂ ór̂ ím̂áĝé îś p̂áîńt̂éd̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)" + } + } }, "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́" }, "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { - "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é m̂ár̂ḱŝ t́ĥé f̂ír̂śt̂ t́îḿê át̂ ẃĥíĉh́ t̂h́ê ṕâǵê'ś m̂áîń t̂h́r̂éâd́ îś q̂úîét̂ én̂óûǵĥ t́ô h́âńd̂ĺê ín̂ṕût́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/f́îŕŝt́-îńt̂ér̂áĉt́îv́ê)." + "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é m̂ár̂ḱŝ t́ĥé f̂ír̂śt̂ t́îḿê át̂ ẃĥíĉh́ t̂h́ê ṕâǵê'ś m̂áîń t̂h́r̂éâd́ îś q̂úîét̂ én̂óûǵĥ t́ô h́âńd̂ĺê ín̂ṕût́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)" + } + } }, "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é" }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { - "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́ m̂éâśûŕêś ŵh́êń t̂h́ê ṕr̂ím̂ár̂ý ĉón̂t́êńt̂ óf̂ á p̂áĝé îś v̂íŝíb̂ĺê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ír̂śt̂-ḿêán̂ín̂ǵf̂úl̂-ṕâín̂t́)." + "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́ m̂éâśûŕêś ŵh́êń t̂h́ê ṕr̂ím̂ár̂ý ĉón̂t́êńt̂ óf̂ á p̂áĝé îś v̂íŝíb̂ĺê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)" + } + } }, "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́" }, "lighthouse-core/audits/metrics/interactive.js | description": { - "message": "T̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê íŝ t́ĥé âḿôún̂t́ ôf́ t̂ím̂é ît́ t̂ák̂éŝ f́ôŕ t̂h́ê ṕâǵê t́ô b́êćôḿê f́ûĺl̂ý îńt̂ér̂áĉt́îv́ê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ĉón̂śîśt̂én̂t́l̂ý-îńt̂ér̂áĉt́îv́ê)." + "message": "T̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê íŝ t́ĥé âḿôún̂t́ ôf́ t̂ím̂é ît́ t̂ák̂éŝ f́ôŕ t̂h́ê ṕâǵê t́ô b́êćôḿê f́ûĺl̂ý îńt̂ér̂áĉt́îv́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)" + } + } }, "lighthouse-core/audits/metrics/interactive.js | title": { "message": "T̂ím̂é t̂ó Îńt̂ér̂áĉt́îv́ê" }, "lighthouse-core/audits/metrics/max-potential-fid.js | description": { - "message": "T̂h́ê ḿâx́îḿûḿ p̂ót̂én̂t́îál̂ F́îŕŝt́ Îńp̂út̂ D́êĺâý t̂h́ât́ ŷóûŕ ûśêŕŝ ćôúl̂d́ êx́p̂ér̂íêńĉé îś t̂h́ê d́ûŕât́îón̂, ín̂ ḿîĺl̂íŝéĉón̂d́ŝ, óf̂ t́ĥé l̂ón̂ǵêśt̂ t́âśk̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/úp̂d́ât́êś/2018/05/f̂ír̂śt̂-ín̂ṕût́-d̂él̂áŷ)." + "message": "T̂h́ê ḿâx́îḿûḿ p̂ót̂én̂t́îál̂ F́îŕŝt́ Îńp̂út̂ D́êĺâý t̂h́ât́ ŷóûŕ ûśêŕŝ ćôúl̂d́ êx́p̂ér̂íêńĉé îś t̂h́ê d́ûŕât́îón̂, ín̂ ḿîĺl̂íŝéĉón̂d́ŝ, óf̂ t́ĥé l̂ón̂ǵêśt̂ t́âśk̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/updates/2018/05/first-input-delay)" + } + } }, "lighthouse-core/audits/metrics/max-potential-fid.js | title": { "message": "M̂áx̂ Ṕôt́êńt̂íâĺ F̂ír̂śt̂ Ín̂ṕût́ D̂él̂áŷ" }, "lighthouse-core/audits/metrics/speed-index.js | description": { - "message": "Ŝṕêéd̂ Ín̂d́êx́ ŝh́ôẃŝ h́ôẃ q̂úîćk̂ĺŷ t́ĥé ĉón̂t́êńt̂ś ôf́ â ṕâǵê ár̂é v̂íŝíb̂ĺŷ ṕôṕûĺât́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/śp̂éêd́-îńd̂éx̂)." + "message": "Ŝṕêéd̂ Ín̂d́êx́ ŝh́ôẃŝ h́ôẃ q̂úîćk̂ĺŷ t́ĥé ĉón̂t́êńt̂ś ôf́ â ṕâǵê ár̂é v̂íŝíb̂ĺŷ ṕôṕûĺât́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/speed-index)" + } + } }, "lighthouse-core/audits/metrics/speed-index.js | title": { "message": "Ŝṕêéd̂ Ín̂d́êx́" }, "lighthouse-core/audits/network-rtt.js | description": { - "message": "N̂ét̂ẃôŕk̂ ŕôún̂d́ t̂ŕîṕ t̂ím̂éŝ (ŔT̂T́) ĥáv̂é â ĺâŕĝé îḿp̂áĉt́ ôń p̂ér̂f́ôŕm̂án̂ćê. Íf̂ t́ĥé R̂T́T̂ t́ô án̂ ór̂íĝín̂ íŝ h́îǵĥ, ít̂'ś âń îńd̂íĉát̂íôń t̂h́ât́ ŝér̂v́êŕŝ ćl̂óŝér̂ t́ô t́ĥé ûśêŕ ĉóûĺd̂ ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://h́p̂b́n̂.ćô/ṕr̂ím̂ér̂-ón̂-ĺât́êńĉý-âńd̂-b́âńd̂ẃîd́t̂h́/)." + "message": "N̂ét̂ẃôŕk̂ ŕôún̂d́ t̂ŕîṕ t̂ím̂éŝ (ŔT̂T́) ĥáv̂é â ĺâŕĝé îḿp̂áĉt́ ôń p̂ér̂f́ôŕm̂án̂ćê. Íf̂ t́ĥé R̂T́T̂ t́ô án̂ ór̂íĝín̂ íŝ h́îǵĥ, ít̂'ś âń îńd̂íĉát̂íôń t̂h́ât́ ŝér̂v́êŕŝ ćl̂óŝér̂ t́ô t́ĥé ûśêŕ ĉóûĺd̂ ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://hpbn.co/primer-on-latency-and-bandwidth/)" + } + } }, "lighthouse-core/audits/network-rtt.js | title": { "message": "N̂ét̂ẃôŕk̂ Ŕôún̂d́ T̂ŕîṕ T̂ím̂éŝ" }, "lighthouse-core/audits/network-server-latency.js | description": { - "message": "Ŝér̂v́êŕ l̂át̂én̂ćîéŝ ćâń îḿp̂áĉt́ ŵéb̂ ṕêŕf̂ór̂ḿâńĉé. Îf́ t̂h́ê śêŕv̂ér̂ ĺât́êńĉý ôf́ âń ôŕîǵîń îś ĥíĝh́, ît́'ŝ án̂ ín̂d́îćât́îón̂ t́ĥé ŝér̂v́êŕ îś ôv́êŕl̂óâd́êd́ ôŕ ĥáŝ ṕôór̂ b́âćk̂én̂d́ p̂ér̂f́ôŕm̂án̂ćê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://h́p̂b́n̂.ćô/ṕr̂ím̂ér̂-ón̂-ẃêb́-p̂ér̂f́ôŕm̂án̂ćê/#án̂ál̂ýẑín̂ǵ-t̂h́ê-ŕêśôúr̂ćê-ẃât́êŕf̂ál̂ĺ)." + "message": "Ŝér̂v́êŕ l̂át̂én̂ćîéŝ ćâń îḿp̂áĉt́ ŵéb̂ ṕêŕf̂ór̂ḿâńĉé. Îf́ t̂h́ê śêŕv̂ér̂ ĺât́êńĉý ôf́ âń ôŕîǵîń îś ĥíĝh́, ît́'ŝ án̂ ín̂d́îćât́îón̂ t́ĥé ŝér̂v́êŕ îś ôv́êŕl̂óâd́êd́ ôŕ ĥáŝ ṕôór̂ b́âćk̂én̂d́ p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)" + } + } }, "lighthouse-core/audits/network-server-latency.js | title": { "message": "Ŝér̂v́êŕ B̂áĉḱêńd̂ Ĺât́êńĉíêś" @@ -837,7 +2145,15 @@ "message": "Ôv́êŕ B̂úd̂ǵêt́" }, "lighthouse-core/audits/performance-budget.js | description": { - "message": "K̂éêṕ t̂h́ê q́ûán̂t́ît́ŷ án̂d́ ŝíẑé ôf́ n̂ét̂ẃôŕk̂ ŕêq́ûéŝt́ŝ ún̂d́êŕ t̂h́ê t́âŕĝét̂ś ŝét̂ b́ŷ t́ĥé p̂ŕôv́îd́êd́ p̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/b̂úd̂ǵêt́ŝ)." + "message": "K̂éêṕ t̂h́ê q́ûán̂t́ît́ŷ án̂d́ ŝíẑé ôf́ n̂ét̂ẃôŕk̂ ŕêq́ûéŝt́ŝ ún̂d́êŕ t̂h́ê t́âŕĝét̂ś ŝét̂ b́ŷ t́ĥé p̂ŕôv́îd́êd́ p̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" + } + } }, "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { "message": "{count, plural,\n =1 {1 r̂éq̂úêśt̂}\n other {# ŕêq́ûéŝt́ŝ}\n }" @@ -846,13 +2162,29 @@ "message": "P̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂" }, "lighthouse-core/audits/redirects.js | description": { - "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ŕêd́îŕêćt̂ś)." + "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/redirects)" + } + } }, "lighthouse-core/audits/redirects.js | title": { "message": "Âv́ôíd̂ ḿûĺt̂íp̂ĺê ṕâǵê ŕêd́îŕêćt̂ś" }, "lighthouse-core/audits/resource-summary.js | description": { - "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/b́ûd́ĝét̂ś)." + "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" + } + } }, "lighthouse-core/audits/resource-summary.js | displayValue": { "message": "{requestCount, plural, =1 {1 r̂éq̂úêśt̂} other {# ŕêq́ûéŝt́ŝ}} • { byteCount, number, bytes } ḰB̂" @@ -861,7 +2193,15 @@ "message": "K̂éêṕ r̂éq̂úêśt̂ ćôún̂t́ŝ ĺôẃ âńd̂ t́r̂án̂śf̂ér̂ śîźêś ŝḿâĺl̂" }, "lighthouse-core/audits/seo/canonical.js | description": { - "message": "Ĉán̂ón̂íĉál̂ ĺîńk̂ś ŝúĝǵêśt̂ ẃĥíĉh́ ÛŔL̂ t́ô śĥóŵ ín̂ śêár̂ćĥ ŕêśûĺt̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ćâńôńîćâĺ)." + "message": "Ĉán̂ón̂íĉál̂ ĺîńk̂ś ŝúĝǵêśt̂ ẃĥíĉh́ ÛŔL̂ t́ô śĥóŵ ín̂ śêár̂ćĥ ŕêśûĺt̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/canonical)" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationConflict": { "message": "M̂úl̂t́îṕl̂é ĉón̂f́l̂íĉt́îńĝ ÚR̂Ĺŝ ({urlList})" @@ -873,7 +2213,13 @@ "message": "Îńv̂ál̂íd̂ ÚR̂Ĺ ({url})" }, "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ `h́r̂éf̂ĺâńĝ` ĺôćât́îón̂ ({url})" + "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ $MARKDOWN_SNIPPET_0$ ĺôćât́îón̂ ({url})", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationRelative": { "message": "R̂él̂át̂ív̂é ÛŔL̂ ({url})" @@ -882,25 +2228,67 @@ "message": "P̂óîńt̂ś t̂ó t̂h́ê d́ôḿâín̂'ś r̂óôt́ ÛŔL̂ (t́ĥé ĥóm̂ép̂áĝé), îńŝt́êád̂ óf̂ án̂ éq̂úîv́âĺêńt̂ ṕâǵê óf̂ ćôńt̂én̂t́" }, "lighthouse-core/audits/seo/canonical.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á v̂ál̂íd̂ `ŕêĺ=ĉán̂ón̂íĉál̂`" + "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=canonical`", + "example": "rel=canonical" + } + } }, "lighthouse-core/audits/seo/canonical.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `ŕêĺ=ĉán̂ón̂íĉál̂`" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`rel=canonical`", + "example": "rel=canonical" + } + } }, "lighthouse-core/audits/seo/font-size.js | description": { - "message": "F̂ón̂t́ ŝíẑéŝ ĺêśŝ t́ĥán̂ 12ṕx̂ ár̂é t̂óô śm̂ál̂ĺ t̂ó b̂é l̂éĝíb̂ĺê án̂d́ r̂éq̂úîŕê ḿôb́îĺê v́îśît́ôŕŝ t́ô “ṕîńĉh́ t̂ó ẑóôḿ” îń ôŕd̂ér̂ t́ô ŕêád̂. Śt̂ŕîv́ê t́ô h́âv́ê >60% óf̂ ṕâǵê t́êx́t̂ ≥12ṕx̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/f̂ón̂t́-ŝíẑéŝ)." + "message": "F̂ón̂t́ ŝíẑéŝ ĺêśŝ t́ĥán̂ 12ṕx̂ ár̂é t̂óô śm̂ál̂ĺ t̂ó b̂é l̂éĝíb̂ĺê án̂d́ r̂éq̂úîŕê ḿôb́îĺê v́îśît́ôŕŝ t́ô “ṕîńĉh́ t̂ó ẑóôḿ” îń ôŕd̂ér̂ t́ô ŕêád̂. Śt̂ŕîv́ê t́ô h́âv́ê >60% óf̂ ṕâǵê t́êx́t̂ ≥12ṕx̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)" + } + } }, "lighthouse-core/audits/seo/font-size.js | displayValue": { - "message": "{decimalProportion, number, extendedPercent} l̂éĝíb̂ĺê t́êx́t̂" + "message": "$COMPLEX_ICU_0$ l̂éĝíb̂ĺê t́êx́t̂", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | explanation": { - "message": "{decimalProportion, number, extendedPercent} ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ." + "message": "$COMPLEX_ICU_0$ ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ.", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | explanationViewport": { "message": "T̂éx̂t́ îś îĺl̂éĝíb̂ĺê b́êćâúŝé t̂h́êŕê'ś n̂ó v̂íêẃp̂ór̂t́ m̂ét̂á t̂áĝ óp̂t́îḿîźêd́ f̂ór̂ ḿôb́îĺê śĉŕêén̂ś." }, "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": { - "message": "{decimalProportion, number, extendedPercent} ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ (b̂áŝéd̂ ón̂ {decimalProportionVisited, number, extendedPercent} śâḿp̂ĺê)." + "message": "$COMPLEX_ICU_0$ ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ (b̂áŝéd̂ ón̂ $COMPLEX_ICU_1$ śâḿp̂ĺê).", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, extendedPercent}", + "example": "37.92%" + }, + "COMPLEX_ICU_1": { + "content": "{decimalProportionVisited, number, extendedPercent}", + "example": "37.92%" + } + } }, "lighthouse-core/audits/seo/font-size.js | failureTitle": { "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ûśê ĺêǵîb́l̂é f̂ón̂t́ ŝíẑéŝ" @@ -909,16 +2297,44 @@ "message": "D̂óĉúm̂én̂t́ ûśêś l̂éĝíb̂ĺê f́ôńt̂ śîźêś" }, "lighthouse-core/audits/seo/hreflang.js | description": { - "message": "ĥŕêf́l̂án̂ǵ l̂ín̂ḱŝ t́êĺl̂ śêár̂ćĥ én̂ǵîńêś ŵh́ât́ v̂ér̂śîón̂ óf̂ á p̂áĝé t̂h́êý ŝh́ôúl̂d́ l̂íŝt́ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ f́ôŕ â ǵîv́êń l̂án̂ǵûáĝé ôŕ r̂éĝíôń. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/h́r̂éf̂ĺâńĝ)." + "message": "ĥŕêf́l̂án̂ǵ l̂ín̂ḱŝ t́êĺl̂ śêár̂ćĥ én̂ǵîńêś ŵh́ât́ v̂ér̂śîón̂ óf̂ á p̂áĝé t̂h́êý ŝh́ôúl̂d́ l̂íŝt́ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ f́ôŕ â ǵîv́êń l̂án̂ǵûáĝé ôŕ r̂éĝíôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/hreflang)" + } + } }, "lighthouse-core/audits/seo/hreflang.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â v́âĺîd́ `ĥŕêf́l̂án̂ǵ`" + "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â v́âĺîd́ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/hreflang.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ `h́r̂éf̂ĺâńĝ`" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`hreflang`", + "example": "hreflang" + } + } }, "lighthouse-core/audits/seo/http-status-code.js | description": { - "message": "P̂áĝéŝ ẃît́ĥ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́êś m̂áŷ ńôt́ b̂é îńd̂éx̂éd̂ ṕr̂óp̂ér̂ĺŷ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ŝúĉćêśŝf́ûĺ-ĥt́t̂ṕ-ĉód̂é)." + "message": "P̂áĝéŝ ẃît́ĥ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́êś m̂áŷ ńôt́ b̂é îńd̂éx̂éd̂ ṕr̂óp̂ér̂ĺŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)" + } + } }, "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { "message": "P̂áĝé ĥáŝ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" @@ -927,7 +2343,15 @@ "message": "P̂áĝé ĥáŝ śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" }, "lighthouse-core/audits/seo/is-crawlable.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ár̂é ûńâb́l̂é t̂ó îńĉĺûd́ê ýôúr̂ ṕâǵêś îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ íf̂ t́ĥéŷ d́ôń't̂ h́âv́ê ṕêŕm̂íŝśîón̂ t́ô ćr̂áŵĺ t̂h́êḿ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ín̂d́êx́îńĝ)." + "message": "Ŝéâŕĉh́ êńĝín̂éŝ ár̂é ûńâb́l̂é t̂ó îńĉĺûd́ê ýôúr̂ ṕâǵêś îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ íf̂ t́ĥéŷ d́ôń't̂ h́âv́ê ṕêŕm̂íŝśîón̂ t́ô ćr̂áŵĺ t̂h́êḿ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/indexing)" + } + } }, "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { "message": "P̂áĝé îś b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" @@ -936,7 +2360,15 @@ "message": "P̂áĝé îśn̂’t́ b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" }, "lighthouse-core/audits/seo/link-text.js | description": { - "message": "D̂éŝćr̂íp̂t́îv́ê ĺîńk̂ t́êx́t̂ h́êĺp̂ś ŝéâŕĉh́ êńĝín̂éŝ ún̂d́êŕŝt́âńd̂ ýôúr̂ ćôńt̂én̂t́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/d́êśĉŕîṕt̂ív̂é-l̂ín̂ḱ-t̂éx̂t́)." + "message": "D̂éŝćr̂íp̂t́îv́ê ĺîńk̂ t́êx́t̂ h́êĺp̂ś ŝéâŕĉh́ êńĝín̂éŝ ún̂d́êŕŝt́âńd̂ ýôúr̂ ćôńt̂én̂t́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)" + } + } }, "lighthouse-core/audits/seo/link-text.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 l̂ín̂ḱ f̂óûńd̂}\n other {# ĺîńk̂ś f̂óûńd̂}\n }" @@ -948,13 +2380,41 @@ "message": "L̂ín̂ḱŝ h́âv́ê d́êśĉŕîṕt̂ív̂é t̂éx̂t́" }, "lighthouse-core/audits/seo/manual/structured-data.js | description": { - "message": "R̂ún̂ t́ĥé [Ŝt́r̂úĉt́ûŕêd́ D̂át̂á T̂éŝt́îńĝ T́ôól̂](h́t̂t́p̂ś://ŝéâŕĉh́.ĝóôǵl̂é.ĉóm̂/śt̂ŕûćt̂úr̂éd̂-d́ât́â/t́êśt̂ín̂ǵ-t̂óôĺ/) âńd̂ t́ĥé [Ŝt́r̂úĉt́ûŕêd́ D̂át̂á L̂ín̂t́êŕ](ĥt́t̂ṕ://l̂ín̂t́êŕ.ŝt́r̂úĉt́ûŕêd́-d̂át̂á.ôŕĝ/) t́ô v́âĺîd́ât́ê śt̂ŕûćt̂úr̂éd̂ d́ât́â. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŝéâŕĉh́/d̂óĉś/ĝúîd́êś/m̂ár̂ḱ-ûṕ-ĉón̂t́êńt̂)." + "message": "R̂ún̂ t́ĥé $LINK_START_0$Ŝt́r̂úĉt́ûŕêd́ D̂át̂á T̂éŝt́îńĝ T́ôól̂$LINK_END_0$ án̂d́ t̂h́ê $LINK_START_1$Śt̂ŕûćt̂úr̂éd̂ D́ât́â Ĺîńt̂ér̂$LINK_END_1$ t́ô v́âĺîd́ât́ê śt̂ŕûćt̂úr̂éd̂ d́ât́â. $LINK_START_2$Ĺêár̂ń m̂ór̂é$LINK_END_2$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://search.google.com/structured-data/testing-tool/)" + }, + "LINK_START_1": { + "content": "[" + }, + "LINK_END_1": { + "content": "](http://linter.structured-data.org/)" + }, + "LINK_START_2": { + "content": "[" + }, + "LINK_END_2": { + "content": "](https://developers.google.com/search/docs/guides/mark-up-content)" + } + } }, "lighthouse-core/audits/seo/manual/structured-data.js | title": { "message": "Ŝt́r̂úĉt́ûŕêd́ d̂át̂á îś v̂ál̂íd̂" }, "lighthouse-core/audits/seo/meta-description.js | description": { - "message": "M̂ét̂á d̂éŝćr̂íp̂t́îón̂ś m̂áŷ b́ê ín̂ćl̂úd̂éd̂ ín̂ śêár̂ćĥ ŕêśûĺt̂ś t̂ó ĉón̂ćîśêĺŷ śûḿm̂ár̂íẑé p̂áĝé ĉón̂t́êńt̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/d̂éŝćr̂íp̂t́îón̂)." + "message": "M̂ét̂á d̂éŝćr̂íp̂t́îón̂ś m̂áŷ b́ê ín̂ćl̂úd̂éd̂ ín̂ śêár̂ćĥ ŕêśûĺt̂ś t̂ó ĉón̂ćîśêĺŷ śûḿm̂ár̂íẑé p̂áĝé ĉón̂t́êńt̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/description)" + } + } }, "lighthouse-core/audits/seo/meta-description.js | explanation": { "message": "D̂éŝćr̂íp̂t́îón̂ t́êx́t̂ íŝ ém̂ṕt̂ý." @@ -966,7 +2426,15 @@ "message": "D̂óĉúm̂én̂t́ ĥáŝ á m̂ét̂á d̂éŝćr̂íp̂t́îón̂" }, "lighthouse-core/audits/seo/plugins.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ćâń't̂ ín̂d́êx́ p̂ĺûǵîń ĉón̂t́êńt̂, án̂d́ m̂án̂ý d̂év̂íĉéŝ ŕêśt̂ŕîćt̂ ṕl̂úĝín̂ś ôŕ d̂ón̂'t́ ŝúp̂ṕôŕt̂ t́ĥém̂. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/p̂ĺûǵîńŝ)." + "message": "Ŝéâŕĉh́ êńĝín̂éŝ ćâń't̂ ín̂d́êx́ p̂ĺûǵîń ĉón̂t́êńt̂, án̂d́ m̂án̂ý d̂év̂íĉéŝ ŕêśt̂ŕîćt̂ ṕl̂úĝín̂ś ôŕ d̂ón̂'t́ ŝúp̂ṕôŕt̂ t́ĥém̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/plugins)" + } + } }, "lighthouse-core/audits/seo/plugins.js | failureTitle": { "message": "D̂óĉúm̂én̂t́ ûśêś p̂ĺûǵîńŝ" @@ -993,10 +2461,24 @@ "message": "r̂ób̂ót̂ś.t̂x́t̂ íŝ v́âĺîd́" }, "lighthouse-core/audits/seo/tap-targets.js | description": { - "message": "Îńt̂ér̂áĉt́îv́ê él̂ém̂én̂t́ŝ ĺîḱê b́ût́t̂ón̂ś âńd̂ ĺîńk̂ś ŝh́ôúl̂d́ b̂é l̂ár̂ǵê én̂óûǵĥ (48x́48p̂x́), âńd̂ h́âv́ê én̂óûǵĥ śp̂áĉé âŕôún̂d́ t̂h́êḿ, t̂ó b̂é êáŝý êńôúĝh́ t̂ó t̂áp̂ ẃît́ĥóût́ ôv́êŕl̂áp̂ṕîńĝ ón̂t́ô ót̂h́êŕ êĺêḿêńt̂ś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/f̂ún̂d́âḿêńt̂ál̂ś/âćĉéŝśîb́îĺît́ŷ/áĉćêśŝíb̂ĺê-śt̂ýl̂éŝ#ḿûĺt̂í-d̂év̂íĉé_r̂éŝṕôńŝív̂é_d̂éŝíĝń)." + "message": "Îńt̂ér̂áĉt́îv́ê él̂ém̂én̂t́ŝ ĺîḱê b́ût́t̂ón̂ś âńd̂ ĺîńk̂ś ŝh́ôúl̂d́ b̂é l̂ár̂ǵê én̂óûǵĥ (48x́48p̂x́), âńd̂ h́âv́ê én̂óûǵĥ śp̂áĉé âŕôún̂d́ t̂h́êḿ, t̂ó b̂é êáŝý êńôúĝh́ t̂ó t̂áp̂ ẃît́ĥóût́ ôv́êŕl̂áp̂ṕîńĝ ón̂t́ô ót̂h́êŕ êĺêḿêńt̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)" + } + } }, "lighthouse-core/audits/seo/tap-targets.js | displayValue": { - "message": "{decimalProportion, number, percent} âṕp̂ŕôṕr̂íât́êĺŷ śîźêd́ t̂áp̂ t́âŕĝét̂ś" + "message": "$COMPLEX_ICU_0$ âṕp̂ŕôṕr̂íât́êĺŷ śîźêd́ t̂áp̂ t́âŕĝét̂ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{decimalProportion, number, percent}", + "example": "54.6%" + } + } }, "lighthouse-core/audits/seo/tap-targets.js | explanationViewportMetaNotOptimized": { "message": "T̂áp̂ t́âŕĝét̂ś âŕê t́ôó ŝḿâĺl̂ b́êćâúŝé t̂h́êŕê'ś n̂ó v̂íêẃp̂ór̂t́ m̂ét̂á t̂áĝ óp̂t́îḿîźêd́ f̂ór̂ ḿôb́îĺê śĉŕêén̂ś" @@ -1023,7 +2505,15 @@ "message": "T̂h́îŕd̂-Ṕâŕt̂ý" }, "lighthouse-core/audits/third-party-summary.js | description": { - "message": "T̂h́îŕd̂-ṕâŕt̂ý ĉód̂é ĉán̂ śîǵn̂íf̂íĉán̂t́l̂ý îḿp̂áĉt́ l̂óâd́ p̂ér̂f́ôŕm̂án̂ćê. Ĺîḿît́ t̂h́ê ńûḿb̂ér̂ óf̂ ŕêd́ûńd̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý p̂ŕôv́îd́êŕŝ án̂d́ t̂ŕŷ t́ô ĺôád̂ t́ĥír̂d́-p̂ár̂t́ŷ ćôd́ê áf̂t́êŕ ŷóûŕ p̂áĝé ĥáŝ ṕr̂ím̂ár̂íl̂ý f̂ín̂íŝh́êd́ l̂óâd́îńĝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/ṕêŕf̂ór̂ḿâńĉé/ôṕt̂ím̂íẑín̂ǵ-ĉón̂t́êńt̂-éf̂f́îćîén̂ćŷ/ĺôád̂ín̂ǵ-t̂h́îŕd̂-ṕâŕt̂ý-ĵáv̂áŝćr̂íp̂t́/)." + "message": "T̂h́îŕd̂-ṕâŕt̂ý ĉód̂é ĉán̂ śîǵn̂íf̂íĉán̂t́l̂ý îḿp̂áĉt́ l̂óâd́ p̂ér̂f́ôŕm̂án̂ćê. Ĺîḿît́ t̂h́ê ńûḿb̂ér̂ óf̂ ŕêd́ûńd̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý p̂ŕôv́îd́êŕŝ án̂d́ t̂ŕŷ t́ô ĺôád̂ t́ĥír̂d́-p̂ár̂t́ŷ ćôd́ê áf̂t́êŕ ŷóûŕ p̂áĝé ĥáŝ ṕr̂ím̂ár̂íl̂ý f̂ín̂íŝh́êd́ l̂óâd́îńĝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)" + } + } }, "lighthouse-core/audits/third-party-summary.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 T̂h́îŕd̂-Ṕâŕt̂ý F̂óûńd̂}\n other {# T́ĥír̂d́-P̂ár̂t́îéŝ F́ôún̂d́}\n }" @@ -1032,10 +2522,24 @@ "message": "T̂h́îŕd̂-Ṕâŕt̂ý Ûśâǵê" }, "lighthouse-core/audits/time-to-first-byte.js | description": { - "message": "T̂ím̂é T̂ó F̂ír̂śt̂ B́ŷt́ê íd̂én̂t́îf́îéŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ ýôúr̂ śêŕv̂ér̂ śêńd̂ś â ŕêśp̂ón̂śê. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/t̂t́f̂b́)." + "message": "T̂ím̂é T̂ó F̂ír̂śt̂ B́ŷt́ê íd̂én̂t́îf́îéŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ ýôúr̂ śêŕv̂ér̂ śêńd̂ś â ŕêśp̂ón̂śê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/ttfb)" + } + } }, "lighthouse-core/audits/time-to-first-byte.js | displayValue": { - "message": "R̂óôt́ d̂óĉúm̂én̂t́ t̂óôḱ {timeInMs, number, milliseconds} m̂ś" + "message": "R̂óôt́ d̂óĉúm̂én̂t́ t̂óôḱ $COMPLEX_ICU_0$ m̂ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/audits/time-to-first-byte.js | failureTitle": { "message": "R̂éd̂úĉé ŝér̂v́êŕ r̂éŝṕôńŝé t̂ím̂éŝ (T́T̂F́B̂)" @@ -1056,7 +2560,15 @@ "message": "T̂ýp̂é" }, "lighthouse-core/audits/user-timings.js | description": { - "message": "Ĉón̂śîd́êŕ îńŝt́r̂úm̂én̂t́îńĝ ýôúr̂ áp̂ṕ ŵít̂h́ t̂h́ê Úŝér̂ T́îḿîńĝ ÁP̂Í t̂ó m̂éâśûŕê ýôúr̂ áp̂ṕ'ŝ ŕêál̂-ẃôŕl̂d́ p̂ér̂f́ôŕm̂án̂ćê d́ûŕîńĝ ḱêý ûśêŕ êx́p̂ér̂íêńĉéŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/âúd̂ít̂ś/ûśêŕ-t̂ím̂ín̂ǵ)." + "message": "Ĉón̂śîd́êŕ îńŝt́r̂úm̂én̂t́îńĝ ýôúr̂ áp̂ṕ ŵít̂h́ t̂h́ê Úŝér̂ T́îḿîńĝ ÁP̂Í t̂ó m̂éâśûŕê ýôúr̂ áp̂ṕ'ŝ ŕêál̂-ẃôŕl̂d́ p̂ér̂f́ôŕm̂án̂ćê d́ûŕîńĝ ḱêý ûśêŕ êx́p̂ér̂íêńĉéŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/user-timing)" + } + } }, "lighthouse-core/audits/user-timings.js | displayValue": { "message": "{itemCount, plural,\n =1 {1 ûśêŕ t̂ím̂ín̂ǵ}\n other {# ûśêŕ t̂ím̂ín̂ǵŝ}\n }" @@ -1065,19 +2577,47 @@ "message": "Ûśêŕ T̂ím̂ín̂ǵ m̂ár̂ḱŝ án̂d́ m̂éâśûŕêś" }, "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"{securityOrigin}\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé `ĉŕôśŝór̂íĝín̂` át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý." + "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"{securityOrigin}\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`crossorigin`", + "example": "crossorigin" + } + } }, "lighthouse-core/audits/uses-rel-preconnect.js | description": { - "message": "Ĉón̂śîd́êŕ âd́d̂ín̂ǵ p̂ŕêćôńn̂éĉt́ ôŕ d̂ńŝ-ṕr̂éf̂ét̂ćĥ ŕêśôúr̂ćê h́îńt̂ś t̂ó êśt̂áb̂ĺîśĥ éâŕl̂ý ĉón̂ńêćt̂íôńŝ t́ô ím̂ṕôŕt̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý ôŕîǵîńŝ. [Ĺêár̂ń m̂ór̂é](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/ṕêŕf̂ór̂ḿâńĉé/r̂éŝóûŕĉé-p̂ŕîór̂ít̂íẑát̂íôń#p̂ŕêćôńn̂éĉt́)." + "message": "Ĉón̂śîd́êŕ âd́d̂ín̂ǵ p̂ŕêćôńn̂éĉt́ ôŕ d̂ńŝ-ṕr̂éf̂ét̂ćĥ ŕêśôúr̂ćê h́îńt̂ś t̂ó êśt̂áb̂ĺîśĥ éâŕl̂ý ĉón̂ńêćt̂íôńŝ t́ô ím̂ṕôŕt̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý ôŕîǵîńŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)" + } + } }, "lighthouse-core/audits/uses-rel-preconnect.js | title": { "message": "P̂ŕêćôńn̂éĉt́ t̂ó r̂éq̂úîŕêd́ ôŕîǵîńŝ" }, "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê `ćr̂óŝśôŕîǵîń` ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ." + "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`crossorigin`", + "example": "crossorigin" + } + } }, "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/t̂óôĺŝ/ĺîǵĥt́ĥóûśê/áûd́ît́ŝ/ṕr̂él̂óâd́)." + "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/audits/preload)" + } + } }, "lighthouse-core/audits/uses-rel-preload.js | title": { "message": "P̂ŕêĺôád̂ ḱêý r̂éq̂úêśt̂ś" @@ -1101,10 +2641,26 @@ "message": "B̂éŝt́ p̂ŕâćt̂íĉéŝ" }, "lighthouse-core/config/default-config.js | a11yCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ h́îǵĥĺîǵĥt́ ôṕp̂ór̂t́ûńît́îéŝ t́ô [ím̂ṕr̂óv̂é t̂h́ê áĉćêśŝíb̂íl̂ít̂ý ôf́ ŷóûŕ ŵéb̂ áp̂ṕ](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/áĉćêśŝíb̂íl̂ít̂ý). Ôńl̂ý â śûb́ŝét̂ óf̂ áĉćêśŝíb̂íl̂ít̂ý îśŝúêś ĉán̂ b́ê áût́ôḿât́îćâĺl̂ý d̂ét̂éĉt́êd́ ŝó m̂án̂úâĺ t̂éŝt́îńĝ íŝ ál̂śô én̂ćôúr̂áĝéd̂." + "message": "T̂h́êśê ćĥéĉḱŝ h́îǵĥĺîǵĥt́ ôṕp̂ór̂t́ûńît́îéŝ t́ô $LINK_START_0$ím̂ṕr̂óv̂é t̂h́ê áĉćêśŝíb̂íl̂ít̂ý ôf́ ŷóûŕ ŵéb̂ áp̂ṕ$LINK_END_0$. Ôńl̂ý â śûb́ŝét̂ óf̂ áĉćêśŝíb̂íl̂ít̂ý îśŝúêś ĉán̂ b́ê áût́ôḿât́îćâĺl̂ý d̂ét̂éĉt́êd́ ŝó m̂án̂úâĺ t̂éŝt́îńĝ íŝ ál̂śô én̂ćôúr̂áĝéd̂.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility)" + } + } }, "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { - "message": "T̂h́êśê ít̂ém̂ś âd́d̂ŕêśŝ ár̂éâś ŵh́îćĥ án̂ áût́ôḿât́êd́ t̂éŝt́îńĝ t́ôól̂ ćâńn̂ót̂ ćôv́êŕ. L̂éâŕn̂ ḿôŕê ín̂ óûŕ ĝúîd́ê ón̂ [ćôńd̂úĉt́îńĝ án̂ áĉćêśŝíb̂íl̂ít̂ý r̂év̂íêẃ](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/f́ûńd̂ám̂én̂t́âĺŝ/áĉćêśŝíb̂íl̂ít̂ý/ĥóŵ-t́ô-ŕêv́îéŵ)." + "message": "T̂h́êśê ít̂ém̂ś âd́d̂ŕêśŝ ár̂éâś ŵh́îćĥ án̂ áût́ôḿât́êd́ t̂éŝt́îńĝ t́ôól̂ ćâńn̂ót̂ ćôv́êŕ. L̂éâŕn̂ ḿôŕê ín̂ óûŕ ĝúîd́ê ón̂ $LINK_START_0$ćôńd̂úĉt́îńĝ án̂ áĉćêśŝíb̂íl̂ít̂ý r̂év̂íêẃ$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/fundamentals/accessibility/how-to-review)" + } + } }, "lighthouse-core/config/default-config.js | a11yCategoryTitle": { "message": "Âćĉéŝśîb́îĺît́ŷ" @@ -1188,7 +2744,15 @@ "message": "P̂Ẃ Óp̂t́îḿîźêd́" }, "lighthouse-core/config/default-config.js | seoCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ én̂śûŕê t́ĥát̂ ýôúr̂ ṕâǵê íŝ óp̂t́îḿîźêd́ f̂ór̂ śêár̂ćĥ én̂ǵîńê ŕêśûĺt̂ś r̂án̂ḱîńĝ. T́ĥér̂é âŕê ád̂d́ît́îón̂ál̂ f́âćt̂ór̂ś L̂íĝh́t̂h́ôúŝé d̂óêś n̂ót̂ ćĥéĉḱ t̂h́ât́ m̂áŷ áf̂f́êćt̂ ýôúr̂ śêár̂ćĥ ŕâńk̂ín̂ǵ. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://ŝúp̂ṕôŕt̂.ǵôóĝĺê.ćôḿ/ŵéb̂ḿâśt̂ér̂ś/âńŝẃêŕ/35769)." + "message": "T̂h́êśê ćĥéĉḱŝ én̂śûŕê t́ĥát̂ ýôúr̂ ṕâǵê íŝ óp̂t́îḿîźêd́ f̂ór̂ śêár̂ćĥ én̂ǵîńê ŕêśûĺt̂ś r̂án̂ḱîńĝ. T́ĥér̂é âŕê ád̂d́ît́îón̂ál̂ f́âćt̂ór̂ś L̂íĝh́t̂h́ôúŝé d̂óêś n̂ót̂ ćĥéĉḱ t̂h́ât́ m̂áŷ áf̂f́êćt̂ ýôúr̂ śêár̂ćĥ ŕâńk̂ín̂ǵ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://support.google.com/webmasters/answer/35769)" + } + } }, "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { "message": "R̂ún̂ t́ĥéŝé âd́d̂ít̂íôńâĺ v̂ál̂íd̂át̂ór̂ś ôń ŷóûŕ ŝít̂é t̂ó ĉh́êćk̂ ád̂d́ît́îón̂ál̂ ŚÊÓ b̂éŝt́ p̂ŕâćt̂íĉéŝ." @@ -1209,7 +2773,15 @@ "message": "Ĉŕâẃl̂ín̂ǵ âńd̂ Ín̂d́êx́îńĝ" }, "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { - "message": "M̂ák̂é ŝúr̂é ŷóûŕ p̂áĝéŝ ár̂é m̂ób̂íl̂é f̂ŕîén̂d́l̂ý ŝó ûśêŕŝ d́ôń’t̂ h́âv́ê t́ô ṕîńĉh́ ôŕ ẑóôḿ îń ôŕd̂ér̂ t́ô ŕêád̂ t́ĥé ĉón̂t́êńt̂ ṕâǵêś. [L̂éâŕn̂ ḿôŕê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/śêár̂ćĥ/ḿôb́îĺê-śît́êś/)." + "message": "M̂ák̂é ŝúr̂é ŷóûŕ p̂áĝéŝ ár̂é m̂ób̂íl̂é f̂ŕîén̂d́l̂ý ŝó ûśêŕŝ d́ôń’t̂ h́âv́ê t́ô ṕîńĉh́ ôŕ ẑóôḿ îń ôŕd̂ér̂ t́ô ŕêád̂ t́ĥé ĉón̂t́êńt̂ ṕâǵêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/search/mobile-sites/)" + } + } }, "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { "message": "M̂ób̂íl̂é F̂ŕîén̂d́l̂ý" @@ -1245,10 +2817,22 @@ "message": "P̂ót̂én̂t́îál̂ Śâv́îńĝś" }, "lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings": { - "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ {wastedBytes, number, bytes} K̂B́" + "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ $COMPLEX_ICU_0$ K̂B́", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{wastedBytes, number, bytes}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings": { - "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ {wastedMs, number, milliseconds} m̂ś" + "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ $COMPLEX_ICU_0$ m̂ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{wastedMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { "message": "D̂óĉúm̂én̂t́" @@ -1263,7 +2847,13 @@ "message": "M̂éd̂íâ" }, "lighthouse-core/lib/i18n/i18n.js | ms": { - "message": "{timeInMs, number, milliseconds} m̂ś" + "message": "$COMPLEX_ICU_0$ m̂ś", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, milliseconds}", + "example": "499" + } + } }, "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { "message": "Ôt́ĥér̂" @@ -1272,7 +2862,13 @@ "message": "Ŝćr̂íp̂t́" }, "lighthouse-core/lib/i18n/i18n.js | seconds": { - "message": "{timeInMs, number, seconds} ŝ" + "message": "$COMPLEX_ICU_0$ ŝ", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{timeInMs, number, seconds}", + "example": "2.4" + } + } }, "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { "message": "Ŝt́ŷĺêśĥéêt́" @@ -1353,7 +2949,15 @@ "message": "L̂áb̂ D́ât́â" }, "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { - "message": "[L̂íĝh́t̂h́ôúŝé](ĥt́t̂ṕŝ://d́êv́êĺôṕêŕŝ.ǵôóĝĺê.ćôḿ/ŵéb̂/t́ôól̂ś/l̂íĝh́t̂h́ôúŝé/) âńâĺŷśîś ôf́ t̂h́ê ćûŕr̂én̂t́ p̂áĝé ôń âń êḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂. V́âĺûéŝ ár̂é êśt̂ím̂át̂éd̂ án̂d́ m̂áŷ v́âŕŷ." + "message": "$LINK_START_0$L̂íĝh́t̂h́ôúŝé$LINK_END_0$ âńâĺŷśîś ôf́ t̂h́ê ćûŕr̂én̂t́ p̂áĝé ôń âń êḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂. V́âĺûéŝ ár̂é êśt̂ím̂át̂éd̂ án̂d́ m̂áŷ v́âŕŷ.", + "placeholders": { + "LINK_START_0": { + "content": "[" + }, + "LINK_END_0": { + "content": "](https://developers.google.com/web/tools/lighthouse/)" + } + } }, "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { "message": "Âd́d̂ít̂íôńâĺ ît́êḿŝ t́ô ḿâńûál̂ĺŷ ćĥéĉḱ" diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 654a7bbe7f8d..6b3c1416cd05 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -49,6 +49,98 @@ function computeDescription(ast, property, startRange) { return ''; } +function convertMessageToPlaceholders(message) { + // Basically the same as markdown parsing in dom.js + const placeholders = {}; + + // replace code snippets + let parts = message.split(/`(.*?)`/g); // Split on markdown code slashes + let newMessage = ''; + let idx = 0; + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, codeText] = parts.splice(0, 2); + newMessage += preambleText; + if (codeText) { + const pName = `MARKDOWN_SNIPPET_${idx++}`; + newMessage += `$${pName}$`; + placeholders[pName] = { + content: `\`${codeText}\``, + example: codeText, + }; + } + } + + // replace links + // Split on markdown links (e.g. [some link](https://...)). + parts = newMessage.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); + newMessage = ''; + idx = 0; + + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, linkText, linkHref] = parts.splice(0, 3); + newMessage += preambleText; + + // Append link if there are any. + if (linkText && linkHref) { + const ls = `LINK_START_${idx}`; + const le = `LINK_END_${idx++}`; + const repr = `$${ls}$${linkText}$${le}$`; + newMessage += repr; + placeholders[ls] = { + content: '[', + }; + placeholders[le] = { + content: `](${linkHref})`, + }; + } + } + + // replace complex ICU + // milliseconds, seconds, bytes, extendedPercent, percent, etc. + + parts = newMessage.split(/\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); + newMessage = ''; + idx = 0; + + while(parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, varName, icuType] = parts.splice(0, 3); + newMessage += preambleText; + + // Append link if there are any. + if (varName && icuType) { + const iName = `COMPLEX_ICU_${idx++}`; + newMessage += `$${iName}$`; + let example = '0'; + + // Make some good examples. + switch (icuType) { + case 'seconds': + example = '2.4'; + break; + case 'percent': + example = '54.6%'; + break; + case 'extendedPercent': + example = '37.92%'; + break; + default: + // Random (but constant) number for examples. + example = '499'; + } + + placeholders[iName] = { + content: `{${varName}, number, ${icuType}}`, + example: example, + }; + } + } + + return {message: newMessage, placeholders}; +} + /** * @param {string} dir * @param {Record<string, ICUMessageDefn>} strings @@ -94,7 +186,13 @@ function collectAllStringsInDir(dir, strings = {}) { const val = exportVars.UIStrings[key]; if (typeof val === 'string') { const description = computeDescription(ast, property, lastPropertyEndIndex); - strings[`${relativePath} | ${key}`] = {message: val, description}; + const converted = convertMessageToPlaceholders(val); + + if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { + strings[`${relativePath} | ${key}`] = {message: converted.message, description}; + } else { + strings[`${relativePath} | ${key}`] = {message: converted.message, description, placeholders: converted.placeholders}; + } lastPropertyEndIndex = property.range[1]; } else { // console.log(property.value.properties[0].range[1]); @@ -103,6 +201,11 @@ function collectAllStringsInDir(dir, strings = {}) { // const prevProp = property.value.properties[1].value.properties[1]; // const thisProp = property.value.properties[1].value.properties[2]; + // search and replace links in message + + // @ts-ignore + message = message.replace(/\[/g, nameLink).replace(/\]\(.*\)/g, nameLink); + const description = computeDescription(ast, property, lastPropertyEndIndex); /** * Transform: @@ -121,30 +224,33 @@ function collectAllStringsInDir(dir, strings = {}) { * } */ // init last prop to the 'messages' end range - let lastPropEndIndex = property.value.properties[0].range[1]; - let idx = 0; - const placeholdersMini = val.placeholders; - /** @type {*} */ - const placeholders = {}; - Object.entries(placeholdersMini).forEach(entry => { - const key = entry[0]; - const value = entry[1]; - const thisProp = property.value.properties[1].value.properties[idx]; - const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); - - placeholders[key] = { - content: value, - }; - if (thisDesc) { - placeholders[key].example = thisDesc; - } - - // replace {.*} with $.*$ - // eslint-disable-next-line no-useless-escape - message = message.replace(`{${key}}`, `\$${key}\$`); - idx++; - lastPropEndIndex = thisProp.range[1]; - }); + // let lastPropEndIndex = property.value.properties[0].range[1]; + // let idx = 0; + // const placeholdersMini = val.placeholders; + // /** @type {*} */ + // const placeholders = {}; + // Object.entries(placeholdersMini).forEach(entry => { + // const key = entry[0]; + // const value = entry[1]; + // const thisProp = property.value.properties[1].value.properties[idx]; + // const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); + + // placeholders[key] = { + // content: value, + // }; + // if (thisDesc) { + // placeholders[key].example = thisDesc; + // } + + // // replace {.*} with $.*$ + // // eslint-disable-next-line no-useless-escape + // message = message.replace(`{${key}}`, `\$${key}\$`); + // idx++; + // lastPropEndIndex = thisProp.range[1]; + // }); + + + // @ts-ignore strings[`${relativePath} | ${key}`] = {message, description, placeholders}; lastPropertyEndIndex = property.range[1]; } From 41828890f390321b00a74576fe6ffb2167f0cb11 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 3 Jul 2019 18:37:28 -0700 Subject: [PATCH 15/71] new jsdoc format for comments + _very_ basic parsing. --- .../audits/byte-efficiency/unminified-css.js | 50 +----- lighthouse-core/lib/i18n/locales/en-US.json | 2 +- lighthouse-core/lib/i18n/locales/en-XL.json | 2 +- .../lib/i18n/pre-locale/en-US.json | 15 +- .../lib/i18n/pre-locale/en-XL.json | 10 +- lighthouse-core/lib/lh-error.js | 5 +- .../scripts/i18n/collect-strings.js | 161 ++++++++++-------- 7 files changed, 114 insertions(+), 131 deletions(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 31aeba7b9c5f..21a2c78fb97f 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -14,7 +14,7 @@ const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ title: 'Minify CSS like `<link rel=stylesheet>`', /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: 'Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms.', + description: 'Minifying CSS files can reduce network payload sizes. [Learn More](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms.', /** [ICU Syntax] Some plural warning... */ warningPlural: '{itemCount, plural, =1 {# error found} other {# errors found}}', /** [ICU Syntax] Some gendered (ICU select) explanation... */ @@ -37,54 +37,6 @@ const UIStrings = { // }, }; -// const UIStrings = { -// /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ -// title: { -// message: 'Minify CSS like {css}', -// placeholders: { -// css: '`<link rel=stylesheet>`', -// }, -// }, -// /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ -// description: { -// message: 'Minifying CSS files can reduce network payload sizes. {link_start}Learn More!!!{link_end}. This audit took {milliseconds} ms.', -// placeholders: { -// link_start: '[->', -// link_end: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', -// /** 520 (Placeholder examples go here) */ -// milliseconds: '{timeInMs, number, milliseconds}', -// }, -// }, -// /** [ICU Syntax] Some plural warning... */ -// warningPlural: '{itemCount, plural, ' + -// '=1 {# error found}' + -// 'other {# errors found}}', -// /** [ICU Syntax] Some gendered (ICU select) explanation... */ -// explanationGender: { -// message: 'Someone minified this, {direct_replace_name}. {static_replacement} {person, select, ' + -// 'female {She minified this CSS.} ' + -// 'male {He minified this CSS.} ' + -// 'other {They minified this CSS.}}', -// placeholders: { -// /** Some static replacement. */ -// static_replacement: '`<link rel=>`', -// }, -// }, -// /** [ICU Syntax] Some gendered (ICU select) explanation... */ -// explanationGender2: { -// message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + -// 'female {She minified this CSS.} ' + -// 'male {He minified this CSS.} ' + -// 'other {They minified this CSS.}}', -// placeholders: { -// /** Some static replacement. */ -// static_replacement: '`<link rel=>`', -// /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ -// name: '{name}', -// }, -// }, -// }; - const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); const IGNORE_THRESHOLD_IN_PERCENT = 5; diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 86d31d3e1353..6d22b8b9a1ba 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -381,7 +381,7 @@ "message": "Avoids enormous network payloads" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. [->Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." + "message": "Minifying CSS files can reduce network payload sizes. [Learn More](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { "message": "Someone minified this, {direct_replace_name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index dde4b1eac1fe..3bd6008650bd 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -381,7 +381,7 @@ "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. [->Ĺêár̂ń M̂ór̂é!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). T̂h́îś âúd̂ít̂ t́ôók̂ {timeInMs, number, milliseconds} ḿŝ." + "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. [Ĺêár̂ń M̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/minify-css). T̂h́îś âúd̂ít̂ t́ôók̂ {timeInMs, number, milliseconds} ḿŝ." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. `<link rel=>` {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}" diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index 017d9ec5549b..ee37adfaf464 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -526,8 +526,7 @@ } }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "placeholder", - "description": "" + "message": "placeholder" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", @@ -1506,7 +1505,7 @@ "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$->Learn More!!!$LINK_END_0$. This audit took $COMPLEX_ICU_0$ ms.", + "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn More$LINK_END_0$. This audit took $COMPLEX_ICU_0$ ms.", "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { "LINK_START_0": { @@ -3304,8 +3303,14 @@ "description": "Error message explaining that Lighthouse timed out while waiting for the initial connection to the Chrome Devtools protocol." }, "lighthouse-core/lib/lh-error.js | didntCollectScreenshots": { - "message": "Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})", - "description": "Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome." + "message": "Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ($ICU_0$)", + "description": "Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome.", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": "NO_SPEEDLINE_FRAMES" + } + } }, "lighthouse-core/lib/lh-error.js | dnsFailure": { "message": "DNS servers could not resolve the provided domain.", diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index a079112d396e..d8329926cf65 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -1379,7 +1379,7 @@ "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$->Ĺêár̂ń M̂ór̂é!!!$LINK_END_0$. T̂h́îś âúd̂ít̂ t́ôók̂ $COMPLEX_ICU_0$ ḿŝ.", + "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$Ĺêár̂ń M̂ór̂é$LINK_END_0$. T̂h́îś âúd̂ít̂ t́ôók̂ $COMPLEX_ICU_0$ ḿŝ.", "placeholders": { "LINK_START_0": { "content": "[" @@ -2886,7 +2886,13 @@ "message": "T̂ím̂éôút̂ ẃâít̂ín̂ǵ f̂ór̂ ín̂ít̂íâĺ D̂éb̂úĝǵêŕ P̂ŕôt́ôćôĺ ĉón̂ńêćt̂íôń." }, "lighthouse-core/lib/lh-error.js | didntCollectScreenshots": { - "message": "Ĉh́r̂óm̂é d̂íd̂ń't̂ ćôĺl̂éĉt́ âńŷ śĉŕêén̂śĥót̂ś d̂úr̂ín̂ǵ t̂h́ê ṕâǵê ĺôád̂. Ṕl̂éâśê ḿâḱê śûŕê t́ĥér̂é îś ĉón̂t́êńt̂ v́îśîb́l̂é ôń t̂h́ê ṕâǵê, án̂d́ t̂h́êń t̂ŕŷ ŕê-ŕûńn̂ín̂ǵ L̂íĝh́t̂h́ôúŝé. ({errorCode})" + "message": "Ĉh́r̂óm̂é d̂íd̂ń't̂ ćôĺl̂éĉt́ âńŷ śĉŕêén̂śĥót̂ś d̂úr̂ín̂ǵ t̂h́ê ṕâǵê ĺôád̂. Ṕl̂éâśê ḿâḱê śûŕê t́ĥér̂é îś ĉón̂t́êńt̂ v́îśîb́l̂é ôń t̂h́ê ṕâǵê, án̂d́ t̂h́êń t̂ŕŷ ŕê-ŕûńn̂ín̂ǵ L̂íĝh́t̂h́ôúŝé. ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": "NO_SPEEDLINE_FRAMES" + } + } }, "lighthouse-core/lib/lh-error.js | dnsFailure": { "message": "D̂ŃŜ śêŕv̂ér̂ś ĉóûĺd̂ ńôt́ r̂éŝól̂v́ê t́ĥé p̂ŕôv́îd́êd́ d̂óm̂áîń." diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index 63804c1acfb8..37eb55ab6380 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -9,7 +9,10 @@ const i18n = require('./i18n/i18n.js'); /* eslint-disable max-len */ const UIStrings = { - /** Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome.*/ + /** + * @description Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome. + * @example {errorCode} NO_SPEEDLINE_FRAMES + * */ didntCollectScreenshots: `Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})`, /** Error message explaining that the network trace was not able to be recorded for the Lighthouse run. */ badTraceRecording: 'Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})', diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 6b3c1416cd05..8e57021c723d 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -43,13 +43,45 @@ function computeDescription(ast, property, startRange) { for (const comment of ast.comments || []) { if (comment.range[0] < startRange) continue; if (comment.range[0] > endRange) continue; - return comment.value.replace('*', '').trim(); + if (comment.value.includes('@description')) { + // This is a complex description with description and examples. + // console.log(comment.value.replace(/\*/g, '').replace(/ {2}/g, '').trim().split('\n')); + /** @type {string} */ + const vals = comment.value.replace(/\*/g, '').replace(/ {2}/g, '').trim(); + let parts = vals.match(/@.*(\n|$)/g); + let description = ''; + let examples = {}; + // console.log(parts); + // eslint-disable-next-line guard-for-in + for (const i in parts) { + let part = parts[i]; + if (part.startsWith('@description')) { + description = part.replace('@description ', '').trim(); + } + if (part.startsWith('@example ')) { + // @ts-ignore + let key = part.match(/\{\w{2,50}\}/).toString(); + key = key.substring(1, key.length - 1); + let value = part.replace(/@example \{\w{2,50}\} /, '').trim(); + examples[key] = value; + } + } + + // if (!desc) { + // break; + // } + // console.log(desc) + // const examples = Array.from(vals.match(/@example (.*) \n?/g)); + // console.log(desc, examples); + return {description, examples}; + } + return {description: comment.value.replace('*', '').trim()}; } - return ''; + return {}; } -function convertMessageToPlaceholders(message) { +function convertMessageToPlaceholders(message, examples={}) { // Basically the same as markdown parsing in dom.js const placeholders = {}; @@ -97,7 +129,7 @@ function convertMessageToPlaceholders(message) { } } - // replace complex ICU + // replace complex ICU numbers // milliseconds, seconds, bytes, extendedPercent, percent, etc. parts = newMessage.split(/\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); @@ -138,6 +170,43 @@ function convertMessageToPlaceholders(message) { } } + // add examples for direct ICU replacement + idx = 0; + // eslint-disable-next-line guard-for-in + for (const [key, value] of Object.entries(examples)) { + console.log(key, value); + + if (!newMessage.includes(`{${key}}`)) continue; + const eName = `ICU_${idx++}`; + newMessage = newMessage.replace(`{${key}}`, `$${eName}$`); + + placeholders[eName] = { + content: `{${key}}`, + example: value, + }; + } + + + // parts = newMessage.split(/\{(\w{2,50}), example, (.*?)\}/g); + // newMessage = ''; + // idx = 0; + // while (parts.length) { + // // Pop off the same number of elements as there are capture groups. + // const [preambleText, varName, exampleText] = parts.splice(0, 3); + // newMessage += preambleText; + + // // Append link if there are any. + // if (varName && exampleText) { + // const eName = `ICU_${idx++}`; + // newMessage += `$${eName}$`; + + // placeholders[eName] = { + // content: `{${varName}}`, + // example: exampleText, + // }; + // } + // } + return {message: newMessage, placeholders}; } @@ -184,76 +253,24 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - if (typeof val === 'string') { - const description = computeDescription(ast, property, lastPropertyEndIndex); - const converted = convertMessageToPlaceholders(val); - - if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { - strings[`${relativePath} | ${key}`] = {message: converted.message, description}; - } else { - strings[`${relativePath} | ${key}`] = {message: converted.message, description, placeholders: converted.placeholders}; - } - lastPropertyEndIndex = property.range[1]; + + const res = computeDescription(ast, property, lastPropertyEndIndex); + + let description = res.description; + let examples = res.examples; + + if (examples) { + console.log(examples); + } + + const converted = convertMessageToPlaceholders(val, examples); + + if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { + strings[`${relativePath} | ${key}`] = {message: converted.message, description}; } else { - // console.log(property.value.properties[0].range[1]); - // console.log(property.value.properties[1].value.properties); - let message = val.message; - // const prevProp = property.value.properties[1].value.properties[1]; - // const thisProp = property.value.properties[1].value.properties[2]; - - // search and replace links in message - - // @ts-ignore - message = message.replace(/\[/g, nameLink).replace(/\]\(.*\)/g, nameLink); - - const description = computeDescription(ast, property, lastPropertyEndIndex); - /** - * Transform: - * placeholders: { - * /** example val *\/ - * key: value, - * ... - * }, - * Into: - * placeholders: { - * key: { - * content: value, - * example: example val, - * }, - * ... - * } - */ - // init last prop to the 'messages' end range - // let lastPropEndIndex = property.value.properties[0].range[1]; - // let idx = 0; - // const placeholdersMini = val.placeholders; - // /** @type {*} */ - // const placeholders = {}; - // Object.entries(placeholdersMini).forEach(entry => { - // const key = entry[0]; - // const value = entry[1]; - // const thisProp = property.value.properties[1].value.properties[idx]; - // const thisDesc = computeDescription(ast, thisProp, lastPropEndIndex); - - // placeholders[key] = { - // content: value, - // }; - // if (thisDesc) { - // placeholders[key].example = thisDesc; - // } - - // // replace {.*} with $.*$ - // // eslint-disable-next-line no-useless-escape - // message = message.replace(`{${key}}`, `\$${key}\$`); - // idx++; - // lastPropEndIndex = thisProp.range[1]; - // }); - - - // @ts-ignore - strings[`${relativePath} | ${key}`] = {message, description, placeholders}; - lastPropertyEndIndex = property.range[1]; + strings[`${relativePath} | ${key}`] = {message: converted.message, description, placeholders: converted.placeholders}; } + lastPropertyEndIndex = property.range[1]; } } } From 8b0f8ea89db72dfdc61447e1d8e3d10daf2f01ba Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 5 Jul 2019 01:56:50 -0700 Subject: [PATCH 16/71] Better parsing, filled out lh-error descriptions. --- .../lib/i18n/pre-locale/en-US.json | 82 +++++++++++++++---- .../lib/i18n/pre-locale/en-XL.json | 66 +++++++++++++-- lighthouse-core/lib/lh-error.js | 41 ++++++++-- .../scripts/i18n/collect-strings.js | 80 +++++------------- 4 files changed, 177 insertions(+), 92 deletions(-) diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index ee37adfaf464..7368aca9d8a1 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -3295,8 +3295,14 @@ "description": "Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page." }, "lighthouse-core/lib/lh-error.js | badTraceRecording": { - "message": "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})", - "description": "Error message explaining that the network trace was not able to be recorded for the Lighthouse run." + "message": "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ($ICU_0$)", + "description": "Error message explaining that the network trace was not able to be recorded for the Lighthouse run.", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": " NO_TRACING_STARTED" + } + } }, "lighthouse-core/lib/lh-error.js | criTimeout": { "message": "Timeout waiting for initial Debugger Protocol connection.", @@ -3308,7 +3314,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": "NO_SPEEDLINE_FRAMES" + "example": " NO_SPEEDLINE_FRAMES" } } }, @@ -3317,16 +3323,28 @@ "description": "Error message explaining that the requested page could not be resolved by the DNS server." }, "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "Required {artifactName} gatherer encountered an error: {errorMessage}", - "description": "Error message explaning that there was an error while trying to collect a resource that was required for testing. \"artifactName\" will be replaced with the name of the resource that wasn't collected; \"errorMessage\" will be replaced with a string description of the error that occurred." + "message": "Required {artifactName} gatherer encountered an error: $ICU_0$", + "description": "Error message explaning that there was an error while trying to collect a resource that was required for testing. \"artifactName\" will be replaced with the name of the resource that wasn't collected; \"errorMessage\" will be replaced with a string description of the error that occurred.", + "placeholders": { + "ICU_0": { + "content": "{errorMessage}", + "example": " ERRORED_REQUIRED_ARTIFACT" + } + } }, "lighthouse-core/lib/lh-error.js | internalChromeError": { "message": "An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse.", "description": "Error message explaining that Chrome has encountered an error during the Lighthouse run, and that Chrome should be restarted." }, "lighthouse-core/lib/lh-error.js | missingRequiredArtifact": { - "message": "Required {artifactName} gatherer did not run.", - "description": "Error message explaning that a resource that was required for testing was never collected. \"artifactName\" will be replaced with the name of the resource that wasn't collected." + "message": "Required $ICU_0$ gatherer did not run.", + "description": "Error message explaning that a resource that was required for testing was never collected. \"artifactName\" will be replaced with the name of the resource that wasn't collected.", + "placeholders": { + "ICU_0": { + "content": "{artifactName}", + "example": " MISSING_REQUIRED_ARTIFACT" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailed": { "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests.", @@ -3337,28 +3355,58 @@ "description": "Error message explaining that Lighthouse couldn't complete because the page has stopped responding to its instructions." }, "lighthouse-core/lib/lh-error.js | pageLoadFailedInsecure": { - "message": "The URL you have provided does not have a valid security certificate. {securityMessages}", - "description": "Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load." + "message": "The URL you have provided does not have a valid security certificate. $ICU_0$", + "description": "Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load.", + "placeholders": { + "ICU_0": { + "content": "{securityMessages}", + "example": " net::ERR_CERT_DATE_INVALID" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailedInterstitial": { "message": "Chrome prevented page load with an interstitial. Make sure you are testing the correct URL and that the server is properly responding to all requests.", "description": "Error message explaining that Chrome prevented the page from loading and displayed an interstitial screen instead, so the URL cannot be accessed." }, "lighthouse-core/lib/lh-error.js | pageLoadFailedWithDetails": { - "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})", - "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability." + "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: $ICU_0$)", + "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability.", + "placeholders": { + "ICU_0": { + "content": "{errorDetails}", + "example": " FAILED_DOCUMENT_REQUEST" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailedWithStatusCode": { - "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: {statusCode})", - "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability." + "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: $ICU_0$)", + "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability.", + "placeholders": { + "ICU_0": { + "content": "{statusCode}", + "example": " 404" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadTookTooLong": { - "message": "Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ({errorCode})", - "description": "Error message explaining that the page loaded too slowly to perform a Lighthouse run." + "message": "Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ($ICU_0$)", + "description": "Error message explaining that the page loaded too slowly to perform a Lighthouse run.", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": " FMP_TOO_LATE_FOR_FCPUI" + } + } }, "lighthouse-core/lib/lh-error.js | protocolTimeout": { - "message": "Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})", - "description": "Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed." + "message": "Waiting for DevTools protocol response has exceeded the allotted time. (Method: $ICU_0$)", + "description": "Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed.", + "placeholders": { + "ICU_0": { + "content": "{protocolMethod}", + "example": " PROTOCOL_TIMEOUT" + } + } }, "lighthouse-core/lib/lh-error.js | requestContentTimeout": { "message": "Fetching resource content has exceeded the allotted time", diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index d8329926cf65..dfeab612238a 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -2880,7 +2880,13 @@ "message": "T̂ót̂ál̂" }, "lighthouse-core/lib/lh-error.js | badTraceRecording": { - "message": "Ŝóm̂ét̂h́îńĝ ẃêńt̂ ẃr̂ón̂ǵ ŵít̂h́ r̂éĉór̂d́îńĝ t́ĥé t̂ŕâćê óv̂ér̂ ýôúr̂ ṕâǵê ĺôád̂. Ṕl̂éâśê ŕûń L̂íĝh́t̂h́ôúŝé âǵâín̂. ({errorCode})" + "message": "Ŝóm̂ét̂h́îńĝ ẃêńt̂ ẃr̂ón̂ǵ ŵít̂h́ r̂éĉór̂d́îńĝ t́ĥé t̂ŕâćê óv̂ér̂ ýôúr̂ ṕâǵê ĺôád̂. Ṕl̂éâśê ŕûń L̂íĝh́t̂h́ôúŝé âǵâín̂. ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": " NO_TRACING_STARTED" + } + } }, "lighthouse-core/lib/lh-error.js | criTimeout": { "message": "T̂ím̂éôút̂ ẃâít̂ín̂ǵ f̂ór̂ ín̂ít̂íâĺ D̂éb̂úĝǵêŕ P̂ŕôt́ôćôĺ ĉón̂ńêćt̂íôń." @@ -2890,7 +2896,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": "NO_SPEEDLINE_FRAMES" + "example": " NO_SPEEDLINE_FRAMES" } } }, @@ -2898,13 +2904,25 @@ "message": "D̂ŃŜ śêŕv̂ér̂ś ĉóûĺd̂ ńôt́ r̂éŝól̂v́ê t́ĥé p̂ŕôv́îd́êd́ d̂óm̂áîń." }, "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "R̂éq̂úîŕêd́ {artifactName} ĝát̂h́êŕêŕ êńĉóûńt̂ér̂éd̂ án̂ ér̂ŕôŕ: {errorMessage}" + "message": "R̂éq̂úîŕêd́ {artifactName} ĝát̂h́êŕêŕ êńĉóûńt̂ér̂éd̂ án̂ ér̂ŕôŕ: $ICU_0$", + "placeholders": { + "ICU_0": { + "content": "{errorMessage}", + "example": " ERRORED_REQUIRED_ARTIFACT" + } + } }, "lighthouse-core/lib/lh-error.js | internalChromeError": { "message": "Âń îńt̂ér̂ńâĺ Ĉh́r̂óm̂é êŕr̂ór̂ óĉćûŕr̂éd̂. Ṕl̂éâśê ŕêśt̂ár̂t́ Ĉh́r̂óm̂é âńd̂ t́r̂ý r̂é-r̂ún̂ńîńĝ Ĺîǵĥt́ĥóûśê." }, "lighthouse-core/lib/lh-error.js | missingRequiredArtifact": { - "message": "R̂éq̂úîŕêd́ {artifactName} ĝát̂h́êŕêŕ d̂íd̂ ńôt́ r̂ún̂." + "message": "R̂éq̂úîŕêd́ $ICU_0$ ĝát̂h́êŕêŕ d̂íd̂ ńôt́ r̂ún̂.", + "placeholders": { + "ICU_0": { + "content": "{artifactName}", + "example": " MISSING_REQUIRED_ARTIFACT" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailed": { "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ." @@ -2913,22 +2931,52 @@ "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé ÛŔL̂ ýôú r̂éq̂úêśt̂éd̂ b́êćâúŝé t̂h́ê ṕâǵê śt̂óp̂ṕêd́ r̂éŝṕôńd̂ín̂ǵ." }, "lighthouse-core/lib/lh-error.js | pageLoadFailedInsecure": { - "message": "T̂h́ê ÚR̂Ĺ ŷóû h́âv́ê ṕr̂óv̂íd̂éd̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ ŝéĉúr̂ít̂ý ĉér̂t́îf́îćât́ê. {securityMessages}" + "message": "T̂h́ê ÚR̂Ĺ ŷóû h́âv́ê ṕr̂óv̂íd̂éd̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ ŝéĉúr̂ít̂ý ĉér̂t́îf́îćât́ê. $ICU_0$", + "placeholders": { + "ICU_0": { + "content": "{securityMessages}", + "example": " net::ERR_CERT_DATE_INVALID" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailedInterstitial": { "message": "Ĉh́r̂óm̂é p̂ŕêv́êńt̂éd̂ ṕâǵê ĺôád̂ ẃît́ĥ án̂ ín̂t́êŕŝt́ît́îál̂. Ḿâḱê śûŕê ýôú âŕê t́êśt̂ín̂ǵ t̂h́ê ćôŕr̂éĉt́ ÛŔL̂ án̂d́ t̂h́ât́ t̂h́ê śêŕv̂ér̂ íŝ ṕr̂óp̂ér̂ĺŷ ŕêśp̂ón̂d́îńĝ t́ô ál̂ĺ r̂éq̂úêśt̂ś." }, "lighthouse-core/lib/lh-error.js | pageLoadFailedWithDetails": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (D́êt́âíl̂ś: {errorDetails})" + "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (D́êt́âíl̂ś: $ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{errorDetails}", + "example": " FAILED_DOCUMENT_REQUEST" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadFailedWithStatusCode": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (Śt̂át̂úŝ ćôd́ê: {statusCode})" + "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (Śt̂át̂úŝ ćôd́ê: $ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{statusCode}", + "example": " 404" + } + } }, "lighthouse-core/lib/lh-error.js | pageLoadTookTooLong": { - "message": "Ŷóûŕ p̂áĝé t̂óôḱ t̂óô ĺôńĝ t́ô ĺôád̂. Ṕl̂éâśê f́ôĺl̂óŵ t́ĥé ôṕp̂ór̂t́ûńît́îéŝ ín̂ t́ĥé r̂ép̂ór̂t́ t̂ó r̂éd̂úĉé ŷóûŕ p̂áĝé l̂óâd́ t̂ím̂é, âńd̂ t́ĥén̂ t́r̂ý r̂é-r̂ún̂ńîńĝ Ĺîǵĥt́ĥóûśê. ({errorCode})" + "message": "Ŷóûŕ p̂áĝé t̂óôḱ t̂óô ĺôńĝ t́ô ĺôád̂. Ṕl̂éâśê f́ôĺl̂óŵ t́ĥé ôṕp̂ór̂t́ûńît́îéŝ ín̂ t́ĥé r̂ép̂ór̂t́ t̂ó r̂éd̂úĉé ŷóûŕ p̂áĝé l̂óâd́ t̂ím̂é, âńd̂ t́ĥén̂ t́r̂ý r̂é-r̂ún̂ńîńĝ Ĺîǵĥt́ĥóûśê. ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{errorCode}", + "example": " FMP_TOO_LATE_FOR_FCPUI" + } + } }, "lighthouse-core/lib/lh-error.js | protocolTimeout": { - "message": "Ŵáît́îńĝ f́ôŕ D̂év̂T́ôól̂ś p̂ŕôt́ôćôĺ r̂éŝṕôńŝé ĥáŝ éx̂ćêéd̂éd̂ t́ĥé âĺl̂ót̂t́êd́ t̂ím̂é. (M̂ét̂h́ôd́: {protocolMethod})" + "message": "Ŵáît́îńĝ f́ôŕ D̂év̂T́ôól̂ś p̂ŕôt́ôćôĺ r̂éŝṕôńŝé ĥáŝ éx̂ćêéd̂éd̂ t́ĥé âĺl̂ót̂t́êd́ t̂ím̂é. (M̂ét̂h́ôd́: $ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{protocolMethod}", + "example": " PROTOCOL_TIMEOUT" + } + } }, "lighthouse-core/lib/lh-error.js | requestContentTimeout": { "message": "F̂ét̂ćĥín̂ǵ r̂éŝóûŕĉé ĉón̂t́êńt̂ h́âś êx́ĉéêd́êd́ t̂h́ê ál̂ĺôt́t̂éd̂ t́îḿê" diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index 37eb55ab6380..0543658a2224 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -7,6 +7,7 @@ const i18n = require('./i18n/i18n.js'); +// TODO(exterkamp): Get better examples. /* eslint-disable max-len */ const UIStrings = { /** @@ -14,17 +15,32 @@ const UIStrings = { * @example {errorCode} NO_SPEEDLINE_FRAMES * */ didntCollectScreenshots: `Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})`, - /** Error message explaining that the network trace was not able to be recorded for the Lighthouse run. */ + /** + * @description Error message explaining that the network trace was not able to be recorded for the Lighthouse run. + * @example {errorCode} NO_TRACING_STARTED + * */ badTraceRecording: 'Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})', - /** Error message explaining that the page loaded too slowly to perform a Lighthouse run. */ + /** + * @description Error message explaining that the page loaded too slowly to perform a Lighthouse run. + * @example {errorCode} FMP_TOO_LATE_FOR_FCPUI + * */ pageLoadTookTooLong: 'Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ({errorCode})', /** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ pageLoadFailed: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests.', - /** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ + /** + * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. + * @example {statusCode} 404 + * */ pageLoadFailedWithStatusCode: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: {statusCode})', - /** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ + /** + * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. + * @example {errorDetails} FAILED_DOCUMENT_REQUEST + * */ pageLoadFailedWithDetails: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})', - /** Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load. */ + /** + * @description Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load. + * @example {securityMessages} net::ERR_CERT_DATE_INVALID + * */ pageLoadFailedInsecure: 'The URL you have provided does not have a valid security certificate. {securityMessages}', /** Error message explaining that Chrome prevented the page from loading and displayed an interstitial screen instead, so the URL cannot be accessed. */ pageLoadFailedInterstitial: 'Chrome prevented page load with an interstitial. Make sure you are testing the correct URL and that the server is properly responding to all requests.', @@ -34,7 +50,10 @@ const UIStrings = { requestContentTimeout: 'Fetching resource content has exceeded the allotted time', /** Error message explaining that the provided URL Lighthouse points to is not valid, and cannot be loaded. */ urlInvalid: 'The URL you have provided appears to be invalid.', - /** Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed. */ + /** + * @description Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed. + * @example {protocolMethod} PROTOCOL_TIMEOUT + * */ protocolTimeout: 'Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})', /** Error message explaining that the requested page could not be resolved by the DNS server. */ dnsFailure: 'DNS servers could not resolve the provided domain.', @@ -42,9 +61,15 @@ const UIStrings = { pageLoadFailedHung: 'Lighthouse was unable to reliably load the URL you requested because the page stopped responding.', /** Error message explaining that Lighthouse timed out while waiting for the initial connection to the Chrome Devtools protocol. */ criTimeout: 'Timeout waiting for initial Debugger Protocol connection.', - /** Error message explaning that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected. */ + /** + * @description Error message explaning that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected. + * @example {artifactName} MISSING_REQUIRED_ARTIFACT + * */ missingRequiredArtifact: 'Required {artifactName} gatherer did not run.', - /** Error message explaning that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. */ + /** + * @description Error message explaning that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. + * @example {errorMessage} ERRORED_REQUIRED_ARTIFACT + * */ erroredRequiredArtifact: 'Required {artifactName} gatherer encountered an error: {errorMessage}', }; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 8e57021c723d..5315cfa320d9 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -45,34 +45,21 @@ function computeDescription(ast, property, startRange) { if (comment.range[0] > endRange) continue; if (comment.value.includes('@description')) { // This is a complex description with description and examples. - // console.log(comment.value.replace(/\*/g, '').replace(/ {2}/g, '').trim().split('\n')); - /** @type {string} */ - const vals = comment.value.replace(/\*/g, '').replace(/ {2}/g, '').trim(); - let parts = vals.match(/@.*(\n|$)/g); let description = ''; - let examples = {}; - // console.log(parts); - // eslint-disable-next-line guard-for-in - for (const i in parts) { - let part = parts[i]; - if (part.startsWith('@description')) { - description = part.replace('@description ', '').trim(); - } - if (part.startsWith('@example ')) { - // @ts-ignore - let key = part.match(/\{\w{2,50}\}/).toString(); - key = key.substring(1, key.length - 1); - let value = part.replace(/@example \{\w{2,50}\} /, '').trim(); - examples[key] = value; + const examples = {}; + + const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; + let myArray; + while ((myArray = r.exec(comment.value)) !== null) { + const tagName = myArray[1]; + const placeholder = myArray[2]; + const message = myArray[3]; + if (tagName === 'description') { + description = message; + } else if (tagName === 'example') { + examples[placeholder.substring(1,placeholder.length-1)] = message; } } - - // if (!desc) { - // break; - // } - // console.log(desc) - // const examples = Array.from(vals.match(/@example (.*) \n?/g)); - // console.log(desc, examples); return {description, examples}; } return {description: comment.value.replace('*', '').trim()}; @@ -81,7 +68,12 @@ function computeDescription(ast, property, startRange) { return {}; } -function convertMessageToPlaceholders(message, examples={}) { +/** + * @param {*} message + * @param {*} examples + */ +function convertMessageToPlaceholders(message, examples = {}) { + // console.log(examples); // Basically the same as markdown parsing in dom.js const placeholders = {}; @@ -131,12 +123,11 @@ function convertMessageToPlaceholders(message, examples={}) { // replace complex ICU numbers // milliseconds, seconds, bytes, extendedPercent, percent, etc. - parts = newMessage.split(/\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); newMessage = ''; idx = 0; - while(parts.length) { + while (parts.length) { // Pop off the same number of elements as there are capture groups. const [preambleText, varName, icuType] = parts.splice(0, 3); newMessage += preambleText; @@ -174,39 +165,16 @@ function convertMessageToPlaceholders(message, examples={}) { idx = 0; // eslint-disable-next-line guard-for-in for (const [key, value] of Object.entries(examples)) { - console.log(key, value); - if (!newMessage.includes(`{${key}}`)) continue; const eName = `ICU_${idx++}`; newMessage = newMessage.replace(`{${key}}`, `$${eName}$`); - + placeholders[eName] = { content: `{${key}}`, example: value, }; } - - // parts = newMessage.split(/\{(\w{2,50}), example, (.*?)\}/g); - // newMessage = ''; - // idx = 0; - // while (parts.length) { - // // Pop off the same number of elements as there are capture groups. - // const [preambleText, varName, exampleText] = parts.splice(0, 3); - // newMessage += preambleText; - - // // Append link if there are any. - // if (varName && exampleText) { - // const eName = `ICU_${idx++}`; - // newMessage += `$${eName}$`; - - // placeholders[eName] = { - // content: `{${varName}}`, - // example: exampleText, - // }; - // } - // } - return {message: newMessage, placeholders}; } @@ -256,12 +224,8 @@ function collectAllStringsInDir(dir, strings = {}) { const res = computeDescription(ast, property, lastPropertyEndIndex); - let description = res.description; - let examples = res.examples; - - if (examples) { - console.log(examples); - } + const description = res.description; + const examples = res.examples; const converted = convertMessageToPlaceholders(val, examples); From ddf8171918e297c98e2efa8a44e7cb8746ded4b1 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Sun, 7 Jul 2019 11:55:09 -0700 Subject: [PATCH 17/71] Fixed tests, made unminified-css and doc-title back to normal. --- .../audits/accessibility/document-title.js | 12 +----- .../audits/byte-efficiency/unminified-css.js | 30 ++------------ lighthouse-core/lib/i18n/i18n.js | 36 ++++++++++++---- lighthouse-core/lib/i18n/locales/en-US.json | 12 ++---- lighthouse-core/lib/i18n/locales/en-XL.json | 12 ++---- .../lib/i18n/pre-locale/en-US.json | 41 ++++++------------- .../lib/i18n/pre-locale/en-XL.json | 34 ++++----------- lighthouse-core/test/lib/i18n/i18n-test.js | 1 + 8 files changed, 61 insertions(+), 117 deletions(-) diff --git a/lighthouse-core/audits/accessibility/document-title.js b/lighthouse-core/audits/accessibility/document-title.js index c3ffce722fc6..8dc37370a1d5 100644 --- a/lighthouse-core/audits/accessibility/document-title.js +++ b/lighthouse-core/audits/accessibility/document-title.js @@ -14,16 +14,8 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - title: 'placeholder', - // title: { - // message: 'Document has a $html_title$ element', - // description: 'Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.', - // placeholders: { - // html_title: { - // content: '`<title>`', - // }, - // }, - // }, + /** Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required. */ + title: 'Document has a `<title>` element', /** Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: 'Document doesn\'t have a `<title>` element', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 21a2c78fb97f..59bb3b3fe224 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -12,29 +12,9 @@ const computeTokenLength = require('../../lib/minification-estimator.js').comput const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ - title: 'Minify CSS like `<link rel=stylesheet>`', + title: 'Minify CSS', /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: 'Minifying CSS files can reduce network payload sizes. [Learn More](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms.', - /** [ICU Syntax] Some plural warning... */ - warningPlural: '{itemCount, plural, =1 {# error found} other {# errors found}}', - /** [ICU Syntax] Some gendered (ICU select) explanation... */ - explanationGender: 'Someone minified this, {direct_replace_name}. `<link rel=>` ' + - '{person, select, female {She minified this CSS.} ' + - 'male {He minified this CSS.} ' + - 'other {They minified this CSS.}}', - /** [ICU Syntax] Some gendered (ICU select) explanation... */ - // explanationGender2: { - // message: 'Someone minified this, {name}. {static_replacement} {person, select, ' + - // 'female {She minified this CSS.} ' + - // 'male {He minified this CSS.} ' + - // 'other {They minified this CSS.}}', - // placeholders: { - // /** Some static replacement. */ - // static_replacement: '`<link rel=>`', - // /** This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen. */ - // name: '{name}', - // }, - // }, + description: 'Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -53,7 +33,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { return { id: 'unminified-css', title: str_(UIStrings.title), - description: str_(UIStrings.description, {timeInMs: 10}), + description: str_(UIStrings.description), scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL'], }; @@ -128,9 +108,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)}, ]; - return {items, headings, explanation: str_(UIStrings.explanationGender, - {person: 'female', direct_replace_name: 'Kim'}), - warnings: [str_(UIStrings.warningPlural, {itemCount: 2})]}; + return {items, headings}; } } diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index ca81ac4fbb34..d754de0d965a 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -165,6 +165,7 @@ function _preprocessMessageValues(icuMessage, values) { /** * @typedef IcuMessageInstance * @prop {string} icuMessageId + * @prop {string} icuMessage * @prop {*} [values] */ @@ -179,11 +180,14 @@ const _ICUMsgNotFoundMsg = 'ICU message not found in destination locale'; * * @param {LH.Locale} locale * @param {string} icuMessageId + * @param {string=} fallbackMessage * @param {*} [values] * @return {{formattedString: string, icuMessage: string}} */ -function _formatIcuMessage(locale, icuMessageId, values) { +function _formatIcuMessage(locale, icuMessageId, fallbackMessage, values) { + // console.log(locale, icuMessageId); const localeMessages = LOCALES[locale]; + if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`); let localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; // fallback to the original english message if we couldn't find a message in the specified locale @@ -191,9 +195,12 @@ function _formatIcuMessage(locale, icuMessageId, values) { if (!localeMessage) { // Backup message localeMessage = LOCALES['en'][icuMessageId] && LOCALES['en'][icuMessageId].message; - if (!localeMessage) { - // panic - throw Error('ICU replacement message not found in locale, or en.'); + if (!localeMessage && fallbackMessage) { + // Use the fallback message at this point. + localeMessage = fallbackMessage; + } else { + // At this point, there is no reasonable string to show to the user, so throw. + throw new Error(_ICUMsgNotFoundMsg); } } @@ -230,6 +237,8 @@ function _formatPathAsString(pathInLHR) { */ function getRendererFormattedStrings(locale) { const localeMessages = LOCALES[locale]; + // console.log(locale); + // console.log(localeMessages); if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`); const icuMessageIds = Object.keys(localeMessages).filter(f => f.includes('core/report/html/')); @@ -245,6 +254,9 @@ function getRendererFormattedStrings(locale) { } /** + * Register a file's UIStrings with i18n, return function to + * generate the string ids. + * * @param {string} filename * @param {Record<string, string>} fileStrings */ @@ -252,7 +264,13 @@ function createMessageInstanceIdFn(filename, fileStrings) { /** @type {Record<string, string>} */ const mergedStrings = {...UIStrings, ...fileStrings}; - /** @param {string} icuMessage @param {*} [values] */ + /** + * Convert a message string & replacement values into an + * indexed id value in the form '{messageid} | # {index}'. + * + * @param {string} icuMessage + * @param {*} [values] + * */ const getMessageInstanceIdFn = (icuMessage, values) => { const keyname = Object.keys(mergedStrings).find(key => mergedStrings[key] === icuMessage); if (!keyname) throw new Error(`Could not locate: ${icuMessage}`); @@ -264,7 +282,7 @@ function createMessageInstanceIdFn(filename, fileStrings) { let indexOfInstance = icuMessageInstances.findIndex(inst => isDeepEqual(inst.values, values)); if (indexOfInstance === -1) { - icuMessageInstances.push({icuMessageId, values}); + icuMessageInstances.push({icuMessageId, icuMessage, values}); indexOfInstance = icuMessageInstances.length - 1; } @@ -309,7 +327,7 @@ function getFormattedFromIdAndValues(locale, icuMessageId, values) { const icuMessageIdRegex = /(.* \| .*)$/; if (!icuMessageIdRegex.test(icuMessageId)) throw new Error('This is not an ICU message ID'); - const {formattedString} = _formatIcuMessage(locale, icuMessageId, values); + const {formattedString} = _formatIcuMessage(locale, icuMessageId, undefined, values); return formattedString; } @@ -325,9 +343,9 @@ function _resolveIcuMessageInstanceId(icuMessageInstanceId, locale) { const [_, icuMessageId, icuMessageInstanceIndex] = matches; const icuMessageInstances = _icuMessageInstanceMap.get(icuMessageId) || []; const icuMessageInstance = icuMessageInstances[Number(icuMessageInstanceIndex)]; - // console.log(locale, "-->", icuMessageInstance.icuMessage); + // console.log(locale, "-->", icuMessageId); const {formattedString} = _formatIcuMessage(locale, icuMessageId, - icuMessageInstance.values); + icuMessageInstance.icuMessage, icuMessageInstance.values); return {icuMessageInstance, formattedString}; } diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 6d22b8b9a1ba..11d20950f270 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -135,7 +135,7 @@ "message": "Document doesn't have a `<title>` element" }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "placeholder" + "message": "Document has a `<title>` element" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)." @@ -381,16 +381,10 @@ "message": "Avoids enormous network payloads" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. [Learn More](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Someone minified this, {direct_replace_name}. `<link rel=>` {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}" + "message": "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "Minify CSS like `<link rel=stylesheet>`" - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# error found} other {# errors found}}" + "message": "Minify CSS" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Minifying JavaScript files can reduce payload sizes and script parse time. [Learn more](https://developers.google.com/speed/docs/insights/MinifyResources)." diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 3bd6008650bd..4d52b82056a6 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -135,7 +135,7 @@ "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â `<title>` él̂ém̂én̂t́" }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "p̂ĺâćêh́ôĺd̂ér̂" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á `<title>` êĺêḿêńt̂" }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. [L̂éâŕn̂ ḿôŕê](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)." @@ -381,16 +381,10 @@ "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. [Ĺêár̂ń M̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/minify-css). T̂h́îś âúd̂ít̂ t́ôók̂ {timeInMs, number, milliseconds} ḿŝ." - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. `<link rel=>` {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}" + "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "M̂ín̂íf̂ý ĈŚŜ ĺîḱê `<link rel=stylesheet>`" - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́} other {# êŕr̂ór̂ś f̂óûńd̂}}" + "message": "M̂ín̂íf̂ý ĈŚŜ" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. [Ĺêár̂ń m̂ór̂é](https://developers.google.com/speed/docs/insights/MinifyResources)." diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index 7368aca9d8a1..9e38d304dcca 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -517,7 +517,7 @@ }, "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { "message": "Document doesn't have a $MARKDOWN_SNIPPET_0$ element", - "description": "title: {", + "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`<title>`", @@ -526,7 +526,14 @@ } }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "placeholder" + "message": "Document has a $MARKDOWN_SNIPPET_0$ element", + "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<title>`", + "example": "<title>" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", @@ -1505,7 +1512,7 @@ "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn More$LINK_END_0$. This audit took $COMPLEX_ICU_0$ ms.", + "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn more$LINK_END_0$.", "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { "LINK_START_0": { @@ -1513,36 +1520,12 @@ }, "LINK_END_0": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - }, - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Someone minified this, {direct_replace_name}. $MARKDOWN_SNIPPET_0$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", - "description": "[ICU Syntax] Some gendered (ICU select) explanation...", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<link rel=>`", - "example": "<link rel=>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "Minify CSS like $MARKDOWN_SNIPPET_0$", - "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<link rel=stylesheet>`", - "example": "<link rel=stylesheet>" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# error found} other {# errors found}}", - "description": "[ICU Syntax] Some plural warning..." + "message": "Minify CSS", + "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Minifying JavaScript files can reduce payload sizes and script parse time. $LINK_START_0$Learn more$LINK_END_0$.", diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index dfeab612238a..1dec40817270 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -481,7 +481,13 @@ } }, "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "p̂ĺâćêh́ôĺd̂ér̂" + "message": "D̂óĉúm̂én̂t́ ĥáŝ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂", + "placeholders": { + "MARKDOWN_SNIPPET_0": { + "content": "`<title>`", + "example": "<title>" + } + } }, "lighthouse-core/audits/accessibility/duplicate-id.js | description": { "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", @@ -1379,40 +1385,18 @@ "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$Ĺêár̂ń M̂ór̂é$LINK_END_0$. T̂h́îś âúd̂ít̂ t́ôók̂ $COMPLEX_ICU_0$ ḿŝ.", + "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", "placeholders": { "LINK_START_0": { "content": "[" }, "LINK_END_0": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - }, - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "Ŝóm̂éôńê ḿîńîf́îéd̂ t́ĥíŝ, {direct_replace_name}. $MARKDOWN_SNIPPET_0$ {person, select, female {Śĥé m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.} male {H́ê ḿîńîf́îéd̂ t́ĥíŝ ĆŜŚ.} other {T̂h́êý m̂ín̂íf̂íêd́ t̂h́îś ĈŚŜ.}}", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<link rel=>`", - "example": "<link rel=>" } } }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "M̂ín̂íf̂ý ĈŚŜ ĺîḱê $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<link rel=stylesheet>`", - "example": "<link rel=stylesheet>" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {# êŕr̂ór̂ f́ôún̂d́} other {# êŕr̂ór̂ś f̂óûńd̂}}" + "message": "M̂ín̂íf̂ý ĈŚŜ" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", diff --git a/lighthouse-core/test/lib/i18n/i18n-test.js b/lighthouse-core/test/lib/i18n/i18n-test.js index 185c1df5e9a9..9397c141486e 100644 --- a/lighthouse-core/test/lib/i18n/i18n-test.js +++ b/lighthouse-core/test/lib/i18n/i18n-test.js @@ -103,6 +103,7 @@ describe('i18n', () => { helloTimeInMsWorld: 'Hello {timeInMs, number, seconds} World', helloPercentWorld: 'Hello {in, number, extendedPercent} World', }; + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); it('formats a basic message', () => { From 705ffb63dd7d18ec55374b2096616a222ccda54f Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Sun, 7 Jul 2019 12:18:38 -0700 Subject: [PATCH 18/71] Updating readme for i18n. --- lighthouse-core/lib/i18n/README.md | 115 +++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 32 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index f799a5d9aeb8..80ec734e5262 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -8,13 +8,16 @@ ### Primitive Formatting -This include number formatting like `{timeInMs, number, milliseconds}` and string replacements like `{some_name}`. +This include number formatting like `{timeInMs, number, milliseconds}` and +string replacements like `{some_name}`. ## message.json Syntax ### Why we use message.json -It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for i18n messages. +It is the +[Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for +i18n messages. ### Parts of a message.json message @@ -37,39 +40,80 @@ It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-message ## Our message system -We use UIStrings & i18n.js to extract strings from individual js files into locale.json files. This allows us to keep strings close -to the code in which they are used so that developers can easily understand their context. It also comes with its own syntax. - -UIStrings can be defined in 1 of 2 ways: -* simple strings (no placeholders): - ```Javascript - /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ - title: 'Minify CSS', - ``` -* nested objects (needs placeholders): - ```Javascript - /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ - title: { - message: 'Minify CSS like {css}', - placeholders: { - css: '`<link rel=stylesheet>`', - }, - }, - ``` +We use UIStrings & i18n.js to extract strings from individual js files into +locale.json files. This allows us to keep strings close to the code in which +they are used so that developers can easily understand their context. It also +comes with its own syntax. + +UIStrings are defined in a simple Object with properties defining the strings. + +* simple string named "title", with no description: + + ```javascript + const UIStrings = { + title: 'Minify CSS', + }; + ``` + +* simple string, with a description above property as a comment: + + ```javascript + const UIStrings = { + /** Imperative title of a Lighthouse audit that ... */ + title: 'Minify CSS', + }; + ``` + +Strings can also contain some limited markdown, that will be rendered in the +report. + +* Code block. + + To format some text as code it should be contained in `backticks`. These + should be used whenever code is non-translatable. Such as HTML tags or + snippets of code. Also note that there is no escape character for using + backticks as part of the string, so ONLY use backticks to define code + blocks. + + Example usage: + + ```javascript + const UIStrings = { + title: 'Document has a `<title>` element', + }; + ``` + +* Link. + + To convert a section of text into a link to another URL, enclose the text + itself in [brackets] and then immediately include a link after it in + (parenthesis). Note that "[link text](https://...)" is NOT VALID because of + the space and will not be converted to a link. + + Example usage: + + ```javascript + const UIStrings = { + description: 'The value of ... [Learn More](https://google.com/)', + }; + ``` + TODO(exterkamp): explain all the comments and where they go/what they become. TODO(exterkamp): explain why we can't use some ICU like number formatting. ### The pipeline -file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> $placeholder$'s replaced -> {ICU} syntax replaced => final string +file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> +$placeholder$'s replaced -> {ICU} syntax replaced => final string TODO(exterkamp): Simple example Complex example: -1. string in `file_with_UIStrings.js` - ```Javascript +1. string in `file_with_UIStrings.js` + + ```javascript /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: { message: 'Minifying CSS files can reduce network payload sizes. {LINK_START}Learn More!!!{LINK_START}. This audit took {MILLISECONDS} ms.', @@ -82,7 +126,8 @@ Complex example: }, ``` -2. string when exported to locale.json file (en-US) +2. string when exported to locale.json file (en-US) + ```json "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { "message": "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_START$. This audit took $MILLISECONDS$ ms.", @@ -101,7 +146,10 @@ Complex example: } }, ``` - 1. string when exported back from translators locale.json file (everything but en-US) + + 1. string when exported back from translators locale.json file (everything + but en-US) + ```json "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { "message": "La réduction des fichiers CSS peut réduire la taille des charges utiles de réseau. $LINK_START$En savoir plus$LINK_START$. Cet audit a pris $MILLISECONDS ms", @@ -119,19 +167,22 @@ Complex example: }, ``` -3. string when read by i18n.js (initially) - ```Javascript +3. string when read by i18n.js (initially) + + ```javascript message = "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_END$. This audit took $MILLISECONDS$ ms." sent_values = {timeInMs: 10} ``` -4. string when placeholders replaced (with the static content) - ```Javascript +4. string when placeholders replaced (with the static content) + + ```javascript message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." sent_values = {timeInMs: 10} ``` -5. string when ICU syntax has been replaced (with the sent_values) - ```Javascript +5. string when ICU syntax has been replaced (with the sent_values) + + ```javascript message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took 10 ms." ``` From 902c2f7bac84b4499be9421fa2d50da2d7bc778d Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Sun, 7 Jul 2019 18:52:31 -0700 Subject: [PATCH 19/71] More readme updates. --- lighthouse-core/lib/i18n/README.md | 70 +++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 80ec734e5262..8fb68f714d05 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -64,6 +64,8 @@ UIStrings are defined in a simple Object with properties defining the strings. }; ``` +### Markdown + Strings can also contain some limited markdown, that will be rendered in the report. @@ -87,7 +89,7 @@ report. To convert a section of text into a link to another URL, enclose the text itself in [brackets] and then immediately include a link after it in - (parenthesis). Note that "[link text](https://...)" is NOT VALID because of + (parenthesis). Note that `[link text] (https://...)` is NOT VALID because of the space and will not be converted to a link. Example usage: @@ -98,12 +100,78 @@ report. }; ``` +### ICU Replacement Syntax + +ICU syntax is used throughout Lighthouse strings, and they are specified +directly in UIStrings. They follow 1 of 3 flavors. + +* Direct replacement + + This is simply a direct replacement of text into a string. Often used for + Proper Nouns, code, or other text that is dynamic and added at runtime, but + requires no additional formatting. + + Example usage: + + ```javascript + const UIStrings = { + didntCollectScreenshots: `Chrome didn't .... ({errorCode})`, + }; + ``` + + ICU replacements can also use a JSDoc type syntax to specify an example for + direct ICU replacements. + + * To specify the description, use + + `@description <description>` + + * To specify an example for an ICU replacement, use + + `@example {<ICU variable name>} <example for ICU replacement>` + + ```javascript + const UIStrings = { + /** + * @description Error message explaining ... + * @example {errorCode} NO_SPEEDLINE_FRAMES + */ + didntCollectScreenshots: `Chrome didn't .... ({errorCode})`, + }; + ``` + +* Complex replacement + + When more complex numerical ICU replacement is needed the syntax is mostly + the same as direct replacement. This is often used when replcaing times, or + percentages. + + Note: these complex ICU formats are automatically given example values based + on their ICU format as specified in `collect-strings.js` + + ```javascript + const UIStrings = { + displayValueText: 'Interactive at {timeInMs, number, seconds} s', + }; + ``` + TODO(exterkamp): explain all the comments and where they go/what they become. TODO(exterkamp): explain why we can't use some ICU like number formatting. ### The pipeline +The translation pipeline has 2 distinct stages, the collection and translation +is done pre-compile time, and the replacement is done at runtime. + +#### Translation Pipeline (pre-compile) + +file_with_UIStrings.js -> collect-strings.js -> pre-locale/en-US.json -> json +translated and sent back as messages.json format -> correct-strings -> +locales/{locale}.json + +#### String Replacement Pipeline (runtime) + file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> $placeholder$'s replaced -> {ICU} syntax replaced => final string From 45071387a3022bd6f8d34bf9c628e6d3d69cceca Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 13:59:29 -0700 Subject: [PATCH 20/71] Move collect code into seperate util file for testing, and the tests for it --- .../lib/i18n/pre-locale/en-US.json | 24 +- .../lib/i18n/pre-locale/en-XL.json | 24 +- lighthouse-core/lib/lh-error.js | 1 + .../scripts/i18n/collect-strings.js | 199 +---------- .../scripts/i18n/collection-util.js | 246 +++++++++++++ .../test/scripts/i18n/collection-util-test.js | 323 ++++++++++++++++++ package.json | 1 + 7 files changed, 604 insertions(+), 214 deletions(-) create mode 100644 lighthouse-core/scripts/i18n/collection-util.js create mode 100644 lighthouse-core/test/scripts/i18n/collection-util-test.js diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index 9e38d304dcca..a8bea1fc7b4b 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -3283,7 +3283,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " NO_TRACING_STARTED" + "example": "NO_TRACING_STARTED" } } }, @@ -3297,7 +3297,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " NO_SPEEDLINE_FRAMES" + "example": "NO_SPEEDLINE_FRAMES" } } }, @@ -3306,12 +3306,16 @@ "description": "Error message explaining that the requested page could not be resolved by the DNS server." }, "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "Required {artifactName} gatherer encountered an error: $ICU_0$", + "message": "Required $ICU_0$ gatherer encountered an error: $ICU_1$", "description": "Error message explaning that there was an error while trying to collect a resource that was required for testing. \"artifactName\" will be replaced with the name of the resource that wasn't collected; \"errorMessage\" will be replaced with a string description of the error that occurred.", "placeholders": { "ICU_0": { + "content": "{artifactName}", + "example": "Lighthouse Artifacts" + }, + "ICU_1": { "content": "{errorMessage}", - "example": " ERRORED_REQUIRED_ARTIFACT" + "example": "ERRORED_REQUIRED_ARTIFACT" } } }, @@ -3325,7 +3329,7 @@ "placeholders": { "ICU_0": { "content": "{artifactName}", - "example": " MISSING_REQUIRED_ARTIFACT" + "example": "MISSING_REQUIRED_ARTIFACT" } } }, @@ -3343,7 +3347,7 @@ "placeholders": { "ICU_0": { "content": "{securityMessages}", - "example": " net::ERR_CERT_DATE_INVALID" + "example": "net::ERR_CERT_DATE_INVALID" } } }, @@ -3357,7 +3361,7 @@ "placeholders": { "ICU_0": { "content": "{errorDetails}", - "example": " FAILED_DOCUMENT_REQUEST" + "example": "FAILED_DOCUMENT_REQUEST" } } }, @@ -3367,7 +3371,7 @@ "placeholders": { "ICU_0": { "content": "{statusCode}", - "example": " 404" + "example": "404" } } }, @@ -3377,7 +3381,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " FMP_TOO_LATE_FOR_FCPUI" + "example": "FMP_TOO_LATE_FOR_FCPUI" } } }, @@ -3387,7 +3391,7 @@ "placeholders": { "ICU_0": { "content": "{protocolMethod}", - "example": " PROTOCOL_TIMEOUT" + "example": "PROTOCOL_TIMEOUT" } } }, diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index 1dec40817270..9c8e87891c75 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -2868,7 +2868,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " NO_TRACING_STARTED" + "example": "NO_TRACING_STARTED" } } }, @@ -2880,7 +2880,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " NO_SPEEDLINE_FRAMES" + "example": "NO_SPEEDLINE_FRAMES" } } }, @@ -2888,11 +2888,15 @@ "message": "D̂ŃŜ śêŕv̂ér̂ś ĉóûĺd̂ ńôt́ r̂éŝól̂v́ê t́ĥé p̂ŕôv́îd́êd́ d̂óm̂áîń." }, "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "R̂éq̂úîŕêd́ {artifactName} ĝát̂h́êŕêŕ êńĉóûńt̂ér̂éd̂ án̂ ér̂ŕôŕ: $ICU_0$", + "message": "R̂éq̂úîŕêd́ $ICU_0$ ĝát̂h́êŕêŕ êńĉóûńt̂ér̂éd̂ án̂ ér̂ŕôŕ: $ICU_1$", "placeholders": { "ICU_0": { + "content": "{artifactName}", + "example": "Lighthouse Artifacts" + }, + "ICU_1": { "content": "{errorMessage}", - "example": " ERRORED_REQUIRED_ARTIFACT" + "example": "ERRORED_REQUIRED_ARTIFACT" } } }, @@ -2904,7 +2908,7 @@ "placeholders": { "ICU_0": { "content": "{artifactName}", - "example": " MISSING_REQUIRED_ARTIFACT" + "example": "MISSING_REQUIRED_ARTIFACT" } } }, @@ -2919,7 +2923,7 @@ "placeholders": { "ICU_0": { "content": "{securityMessages}", - "example": " net::ERR_CERT_DATE_INVALID" + "example": "net::ERR_CERT_DATE_INVALID" } } }, @@ -2931,7 +2935,7 @@ "placeholders": { "ICU_0": { "content": "{errorDetails}", - "example": " FAILED_DOCUMENT_REQUEST" + "example": "FAILED_DOCUMENT_REQUEST" } } }, @@ -2940,7 +2944,7 @@ "placeholders": { "ICU_0": { "content": "{statusCode}", - "example": " 404" + "example": "404" } } }, @@ -2949,7 +2953,7 @@ "placeholders": { "ICU_0": { "content": "{errorCode}", - "example": " FMP_TOO_LATE_FOR_FCPUI" + "example": "FMP_TOO_LATE_FOR_FCPUI" } } }, @@ -2958,7 +2962,7 @@ "placeholders": { "ICU_0": { "content": "{protocolMethod}", - "example": " PROTOCOL_TIMEOUT" + "example": "PROTOCOL_TIMEOUT" } } }, diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index 0543658a2224..1f76253e1ba1 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -68,6 +68,7 @@ const UIStrings = { missingRequiredArtifact: 'Required {artifactName} gatherer did not run.', /** * @description Error message explaning that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. + * @example {artifactName} Lighthouse Artifacts * @example {errorMessage} ERRORED_REQUIRED_ARTIFACT * */ erroredRequiredArtifact: 'Required {artifactName} gatherer encountered an error: {errorMessage}', diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 5315cfa320d9..767c9f642964 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -11,6 +11,7 @@ const fs = require('fs'); const path = require('path'); const esprima = require('esprima'); +const collUtil = require('./collection-util.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; @@ -19,7 +20,7 @@ const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; * @typedef ICUMessageDefn * @property {string} message * @property {string} [description] - * @property {*} [placeholders] + * @property {Record<string, ICUPlaceholderDefn>} [placeholders] */ /** @@ -37,147 +38,6 @@ const ignoredPathComponents = [ '-renderer.js', ]; -// @ts-ignore - @types/esprima lacks all of these -function computeDescription(ast, property, startRange) { - const endRange = property.range[0]; - for (const comment of ast.comments || []) { - if (comment.range[0] < startRange) continue; - if (comment.range[0] > endRange) continue; - if (comment.value.includes('@description')) { - // This is a complex description with description and examples. - let description = ''; - const examples = {}; - - const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; - let myArray; - while ((myArray = r.exec(comment.value)) !== null) { - const tagName = myArray[1]; - const placeholder = myArray[2]; - const message = myArray[3]; - if (tagName === 'description') { - description = message; - } else if (tagName === 'example') { - examples[placeholder.substring(1,placeholder.length-1)] = message; - } - } - return {description, examples}; - } - return {description: comment.value.replace('*', '').trim()}; - } - - return {}; -} - -/** - * @param {*} message - * @param {*} examples - */ -function convertMessageToPlaceholders(message, examples = {}) { - // console.log(examples); - // Basically the same as markdown parsing in dom.js - const placeholders = {}; - - // replace code snippets - let parts = message.split(/`(.*?)`/g); // Split on markdown code slashes - let newMessage = ''; - let idx = 0; - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, codeText] = parts.splice(0, 2); - newMessage += preambleText; - if (codeText) { - const pName = `MARKDOWN_SNIPPET_${idx++}`; - newMessage += `$${pName}$`; - placeholders[pName] = { - content: `\`${codeText}\``, - example: codeText, - }; - } - } - - // replace links - // Split on markdown links (e.g. [some link](https://...)). - parts = newMessage.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); - newMessage = ''; - idx = 0; - - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, linkText, linkHref] = parts.splice(0, 3); - newMessage += preambleText; - - // Append link if there are any. - if (linkText && linkHref) { - const ls = `LINK_START_${idx}`; - const le = `LINK_END_${idx++}`; - const repr = `$${ls}$${linkText}$${le}$`; - newMessage += repr; - placeholders[ls] = { - content: '[', - }; - placeholders[le] = { - content: `](${linkHref})`, - }; - } - } - - // replace complex ICU numbers - // milliseconds, seconds, bytes, extendedPercent, percent, etc. - parts = newMessage.split(/\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); - newMessage = ''; - idx = 0; - - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, varName, icuType] = parts.splice(0, 3); - newMessage += preambleText; - - // Append link if there are any. - if (varName && icuType) { - const iName = `COMPLEX_ICU_${idx++}`; - newMessage += `$${iName}$`; - let example = '0'; - - // Make some good examples. - switch (icuType) { - case 'seconds': - example = '2.4'; - break; - case 'percent': - example = '54.6%'; - break; - case 'extendedPercent': - example = '37.92%'; - break; - default: - // Random (but constant) number for examples. - example = '499'; - } - - placeholders[iName] = { - content: `{${varName}, number, ${icuType}}`, - example: example, - }; - } - } - - // add examples for direct ICU replacement - idx = 0; - // eslint-disable-next-line guard-for-in - for (const [key, value] of Object.entries(examples)) { - if (!newMessage.includes(`{${key}}`)) continue; - const eName = `ICU_${idx++}`; - newMessage = newMessage.replace(`{${key}}`, `$${eName}$`); - - placeholders[eName] = { - content: `{${key}}`, - example: value, - }; - } - - return {message: newMessage, placeholders}; -} - /** * @param {string} dir * @param {Record<string, ICUMessageDefn>} strings @@ -221,13 +81,12 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - - const res = computeDescription(ast, property, lastPropertyEndIndex); + const res = collUtil.computeDescription(ast, property, val, lastPropertyEndIndex); const description = res.description; const examples = res.examples; - const converted = convertMessageToPlaceholders(val, examples); + const converted = collUtil.convertMessageToPlaceholders(val, examples); if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { strings[`${relativePath} | ${key}`] = {message: converted.message, description}; @@ -244,54 +103,6 @@ function collectAllStringsInDir(dir, strings = {}) { return strings; } -/** - * @param {Record<string, ICUMessageDefn>} strings - */ -function createPsuedoLocaleStrings(strings) { - /** @type {Record<string, ICUMessageDefn>} */ - const psuedoLocalizedStrings = {}; - for (const [key, defn] of Object.entries(strings)) { - const message = defn.message; - const psuedoLocalizedString = []; - let braceCount = 0; - let inPlaceholder = false; - let useHatForAccentMark = true; - for (const char of message) { - psuedoLocalizedString.push(char); - if (char === '$') { - inPlaceholder = !inPlaceholder; - continue; - } - if (inPlaceholder) { - continue; - } - - if (char === '{') { - braceCount++; - } else if (char === '}') { - braceCount--; - } - - // Hack to not change {plural{ICU}braces} nested an odd number of times. - // ex: "{itemCount, plural, =1 {1 link found} other {# links found}}" - // becomes "{itemCount, plural, =1 {1 l̂ín̂ḱ f̂óûńd̂} other {# ĺîńk̂ś f̂óûńd̂}}" - // ex: "{itemCount, plural, =1 {1 link {nested_replacement} found} other {# links {nested_replacement} found}}" - // becomes: "{itemCount, plural, =1 {1 l̂ín̂ḱ {nested_replacement} f̂óûńd̂} other {# ĺîńk̂ś {nested_replacement} f̂óûńd̂}}" - if (braceCount % 2 === 1) continue; - - // Add diacritical marks to the preceding letter, alternating between a hat ( ̂ ) and an acute (´). - if (/[a-z]/i.test(char)) { - psuedoLocalizedString.push(useHatForAccentMark ? `\u0302` : `\u0301`); - useHatForAccentMark = !useHatForAccentMark; - } - } - - psuedoLocalizedStrings[key] = {message: psuedoLocalizedString.join(''), placeholders: defn.placeholders}; - } - - return psuedoLocalizedStrings; -} - /** * @param {string} locale * @param {Record<string, ICUMessageDefn>} strings @@ -312,7 +123,7 @@ function writeStringsToLocaleFormat(locale, strings) { } const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core')); -const psuedoLocalizedStrings = createPsuedoLocaleStrings(strings); +const psuedoLocalizedStrings = collUtil.createPsuedoLocaleStrings(strings); console.log('Collected from LH core!'); collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js new file mode 100644 index 000000000000..d13858580cad --- /dev/null +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -0,0 +1,246 @@ +#!/usr/bin/env node +/** +* @license Copyright 2019 Google Inc. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +*/ +'use strict'; + +/** + * @typedef ICUMessageDefn + * @property {string} message + * @property {string} [description] + * @property {Record<string, ICUPlaceholderDefn>} [placeholders] + */ + +/** + * @typedef ICUPlaceholderDefn + * @property {string} content + * @property {string} [example] + */ + +// @ts-ignore - @types/esprima lacks all of these +function computeDescription(ast, property, value, startRange) { + const endRange = property.range[0]; + for (const comment of ast.comments || []) { + if (comment.range[0] < startRange) continue; + if (comment.range[0] > endRange) continue; + if (comment.value.includes('@')) { + // This is a complex description with description and examples. + let description = ''; + /** @type {Record<string, string>} */ + const examples = {}; + + const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; + let resArr; + while ((resArr = r.exec(comment.value)) !== null) { + const tagName = resArr[1]; + const placeholder = resArr[2]; + const message = resArr[3].trim(); + + if (tagName === 'description') { + description = message; + } else if (tagName === 'example') { + // Make sure the ICU var exists in string + if (!value.includes(placeholder)) { + throw Error('Example missing ICU replacement'); + } + examples[placeholder.substring(1, placeholder.length - 1)] = message; + } + } + // Make sure all ICU vars have examples + const rMini = /\{(\w+)\}/g; + while ((resArr = rMini.exec(value)) !== null) { + const varName = resArr[1]; + if (!examples[varName]) throw Error(`Variable '${varName}' is missing example comment`); + } + return {description, examples}; + } + return {description: comment.value.replace('*', '').trim()}; + } + return {}; +} + +/** + * @param {*} message + * @param {*} examples + * @returns {ICUMessageDefn} + */ +function convertMessageToPlaceholders(message, examples = {}) { + // console.log(examples); + // Basically the same as markdown parsing in dom.js + /** @type {Record<string, ICUPlaceholderDefn>} */ + const placeholders = {}; + + // Sanity checks + // Number of backticks is even. + if ((message.split('`').length - 1) % 2 !== 0) { + throw Error(`Open backtick in message "${message}"`); + } + // Link markdown is not slightly off. + if (message.match(/\[.*\] \(.*\)/)) { + throw Error(`Bad Link syntax in message "${message}"`); + } + // Complex ICU using non-supported format + if (message.match( + /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { + throw Error(`Non supported ICU format in message "${message}"`); + } + + // replace code snippets + let parts = message.split(/`(.*?)`/g); // Split on markdown code slashes + let newMessage = ''; + let idx = 0; + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, codeText] = parts.splice(0, 2); + newMessage += preambleText; + if (codeText) { + const pName = `MARKDOWN_SNIPPET_${idx++}`; + newMessage += `$${pName}$`; + placeholders[pName] = { + content: `\`${codeText}\``, + example: codeText, + }; + } + } + + // replace links + // Split on markdown links (e.g. [some link](https://...)). + parts = newMessage.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); + newMessage = ''; + idx = 0; + + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, linkText, linkHref] = parts.splice(0, 3); + newMessage += preambleText; + + // Append link if there are any. + if (linkText && linkHref) { + const ls = `LINK_START_${idx}`; + const le = `LINK_END_${idx++}`; + const repr = `$${ls}$${linkText}$${le}$`; + newMessage += repr; + placeholders[ls] = { + content: '[', + }; + placeholders[le] = { + content: `](${linkHref})`, + }; + } + } + + // replace complex ICU numbers + // milliseconds, seconds, bytes, extendedPercent, percent, etc. + parts = newMessage.split( + /\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); + newMessage = ''; + idx = 0; + + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, varName, icuType] = parts.splice(0, 3); + newMessage += preambleText; + + // Append link if there are any. + if (varName && icuType) { + const iName = `COMPLEX_ICU_${idx++}`; + newMessage += `$${iName}$`; + let example = '0'; + + // Make some good examples. + switch (icuType) { + case 'seconds': + example = '2.4'; + break; + case 'percent': + example = '54.6%'; + break; + case 'extendedPercent': + example = '37.92%'; + break; + default: + // Random (but constant) number for examples. + example = '499'; + } + + placeholders[iName] = { + content: `{${varName}, number, ${icuType}}`, + example: example, + }; + } + } + + // add examples for direct ICU replacement + idx = 0; + // eslint-disable-next-line guard-for-in + for (const [key, value] of Object.entries(examples)) { + if (!newMessage.includes(`{${key}}`)) continue; + const eName = `ICU_${idx++}`; + newMessage = newMessage.replace(`{${key}}`, `$${eName}$`); + + placeholders[eName] = { + content: `{${key}}`, + example: value, + }; + } + + return {message: newMessage, placeholders}; +} + + +/** + * @param {Record<string, ICUMessageDefn>} strings + */ +function createPsuedoLocaleStrings(strings) { + /** @type {Record<string, ICUMessageDefn>} */ + const psuedoLocalizedStrings = {}; + for (const [key, defn] of Object.entries(strings)) { + const message = defn.message; + const psuedoLocalizedString = []; + let braceCount = 0; + let inPlaceholder = false; + let useHatForAccentMark = true; + for (const char of message) { + psuedoLocalizedString.push(char); + if (char === '$') { + inPlaceholder = !inPlaceholder; + continue; + } + if (inPlaceholder) { + continue; + } + + if (char === '{') { + braceCount++; + } else if (char === '}') { + braceCount--; + } + + // Hack to not change {plural{ICU}braces} nested an odd number of times. + // ex: "{itemCount, plural, =1 {1 link found} other {# links found}}" + // becomes "{itemCount, plural, =1 {1 l̂ín̂ḱ f̂óûńd̂} other {# ĺîńk̂ś f̂óûńd̂}}" + // ex: "{itemCount, plural, =1 {1 link {nested_replacement} found} other {# links {nested_replacement} found}}" + // becomes: "{itemCount, plural, =1 {1 l̂ín̂ḱ {nested_replacement} f̂óûńd̂} other {# ĺîńk̂ś {nested_replacement} f̂óûńd̂}}" + if (braceCount % 2 === 1) continue; + + // Add diacritical marks to the preceding letter, alternating between a hat ( ̂ ) and an acute (´). + if (/[a-z]/i.test(char)) { + psuedoLocalizedString.push(useHatForAccentMark ? `\u0302` : `\u0301`); + useHatForAccentMark = !useHatForAccentMark; + } + } + psuedoLocalizedStrings[key] = { + message: psuedoLocalizedString.join(''), + placeholders: defn.placeholders, + }; + } + return psuedoLocalizedStrings; +} + +module.exports = { + computeDescription, + convertMessageToPlaceholders, + createPsuedoLocaleStrings, +}; diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collection-util-test.js new file mode 100644 index 000000000000..d29de3930a3c --- /dev/null +++ b/lighthouse-core/test/scripts/i18n/collection-util-test.js @@ -0,0 +1,323 @@ +/** + * @license Copyright 2019 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +/* eslint-env jest */ + +const collect = require('../../../scripts/i18n/collection-util.js'); +const esprima = require('esprima'); + +describe('Compute Description', () => { + it('collects description', () => { + const justUIStrings = + `const UIStrings = { + /** Description for Hello World. */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + const res = collect.computeDescription(ast, prop, 'Hello World', 0); + expect(res.description).toBe('Description for Hello World.'); + }); + + it('collects nothing, when no description present', () => { + const justUIStrings = + `const UIStrings = { + message: 'Hello World', + /** ^ no description for this one. */ + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + const res = collect.computeDescription(ast, prop, 'Hello World', 0); + expect(res.description).toBe(undefined); + }); + + it('collects complex description', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description Tagged description for Hello World. + */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + const res = collect.computeDescription(ast, prop, 'Hello World', 0); + expect(res.description).toBe('Tagged description for Hello World.'); + }); + + it('collects complex description with example', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description Tagged description for Hello World. + * @example {variable} Variable example. + */ + message: 'Hello World {variable}', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + const res = collect.computeDescription(ast, prop, 'Hello World {variable}', 0); + expect(res.description).toBe('Tagged description for Hello World.'); + expect(res.examples['variable']).toBe('Variable example.'); + }); + + it('errors when example given without variable', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description Tagged description for Hello World. + * @example {variable} Variable example. + */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) + .toThrow(/Example missing ICU replacement/); + }); + + it('errors when variable has no example', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description Tagged description for Hello World. + */ + message: 'Hello World {variable}', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)) + .toThrow(/Variable 'variable' is missing example comment/); + }); +}); + +describe('Convert Message to Placeholder', () => { + it('passthroughs a basic message unchanged', () => { + const message = 'Hello World.'; + const res = collect.convertMessageToPlaceholders(message, undefined); + expect(res.message).toBe(message); + expect(res.placeholders).toEqual({}); + }); + + it('converts code block to placeholder', () => { + const message = 'Hello `World`.'; + const res = collect.convertMessageToPlaceholders(message, undefined); + const expectation = 'Hello $MARKDOWN_SNIPPET_0$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + MARKDOWN_SNIPPET_0: { + content: '`World`', + example: 'World', + }, + }); + }); + + it('numbers code blocks in increasing order', () => { + const message = '`Hello` `World`.'; + const res = collect.convertMessageToPlaceholders(message, undefined); + const expectation = '$MARKDOWN_SNIPPET_0$ $MARKDOWN_SNIPPET_1$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + MARKDOWN_SNIPPET_0: { + content: '`Hello`', + example: 'Hello', + }, + MARKDOWN_SNIPPET_1: { + content: '`World`', + example: 'World', + }, + }); + }); + + it('errors when open backtick', () => { + const message = '`Hello World.'; + expect(() => collect.convertMessageToPlaceholders(message, undefined)) + .toThrow(/Open backtick in message "`Hello World."/); + }); + + it('allows other markdown in code block', () => { + const message = 'Hello World `[Link](https://google.com/)`.'; + const res = collect.convertMessageToPlaceholders(message, undefined); + const expectation = 'Hello World $MARKDOWN_SNIPPET_0$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + MARKDOWN_SNIPPET_0: { + content: '`[Link](https://google.com/)`', + example: '[Link](https://google.com/)', + }, + }); + }); + + it('converts links to placeholders', () => { + const message = 'Hello [World](https://google.com/).'; + const res = collect.convertMessageToPlaceholders(message, undefined); + const expectation = 'Hello $LINK_START_0$World$LINK_END_0$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + LINK_START_0: { + content: '[', + }, + LINK_END_0: { + content: '](https://google.com/)', + }, + }); + }); + + it('catches common link markdown mistakes', () => { + const message = 'Hello [World] (https://google.com/).'; + expect(() => collect.convertMessageToPlaceholders(message, undefined)) + .toThrow(/Bad Link syntax in message "Hello \[World\] \(https:\/\/google\.com\/\)\."/); + }); + + it('converts complex ICU to placholders', () => { + const message = 'Hello World took {timeInMs, number, milliseconds} ms, ' + + '{timeInSec, number, seconds} s, used {bytes, number, bytes} KB, ' + + '{perc, number, percent} of {percEx, number, extendedPercent}.'; + + const res = collect.convertMessageToPlaceholders(message, undefined); + const expectation = 'Hello World took $COMPLEX_ICU_0$ ms, ' + + '$COMPLEX_ICU_1$ s, used $COMPLEX_ICU_2$ KB, ' + + '$COMPLEX_ICU_3$ of $COMPLEX_ICU_4$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + COMPLEX_ICU_0: { + content: '{timeInMs, number, milliseconds}', + example: '499', + }, + COMPLEX_ICU_1: { + content: '{timeInSec, number, seconds}', + example: '2.4', + }, + COMPLEX_ICU_2: { + content: '{bytes, number, bytes}', + example: '499', + }, + COMPLEX_ICU_3: { + content: '{perc, number, percent}', + example: '54.6%', + }, + COMPLEX_ICU_4: { + content: '{percEx, number, extendedPercent}', + example: '37.92%', + }, + }); + }); + + it('errors when using non-supported complex ICU format', () => { + const message = 'Hello World took {var, number, global_int}.'; + expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( + /Non supported ICU format in message "Hello World took {var, number, global_int}\."/); + }); + + it('converts direct ICU with examples to placeholders', () => { + const message = 'Hello {name}.'; + const res = collect.convertMessageToPlaceholders(message, {name: 'Mary'}); + const expectation = 'Hello $ICU_0$.'; + expect(res.message).toBe(expectation); + expect(res.placeholders).toEqual({ + ICU_0: { + content: '{name}', + example: 'Mary', + }, + }); + }); + + it('ignores direct ICU with no examples', () => { + const message = 'Hello {name}.'; + const res = collect.convertMessageToPlaceholders(message, undefined); + expect(res.message).toBe(message); + expect(res.placeholders).toEqual({}); + }); +}); + +describe('PseudoLocalizer', () => { + it('adds cute hats to strings', () => { + const strings = { + hello: { + message: 'world', + }, + }; + const res = collect.createPsuedoLocaleStrings(strings); + expect(res).toEqual({ + hello: { + message: 'ŵór̂ĺd̂', + }, + }); + }); + + it('does not pseudolocalize ICU messages', () => { + const strings = { + hello: { + message: '{world}', + }, + }; + const res = collect.createPsuedoLocaleStrings(strings); + expect(res).toEqual({ + hello: { + message: '{world}', + }, + }); + }); + + it('does not pseudolocalize ordinal ICU message control markers', () => { + const strings = { + hello: { + message: '{num_worlds, plural, =1{world} other{worlds}}', + }, + }; + const res = collect.createPsuedoLocaleStrings(strings); + expect(res).toEqual({ + hello: { + message: '{num_worlds, plural, =1{ŵór̂ĺd̂} other{ẃôŕl̂d́ŝ}}', + }, + }); + }); + + it('does not pseudolocalize placeholders', () => { + const strings = { + hello: { + message: 'Hello $MARKDOWN_SNIPPET_0$', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + example: 'World', + }, + }, + }, + }; + const res = collect.createPsuedoLocaleStrings(strings); + expect(res).toEqual({ + hello: { + message: 'Ĥél̂ĺô $MARKDOWN_SNIPPET_0$', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + example: 'World', + }, + }, + }, + }); + }); +}); diff --git a/package.json b/package.json index 60e32f08e940..fc6d54938346 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", "i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js", "i18n:correct-strings": "node lighthouse-core/scripts/i18n/pseudolocalize.js", + "i18n:collect-and-correct": "yarn i18n:collect-strings && yarn i18n:correct-strings", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", From 29e29df4df1872f4cd971142221485ce0beb5eb1 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 14:14:47 -0700 Subject: [PATCH 21/71] Add placeholder baking tests. --- .../scripts/i18n/collection-util.js | 35 +++++++++++ .../scripts/i18n/correct-strings.js | 29 +-------- .../test/scripts/i18n/collection-util-test.js | 61 +++++++++++++++++++ 3 files changed, 98 insertions(+), 27 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index d13858580cad..340d0ae0e3d3 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -239,8 +239,43 @@ function createPsuedoLocaleStrings(strings) { return psuedoLocalizedStrings; } +/** + * @param {Record<string, ICUMessageDefn>} messages + * @returns {Record<string, ICUMessageDefn>} + */ +function bakePlaceholders(messages) { + for (const key in messages) { + if (!Object.prototype.hasOwnProperty.call(messages, key)) continue; + + delete messages[key]['description']; + + let message = messages[key]['message']; + const placeholders = messages[key]['placeholders']; + + for (const placeholder in placeholders) { + if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; + + const content = placeholders[placeholder]['content']; + const re = new RegExp('\\$' + placeholder + '\\$'); + if (!message.match(re)) { + throw Error(`Message "${message}" has extra placeholder "${placeholder}"`); + } + message = message.replace(re, content); + } + + // Sanity check that all placeholders are gone + if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); + + messages[key]['message'] = message; + + delete messages[key]['placeholders']; + } + return messages; +} + module.exports = { computeDescription, convertMessageToPlaceholders, createPsuedoLocaleStrings, + bakePlaceholders, }; diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js index 8ed230570183..ef93e7247777 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -10,6 +10,7 @@ const fs = require('fs'); const path = require('path'); +const collUtil = require('./collection-util.js'); /** * @typedef ICUMessageDefn @@ -35,32 +36,6 @@ function collectPreLocaleStrings(file) { return messages; } -/** - * @param {*} messages - */ -function bakePlaceholders(messages) { - for (const key in messages) { - if (!Object.prototype.hasOwnProperty.call(messages, key)) continue; - - delete messages[key]['description']; - - let message = messages[key]['message']; - const placeholders = messages[key]['placeholders']; - - for (const placeholder in placeholders) { - if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; - - const content = placeholders[placeholder]['content']; - const re = new RegExp('\\$' + placeholder + '\\$'); - message = message.replace(re, content); - } - messages[key]['message'] = message; - - delete messages[key]['placeholders']; - } - return messages; -} - /** * @param {*} path * @param {*} output @@ -82,7 +57,7 @@ function collectAllPreLocaleStrings(dir, output) { if (name.endsWith('.json')) { if (!process.env.CI) console.log('Correcting from', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); - const strings = bakePlaceholders(preLocaleStrings); + const strings = collUtil.bakePlaceholders(preLocaleStrings); saveLocaleStrings(output + path.basename(name), strings); } } diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collection-util-test.js index d29de3930a3c..465f62925663 100644 --- a/lighthouse-core/test/scripts/i18n/collection-util-test.js +++ b/lighthouse-core/test/scripts/i18n/collection-util-test.js @@ -321,3 +321,64 @@ describe('PseudoLocalizer', () => { }); }); }); + +describe('Baking Placeholders', () => { + it('passthroughs a basic message unchanged', () => { + const strings = { + hello: { + message: 'world', + }, + }; + const res = collect.bakePlaceholders(strings); + expect(res).toEqual({ + hello: { + message: 'world', + }, + }); + }); + + it('bakes a placeholder into the output string', () => { + const strings = { + hello: { + message: '$MARKDOWN_SNIPPET_0$', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + }, + }, + }, + }; + const res = collect.bakePlaceholders(strings); + expect(res).toEqual({ + hello: { + message: '`World`', + placeholders: undefined, + }, + }); + }); + + it('throws when a placeholder cannot be found', () => { + const strings = { + hello: { + message: '$MARKDOWN_SNIPPET_0$', + }, + }; + expect(() => collect.bakePlaceholders(strings)) + .toThrow(/Message "\$MARKDOWN_SNIPPET_0\$" is missing placeholder/); + }); + + it('throws when a placeholder is not in string', () => { + const strings = { + hello: { + message: 'World', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + }, + }, + }, + }; + expect(() => collect.bakePlaceholders(strings)) + .toThrow(/Message "World" has extra placeholder "MARKDOWN_SNIPPET_0"/); + }); +}); From 393beb6add3ff299174cd3d953e35bb7ad953784 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 14:28:29 -0700 Subject: [PATCH 22/71] readme updates --- lighthouse-core/lib/i18n/README.md | 115 ++++++++++++++++++----------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 8fb68f714d05..dbbc5e64adb4 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -166,91 +166,116 @@ is done pre-compile time, and the replacement is done at runtime. #### Translation Pipeline (pre-compile) -file_with_UIStrings.js -> collect-strings.js -> pre-locale/en-US.json -> json +`file_with_UIStrings.js -> collect-strings.js -> pre-locale/en-US.json -> json translated and sent back as messages.json format -> correct-strings -> -locales/{locale}.json +locales/{locale}.json` + +This is done with yarn commands: + +```shell +# collect UIStrings into pre-locales +$ yarn i18n:collect-strings + +# make the final en-US and en-XL files +$ yarn i18n:correct-strings + +# Send off to translators, and the i18n:correct-strings again +# once those .json's are done. +``` #### String Replacement Pipeline (runtime) -file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> -$placeholder$'s replaced -> {ICU} syntax replaced => final string +`file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> +$placeholder$'s replaced -> {ICU} syntax replaced => final string` TODO(exterkamp): Simple example -Complex example: +##### Simple example, no ICU: 1. string in `file_with_UIStrings.js` ```javascript - /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: { - message: 'Minifying CSS files can reduce network payload sizes. {LINK_START}Learn More!!!{LINK_START}. This audit took {MILLISECONDS} ms.', - placeholders: { - LINK_START: '[', - LINK_START: '](https://developers.google.com/web/tools/lighthouse/audits/minify-css)', - /** 520 (Placeholder examples go here) */ - MILLISECONDS: '{timeInMs, number, milliseconds}', - }, - }, + const UIStrings = { + /** Description of a Lighthouse audit that tells the user ...*/ + description: 'Minifying CSS files can reduce network payload sizes. ' + + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', + }; ``` -2. string when exported to locale.json file (en-US) +2. string when exported to pre-locale/{locale}.json file (en-US) ```json "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_START$. This audit took $MILLISECONDS$ ms.", + "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn more$LINK_END_0$.", "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { - "LINK_START": { + "LINK_START_0": { "content": "[" }, - "LINK_START": { + "LINK_END_0": { "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - }, - "MILLISECONDS": { - "content": "{timeInMs, number, milliseconds}", - "example": "520 (Placeholder examples go here)" } } }, ``` - 1. string when exported back from translators locale.json file (everything - but en-US) + 1. string when corrected and in locales/{locale}.json file. ```json "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "La réduction des fichiers CSS peut réduire la taille des charges utiles de réseau. $LINK_START$En savoir plus$LINK_START$. Cet audit a pris $MILLISECONDS ms", - "placeholders": { - "LINK_START": { - "content": "[" - }, - "LINK_START": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - }, - "MILLISECONDS": { - "content": "{timeInMs, number, milliseconds}", - } - } + "message": "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." }, ``` -3. string when read by i18n.js (initially) +3. string when read by i18n.js ```javascript - message = "Minifying CSS files can reduce network payload sizes. $LINK_START$Learn More!!!$LINK_END$. This audit took $MILLISECONDS$ ms." - sent_values = {timeInMs: 10} + message = "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." ``` -4. string when placeholders replaced (with the static content) +##### Complex example, with ICU + +1. string in `file_with_UIStrings.js` + + ```javascript + const UIStrings = { + /** Used to summarize the total byte size ...*/ + displayValue: 'Total size was {totalBytes, number, bytes}\xa0KB', + }; + ``` + +2. string when exported to pre-locale/{locale}.json file (en-US) + + ```json + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { + "message": "Total size was $COMPLEX_ICU_0$ KB", + "description": "Used to summarize the total byte size of the page and all its network requests. The `{totalBytes}` placeholder will be replaced with the total byte sizes, shown in kilobytes (e.g. 142 KB)", + "placeholders": { + "COMPLEX_ICU_0": { + "content": "{totalBytes, number, bytes}", + "example": "499" + } + } + }, + ``` + + 1. string when corrected and in locales/{locale}.json file. + + ```json + "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { + "message": "Total size was {totalBytes, number, bytes} KB" + }, + ``` + +3. string when read by i18n.js ```javascript - message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took {timeInMs, number, milliseconds} ms." - sent_values = {timeInMs: 10} + message = "Total size was {totalBytes, number, bytes} KB" + sent_values = {totalBytes: 10} ``` -5. string when ICU syntax has been replaced (with the sent_values) +4. string when ICU syntax has been replaced (with the sent_values) ```javascript - message = "Minifying CSS files can reduce network payload sizes. [Learn More!!!](https://developers.google.com/web/tools/lighthouse/audits/minify-css). This audit took 10 ms." + message = "Total size was 10 KB" ``` From 799084c5cb00a116635032dbacffcf438c37dabd Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 15:32:43 -0700 Subject: [PATCH 23/71] More readme details. --- lighthouse-core/lib/i18n/README.md | 124 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index dbbc5e64adb4..eab0f9c208b1 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -166,11 +166,28 @@ is done pre-compile time, and the replacement is done at runtime. #### Translation Pipeline (pre-compile) -`file_with_UIStrings.js -> collect-strings.js -> pre-locale/en-US.json -> json -translated and sent back as messages.json format -> correct-strings -> -locales/{locale}.json` +1. `file_with_UIStrings.js` this is where strings start. Optimized for + programmer ease of use and not for machine parsing. Uses ICU syntax and + markdown control characters inline. -This is done with yarn commands: +2. `yarn i18n:collect-strings` collects all UIStrings, and generates the + pre-locales. Does some parsing to make sure that common mistakes are + avoided. + +3. `pre-locale/en-US.json` this is the well formatted _machine parsable_ + fileset that is uploaded to be translated, i.e. they use $placeholder$ + syntax instead of ICU. These will never be used by the internal i18n system, + they are solely used to send to translators. + +4. `yarn i18n:correct-strings` collects all pre-locales (or returned .json + files of all languages if you're a Googler importing strings) and converts + them back to Lighthouse json format and puts them into `locales/`. + +5. `locales/{locale}.json` the Lighthouse json files. Used by the i18n.js + system to i18n strings. Uses ICU and not $placeholder$ syntax. Optimized for + i18n machine use. + +This pipeline is best seen with its component yarn commands: ```shell # collect UIStrings into pre-locales @@ -181,6 +198,7 @@ $ yarn i18n:correct-strings # Send off to translators, and the i18n:correct-strings again # once those .json's are done. +$ sh google_import_script_that_calls_correct_strings ``` #### String Replacement Pipeline (runtime) @@ -188,6 +206,13 @@ $ yarn i18n:correct-strings `file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> $placeholder$'s replaced -> {ICU} syntax replaced => final string` +1. String called in `.js` file, converted to i18n id. + +2. i18n id in lookup table along with backup message. + +3. Message is looked up via `replaceIcuMessageInstanceIds` & + `_formatIcuMessage`. + TODO(exterkamp): Simple example ##### Simple example, no ICU: @@ -195,86 +220,61 @@ TODO(exterkamp): Simple example 1. string in `file_with_UIStrings.js` ```javascript + // Declare UIStrings const UIStrings = { /** Description of a Lighthouse audit that tells the user ...*/ description: 'Minifying CSS files can reduce network payload sizes. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', }; - ``` - -2. string when exported to pre-locale/{locale}.json file (en-US) - - ```json - "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - } - } - }, - ``` - 1. string when corrected and in locales/{locale}.json file. + // i18n init + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); - ```json - "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." - }, - ``` + // String called with i18n + // Will become id like "lighthouse-core/audits/byte-efficiency/unminified-css.js | description" + let description = str_(UIStrings.description); + ``` -3. string when read by i18n.js +2. i18n lookup map registered the string (i18n.js) ```javascript - message = "Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." - ``` + const _icuMessageInstanceMap = new Map(); -##### Complex example, with ICU + // example value in _icuMessageInstanceMap + 'lighthouse-core/audits/byte-efficiency/unminified-css.js | description': { + icuMessageId: 'lighthouse-core/audits/byte-efficiency/unminified-css.js | description' + icuMessage: 'Minifying CSS files can reduce network payload sizes. ' + + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).' + } + ``` -1. string in `file_with_UIStrings.js` +3. Lookup in `i18n.js`. `_formatIcuMessage` will attempt to lookup in this + order: - ```javascript - const UIStrings = { - /** Used to summarize the total byte size ...*/ - displayValue: 'Total size was {totalBytes, number, bytes}\xa0KB', - }; - ``` + 1. `locales/{locale}.json` The best result, the string is found in the + target locale, and should appear correct. -2. string when exported to pre-locale/{locale}.json file (en-US) - - ```json - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "Total size was $COMPLEX_ICU_0$ KB", - "description": "Used to summarize the total byte size of the page and all its network requests. The `{totalBytes}` placeholder will be replaced with the total byte sizes, shown in kilobytes (e.g. 142 KB)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{totalBytes, number, bytes}", - "example": "499" - } - } - }, - ``` + 2. `locales/en.json` _Okay_ result. The string was not found in the target + locale, but was in `en`, so show the English string. - 1. string when corrected and in locales/{locale}.json file. + 3. The fallback message passed to `_formatIcuMessage`. This lookup is + subtley different than the en lookup. A string that is provided in the + UIStrings, but not en may be part of a swap-locale that is using an old + deprecated string, so would need to be populated by UIString replacement + here instead. - ```json - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "Total size was {totalBytes, number, bytes} KB" - }, - ``` + 4. Throw `_ICUMsgNotFoundMsg` Error. This is preferrable to showing the + user some id control lookup like + "lighthouse-core/audits/byte-efficiency/unminified-css.js | description" -3. string when read by i18n.js + This is also the point at which ICU is replaced by values. So this... ```javascript message = "Total size was {totalBytes, number, bytes} KB" - sent_values = {totalBytes: 10} + sent_values = {totalBytes: 10.75} ``` -4. string when ICU syntax has been replaced (with the sent_values) + Becomes... ```javascript message = "Total size was 10 KB" From 86e1593f834aa9e962486a080f9442caf28d2e1c Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 16:37:11 -0700 Subject: [PATCH 24/71] Added test for ICU with examples, fixed audits that violated this. --- .../audits/dobetterweb/appcache-manifest.js | 5 +- .../external-anchors-use-rel-noopener.js | 5 +- lighthouse-core/audits/font-display.js | 5 +- lighthouse-core/audits/image-aspect-ratio.js | 5 +- lighthouse-core/audits/seo/canonical.js | 25 +++- lighthouse-core/audits/seo/robots-txt.js | 5 +- lighthouse-core/audits/uses-rel-preconnect.js | 5 +- lighthouse-core/audits/uses-rel-preload.js | 5 +- .../lib/i18n/pre-locale/en-US.json | 110 ++++++++++++++---- .../lib/i18n/pre-locale/en-XL.json | 90 ++++++++++++-- .../scripts/i18n/collection-util.js | 16 ++- .../test/scripts/i18n/collection-util-test.js | 21 +++- 12 files changed, 244 insertions(+), 53 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/appcache-manifest.js b/lighthouse-core/audits/dobetterweb/appcache-manifest.js index 1f133a89aa14..26efe635f67a 100644 --- a/lighthouse-core/audits/dobetterweb/appcache-manifest.js +++ b/lighthouse-core/audits/dobetterweb/appcache-manifest.js @@ -21,7 +21,10 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user why they should not use the Application Cache API. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Application Cache is deprecated. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).', - /** Label for the audit identifying uses of the Application Cache. */ + /** + * @description Label for the audit identifying uses of the Application Cache. + * @example {AppCacheManifest} AppCacheManifest + */ displayValue: 'Found "{AppCacheManifest}"', }; diff --git a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js index f7ad647bb108..ab4c8ed383f0 100644 --- a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +++ b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js @@ -18,7 +18,10 @@ const UIStrings = { 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 that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety. */ + /** + * @description Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety. + * @example {anchorHTML} <a> + * */ warning: 'Unable to determine the destination for anchor ({anchorHTML}). ' + 'If not used as a hyperlink, consider removing target=_blank.', /** Label for a column in a data table; entries will be the target attribute of a link. Each entry is either an empty string or a string like `_blank`. */ diff --git a/lighthouse-core/audits/font-display.js b/lighthouse-core/audits/font-display.js index 9f273a0a2179..ce3743043513 100644 --- a/lighthouse-core/audits/font-display.js +++ b/lighthouse-core/audits/font-display.js @@ -24,7 +24,10 @@ const UIStrings = { 'Leverage the font-display CSS feature to ensure text is user-visible while ' + 'webfonts are loading. ' + '[Learn more](https://developers.google.com/web/updates/2016/02/font-display).', - /** A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it. */ + /** + * @description A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it. + * @example {fontURL} https://font.cdn.com/ + */ undeclaredFontURLWarning: 'Lighthouse was unable to automatically check the font-display value ' + 'for the following URL: {fontURL}.', }; diff --git a/lighthouse-core/audits/image-aspect-ratio.js b/lighthouse-core/audits/image-aspect-ratio.js index 8dd975f975c2..cb3d0481d360 100644 --- a/lighthouse-core/audits/image-aspect-ratio.js +++ b/lighthouse-core/audits/image-aspect-ratio.js @@ -23,7 +23,10 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user why they should maintain the correct aspect ratios for all images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Image display dimensions should match natural aspect ratio. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio).', - /** Warning that the size information for an image was nonsensical. `url` will be replaced with the url of that image. */ + /** + * @description Warning that the size information for an image was nonsensical. + * @example {url} https://image.cdn.com/ + */ warningCompute: 'Invalid image sizing information {url}', /** Label for a column in a data table; entries in the column will be the numeric aspect ratio of an image as displayed in a web page. */ columnDisplayed: 'Aspect Ratio (Displayed)', diff --git a/lighthouse-core/audits/seo/canonical.js b/lighthouse-core/audits/seo/canonical.js index b1bbaba43491..0f44bfb8bc56 100644 --- a/lighthouse-core/audits/seo/canonical.js +++ b/lighthouse-core/audits/seo/canonical.js @@ -18,15 +18,30 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Canonical links suggest which URL to show in search results. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).', - /** Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. "urlList" will be replaced by a list of URLs (e.g. https://example.com, https://example2.com, etc ). */ + /** + * @description Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. + * @example {urlList} https://example.com, https://example2.com + * */ explanationConflict: 'Multiple conflicting URLs ({urlList})', - /** Explanatory message stating that there was a failure in an audit caused by a URL being invalid. "url" will be replaced by the invalid URL (e.g. https://example.com). */ + /** + * @description Explanatory message stating that there was a failure in an audit caused by a URL being invalid. + * @example {url} https://example.com/ + * */ explanationInvalid: 'Invalid URL ({url})', - /** Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute. "url" will be replaced by the invalid URL (e.g. https://example.com). */ + /** + * @description Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute. + * @example {url} https://example.com/ + * */ explanationRelative: 'Relative URL ({url})', - /** Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. "url" will be replaced by the invalid URL (e.g. https://example.com). 'hreflang' is an HTML attribute and should not be translated. */ + /** + * @description Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context.'hreflang' is an HTML attribute and should not be translated. + * @example {url} https://example.com/ + */ explanationPointsElsewhere: 'Points to another `hreflang` location ({url})', - /** Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. "url" will be replaced by the invalid URL (e.g. https://example.com). */ + /** + * @description Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. + * @example {url} https://example.com/ + * */ explanationDifferentDomain: 'Points to a different domain ({url})', /** Explanatory message stating that the page's canonical URL was pointing to the domain's root URL, which is a common mistake. "points" refers to the action of the 'rel=canonical' referencing another link. "root" refers to the starting/home page of the website. "domain" refers to the registered domain name of the website. */ explanationRoot: 'Points to the domain\'s root URL (the homepage), ' + diff --git a/lighthouse-core/audits/seo/robots-txt.js b/lighthouse-core/audits/seo/robots-txt.js index c8a1fc2f4cb9..c9e919c64d2c 100644 --- a/lighthouse-core/audits/seo/robots-txt.js +++ b/lighthouse-core/audits/seo/robots-txt.js @@ -41,7 +41,10 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user *why* they need to have a valid robots.txt file. Note: "robots.txt" is a canonical filename and should not be translated. This is displayed after a user expands the section to see more. No character length limits. */ description: 'If your robots.txt file is malformed, crawlers may not be able to understand ' + 'how you want your website to be crawled or indexed.', - /** Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: "robots.txt" is a canonical filename and should not be translated. "statusCode" will be replaced with a 3 digit integer which represents the status of the HTTP connectiong for this page. */ + /** + * @description Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: "robots.txt" is a canonical filename and should not be translated. + * @example {statusCode} 500 + * */ displayValueHttpBadCode: 'request for robots.txt returned HTTP status: {statusCode}', /** [ICU Syntax] Label for the audit identifying the number of errors that occured while validating the robots.txt file. "itemCount" will be replaced by the integer count of errors encountered. */ displayValueValidationError: `{itemCount, plural, diff --git a/lighthouse-core/audits/uses-rel-preconnect.js b/lighthouse-core/audits/uses-rel-preconnect.js index 7ec30b105b4c..2ea08d3a0d3c 100644 --- a/lighthouse-core/audits/uses-rel-preconnect.js +++ b/lighthouse-core/audits/uses-rel-preconnect.js @@ -29,7 +29,10 @@ const UIStrings = { description: 'Consider adding preconnect or dns-prefetch resource hints to establish early ' + `connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, - /** A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links. */ + /** + * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links. + * @example {securityOrigin} <link rel="preconnect" href="..."> + * */ crossoriginWarning: 'A preconnect <link> was found for "{securityOrigin}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', }; diff --git a/lighthouse-core/audits/uses-rel-preload.js b/lighthouse-core/audits/uses-rel-preload.js index 1c602b4d6853..ccd6b56cb303 100644 --- a/lighthouse-core/audits/uses-rel-preload.js +++ b/lighthouse-core/audits/uses-rel-preload.js @@ -20,7 +20,10 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user *why* they should preload important network requests. The associated network requests are started halfway through pageload (or later) but should be started at the beginning. This is displayed after a user expands the section to see more. No character length limits. '<link rel=preload>' is the html code the user would include in their page and shouldn't be translated. 'Learn More' becomes link text to additional documentation. */ description: 'Consider using <link rel=preload> to prioritize fetching resources that are ' + 'currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).', - /** A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links. */ + /** + * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links. + * @example {preloadURL} <link rel="preload" href="..."> + * */ crossoriginWarning: 'A preload <link> was found for "{preloadURL}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', }; diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index a8bea1fc7b4b..5682481831f3 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -1720,8 +1720,14 @@ } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { - "message": "Found \"{AppCacheManifest}\"", - "description": "Label for the audit identifying uses of the Application Cache." + "message": "Found \"$ICU_0$\"", + "description": "Label for the audit identifying uses of the Application Cache.", + "placeholders": { + "ICU_0": { + "content": "{AppCacheManifest}", + "example": "AppCacheManifest" + } + } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | failureTitle": { "message": "Uses Application Cache", @@ -1870,8 +1876,14 @@ "description": "Title of a Lighthouse audit that provides detail on the cross-origin links that the web page contains, and whether the links can be considered safe. This descriptive title is shown to users when all links are safe." }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | warning": { - "message": "Unable to determine the destination for anchor ({anchorHTML}). If not used as a hyperlink, consider removing target=_blank.", - "description": "Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety." + "message": "Unable to determine the destination for anchor ($ICU_0$). If not used as a hyperlink, consider removing target=_blank.", + "description": "Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety.", + "placeholders": { + "ICU_0": { + "content": "{anchorHTML}", + "example": "<a>" + } + } }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { "message": "Users are mistrustful of or confused by sites that request their location without context. Consider tying the request to a user action instead. $LINK_START_0$Learn more$LINK_END_0$.", @@ -2126,8 +2138,14 @@ "description": "Title of a diagnostic audit that provides detail on if all the text on a webpage was visible while the page was loading its webfonts. This descriptive title is shown to users when the amount is acceptable and no user action is required." }, "lighthouse-core/audits/font-display.js | undeclaredFontURLWarning": { - "message": "Lighthouse was unable to automatically check the font-display value for the following URL: {fontURL}.", - "description": "A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it." + "message": "Lighthouse was unable to automatically check the font-display value for the following URL: $ICU_0$.", + "description": "A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it.", + "placeholders": { + "ICU_0": { + "content": "{fontURL}", + "example": "https://font.cdn.com/" + } + } }, "lighthouse-core/audits/image-aspect-ratio.js | columnActual": { "message": "Aspect Ratio (Actual)", @@ -2158,8 +2176,14 @@ "description": "Title of a Lighthouse audit that provides detail on the aspect ratios of all images on the page. This descriptive title is shown to users when all images use correct aspect ratios." }, "lighthouse-core/audits/image-aspect-ratio.js | warningCompute": { - "message": "Invalid image sizing information {url}", - "description": "Warning that the size information for an image was nonsensical. `url` will be replaced with the url of that image." + "message": "Invalid image sizing information $ICU_0$", + "description": "Warning that the size information for an image was nonsensical.", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://image.cdn.com/" + } + } }, "lighthouse-core/audits/is-on-https.js | columnInsecureURL": { "message": "Insecure URL", @@ -2462,30 +2486,58 @@ } }, "lighthouse-core/audits/seo/canonical.js | explanationConflict": { - "message": "Multiple conflicting URLs ({urlList})", - "description": "Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. \"urlList\" will be replaced by a list of URLs (e.g. https://example.com, https://example2.com, etc )." + "message": "Multiple conflicting URLs ($ICU_0$)", + "description": "Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other.", + "placeholders": { + "ICU_0": { + "content": "{urlList}", + "example": "https://example.com, https://example2.com" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain": { - "message": "Points to a different domain ({url})", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. \"url\" will be replaced by the invalid URL (e.g. https://example.com)." + "message": "Points to a different domain ($ICU_0$)", + "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain.", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationInvalid": { - "message": "Invalid URL ({url})", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL being invalid. \"url\" will be replaced by the invalid URL (e.g. https://example.com)." + "message": "Invalid URL ($ICU_0$)", + "description": "Explanatory message stating that there was a failure in an audit caused by a URL being invalid.", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "Points to another $MARKDOWN_SNIPPET_0$ location ({url})", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. \"url\" will be replaced by the invalid URL (e.g. https://example.com). 'hreflang' is an HTML attribute and should not be translated.", + "message": "Points to another $MARKDOWN_SNIPPET_0$ location ($ICU_0$)", + "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context.'hreflang' is an HTML attribute and should not be translated.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`hreflang`", "example": "hreflang" + }, + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" } } }, "lighthouse-core/audits/seo/canonical.js | explanationRelative": { - "message": "Relative URL ({url})", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute. \"url\" will be replaced by the invalid URL (e.g. https://example.com)." + "message": "Relative URL ($ICU_0$)", + "description": "Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute.", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationRoot": { "message": "Points to the domain's root URL (the homepage), instead of an equivalent page of content", @@ -2742,8 +2794,14 @@ "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid robots.txt file. Note: \"robots.txt\" is a canonical filename and should not be translated. This is displayed after a user expands the section to see more. No character length limits." }, "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": { - "message": "request for robots.txt returned HTTP status: {statusCode}", - "description": "Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: \"robots.txt\" is a canonical filename and should not be translated. \"statusCode\" will be replaced with a 3 digit integer which represents the status of the HTTP connectiong for this page." + "message": "request for robots.txt returned HTTP status: $ICU_0$", + "description": "Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: \"robots.txt\" is a canonical filename and should not be translated.", + "placeholders": { + "ICU_0": { + "content": "{statusCode}", + "example": "500" + } + } }, "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": { "message": "{itemCount, plural,\n =1 {1 error found}\n other {# errors found}\n }", @@ -2902,12 +2960,16 @@ "description": "Descriptive title of a diagnostic audit that provides details on any timestamps generated by the page. User Timing refers to the 'User Timing API', which enables a website to record specific times as 'marks', or spans of time as 'measures'." }, "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": "A preconnect <link> was found for \"{securityOrigin}\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", + "message": "A preconnect <link> was found for \"$ICU_0$\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`crossorigin`", "example": "crossorigin" + }, + "ICU_0": { + "content": "{securityOrigin}", + "example": "<link rel=\"preconnect\" href=\"...\">" } } }, @@ -2928,12 +2990,16 @@ "description": "Imperative title of a Lighthouse audit that tells the user to connect early to internet domains that will be used to load page resources. Origin is the correct term, however 'domain name' could be used if neccsesary. This is displayed in a list of audit titles that Lighthouse generates." }, "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": "A preload <link> was found for \"{preloadURL}\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", + "message": "A preload <link> was found for \"$ICU_0$\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`crossorigin`", "example": "crossorigin" + }, + "ICU_0": { + "content": "{preloadURL}", + "example": "<link rel=\"preload\" href=\"...\">" } } }, diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json index 9c8e87891c75..abc7ef36f6a7 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-XL.json @@ -1563,7 +1563,13 @@ } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { - "message": "F̂óûńd̂ \"{AppCacheManifest}\"" + "message": "F̂óûńd̂ \"$ICU_0$\"", + "placeholders": { + "ICU_0": { + "content": "{AppCacheManifest}", + "example": "AppCacheManifest" + } + } }, "lighthouse-core/audits/dobetterweb/appcache-manifest.js | failureTitle": { "message": "Ûśêś Âṕp̂ĺîćât́îón̂ Ćâćĥé" @@ -1688,7 +1694,13 @@ "message": "L̂ín̂ḱŝ t́ô ćr̂óŝś-ôŕîǵîń d̂éŝt́îńât́îón̂ś âŕê śâf́ê" }, "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | warning": { - "message": "Ûńâb́l̂é t̂ó d̂ét̂ér̂ḿîńê t́ĥé d̂éŝt́îńât́îón̂ f́ôŕ âńĉh́ôŕ ({anchorHTML}). Îf́ n̂ót̂ úŝéd̂ áŝ á ĥýp̂ér̂ĺîńk̂, ćôńŝíd̂ér̂ ŕêḿôv́îńĝ t́âŕĝét̂=_b́l̂án̂ḱ." + "message": "Ûńâb́l̂é t̂ó d̂ét̂ér̂ḿîńê t́ĥé d̂éŝt́îńât́îón̂ f́ôŕ âńĉh́ôŕ ($ICU_0$). Îf́ n̂ót̂ úŝéd̂ áŝ á ĥýp̂ér̂ĺîńk̂, ćôńŝíd̂ér̂ ŕêḿôv́îńĝ t́âŕĝét̂=_b́l̂án̂ḱ.", + "placeholders": { + "ICU_0": { + "content": "{anchorHTML}", + "example": "<a>" + } + } }, "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", @@ -1901,7 +1913,13 @@ "message": "Âĺl̂ t́êx́t̂ ŕêḿâín̂ś v̂íŝíb̂ĺê d́ûŕîńĝ ẃêb́f̂ón̂t́ l̂óâd́ŝ" }, "lighthouse-core/audits/font-display.js | undeclaredFontURLWarning": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô áût́ôḿât́îćâĺl̂ý ĉh́êćk̂ t́ĥé f̂ón̂t́-d̂íŝṕl̂áŷ v́âĺûé f̂ór̂ t́ĥé f̂ól̂ĺôẃîńĝ ÚR̂Ĺ: {fontURL}." + "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô áût́ôḿât́îćâĺl̂ý ĉh́êćk̂ t́ĥé f̂ón̂t́-d̂íŝṕl̂áŷ v́âĺûé f̂ór̂ t́ĥé f̂ól̂ĺôẃîńĝ ÚR̂Ĺ: $ICU_0$.", + "placeholders": { + "ICU_0": { + "content": "{fontURL}", + "example": "https://font.cdn.com/" + } + } }, "lighthouse-core/audits/image-aspect-ratio.js | columnActual": { "message": "Âśp̂éĉt́ R̂át̂íô (Áĉt́ûál̂)" @@ -1927,7 +1945,13 @@ "message": "D̂íŝṕl̂áŷś îḿâǵêś ŵít̂h́ ĉór̂ŕêćt̂ áŝṕêćt̂ ŕât́îó" }, "lighthouse-core/audits/image-aspect-ratio.js | warningCompute": { - "message": "Îńv̂ál̂íd̂ ím̂áĝé ŝíẑín̂ǵ îńf̂ór̂ḿât́îón̂ {url}" + "message": "Îńv̂ál̂íd̂ ím̂áĝé ŝíẑín̂ǵ îńf̂ór̂ḿât́îón̂ $ICU_0$", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://image.cdn.com/" + } + } }, "lighthouse-core/audits/is-on-https.js | columnInsecureURL": { "message": "Îńŝéĉúr̂é ÛŔL̂" @@ -2188,25 +2212,53 @@ } }, "lighthouse-core/audits/seo/canonical.js | explanationConflict": { - "message": "M̂úl̂t́îṕl̂é ĉón̂f́l̂íĉt́îńĝ ÚR̂Ĺŝ ({urlList})" + "message": "M̂úl̂t́îṕl̂é ĉón̂f́l̂íĉt́îńĝ ÚR̂Ĺŝ ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{urlList}", + "example": "https://example.com, https://example2.com" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain": { - "message": "P̂óîńt̂ś t̂ó â d́îf́f̂ér̂én̂t́ d̂óm̂áîń ({url})" + "message": "P̂óîńt̂ś t̂ó â d́îf́f̂ér̂én̂t́ d̂óm̂áîń ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationInvalid": { - "message": "Îńv̂ál̂íd̂ ÚR̂Ĺ ({url})" + "message": "Îńv̂ál̂íd̂ ÚR̂Ĺ ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ $MARKDOWN_SNIPPET_0$ ĺôćât́îón̂ ({url})", + "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ $MARKDOWN_SNIPPET_0$ ĺôćât́îón̂ ($ICU_0$)", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`hreflang`", "example": "hreflang" + }, + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" } } }, "lighthouse-core/audits/seo/canonical.js | explanationRelative": { - "message": "R̂él̂át̂ív̂é ÛŔL̂ ({url})" + "message": "R̂él̂át̂ív̂é ÛŔL̂ ($ICU_0$)", + "placeholders": { + "ICU_0": { + "content": "{url}", + "example": "https://example.com/" + } + } }, "lighthouse-core/audits/seo/canonical.js | explanationRoot": { "message": "P̂óîńt̂ś t̂ó t̂h́ê d́ôḿâín̂'ś r̂óôt́ ÛŔL̂ (t́ĥé ĥóm̂ép̂áĝé), îńŝt́êád̂ óf̂ án̂ éq̂úîv́âĺêńt̂ ṕâǵê óf̂ ćôńt̂én̂t́" @@ -2430,7 +2482,13 @@ "message": "Îf́ ŷóûŕ r̂ób̂ót̂ś.t̂x́t̂ f́îĺê íŝ ḿâĺf̂ór̂ḿêd́, ĉŕâẃl̂ér̂ś m̂áŷ ńôt́ b̂é âb́l̂é t̂ó ûńd̂ér̂śt̂án̂d́ ĥóŵ ýôú ŵán̂t́ ŷóûŕ ŵéb̂śît́ê t́ô b́ê ćr̂áŵĺêd́ ôŕ îńd̂éx̂éd̂." }, "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": { - "message": "r̂éq̂úêśt̂ f́ôŕ r̂ób̂ót̂ś.t̂x́t̂ ŕêt́ûŕn̂éd̂ H́T̂T́P̂ śt̂át̂úŝ: {statusCode}" + "message": "r̂éq̂úêśt̂ f́ôŕ r̂ób̂ót̂ś.t̂x́t̂ ŕêt́ûŕn̂éd̂ H́T̂T́P̂ śt̂át̂úŝ: $ICU_0$", + "placeholders": { + "ICU_0": { + "content": "{statusCode}", + "example": "500" + } + } }, "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": { "message": "{itemCount, plural,\n =1 {1 êŕr̂ór̂ f́ôún̂d́}\n other {# êŕr̂ór̂ś f̂óûńd̂}\n }" @@ -2561,11 +2619,15 @@ "message": "Ûśêŕ T̂ím̂ín̂ǵ m̂ár̂ḱŝ án̂d́ m̂éâśûŕêś" }, "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"{securityOrigin}\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ.", + "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"$ICU_0$\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`crossorigin`", "example": "crossorigin" + }, + "ICU_0": { + "content": "{securityOrigin}", + "example": "<link rel=\"preconnect\" href=\"...\">" } } }, @@ -2584,11 +2646,15 @@ "message": "P̂ŕêćôńn̂éĉt́ t̂ó r̂éq̂úîŕêd́ ôŕîǵîńŝ" }, "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý.", + "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"$ICU_0$\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý.", "placeholders": { "MARKDOWN_SNIPPET_0": { "content": "`crossorigin`", "example": "crossorigin" + }, + "ICU_0": { + "content": "{preloadURL}", + "example": "<link rel=\"preload\" href=\"...\">" } } }, diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 340d0ae0e3d3..56015ff112a0 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -22,6 +22,7 @@ // @ts-ignore - @types/esprima lacks all of these function computeDescription(ast, property, value, startRange) { const endRange = property.range[0]; + const findIcu = /\{(\w+)\}/g; for (const comment of ast.comments || []) { if (comment.range[0] < startRange) continue; if (comment.range[0] > endRange) continue; @@ -43,19 +44,26 @@ function computeDescription(ast, property, value, startRange) { } else if (tagName === 'example') { // Make sure the ICU var exists in string if (!value.includes(placeholder)) { - throw Error('Example missing ICU replacement'); + throw Error(`Example missing ICU replacement in message "${message}"`); } examples[placeholder.substring(1, placeholder.length - 1)] = message; } } // Make sure all ICU vars have examples - const rMini = /\{(\w+)\}/g; - while ((resArr = rMini.exec(value)) !== null) { + while ((resArr = findIcu.exec(value)) !== null) { const varName = resArr[1]; - if (!examples[varName]) throw Error(`Variable '${varName}' is missing example comment`); + if (!examples[varName]) { + throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); + } } return {description, examples}; } + // Make sure all ICU vars have examples + if (value.match(findIcu)) { + throw Error(`Variable '${value.match(/.*\{(\w+)\}.*/)[1]}' ` + + `is missing example comment in message "${value}"`); + } + return {description: comment.value.replace('*', '').trim()}; } return {}; diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collection-util-test.js index 465f62925663..f098ee93c779 100644 --- a/lighthouse-core/test/scripts/i18n/collection-util-test.js +++ b/lighthouse-core/test/scripts/i18n/collection-util-test.js @@ -92,7 +92,7 @@ describe('Compute Description', () => { const stmt = ast.body[0]; const prop = stmt.declarations[0].init.properties[0]; expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) - .toThrow(/Example missing ICU replacement/); + .toThrow(/Example missing ICU replacement in message "Variable example."/); }); it('errors when variable has no example', () => { @@ -108,8 +108,23 @@ describe('Compute Description', () => { const stmt = ast.body[0]; const prop = stmt.declarations[0].init.properties[0]; - expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)) - .toThrow(/Variable 'variable' is missing example comment/); + expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)).toThrow( + /Variable 'variable' is missing example comment in message "Hello World {variable}"/); + }); + + it('errors when variable has no example, with basic description', () => { + const justUIStrings = + `const UIStrings = { + /** Tagged description for Hello World. */ + message: 'Hello World {variable}', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)).toThrow( + /Variable 'variable' is missing example comment in message "Hello World {variable}"/); }); }); From 6160402725935f8213f66ed6cd1ce3ab159f2a91 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 17:36:24 -0700 Subject: [PATCH 25/71] Patrick foodback --- lighthouse-core/lib/i18n/README.md | 2 +- .../scripts/i18n/collect-strings.js | 15 +++++------ .../scripts/i18n/collection-util.js | 27 +++++++++---------- .../test/scripts/i18n/collection-util-test.js | 24 ++++++++++++++--- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index eab0f9c208b1..4c2997d7a45f 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -271,7 +271,7 @@ TODO(exterkamp): Simple example ```javascript message = "Total size was {totalBytes, number, bytes} KB" - sent_values = {totalBytes: 10.75} + sent_values = {totalBytes: 10240} ``` Becomes... diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 767c9f642964..32c9ba24bdee 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -11,7 +11,7 @@ const fs = require('fs'); const path = require('path'); const esprima = require('esprima'); -const collUtil = require('./collection-util.js'); +const collectionUtil = require('./collection-util.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; @@ -81,17 +81,16 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - const res = collUtil.computeDescription(ast, property, val, lastPropertyEndIndex); + const {description, examples} = collectionUtil.computeDescription(ast, property, val, lastPropertyEndIndex); - const description = res.description; - const examples = res.examples; + const converted = collectionUtil.convertMessageToPlaceholders(val, examples); - const converted = collUtil.convertMessageToPlaceholders(val, examples); + const messageKey = `${relativePath} | ${key}`; if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { - strings[`${relativePath} | ${key}`] = {message: converted.message, description}; + strings[messageKey] = {message: converted.message, description}; } else { - strings[`${relativePath} | ${key}`] = {message: converted.message, description, placeholders: converted.placeholders}; + strings[messageKey] = {message: converted.message, description, placeholders: converted.placeholders}; } lastPropertyEndIndex = property.range[1]; } @@ -123,7 +122,7 @@ function writeStringsToLocaleFormat(locale, strings) { } const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core')); -const psuedoLocalizedStrings = collUtil.createPsuedoLocaleStrings(strings); +const psuedoLocalizedStrings = collectionUtil.createPsuedoLocaleStrings(strings); console.log('Collected from LH core!'); collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 56015ff112a0..9980671ca8bc 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -64,6 +64,7 @@ function computeDescription(ast, property, value, startRange) { `is missing example comment in message "${value}"`); } + // The entire comment is the description, so return everything. return {description: comment.value.replace('*', '').trim()}; } return {}; @@ -92,7 +93,7 @@ function convertMessageToPlaceholders(message, examples = {}) { // Complex ICU using non-supported format if (message.match( /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { - throw Error(`Non supported ICU format in message "${message}"`); + throw Error(`Unsupported ICU format in message "${message}"`); } // replace code snippets @@ -105,9 +106,10 @@ function convertMessageToPlaceholders(message, examples = {}) { newMessage += preambleText; if (codeText) { const pName = `MARKDOWN_SNIPPET_${idx++}`; - newMessage += `$${pName}$`; + // Backtick replacement looks unreadable here, so .join() instead. + newMessage += ['$', pName, '$'].join(''); placeholders[pName] = { - content: `\`${codeText}\``, + content: ['`', codeText, '`'].join(''), example: codeText, }; } @@ -252,31 +254,28 @@ function createPsuedoLocaleStrings(strings) { * @returns {Record<string, ICUMessageDefn>} */ function bakePlaceholders(messages) { - for (const key in messages) { - if (!Object.prototype.hasOwnProperty.call(messages, key)) continue; + for (const [_, defn] of Object.entries(messages)) { + delete defn['description']; - delete messages[key]['description']; - - let message = messages[key]['message']; - const placeholders = messages[key]['placeholders']; + let message = defn['message']; + const placeholders = defn['placeholders']; for (const placeholder in placeholders) { if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; const content = placeholders[placeholder]['content']; - const re = new RegExp('\\$' + placeholder + '\\$'); - if (!message.match(re)) { + if (!message.includes(`$${placeholder}$`)) { throw Error(`Message "${message}" has extra placeholder "${placeholder}"`); } - message = message.replace(re, content); + message = message.replace(`$${placeholder}$`, content); } // Sanity check that all placeholders are gone if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); - messages[key]['message'] = message; + defn['message'] = message; - delete messages[key]['placeholders']; + delete defn['placeholders']; } return messages; } diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collection-util-test.js index f098ee93c779..25575ce68596 100644 --- a/lighthouse-core/test/scripts/i18n/collection-util-test.js +++ b/lighthouse-core/test/scripts/i18n/collection-util-test.js @@ -58,6 +58,25 @@ describe('Compute Description', () => { expect(res.description).toBe('Tagged description for Hello World.'); }); + it.skip('collects complex multi-line description', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description Tagged description for Hello World, + * which is a long description, that wraps. + */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + const res = collect.computeDescription(ast, prop, 'Hello World', 0); + expect(res.description) + .toBe('Tagged description for Hello World, which is a long description, that wraps.'); + }); + it('collects complex description with example', () => { const justUIStrings = `const UIStrings = { @@ -132,8 +151,7 @@ describe('Convert Message to Placeholder', () => { it('passthroughs a basic message unchanged', () => { const message = 'Hello World.'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res.message).toBe(message); - expect(res.placeholders).toEqual({}); + expect(res).toEqual({message, placeholders: {}}); }); it('converts code block to placeholder', () => { @@ -243,7 +261,7 @@ describe('Convert Message to Placeholder', () => { it('errors when using non-supported complex ICU format', () => { const message = 'Hello World took {var, number, global_int}.'; expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( - /Non supported ICU format in message "Hello World took {var, number, global_int}\."/); + /Unsupported ICU format in message "Hello World took {var, number, global_int}\."/); }); it('converts direct ICU with examples to placeholders', () => { From 02e8977a81fc99e1730fa99b5d4887d41db86fcc Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 17:53:29 -0700 Subject: [PATCH 26/71] ICU select & ordinal readme examples. made runtime example more accurate. --- lighthouse-core/lib/i18n/README.md | 44 +++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 4c2997d7a45f..df4e344ce015 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -2,9 +2,37 @@ ## ICU Syntax -### Ordinals +More about [complex ICU](http://userguide.icu-project.org/formatparse/messages) +formatting. + +### Selects + +A select ICU message is used when the message should select a sub-message based +on the value of a variable `pronoun` in this case. This is often used for gender +based selections, but can be used for any enum. Lighthouse does not use selects +very often. + +```javascript +displayValue: `{pronoun, select, + male {He programmed the link.} + female {She programmed the link.} + other {They programmed the link} + }`, +``` + +### Ordinals (Numeric Selects) + +An ordinal ICU message is used when the message contains "plurals", wherein a +sub-message would need to be selected from a list of messages depending on the +value of `itemCount` (in this example). They are a flavor of "Selects" that +have a unique syntax. -### Selects (Gender) +```javascript +displayValue: `{itemCount, plural, + =1 {1 link found} + other {# links found} + }`, +``` ### Primitive Formatting @@ -119,7 +147,7 @@ directly in UIStrings. They follow 1 of 3 flavors. }; ``` - ICU replacements can also use a JSDoc type syntax to specify an example for + ICU replacements must use a JSDoc type syntax to specify an example for direct ICU replacements. * To specify the description, use @@ -147,7 +175,8 @@ directly in UIStrings. They follow 1 of 3 flavors. percentages. Note: these complex ICU formats are automatically given example values based - on their ICU format as specified in `collect-strings.js` + on their ICU format as specified in `collect-strings.js`. Therefore a normal + description string can be used. ```javascript const UIStrings = { @@ -203,9 +232,6 @@ $ sh google_import_script_that_calls_correct_strings #### String Replacement Pipeline (runtime) -`file_with_UIStrings.js -> exported to locale.json file -> read by i18n.js -> -$placeholder$'s replaced -> {ICU} syntax replaced => final string` - 1. String called in `.js` file, converted to i18n id. 2. i18n id in lookup table along with backup message. @@ -213,9 +239,7 @@ $placeholder$'s replaced -> {ICU} syntax replaced => final string` 3. Message is looked up via `replaceIcuMessageInstanceIds` & `_formatIcuMessage`. -TODO(exterkamp): Simple example - -##### Simple example, no ICU: +##### Example: 1. string in `file_with_UIStrings.js` From f5083b81d6ce1c936c3bcf3872bb3fe39f15a912 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 18:13:00 -0700 Subject: [PATCH 27/71] collection-util docstrings --- .../scripts/i18n/collection-util.js | 71 +++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 9980671ca8bc..0ed7362a1b53 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -71,8 +71,36 @@ function computeDescription(ast, property, value, startRange) { } /** - * @param {*} message - * @param {*} examples + * Take a series of lighthouse-i18n-json format ICU messages and converts them + * to messages.json format by replacing {ICU} and `markdown` with + * $placeholders$. Functional opposite of `bakePlaceholders`. This is commonly + * called as one of the first steps in translation, via collect-strings.js. + * + * Converts this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ({url})", + * }, + * }, + * } + * + * Into this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ($ICU_0$)", + * "placeholders": { + * "ICU_0": { + * "content": "{url}", + * "example": "https://example.com/" + * }, + * }, + * }, + * } + * + * Throws if the message violates some basic sanity checking. + * + * @param {string} message + * @param {Record<string, string>} examples * @returns {ICUMessageDefn} */ function convertMessageToPlaceholders(message, examples = {}) { @@ -184,7 +212,6 @@ function convertMessageToPlaceholders(message, examples = {}) { // add examples for direct ICU replacement idx = 0; - // eslint-disable-next-line guard-for-in for (const [key, value] of Object.entries(examples)) { if (!newMessage.includes(`{${key}}`)) continue; const eName = `ICU_${idx++}`; @@ -201,12 +228,15 @@ function convertMessageToPlaceholders(message, examples = {}) { /** - * @param {Record<string, ICUMessageDefn>} strings + * Take a series of messages and apply ĥât̂ markers to the translatable portions + * of the text. Used to generate `en-XL` locale to debug i18n strings. + * + * @param {Record<string, ICUMessageDefn>} messages */ -function createPsuedoLocaleStrings(strings) { +function createPsuedoLocaleStrings(messages) { /** @type {Record<string, ICUMessageDefn>} */ const psuedoLocalizedStrings = {}; - for (const [key, defn] of Object.entries(strings)) { + for (const [key, defn] of Object.entries(messages)) { const message = defn.message; const psuedoLocalizedString = []; let braceCount = 0; @@ -250,6 +280,35 @@ function createPsuedoLocaleStrings(strings) { } /** + * Take a series of messages.json format ICU messages and converts them to + * lighthouse-i18n-json format by replacing $placeholders$ with their {ICU} + * values. Functional opposite of `convertMessageToPlaceholders`. This is + * commonly called as the last step in translation, via correct-strings.js. + * + * Converts this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ($ICU_0$)", + * "placeholders": { + * "ICU_0": { + * "content": "{url}", + * "example": "https://example.com/" + * }, + * }, + * }, + * } + * + * Into this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ({url})", + * }, + * }, + * } + * + * Throws if there is a $placeholder$ in the message that has no corresponding + * value in the placeholders object, or vice versa. + * * @param {Record<string, ICUMessageDefn>} messages * @returns {Record<string, ICUMessageDefn>} */ From 5aca05a9db94bdec614d82cbeea8d5f760d5e3b4 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 8 Jul 2019 18:31:00 -0700 Subject: [PATCH 28/71] remove old console log --- lighthouse-core/lib/i18n/i18n.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index d754de0d965a..281c7118bcd6 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -129,7 +129,6 @@ function lookupLocale(locale) { */ function _preprocessMessageValues(icuMessage, values) { if (!values) return; - // console.log(icuMessage, values); const clonedValues = JSON.parse(JSON.stringify(values)); const parsed = MessageParser.parse(icuMessage); // Throw an error if a message's value isn't provided From ee3e235bfb223b13163318b2cffce446e0b6622f Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 9 Jul 2019 00:02:16 -0700 Subject: [PATCH 29/71] update assert on strings to new en-US --- lighthouse-core/scripts/i18n/assert-strings-collected.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/scripts/i18n/assert-strings-collected.sh b/lighthouse-core/scripts/i18n/assert-strings-collected.sh index c6e4384b8151..3ddc1b0a88e0 100755 --- a/lighthouse-core/scripts/i18n/assert-strings-collected.sh +++ b/lighthouse-core/scripts/i18n/assert-strings-collected.sh @@ -18,7 +18,7 @@ colorText() { printf "\\n$2$1%b\\n" '\033[0m' } -collectedstringsPath="$lhroot_path/lighthouse-core/lib/i18n/en-US.json"; +collectedstringsPath="$lhroot_path/lighthouse-core/lib/i18n/locales/en-US.json"; currentstringsPath="$lh_tmp_path/current_strings.json"; freshstringsPath="$lh_tmp_path/fresh_strings.json"; From 6b8297d24a55dc38b51b2c7d2e4c7579cda04b55 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 9 Jul 2019 00:41:40 -0700 Subject: [PATCH 30/71] polish --- .../audits/byte-efficiency/unminified-css.js | 5 +- lighthouse-core/lib/i18n/i18n.js | 9 +--- lighthouse-core/lib/i18n/locales/de.json | 46 +------------------ .../lib/i18n/pre-locale/en-US.json | 2 +- .../scripts/i18n/collect-strings.js | 3 -- .../scripts/i18n/collection-util.js | 1 - .../scripts/i18n/correct-strings.js | 4 +- lighthouse-core/test/lib/i18n/i18n-test.js | 1 - 8 files changed, 9 insertions(+), 62 deletions(-) diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 59bb3b3fe224..4ebde58c6e81 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -13,8 +13,9 @@ const computeTokenLength = require('../../lib/minification-estimator.js').comput const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates. */ title: 'Minify CSS', - /** (Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ - description: 'Minifying CSS files can reduce network payload sizes. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', + /** Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + description: 'Minifying CSS files can reduce network payload sizes. ' + + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 281c7118bcd6..c4e1633e9eea 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -129,6 +129,7 @@ function lookupLocale(locale) { */ function _preprocessMessageValues(icuMessage, values) { if (!values) return; + const clonedValues = JSON.parse(JSON.stringify(values)); const parsed = MessageParser.parse(icuMessage); // Throw an error if a message's value isn't provided @@ -168,9 +169,6 @@ function _preprocessMessageValues(icuMessage, values) { * @prop {*} [values] */ -// Only used for value lookups, default mapping to en is done with a lookup to the en file, -// not this pre-baked msg map. - /** @type {Map<string, IcuMessageInstance[]>} */ const _icuMessageInstanceMap = new Map(); @@ -184,7 +182,6 @@ const _ICUMsgNotFoundMsg = 'ICU message not found in destination locale'; * @return {{formattedString: string, icuMessage: string}} */ function _formatIcuMessage(locale, icuMessageId, fallbackMessage, values) { - // console.log(locale, icuMessageId); const localeMessages = LOCALES[locale]; if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`); let localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; @@ -236,8 +233,6 @@ function _formatPathAsString(pathInLHR) { */ function getRendererFormattedStrings(locale) { const localeMessages = LOCALES[locale]; - // console.log(locale); - // console.log(localeMessages); if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`); const icuMessageIds = Object.keys(localeMessages).filter(f => f.includes('core/report/html/')); @@ -342,7 +337,7 @@ function _resolveIcuMessageInstanceId(icuMessageInstanceId, locale) { const [_, icuMessageId, icuMessageInstanceIndex] = matches; const icuMessageInstances = _icuMessageInstanceMap.get(icuMessageId) || []; const icuMessageInstance = icuMessageInstances[Number(icuMessageInstanceIndex)]; - // console.log(locale, "-->", icuMessageId); + const {formattedString} = _formatIcuMessage(locale, icuMessageId, icuMessageInstance.icuMessage, icuMessageInstance.values); diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index af886f9bb1fc..47731ac6e12c 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -369,52 +369,10 @@ "message": "Vermeidet sehr große Netzwerknutzlasten" }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Durch die Komprimierung von CSS-Dateien kann die Größe von Netzwerknutzlasten reduziert werden. $link_start$Weitere Informationen$link_end$. This audit took $milliseconds$ ms.", - "placeholders": { - "link_start": { - "content": "[->" - }, - "link_end": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - }, - "milliseconds": { - "content": "{timeInMs, number, milliseconds}", - "example": "520" - } - } + "message": "Durch die Komprimierung von CSS-Dateien kann die Größe von Netzwerknutzlasten reduziert werden. [Weitere Informationen](https://developers.google.com/web/tools/lighthouse/audits/minify-css)." }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "CSS komprimieren $css$", - "placeholders": { - "css": { - "content": "`<link rel=stylesheet>`" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender": { - "message": "<GERMAN> Someone minified this, {direct_replace_name}. $static_replacement$ {person, select, female {<GERMAN> She minified this CSS.} male {<GERMAN> He minified this CSS.} other {<GERMAN> They minified this CSS.}}", - "placeholders": { - "static_replacement": { - "content": "`<link rel=>`", - "example": "Some static replacement." - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | explanationGender2": { - "message": "Someone minified this, $name$. $static_replacement$ {person, select, female {She minified this CSS.} male {He minified this CSS.} other {They minified this CSS.}}", - "placeholders": { - "static_replacement": { - "content": "`<link rel=>`", - "example": "Some static replacement." - }, - "name": { - "content": "{name}", - "example": "This stutters, BUT we have the opportunity to tell translators an example, and give context? Example text: Karen." - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | warningPlural": { - "message": "{itemCount, plural, =1 {<GERMAN> # error found}other {<GERMAN> # errors found}}" + "message": "CSS komprimieren" }, "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { "message": "Durch die Komprimierung von JavaScript-Dateien können Nutzlastgrößen und die Zeit zum Parsen von Skripts reduziert werden. [Weitere Informationen](https://developers.google.com/speed/docs/insights/MinifyResources)." diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json index 5682481831f3..8f6d6f7f1143 100644 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ b/lighthouse-core/lib/i18n/pre-locale/en-US.json @@ -1513,7 +1513,7 @@ }, "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "(Message Description goes here) Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", + "description": "Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", "placeholders": { "LINK_START_0": { "content": "[" diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 32c9ba24bdee..695d5212f0db 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -107,9 +107,6 @@ function collectAllStringsInDir(dir, strings = {}) { * @param {Record<string, ICUMessageDefn>} strings */ function writeStringsToLocaleFormat(locale, strings) { - // function writeEnStringsToLocaleFormat(strings) { - // const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/pre-locale/en-US.json`); - const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/${locale}.json`); /** @type {Record<string, ICUMessageDefn>} */ const output = {}; diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 0ed7362a1b53..79fba616e27e 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -104,7 +104,6 @@ function computeDescription(ast, property, value, startRange) { * @returns {ICUMessageDefn} */ function convertMessageToPlaceholders(message, examples = {}) { - // console.log(examples); // Basically the same as markdown parsing in dom.js /** @type {Record<string, ICUPlaceholderDefn>} */ const placeholders = {}; diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js index ef93e7247777..fcac5c81c270 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -1,6 +1,6 @@ #!/usr/bin/env node /** - * @license Copyright 2018 Google Inc. All Rights Reserved. + * @license Copyright 2019 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ @@ -63,8 +63,6 @@ function collectAllPreLocaleStrings(dir, output) { } } -// collectAllPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/')); - module.exports = { collectAllPreLocaleStrings, }; diff --git a/lighthouse-core/test/lib/i18n/i18n-test.js b/lighthouse-core/test/lib/i18n/i18n-test.js index 9397c141486e..185c1df5e9a9 100644 --- a/lighthouse-core/test/lib/i18n/i18n-test.js +++ b/lighthouse-core/test/lib/i18n/i18n-test.js @@ -103,7 +103,6 @@ describe('i18n', () => { helloTimeInMsWorld: 'Hello {timeInMs, number, seconds} World', helloPercentWorld: 'Hello {in, number, extendedPercent} World', }; - const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); it('formats a basic message', () => { From 77fcd92783855222df774d93e9cbc1b4cae925a5 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 9 Jul 2019 01:34:57 -0700 Subject: [PATCH 31/71] refactoring conversion method, testing conversion to follow. --- .../scripts/i18n/collection-util.js | 143 +++++++++++------- 1 file changed, 91 insertions(+), 52 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 79fba616e27e..22a73aca1527 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -33,11 +33,11 @@ function computeDescription(ast, property, value, startRange) { const examples = {}; const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; - let resArr; - while ((resArr = r.exec(comment.value)) !== null) { - const tagName = resArr[1]; - const placeholder = resArr[2]; - const message = resArr[3].trim(); + let matches; + while ((matches = r.exec(comment.value)) !== null) { + const tagName = matches[1]; + const placeholder = matches[2]; + const message = matches[3].trim(); if (tagName === 'description') { description = message; @@ -50,8 +50,8 @@ function computeDescription(ast, property, value, startRange) { } } // Make sure all ICU vars have examples - while ((resArr = findIcu.exec(value)) !== null) { - const varName = resArr[1]; + while ((matches = findIcu.exec(value)) !== null) { + const varName = matches[1]; if (!examples[varName]) { throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); } @@ -105,85 +105,118 @@ function computeDescription(ast, property, value, startRange) { */ function convertMessageToPlaceholders(message, examples = {}) { // Basically the same as markdown parsing in dom.js - /** @type {Record<string, ICUPlaceholderDefn>} */ - const placeholders = {}; + const icu = { + message, + placeholders: {}, + }; - // Sanity checks - // Number of backticks is even. - if ((message.split('`').length - 1) % 2 !== 0) { - throw Error(`Open backtick in message "${message}"`); - } - // Link markdown is not slightly off. - if (message.match(/\[.*\] \(.*\)/)) { - throw Error(`Bad Link syntax in message "${message}"`); - } - // Complex ICU using non-supported format - if (message.match( - /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { - throw Error(`Unsupported ICU format in message "${message}"`); + // Process each placeholder type + _processPlaceholderMarkdownCode(icu); + + _processPlaceholderMarkdownLink(icu); + + _processPlaceholderComplexIcu(icu); + + _processPlaceholderDirectIcu(icu, examples); + + return icu; +} + +/** + * Convert markdown code blocks into placeholders with examples. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderMarkdownCode(icu) { + // Check that number of backticks is even. + if ((icu.message.split('`').length - 1) % 2 !== 0) { + throw Error(`Open backtick in message "${icu.message}"`); } - // replace code snippets - let parts = message.split(/`(.*?)`/g); // Split on markdown code slashes - let newMessage = ''; + // Split on markdown code slashes + const parts = icu.message.split(/`(.*?)`/g); + icu.message = ''; let idx = 0; while (parts.length) { // Pop off the same number of elements as there are capture groups. const [preambleText, codeText] = parts.splice(0, 2); - newMessage += preambleText; + icu.message += preambleText; if (codeText) { const pName = `MARKDOWN_SNIPPET_${idx++}`; // Backtick replacement looks unreadable here, so .join() instead. - newMessage += ['$', pName, '$'].join(''); - placeholders[pName] = { + icu.message += ['$', pName, '$'].join(''); + icu.placeholders[pName] = { content: ['`', codeText, '`'].join(''), example: codeText, }; } } +} + +/** + * Convert markdown html links into placeholders. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderMarkdownLink(icu) { + // Check that link markdown is not slightly off. + if (icu.message.match(/\[.*\] \(.*\)/)) { + throw Error(`Bad Link syntax in message "${icu.message}"`); + } - // replace links // Split on markdown links (e.g. [some link](https://...)). - parts = newMessage.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); - newMessage = ''; - idx = 0; + const parts = icu.message.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); + icu.message = ''; + let idx = 0; while (parts.length) { // Pop off the same number of elements as there are capture groups. const [preambleText, linkText, linkHref] = parts.splice(0, 3); - newMessage += preambleText; + icu.message += preambleText; // Append link if there are any. if (linkText && linkHref) { const ls = `LINK_START_${idx}`; const le = `LINK_END_${idx++}`; const repr = `$${ls}$${linkText}$${le}$`; - newMessage += repr; - placeholders[ls] = { + icu.message += repr; + icu.placeholders[ls] = { content: '[', }; - placeholders[le] = { + icu.placeholders[le] = { content: `](${linkHref})`, }; } } +} - // replace complex ICU numbers - // milliseconds, seconds, bytes, extendedPercent, percent, etc. - parts = newMessage.split( +/** + * Convert complex ICU syntax into placeholders with examples. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderComplexIcu(icu) { + // Check that complex ICU not using non-supported format + if (icu.message.match( + /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { + throw Error(`Unsupported ICU format in message "${icu.message}"`); + } + + // Split on complex ICU: {var, number, type} + const parts = icu.message.split( /\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); - newMessage = ''; - idx = 0; + icu.message = ''; + let idx = 0; while (parts.length) { // Pop off the same number of elements as there are capture groups. const [preambleText, varName, icuType] = parts.splice(0, 3); - newMessage += preambleText; + icu.message += preambleText; // Append link if there are any. if (varName && icuType) { const iName = `COMPLEX_ICU_${idx++}`; - newMessage += `$${iName}$`; + icu.message += `$${iName}$`; let example = '0'; // Make some good examples. @@ -202,30 +235,36 @@ function convertMessageToPlaceholders(message, examples = {}) { example = '499'; } - placeholders[iName] = { + icu.placeholders[iName] = { content: `{${varName}, number, ${icuType}}`, example: example, }; } } +} - // add examples for direct ICU replacement - idx = 0; +/** + * Add examples for direct ICU replacement. + * + * @param {ICUMessageDefn} icu + * @param {Record<string, string>} examples + */ +function _processPlaceholderDirectIcu(icu, examples) { + let tempMessage = icu.message; + let idx = 0; for (const [key, value] of Object.entries(examples)) { - if (!newMessage.includes(`{${key}}`)) continue; + if (!icu.message.includes(`{${key}}`)) continue; const eName = `ICU_${idx++}`; - newMessage = newMessage.replace(`{${key}}`, `$${eName}$`); + tempMessage = tempMessage.replace(`{${key}}`, `$${eName}$`); - placeholders[eName] = { + icu.placeholders[eName] = { content: `{${key}}`, example: value, }; } - - return {message: newMessage, placeholders}; + icu.message = tempMessage; } - /** * Take a series of messages and apply ĥât̂ markers to the translatable portions * of the text. Used to generate `en-XL` locale to debug i18n strings. From 7252f3d1645e78f5b8b9728c5a241fa8389842a3 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 9 Jul 2019 17:38:52 -0700 Subject: [PATCH 32/71] brendan readme foodback. --- lighthouse-core/lib/i18n/README.md | 165 +++++++++++------------------ 1 file changed, 59 insertions(+), 106 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index df4e344ce015..b0cbebed7f28 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -2,30 +2,11 @@ ## ICU Syntax -More about [complex ICU](http://userguide.icu-project.org/formatparse/messages) -formatting. - -### Selects - -A select ICU message is used when the message should select a sub-message based -on the value of a variable `pronoun` in this case. This is often used for gender -based selections, but can be used for any enum. Lighthouse does not use selects -very often. - -```javascript -displayValue: `{pronoun, select, - male {He programmed the link.} - female {She programmed the link.} - other {They programmed the link} - }`, -``` +More about [complex ICU](http://userguide.icu-project.org/formatparse/messages) formatting. ### Ordinals (Numeric Selects) -An ordinal ICU message is used when the message contains "plurals", wherein a -sub-message would need to be selected from a list of messages depending on the -value of `itemCount` (in this example). They are a flavor of "Selects" that -have a unique syntax. +An ordinal ICU message is used when the message contains "plurals", wherein a sub-message would need to be selected from a list of messages depending on the value of `itemCount` (in this example). They are a flavor of "Selects" that have a unique syntax. ```javascript displayValue: `{itemCount, plural, @@ -36,16 +17,31 @@ displayValue: `{itemCount, plural, ### Primitive Formatting -This include number formatting like `{timeInMs, number, milliseconds}` and -string replacements like `{some_name}`. +This include number formatting like `{timeInMs, number, milliseconds}` and string replacements like `{some_name}`. + +Note: In the context of Lighthouse we make the distinction between these kinds of ICU formatting. + +* `{timeInMs, number, milliseconds}` is called "Complex ICU" since the replacement is for complex numbers and uses the custom formatters in Lighthouse. The supported complex ICU formats are: milliseconds, seconds, bytes, percent, and extendedPercent. + +* `{some_name}` is called "Direct ICU" since the replacement is a direct substitution of ICU with a variable and uses no custom formatting. + +### Selects + +A select ICU message is used when the message should select a sub-message based on the value of a variable `pronoun` in this case. This is often used for gender based selections, but can be used for any enum. Lighthouse does not use selects very often. + +```javascript +displayValue: `{pronoun, select, + male {He programmed the link.} + female {She programmed the link.} + other {They programmed the link} + }`, +``` ## message.json Syntax ### Why we use message.json -It is the -[Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for -i18n messages. +It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for i18n messages. ### Parts of a message.json message @@ -68,12 +64,9 @@ i18n messages. ## Our message system -We use UIStrings & i18n.js to extract strings from individual js files into -locale.json files. This allows us to keep strings close to the code in which -they are used so that developers can easily understand their context. It also -comes with its own syntax. +We use UIStrings & i18n.js to extract strings from individual js files into locale.json files. This allows us to keep strings close to the code in which they are used so that developers can easily understand their context. It also comes with its own syntax. -UIStrings are defined in a simple Object with properties defining the strings. +UIStrings are defined in an Object with the strings as its properties. JSDoc is used to provide additional information about each string. * simple string named "title", with no description: @@ -94,16 +87,11 @@ UIStrings are defined in a simple Object with properties defining the strings. ### Markdown -Strings can also contain some limited markdown, that will be rendered in the -report. +Some strings, like audit descriptions, can also contain a subset of markdown. See [`audit.d.ts`](https://github.com/GoogleChrome/lighthouse/blob/5e52dcca72b35943d14cc7c27613517c425250b9/types/audit.d.ts) for which properties support markdown rendering and will be rendered in the report. -* Code block. +* Inline code block. - To format some text as code it should be contained in `backticks`. These - should be used whenever code is non-translatable. Such as HTML tags or - snippets of code. Also note that there is no escape character for using - backticks as part of the string, so ONLY use backticks to define code - blocks. + To format some text as code it should be contained in `backticks`. Any text within the backticks will not be translated. This should be used whenever code is non-translatable. Such as HTML tags or snippets of code. Also note that there is no escape character for using backticks as part of the string, so ONLY use backticks to define code blocks. Example usage: @@ -115,10 +103,7 @@ report. * Link. - To convert a section of text into a link to another URL, enclose the text - itself in [brackets] and then immediately include a link after it in - (parenthesis). Note that `[link text] (https://...)` is NOT VALID because of - the space and will not be converted to a link. + To convert a section of text into a link to another URL, enclose the text itself in [brackets] and then immediately include a link after it in (parentheses). Note that `[link text] (https://...)` is NOT VALID because of the space and will not be converted to a link. Example usage: @@ -130,25 +115,13 @@ report. ### ICU Replacement Syntax -ICU syntax is used throughout Lighthouse strings, and they are specified -directly in UIStrings. They follow 1 of 3 flavors. +ICU syntax is used throughout Lighthouse strings, and they are specified directly in UIStrings. They follow 1 of 2 flavors. * Direct replacement - This is simply a direct replacement of text into a string. Often used for - Proper Nouns, code, or other text that is dynamic and added at runtime, but - requires no additional formatting. + This is simply a direct replacement of text into a string. Often used for proper nouns, code, or other text that is dynamic and added at runtime, but requires no additional formatting. - Example usage: - - ```javascript - const UIStrings = { - didntCollectScreenshots: `Chrome didn't .... ({errorCode})`, - }; - ``` - - ICU replacements must use a JSDoc type syntax to specify an example for - direct ICU replacements. + ICU replacements must use a JSDoc type syntax to specify an example for direct ICU replacements. * To specify the description, use @@ -170,16 +143,13 @@ directly in UIStrings. They follow 1 of 3 flavors. * Complex replacement - When more complex numerical ICU replacement is needed the syntax is mostly - the same as direct replacement. This is often used when replcaing times, or - percentages. + When more complex numerical ICU replacement is needed the syntax is mostly the same as direct replacement. This is often used when replcaing times, or percentages. - Note: these complex ICU formats are automatically given example values based - on their ICU format as specified in `collect-strings.js`. Therefore a normal - description string can be used. + Note: these complex ICU formats are automatically given example values based on their ICU format as specified in `collect-strings.js`. Therefore a normal description string can be used. ```javascript const UIStrings = { + /** Description of display value. */ displayValueText: 'Interactive at {timeInMs, number, seconds} s', }; ``` @@ -188,38 +158,30 @@ TODO(exterkamp): explain all the comments and where they go/what they become. TODO(exterkamp): explain why we can't use some ICU like number formatting. +TODO(exterkamp): example of plural and ordinal. + ### The pipeline -The translation pipeline has 2 distinct stages, the collection and translation -is done pre-compile time, and the replacement is done at runtime. +The translation pipeline has 2 distinct stages, the collection and translation is done at build time, and the replacement is done at runtime. + +#### Translation Pipeline (build time) -#### Translation Pipeline (pre-compile) +1. `file_with_UIStrings.js` this is where strings start. Optimized for programmer ease of use and not for machine parsing. Uses ICU syntax and markdown control characters inline. -1. `file_with_UIStrings.js` this is where strings start. Optimized for - programmer ease of use and not for machine parsing. Uses ICU syntax and - markdown control characters inline. +2. `yarn i18n:collect-strings` collects all UIStrings, and generates the pre-locale files. Does some parsing to make sure that common mistakes are avoided. -2. `yarn i18n:collect-strings` collects all UIStrings, and generates the - pre-locales. Does some parsing to make sure that common mistakes are - avoided. +3. `pre-locale/en-US.json` this is the well formatted _machine parsable_ fileset that is uploaded to be translated, i.e. they use $placeholder$ syntax instead of ICU. These aren't used by Lighthouse's i18n system, they are solely used to send to translators. -3. `pre-locale/en-US.json` this is the well formatted _machine parsable_ - fileset that is uploaded to be translated, i.e. they use $placeholder$ - syntax instead of ICU. These will never be used by the internal i18n system, - they are solely used to send to translators. + 1. Googlers will take the `pre-locale/` files to translators and have the files translated and returned to be consumed by `correct-strings` -4. `yarn i18n:correct-strings` collects all pre-locales (or returned .json - files of all languages if you're a Googler importing strings) and converts - them back to Lighthouse json format and puts them into `locales/`. +4. `yarn i18n:correct-strings` collects all pre-locale files, or returned .json files of all languages if you're a Googler importing strings (see 3.1), and converts them back to Lighthouse json format and puts them into `locales/`. -5. `locales/{locale}.json` the Lighthouse json files. Used by the i18n.js - system to i18n strings. Uses ICU and not $placeholder$ syntax. Optimized for - i18n machine use. +5. `locales/{locale}.json` the Lighthouse json files. Used by the i18n.js system to localize strings. Uses ICU and not $placeholder$ syntax. -This pipeline is best seen with its component yarn commands: +This pipeline is best seen with its component commands: ```shell -# collect UIStrings into pre-locales +# collect UIStrings into pre-locale files $ yarn i18n:collect-strings # make the final en-US and en-XL files @@ -237,7 +199,7 @@ $ sh google_import_script_that_calls_correct_strings 2. i18n id in lookup table along with backup message. 3. Message is looked up via `replaceIcuMessageInstanceIds` & - `_formatIcuMessage`. + `getFormatted`. ##### Example: @@ -247,16 +209,16 @@ $ sh google_import_script_that_calls_correct_strings // Declare UIStrings const UIStrings = { /** Description of a Lighthouse audit that tells the user ...*/ - description: 'Minifying CSS files can reduce network payload sizes. ' + + message: 'Minifying CSS files can reduce network payload sizes. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).', }; - // i18n init + // Init the strings in this file with the i18n system. const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); // String called with i18n - // Will become id like "lighthouse-core/audits/byte-efficiency/unminified-css.js | description" - let description = str_(UIStrings.description); + // Will become id like "lighthouse-core/audits/byte-efficiency/unminified-css.js | message" + let message = str_(UIStrings.message); ``` 2. i18n lookup map registered the string (i18n.js) @@ -265,31 +227,22 @@ $ sh google_import_script_that_calls_correct_strings const _icuMessageInstanceMap = new Map(); // example value in _icuMessageInstanceMap - 'lighthouse-core/audits/byte-efficiency/unminified-css.js | description': { - icuMessageId: 'lighthouse-core/audits/byte-efficiency/unminified-css.js | description' + 'lighthouse-core/audits/byte-efficiency/unminified-css.js | message': { + icuMessageId: 'lighthouse-core/audits/byte-efficiency/unminified-css.js | message' icuMessage: 'Minifying CSS files can reduce network payload sizes. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/minify-css).' } ``` -3. Lookup in `i18n.js`. `_formatIcuMessage` will attempt to lookup in this - order: +3. Lookup in `i18n.js`. `replaceIcuMessageInstanceIds` and `getFormatted` will attempt to lookup in this order: - 1. `locales/{locale}.json` The best result, the string is found in the - target locale, and should appear correct. + 1. `locales/{locale}.json` The best result, the string is found in the target locale, and should appear correct. - 2. `locales/en.json` _Okay_ result. The string was not found in the target - locale, but was in `en`, so show the English string. + 2. `locales/en.json` _Okay_ result. The string was not found in the target locale, but was in `en`, so show the English string. - 3. The fallback message passed to `_formatIcuMessage`. This lookup is - subtley different than the en lookup. A string that is provided in the - UIStrings, but not en may be part of a swap-locale that is using an old - deprecated string, so would need to be populated by UIString replacement - here instead. + 3. The fallback message passed to `_formatIcuMessage`. This lookup is subtley different than the en lookup. A string that is provided in the UIStrings, but not en may be part of a swap-locale that is using an old deprecated string, so would need to be populated by UIString replacement here instead. - 4. Throw `_ICUMsgNotFoundMsg` Error. This is preferrable to showing the - user some id control lookup like - "lighthouse-core/audits/byte-efficiency/unminified-css.js | description" + 4. Throw `_ICUMsgNotFoundMsg` Error. This is preferrable to showing the user some id control lookup like "lighthouse-core/audits/byte-efficiency/unminified-css.js | description" This is also the point at which ICU is replaced by values. So this... From d4dd3ac0461ef3bb0a986f0d8cd1229bceea02f1 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 9 Jul 2019 17:51:46 -0700 Subject: [PATCH 33/71] check for empty descriptions --- .../scripts/i18n/collection-util.js | 13 ++++++- .../test/scripts/i18n/collection-util-test.js | 38 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js index 22a73aca1527..29c836f04d38 100644 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ b/lighthouse-core/scripts/i18n/collection-util.js @@ -56,18 +56,27 @@ function computeDescription(ast, property, value, startRange) { throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); } } + + // Make sure description is not empty + if (description.length === 0) throw Error(`Empty @description for message "${value}"`); return {description, examples}; } + + const description = comment.value.replace('*', '').trim(); + // Make sure all ICU vars have examples if (value.match(findIcu)) { throw Error(`Variable '${value.match(/.*\{(\w+)\}.*/)[1]}' ` + `is missing example comment in message "${value}"`); } + // Make sure description is not empty + if (description.length === 0) throw Error(`Empty description for message "${value}"`); + // The entire comment is the description, so return everything. - return {description: comment.value.replace('*', '').trim()}; + return {description}; } - return {}; + throw Error(`No Description for message "${value}"`); } /** diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collection-util-test.js index 25575ce68596..5730b4e07c71 100644 --- a/lighthouse-core/test/scripts/i18n/collection-util-test.js +++ b/lighthouse-core/test/scripts/i18n/collection-util-test.js @@ -26,7 +26,7 @@ describe('Compute Description', () => { expect(res.description).toBe('Description for Hello World.'); }); - it('collects nothing, when no description present', () => { + it('errors when no description present', () => { const justUIStrings = `const UIStrings = { message: 'Hello World', @@ -37,8 +37,40 @@ describe('Compute Description', () => { const stmt = ast.body[0]; const prop = stmt.declarations[0].init.properties[0]; - const res = collect.computeDescription(ast, prop, 'Hello World', 0); - expect(res.description).toBe(undefined); + expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) + .toThrow(/No Description for message "Hello World"/); + }); + + it('errors when description is blank', () => { + const justUIStrings = + `const UIStrings = { + /** */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) + .toThrow(/Empty description for message "Hello World"/); + }); + + it('errors when description is blank', () => { + const justUIStrings = + `const UIStrings = { + /** + * @description + */ + message: 'Hello World', + };`; + + const ast = esprima.parse(justUIStrings, {comment: true, range: true}); + + const stmt = ast.body[0]; + const prop = stmt.declarations[0].init.properties[0]; + expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) + .toThrow(/Empty @description for message "Hello World"/); }); it('collects complex description', () => { From 996ee5ca21db99dc256b7a24b7354f35e4cf040f Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 11 Jul 2019 10:35:36 -0700 Subject: [PATCH 34/71] Use UIString as primary fallback, since it is just en. Update fallback msg name to be more clear. --- lighthouse-core/lib/i18n/i18n.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index c4e1633e9eea..868e72bcd18f 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -177,28 +177,31 @@ const _ICUMsgNotFoundMsg = 'ICU message not found in destination locale'; * * @param {LH.Locale} locale * @param {string} icuMessageId - * @param {string=} fallbackMessage + * @param {string=} uiStringMessage The original string given in 'UIStrings', used as a backup if no locale message can be found * @param {*} [values] * @return {{formattedString: string, icuMessage: string}} */ -function _formatIcuMessage(locale, icuMessageId, fallbackMessage, values) { +function _formatIcuMessage(locale, icuMessageId, uiStringMessage, values) { const localeMessages = LOCALES[locale]; if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`); let localeMessage = localeMessages[icuMessageId] && localeMessages[icuMessageId].message; // fallback to the original english message if we couldn't find a message in the specified locale // better to have an english message than no message at all, in some number cases it won't even matter - if (!localeMessage) { - // Backup message - localeMessage = LOCALES['en'][icuMessageId] && LOCALES['en'][icuMessageId].message; - if (!localeMessage && fallbackMessage) { - // Use the fallback message at this point. - localeMessage = fallbackMessage; - } else { - // At this point, there is no reasonable string to show to the user, so throw. - throw new Error(_ICUMsgNotFoundMsg); + if (!localeMessage && uiStringMessage) { + // Try to use the original uiStringMessage + localeMessage = uiStringMessage; + + // Warn the user that the UIString message != the `en` message ∴ they should update the strings + if (LOCALES['en'][icuMessageId] && localeMessage !== LOCALES['en'][icuMessageId].message) { + log.warn('i18n', `Message "${icuMessageId}" does not match its 'en' counterpart. ` + + `Run 'collect-and-correct' to update.`); } } + // At this point, there is no reasonable string to show to the user, so throw. + if (!localeMessage) { + throw new Error(_ICUMsgNotFoundMsg); + } // when using accented english, force the use of a different locale for number formatting const localeForMessageFormat = (locale === 'en-XA' || locale === 'en-XL') ? 'de-DE' : locale; From 4ff414aca69f5cde1f623278c6da1c28c664da66 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 11 Jul 2019 10:42:31 -0700 Subject: [PATCH 35/71] Untrack pre-locales. --- .gitignore | 1 + .../lib/i18n/pre-locale/en-US.json | 3726 ----------------- .../lib/i18n/pre-locale/en-XL.json | 3106 -------------- .../scripts/i18n/collect-strings.js | 3 + 4 files changed, 4 insertions(+), 6832 deletions(-) delete mode 100644 lighthouse-core/lib/i18n/pre-locale/en-US.json delete mode 100644 lighthouse-core/lib/i18n/pre-locale/en-XL.json diff --git a/.gitignore b/.gitignore index fadf1382d5b3..b3cfc46c0428 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ last-run-results.html *.report.pretty *.artifacts.log +lighthouse-core/lib/i18n/pre-locale !lighthouse-core/test/results/artifacts/*.trace.json !lighthouse-core/test/results/artifacts/*.devtoolslog.json !lighthouse-core/test/fixtures/artifacts/**/*.trace.json diff --git a/lighthouse-core/lib/i18n/pre-locale/en-US.json b/lighthouse-core/lib/i18n/pre-locale/en-US.json deleted file mode 100644 index 8f6d6f7f1143..000000000000 --- a/lighthouse-core/lib/i18n/pre-locale/en-US.json +++ /dev/null @@ -1,3726 +0,0 @@ -{ - "lighthouse-core/audits/accessibility/accesskeys.js | description": { - "message": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ values are not unique", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[accesskey]`", - "example": "[accesskey]" - } - } - }, - "lighthouse-core/audits/accessibility/accesskeys.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ values are unique", - "description": "Title of an accesibility audit that evaluates if the accesskey HTML attribute values are unique across all elements. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[accesskey]`", - "example": "[accesskey]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { - "message": "Each ARIA $MARKDOWN_SNIPPET_0$ supports a specific subset of $MARKDOWN_SNIPPET_1$ attributes. Mismatching these invalidates the $MARKDOWN_SNIPPET_2$ attributes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`role`", - "example": "role" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`aria-*`", - "example": "aria-*" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`aria-*`", - "example": "aria-*" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ attributes do not match their roles", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ attributes match their roles", - "description": "Title of an accesibility audit that evaluates if the ARIA HTML attributes are misaligned with the aria-role HTML attribute specificed on the element, such mismatches are invalid. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { - "message": "Some ARIA roles have required attributes that describe the state of the element to screen readers. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$s do not have all required $MARKDOWN_SNIPPET_1$ attributes", - "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$s have all required $MARKDOWN_SNIPPET_1$ attributes", - "description": "Title of an accesibility audit that evaluates if all elements with the aria-role attribute have the other corresponding ARIA attributes set as well. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | description": { - "message": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { - "message": "Elements with $MARKDOWN_SNIPPET_0$ that require specific children $MARKDOWN_SNIPPET_1$s, are missing.", - "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | title": { - "message": "Elements with $MARKDOWN_SNIPPET_0$ that require specific children $MARKDOWN_SNIPPET_1$s, are present", - "description": "Title of an accesibility audit that evaluates if the elements with an aria-role that require child elements have the required children. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { - "message": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$s are not contained by their required parent element", - "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { - "message": "$MARKDOWN_SNIPPET_0$s are contained by their required parent element", - "description": "Title of an accesibility audit that evaluates valid aria-role usage. Some ARIA roles require that elements must be a child of specific parent element. This audit checks that when those roles are used, the element with the role is in fact a child of the required parent. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | description": { - "message": "ARIA roles must have valid values in order to perform their intended accessibility functions. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ values are not valid", - "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ values are valid", - "description": "Title of an accesibility audit that evaluates if all elements have valid aria-role HTML attributes. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { - "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ attributes do not have valid values", - "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ attributes have valid values", - "description": "Title of an accesibility audit that evaluates if all elements that have an ARIA HTML attribute have a valid value for that attribute. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { - "message": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ attributes are not valid or misspelled", - "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ attributes are valid and not misspelled", - "description": "Title of an accesibility audit that evaluates if all elements with ARIA HTML attributes have spelled the name of attribute correctly. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | description": { - "message": "Captions make audio elements usable for deaf or hearing-impaired users, providing critical information such as who is talking, what they're saying, and other non-speech information. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements are missing a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", - "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<audio>`", - "example": "<audio>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", - "description": "Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<audio>`", - "example": "<audio>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { - "message": "Failing Elements", - "description": "Label of a table column that identifies HTML elements that have failed an audit." - }, - "lighthouse-core/audits/accessibility/button-name.js | description": { - "message": "When a button doesn't have an accessible name, screen readers announce it as \"button\", making it unusable for users who rely on screen readers. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { - "message": "Buttons do not have an accessible name", - "description": "Title of an accesibility audit that evaluates if all button elements have names accessible to screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." - }, - "lighthouse-core/audits/accessibility/button-name.js | title": { - "message": "Buttons have an accessible name", - "description": "Title of an accesibility audit that evaluates if all button elements have names accessible to screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." - }, - "lighthouse-core/audits/accessibility/bypass.js | description": { - "message": "Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { - "message": "The page does not contain a heading, skip link, or landmark region", - "description": "Title of an accesibility audit that evaluates if the page has elements that let screen reader users skip over repetitive content. `heading`, `skip link`, and `landmark region` are technical terms for the elements that enable quick page navigation. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." - }, - "lighthouse-core/audits/accessibility/bypass.js | title": { - "message": "The page contains a heading, skip link, or landmark region", - "description": "Title of an accesibility audit that evaluates if the page has elements that let screen reader users skip over repetitive content. `heading`, `skip link`, and `landmark region` are technical terms for the elements that enable quick page navigation. This title is descriptive of the successful state and is shown to users when no user action is required." - }, - "lighthouse-core/audits/accessibility/color-contrast.js | description": { - "message": "Low-contrast text is difficult or impossible for many users to read. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { - "message": "Background and foreground colors do not have a sufficient contrast ratio.", - "description": "Title of an accesibility audit that evaluates if all foreground colors are distinct enough from their background colors to be legible for users. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." - }, - "lighthouse-core/audits/accessibility/color-contrast.js | title": { - "message": "Background and foreground colors have a sufficient contrast ratio", - "description": "Title of an accesibility audit that evaluates if all foreground colors are distinct enough from their background colors to be legible for users. This title is descriptive of the successful state and is shown to users when no user action is required." - }, - "lighthouse-core/audits/accessibility/definition-list.js | description": { - "message": "When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$'s do not contain only properly-ordered $MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$ groups, $MARKDOWN_SNIPPET_3$ or $MARKDOWN_SNIPPET_4$ elements.", - "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_4": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/definition-list.js | title": { - "message": "$MARKDOWN_SNIPPET_0$'s contain only properly-ordered $MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$ groups, $MARKDOWN_SNIPPET_3$ or $MARKDOWN_SNIPPET_4$ elements.", - "description": "Title of an accesibility audit that evaluates if all the definition list elements have valid markup for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_4": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | description": { - "message": "Definition list items ($MARKDOWN_SNIPPET_0$ and $MARKDOWN_SNIPPET_1$) must be wrapped in a parent $MARKDOWN_SNIPPET_2$ element to ensure that screen readers can properly announce them. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dl>`", - "example": "<dl>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { - "message": "Definition list items are not wrapped in $MARKDOWN_SNIPPET_0$ elements", - "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | title": { - "message": "Definition list items are wrapped in $MARKDOWN_SNIPPET_0$ elements", - "description": "Title of an accesibility audit that evaluates if all definition list item elements (`<dt>`/`<dd>`) have a definition list parent element (`<dl>`). This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | description": { - "message": "The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/title)" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { - "message": "Document doesn't have a $MARKDOWN_SNIPPET_0$ element", - "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<title>`", - "example": "<title>" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "Document has a $MARKDOWN_SNIPPET_0$ element", - "description": "Title of an accesibility audit that evaluates if the page has a <title> element that describes the page. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<title>`", - "example": "<title>" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | description": { - "message": "The value of an id attribute must be unique to prevent other instances from being overlooked by assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ attributes on the page are not unique", - "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[id]`", - "example": "[id]" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ attributes on the page are unique", - "description": "Title of an accesibility audit that evaluates if there are any duplicate id HTML attributes on the page. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[id]`", - "example": "[id]" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | description": { - "message": "Screen reader users rely on frame titles to describe the contents of frames. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ elements do not have a title", - "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<frame>`", - "example": "<frame>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<iframe>`", - "example": "<iframe>" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ elements have a title", - "description": "Title of an accesibility audit that evaluates if all `<frame>` and `<iframe>` elements on the page have a title HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<frame>`", - "example": "<frame>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<iframe>`", - "example": "<iframe>" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | description": { - "message": "If a page doesn't specify a lang attribute, a screen reader assumes that the page is in the default language that the user chose when setting up the screen reader. If the page isn't actually in the default language, then the screen reader might not announce the page's text correctly. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ element does not have a $MARKDOWN_SNIPPET_1$ attribute", - "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ element has a $MARKDOWN_SNIPPET_1$ attribute", - "description": "Title of an accesibility audit that evaluates if the root HTML tag has a lang attribute identifying the page's language. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { - "message": "Specifying a valid $LINK_START_0$BCP 47 language$LINK_END_0$ helps screen readers announce text properly. $LINK_START_1$Learn more$LINK_END_1$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ element does not have a valid value for its $MARKDOWN_SNIPPET_1$ attribute.", - "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ element has a valid value for its $MARKDOWN_SNIPPET_1$ attribute", - "description": "Title of an accesibility audit that evaluates if the value for root HTML tag's lang attribute is a valid BCP 47 language. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | description": { - "message": "Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { - "message": "Image elements do not have $MARKDOWN_SNIPPET_0$ attributes", - "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | title": { - "message": "Image elements have $MARKDOWN_SNIPPET_0$ attributes", - "description": "Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | description": { - "message": "When an image is being used as an $MARKDOWN_SNIPPET_0$ button, providing alternative text can help screen reader users understand the purpose of the button. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input>`", - "example": "<input>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements do not have $MARKDOWN_SNIPPET_1$ text", - "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input type=\"image\">`", - "example": "<input type=\"image\">" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements have $MARKDOWN_SNIPPET_1$ text", - "description": "Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input type=\"image\">`", - "example": "<input type=\"image\">" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/label.js | description": { - "message": "Labels ensure that form controls are announced properly by assistive technologies, like screen readers. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/label.js | failureTitle": { - "message": "Form elements do not have associated labels", - "description": "Title of an accesibility audit that evaluates if all form elements have corresponding label elements. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." - }, - "lighthouse-core/audits/accessibility/label.js | title": { - "message": "Form elements have associated labels", - "description": "Title of an accesibility audit that evaluates if all form elements have corresponding label elements. This title is descriptive of the successful state and is shown to users when no user action is required." - }, - "lighthouse-core/audits/accessibility/layout-table.js | description": { - "message": "A table being used for layout purposes should not include data elements, such as the th or caption elements or the summary attribute, because this can create a confusing experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { - "message": "Presentational $MARKDOWN_SNIPPET_0$ elements do not avoid using $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ or the $MARKDOWN_SNIPPET_3$ attribute.", - "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<caption>`", - "example": "<caption>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`[summary]`", - "example": "[summary]" - } - } - }, - "lighthouse-core/audits/accessibility/layout-table.js | title": { - "message": "Presentational $MARKDOWN_SNIPPET_0$ elements avoid using $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ or the $MARKDOWN_SNIPPET_3$ attribute.", - "description": "Title of an accesibility audit that evaluates if a table intended for layout contains data annotations as it can be confusing for screen readers. This is evaluated by checking if tables with the ARIA role of `presentation` or `none` contain any data elements such as table headers (`<th>`). This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<caption>`", - "example": "<caption>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`[summary]`", - "example": "[summary]" - } - } - }, - "lighthouse-core/audits/accessibility/link-name.js | description": { - "message": "Link text (and alternate text for images, when used as links) that is discernible, unique, and focusable improves the navigation experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { - "message": "Links do not have a discernible name", - "description": "Title of an accesibility audit that evaluates if all link elements have a non-generic name to screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed." - }, - "lighthouse-core/audits/accessibility/link-name.js | title": { - "message": "Links have a discernible name", - "description": "Title of an accesibility audit that evaluates if all link elements have a non-generic name to screen readers. This title is descriptive of the successful state and is shown to users when no user action is required." - }, - "lighthouse-core/audits/accessibility/list.js | description": { - "message": "Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/list.js | failureTitle": { - "message": "Lists do not contain only $MARKDOWN_SNIPPET_0$ elements and script supporting elements ($MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$).", - "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/list.js | title": { - "message": "Lists contain only $MARKDOWN_SNIPPET_0$ elements and script supporting elements ($MARKDOWN_SNIPPET_1$ and $MARKDOWN_SNIPPET_2$).", - "description": "Title of an accesibility audit that evaluates if all list elements have a valid structure containing only list items. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | description": { - "message": "Screen readers require list items ($MARKDOWN_SNIPPET_0$) to be contained within a parent $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ to be announced properly. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { - "message": "List items ($MARKDOWN_SNIPPET_0$) are not contained within $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ parent elements.", - "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | title": { - "message": "List items ($MARKDOWN_SNIPPET_0$) are contained within $MARKDOWN_SNIPPET_1$ or $MARKDOWN_SNIPPET_2$ parent elements", - "description": "Title of an accesibility audit that evaluates if any list item elements do not have list parent elements. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | description": { - "message": "Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { - "message": "The document uses $MARKDOWN_SNIPPET_0$", - "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<meta http-equiv=\"refresh\">`", - "example": "<meta http-equiv=\"refresh\">" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | title": { - "message": "The document does not use $MARKDOWN_SNIPPET_0$", - "description": "Title of an accesibility audit that evaluates if the page uses a meta tag that refreshes the page automatically. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<meta http-equiv=\"refresh\">`", - "example": "<meta http-equiv=\"refresh\">" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | description": { - "message": "Disabling zooming is problematic for users with low vision who rely on screen magnification to properly see the contents of a web page. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ is used in the $MARKDOWN_SNIPPET_1$ element or the $MARKDOWN_SNIPPET_2$ attribute is less than 5.", - "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[user-scalable=\"no\"]`", - "example": "[user-scalable=\"no\"]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<meta name=\"viewport\">`", - "example": "<meta name=\"viewport\">" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[maximum-scale]`", - "example": "[maximum-scale]" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ is not used in the $MARKDOWN_SNIPPET_1$ element and the $MARKDOWN_SNIPPET_2$ attribute is not less than 5.", - "description": "Title of an accesibility audit that evaluates if the page has limited the scaling properties of the page in a way that harms users with low vision. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[user-scalable=\"no\"]`", - "example": "[user-scalable=\"no\"]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<meta name=\"viewport\">`", - "example": "<meta name=\"viewport\">" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[maximum-scale]`", - "example": "[maximum-scale]" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | description": { - "message": "Screen readers cannot translate non-text content. Adding alt text to $MARKDOWN_SNIPPET_0$ elements helps screen readers convey meaning to users. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements do not have $MARKDOWN_SNIPPET_1$ text", - "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements have $MARKDOWN_SNIPPET_1$ text", - "description": "Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | description": { - "message": "A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { - "message": "Some elements have a $MARKDOWN_SNIPPET_0$ value greater than 0", - "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[tabindex]`", - "example": "[tabindex]" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | title": { - "message": "No element has a $MARKDOWN_SNIPPET_0$ value greater than 0", - "description": "Title of an accesibility audit that evaluates if any elements have custom tabindex HTML attributes that might frustrate users of assitive technology. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[tabindex]`", - "example": "[tabindex]" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { - "message": "Screen readers have features to make navigating tables easier. Ensuring $MARKDOWN_SNIPPET_0$ cells using the $MARKDOWN_SNIPPET_1$ attribute only refer to other cells in the same table may improve the experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<td>`", - "example": "<td>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { - "message": "Cells in a $MARKDOWN_SNIPPET_0$ element that use the $MARKDOWN_SNIPPET_1$ attribute refers to other cells of that same table.", - "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { - "message": "Cells in a $MARKDOWN_SNIPPET_0$ element that use the $MARKDOWN_SNIPPET_1$ attribute only refer to other cells of that same table.", - "description": "Title of an accesibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to cells within the same table. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { - "message": "Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements and elements with $MARKDOWN_SNIPPET_1$ do not have data cells they describe.", - "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role=\"columnheader\"/\"rowheader\"]`", - "example": "[role=\"columnheader\"/\"rowheader\"]" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements and elements with $MARKDOWN_SNIPPET_1$ have data cells they describe.", - "description": "Title of an accesibility audit that evaluates if all table header elements have children. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role=\"columnheader\"/\"rowheader\"]`", - "example": "[role=\"columnheader\"/\"rowheader\"]" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | description": { - "message": "Specifying a valid $LINK_START_0$BCP 47 language$LINK_END_0$ on elements helps ensure that text is pronounced correctly by a screen reader. $LINK_START_1$Learn more$LINK_END_1$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ attributes do not have a valid value", - "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ attributes have a valid value", - "description": "Title of an accesibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | description": { - "message": "When a video provides a caption it is easier for deaf and hearing impaired users to access its information. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements do not contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", - "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", - "description": "Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | description": { - "message": "Audio descriptions provide relevant information for videos that dialogue cannot, such as facial expressions and scenes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ elements do not contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$.", - "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"description\"]`", - "example": "[kind=\"description\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ elements contain a $MARKDOWN_SNIPPET_1$ element with $MARKDOWN_SNIPPET_2$", - "description": "Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"description\"]`", - "example": "[kind=\"description\"]" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | description": { - "message": "For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG. $LINK_START_0$Learn More$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user what having a valid apple-touch-icon does. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { - "message": "Does not provide a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page does not contain a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { - "message": "$MARKDOWN_SNIPPET_0$ is out of date; $MARKDOWN_SNIPPET_1$ is preferred.", - "description": "Warning that HTML attribute `apple-touch-icon-precomposed` should not be used in favor of `apple-touch-icon`. \"apple-touch-icon-precomposed\" and \"apple-touch-icon\" are HTML attribute values and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon-precomposed`", - "example": "apple-touch-icon-precomposed" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | title": { - "message": "Provides a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that tells the user that their site contains a vaild touch icon. This descriptive title is shown when the page contains a valid iOS touch icon. \"apple-touch-icon\" is an HTML attribute value and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { - "message": "Chrome extensions negatively affected this page's load performance. Try auditing the page in incognito mode or from a Chrome profile without extensions.", - "description": "A message displayed in a Lighthouse audit result warning that Chrome extensions on the user's system substantially affected Lighthouse's measurements and instructs the user on how to run again without those extensions." - }, - "lighthouse-core/audits/bootup-time.js | columnScriptEval": { - "message": "Script Evaluation", - "description": "Label for a time column in a data table; entries will be the number of milliseconds spent evaluating script for every script loaded by the page." - }, - "lighthouse-core/audits/bootup-time.js | columnScriptParse": { - "message": "Script Parse", - "description": "Label for a time column in a data table; entries will be the number of milliseconds spent parsing script files for every script loaded by the page." - }, - "lighthouse-core/audits/bootup-time.js | columnTotal": { - "message": "Total CPU Time", - "description": "Label for the total time column in a data table; entries will be the number of milliseconds spent executing per resource loaded by the page." - }, - "lighthouse-core/audits/bootup-time.js | description": { - "message": "Consider reducing the time spent parsing, compiling, and executing JS. You may find delivering smaller JS payloads helps with this. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user that they should reduce the amount of time spent executing javascript and one method of doing so. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/bootup)" - } - } - }, - "lighthouse-core/audits/bootup-time.js | failureTitle": { - "message": "Reduce JavaScript execution time", - "description": "Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/bootup-time.js | title": { - "message": "JavaScript execution time", - "description": "Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { - "message": "Large GIFs are inefficient for delivering animated content. Consider using MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save network bytes. $LINK_START_0$Learn more$LINK_END_0$", - "description": "Description of a Lighthouse audit that tells the user *why* they should use video instead of GIF format for delivering animated content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { - "message": "Use video formats for animated content", - "description": "Imperative title of a Lighthouse audit that tells the user to use video formats rather than animated GIFs, which are wasteful. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { - "message": "Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { - "message": "Defer offscreen images", - "description": "Imperative title of a Lighthouse audit that tells the user to defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { - "message": "Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce or remove network resources that block the initial render of the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { - "message": "Eliminate render-blocking resources", - "description": "Imperative title of a Lighthouse audit that tells the user to reduce or remove network resources that block the initial render of the page. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { - "message": "Large network payloads cost users real money and are highly correlated with long load times. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the network resources required by the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "Total size was $COMPLEX_ICU_0$ KB", - "description": "Used to summarize the total byte size of the page and all its network requests. The `{totalBytes}` placeholder will be replaced with the total byte sizes, shown in kilobytes (e.g. 142 KB)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{totalBytes, number, bytes}", - "example": "499" - } - } - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | failureTitle": { - "message": "Avoid enormous network payloads", - "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | title": { - "message": "Avoids enormous network payloads", - "description": "Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "Minifying CSS files can reduce network payload sizes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should minify (remove whitespace) the page's CSS code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "Minify CSS", - "description": "Imperative title of a Lighthouse audit that tells the user to minify (remove whitespace) the page's CSS code. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { - "message": "Minifying JavaScript files can reduce payload sizes and script parse time. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should minify the page’s JS code to reduce file size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/speed/docs/insights/MinifyResources)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { - "message": "Minify JavaScript", - "description": "Imperative title of a Lighthouse audit that tells the user to minify the page’s JS code to reduce file size. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { - "message": "Remove dead rules from stylesheets and defer the loading of CSS not used for above-the-fold content to reduce unnecessary bytes consumed by network activity. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should defer loading any content in CSS that isn’t needed at page load. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/unused-css)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { - "message": "Remove unused CSS", - "description": "Imperative title of a Lighthouse audit that tells the user to remove content from their CSS that isn’t needed immediately and instead load that content at a later time. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/unused-javascript.js | description": { - "message": "Remove unused JavaScript to reduce bytes consumed by network activity.", - "description": "Description of a Lighthouse audit that tells the user *why* they should remove JavaScript that is never needed/evaluated by the browser. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." - }, - "lighthouse-core/audits/byte-efficiency/unused-javascript.js | title": { - "message": "Remove unused JavaScript", - "description": "Imperative title of a Lighthouse audit that tells the user to remove JavaScript that is never evaluated during page load. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { - "message": "A long cache lifetime can speed up repeat visits to your page. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to adopt a long cache lifetime policy. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 resource found}\n other {# resources found}\n }", - "description": "[ICU Syntax] Label for the audit identifying network resources with inefficient cache values. Clicking this will expand the audit to show the resources." - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | failureTitle": { - "message": "Serve static assets with an efficient cache policy", - "description": "Title of a diagnostic audit that provides details on the any page resources that could have been served with more efficient cache policies. Cache refers to browser disk cache, which keeps old versions of network resources around for future use. This imperative title is shown to users when there is a significant amount of assets served with poor cache policies." - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | title": { - "message": "Uses efficient cache policy on static assets", - "description": "Title of a diagnostic audit that provides detail on the cache policy applies to the page's static assets. Cache refers to browser disk cache, which keeps old versions of network resources around for future use. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { - "message": "Optimized images load faster and consume less cellular data. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to efficiently encode images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { - "message": "Efficiently encode images", - "description": "Imperative title of a Lighthouse audit that tells the user to encode images with optimization (better compression). This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { - "message": "Serve images that are appropriately-sized to save cellular data and improve load time. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to serve appropriately sized images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { - "message": "Properly size images", - "description": "Imperative title of a Lighthouse audit that tells the user to resize images to match the display dimensions. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { - "message": "Text-based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* their text-based resources should be served with compression (like gzip). This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/text-compression)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { - "message": "Enable text compression", - "description": "Imperative title of a Lighthouse audit that tells the user to enable text compression (like gzip) in order to enhance the performance of a page. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { - "message": "Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should use newer and more efficient image formats. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/webp)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { - "message": "Serve images in next-gen formats", - "description": "Imperative title of a Lighthouse audit that tells the user to serve images in newer and more efficient image formats in order to enhance the performance of a page. A non-modern image format was designed 20+ years ago. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/critical-request-chains.js | description": { - "message": "The Critical Request Chains below show you what resources are loaded with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the depth of critical network requests to enhance initial load of a page . This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)" - } - } - }, - "lighthouse-core/audits/critical-request-chains.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 chain found}\n other {# chains found}\n }", - "description": "[ICU Syntax] Label for an audit identifying the number of sequences of dependent network requests used to load the page." - }, - "lighthouse-core/audits/critical-request-chains.js | title": { - "message": "Minimize Critical Requests Depth", - "description": "Imperative title of a Lighthouse audit that tells the user to reduce the depth of critical network requests to enhance initial load of a page. Critical request chains are series of dependent network requests that are important for page rendering. For example, here's a 4-request-deep chain: The biglogo.jpg image is required, but is requested via the styles.css style code, which is requested by the initialize.js javascript, which is requested by the page's HTML. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/deprecations.js | columnDeprecate": { - "message": "Deprecation / Warning", - "description": "Header of the table column which displays the warning message describing use of a deprecated API by code running in the web page." - }, - "lighthouse-core/audits/deprecations.js | columnLine": { - "message": "Line", - "description": "Table column header for line of code (eg. 432) that is using a deprecated API." - }, - "lighthouse-core/audits/deprecations.js | description": { - "message": "Deprecated APIs will eventually be removed from the browser. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should not use deprecated APIs on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.chromestatus.com/features#deprecated)" - } - } - }, - "lighthouse-core/audits/deprecations.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 warning found}\n other {# warnings found}\n }", - "description": "[ICU Syntax] Label for the audit identifying the number of warnings generated by using deprecated APIs." - }, - "lighthouse-core/audits/deprecations.js | failureTitle": { - "message": "Uses deprecated APIs", - "description": "Title of a Lighthouse audit that provides detail on the use of deprecated APIs. This descriptive title is shown to users when the page uses deprecated APIs." - }, - "lighthouse-core/audits/deprecations.js | title": { - "message": "Avoids deprecated APIs", - "description": "Title of a Lighthouse audit that provides detail on the use of deprecated APIs. This descriptive title is shown to users when the page does not use deprecated APIs." - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | description": { - "message": "Application Cache is deprecated. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should not use the Application Cache API. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/appcache)" - } - } - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { - "message": "Found \"$ICU_0$\"", - "description": "Label for the audit identifying uses of the Application Cache.", - "placeholders": { - "ICU_0": { - "content": "{AppCacheManifest}", - "example": "AppCacheManifest" - } - } - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | failureTitle": { - "message": "Uses Application Cache", - "description": "Title of a Lighthouse audit that provides detail on the use of the Application Cache API. This descriptive title is shown to users when they do use the Application Cache API, which is considered bad practice." - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | title": { - "message": "Avoids Application Cache", - "description": "Title of a Lighthouse audit that provides detail on the use of the Application Cache API. This descriptive title is shown to users when they do not use the Application Cache API." - }, - "lighthouse-core/audits/dobetterweb/doctype.js | description": { - "message": "Specifying a doctype prevents the browser from switching to quirks-mode. Read more on the $LINK_START_0$MDN Web Docs page$LINK_END_0$", - "description": "Description of a Lighthouse audit that tells the user why they should define an HTML doctype. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)" - } - } - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationBadDoctype": { - "message": "Doctype name must be the lowercase string $MARKDOWN_SNIPPET_0$", - "description": "Explanatory message stating that the doctype is set, but is not \"html\" and is therefore invalid.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`html`", - "example": "html" - } - } - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationNoDoctype": { - "message": "Document must contain a doctype", - "description": "Explanatory message stating that the document has no doctype." - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationPublicId": { - "message": "Expected publicId to be an empty string", - "description": "Explanatory message stating that the publicId field is not empty." - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationSystemId": { - "message": "Expected systemId to be an empty string", - "description": "Explanatory message stating that the systemId field is not empty." - }, - "lighthouse-core/audits/dobetterweb/doctype.js | failureTitle": { - "message": "Page lacks the HTML doctype, thus triggering quirks-mode", - "description": "Title of a Lighthouse audit that provides detail on the doctype of a page. This descriptive title is shown to users when the page's doctype is not set to HTML." - }, - "lighthouse-core/audits/dobetterweb/doctype.js | title": { - "message": "Page has the HTML doctype", - "description": "Title of a Lighthouse audit that provides detail on the doctype of a page. This descriptive title is shown to users when the pages's doctype is set to HTML." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnElement": { - "message": "Element", - "description": "Table column header for the DOM element. Each DOM element is described with its HTML representation." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnStatistic": { - "message": "Statistic", - "description": "Table column header for the type of statistic. These statistics describe how big the DOM is (count of DOM elements, children, depth)." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnValue": { - "message": "Value", - "description": "Table column header for the observed value of the DOM statistic." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | description": { - "message": "Browser engineers recommend pages contain fewer than ~1,500 DOM elements. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer $LINK_START_0$style calculations$LINK_END_0$, and produce costly $LINK_START_1$layout reflows$LINK_END_1$. $LINK_START_2$Learn more$LINK_END_2$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://developers.google.com/speed/articles/reflow)" - }, - "LINK_START_2": { - "content": "[" - }, - "LINK_END_2": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/dom-size)" - } - } - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 element}\n other {# elements}\n }", - "description": "[ICU Syntax] Label for an audit identifying the number of DOM elements found in the page." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | failureTitle": { - "message": "Avoid an excessive DOM size", - "description": "Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMDepth": { - "message": "Maximum DOM Depth", - "description": "Label for the numeric value of the maximum depth in the page's DOM tree." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMElements": { - "message": "Total DOM Elements", - "description": "Label for the total number of DOM elements found in the page." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMWidth": { - "message": "Maximum Child Elements", - "description": "Label for the numeric value of the maximum number of children any DOM element in the page has. The element described will have the most children in the page." - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | title": { - "message": "Avoids an excessive DOM size", - "description": "Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnRel": { - "message": "Rel", - "description": "Label for a column in a data table; entries will be the values of the html \"rel\" attribute from link in a page." - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnTarget": { - "message": "Target", - "description": "Label for a column in a data table; entries will be the target attribute of a link. Each entry is either an empty string or a string like `_blank`." - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description": { - "message": "Add $MARKDOWN_SNIPPET_0$ or $MARKDOWN_SNIPPET_1$ to any external links to improve performance and prevent security vulnerabilities. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why and how they should secure cross-origin links. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=\"noopener\"`", - "example": "rel=\"noopener\"" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`rel=\"noreferrer\"`", - "example": "rel=\"noreferrer\"" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/noopener)" - } - } - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle": { - "message": "Links to cross-origin destinations are unsafe", - "description": "Title of a Lighthouse audit that provides detail on the cross-origin links that the web page contains, and whether the links can be considered safe. This descriptive title is shown to users when not all links can be considered safe." - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | title": { - "message": "Links to cross-origin destinations are safe", - "description": "Title of a Lighthouse audit that provides detail on the cross-origin links that the web page contains, and whether the links can be considered safe. This descriptive title is shown to users when all links are safe." - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | warning": { - "message": "Unable to determine the destination for anchor ($ICU_0$). If not used as a hyperlink, consider removing target=_blank.", - "description": "Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety.", - "placeholders": { - "ICU_0": { - "content": "{anchorHTML}", - "example": "<a>" - } - } - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { - "message": "Users are mistrustful of or confused by sites that request their location without context. Consider tying the request to a user action instead. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should not ask for geolocation permissions on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load)" - } - } - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | failureTitle": { - "message": "Requests the geolocation permission on page load", - "description": "Title of a Lighthouse audit that provides detail on geolocation permissions requests. This descriptive title is shown to users when the page does ask for geolocation permissions on load." - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { - "message": "Avoids requesting the geolocation permission on page load", - "description": "Title of a Lighthouse audit that provides detail on geolocation permission requests while the page is loading. This descriptive title is shown to users when the page does not ask for geolocation permissions on load." - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnName": { - "message": "Name", - "description": "Label for a column in a data table; entries will be the names of the detected Javascript libraries." - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { - "message": "Version", - "description": "Label for a column in a data table; entries will be the version numbers of the detected Javascript libraries." - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | description": { - "message": "All front-end JavaScript libraries detected on the page.", - "description": "Description of a Lighthouse audit that tells the user what this audit is detecting. This is displayed after a user expands the section to see more. No character length limits." - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | title": { - "message": "Detected JavaScript libraries", - "description": "Title of a Lighthouse audit that provides detail on the Javascript libraries that are used on the page." - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | description": { - "message": "For users on slow connections, external scripts dynamically injected via $MARKDOWN_SNIPPET_0$ can delay page load by tens of seconds. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should avoid `document.write`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/document-write)" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": { - "message": "Uses $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does use `document.write`.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | title": { - "message": "Avoids $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on the page's use of the `document.write` API. This descriptive title is shown to users when the page does not use `document.write`.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnSeverity": { - "message": "Highest Severity", - "description": "Label for a column in a data table; entries will be the severity of the vulnerabilities found within a Javascript library." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnVersion": { - "message": "Library Version", - "description": "Label for a column in a data table; entries will be the version numbers of the Javascript libraries found." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnVuln": { - "message": "Vulnerability Count", - "description": "Label for a column in a data table; entries will be the counts of JavaScript-library vulnerabilities found." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description": { - "message": "Some third-party scripts may contain known security vulnerabilities that are easily identified and exploited by attackers. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should be concerned about the third party Javascript libraries that they use. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities)" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 vulnerability detected}\n other {# vulnerabilities detected}\n }", - "description": "[ICU Syntax] Label for the audit identifying the number of vulnerable Javascript libraries found." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | failureTitle": { - "message": "Includes front-end JavaScript libraries with known security vulnerabilities", - "description": "Title of a Lighthouse audit that provides detail on Javascript libraries the page uses. This descriptive title is shown to users when some detected Javascript libraries have known security vulnerabilities." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityHigh": { - "message": "High", - "description": "Table row value for the severity of a high impact, or dangerous Javascript vulnerability. Part of a ranking scale in the form: low, medium, high." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityLow": { - "message": "Low", - "description": "Table row value for the severity of a small, or low impact Javascript vulnerability. Part of a ranking scale in the form: low, medium, high." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityMedium": { - "message": "Medium", - "description": "Table row value for the severity of a Javascript vulnerability. Part of a ranking scale in the form: low, medium, high." - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | title": { - "message": "Avoids front-end JavaScript libraries with known security vulnerabilities", - "description": "Title of a Lighthouse audit that provides detail on Javascript libraries the page uses. This descriptive title is shown to users when all Javascript libraries are free of known security vulnerabilities." - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | description": { - "message": "Users are mistrustful of or confused by sites that request to send notifications without context. Consider tying the request to user gestures instead. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should not ask for notification permission on load. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load)" - } - } - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | failureTitle": { - "message": "Requests the notification permission on page load", - "description": "Title of a Lighthouse audit that provides detail on the page's notification permission requests. This descriptive title is shown to users when the page does ask for notification permission on load." - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { - "message": "Avoids requesting the notification permission on page load", - "description": "Title of a Lighthouse audit that provides detail on the page's notification permission requests. This descriptive title is shown to users when the page does not ask for notification permission on load." - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Failing Elements", - "description": "Table column header for the HTML elements that do not allow pasting of content." - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { - "message": "Preventing password pasting undermines good security policy. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/password-pasting)" - } - } - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | failureTitle": { - "message": "Prevents users to paste into password fields", - "description": "Title of a Lighthouse audit that provides detail on the ability to paste into password fields. This descriptive title is shown to users when the page does not allow pasting of content into password fields." - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | title": { - "message": "Allows users to paste into password fields", - "description": "Title of a Lighthouse audit that provides detail on the ability to paste into password fields. This descriptive title is shown to users when the page allows pasting of content into password fields." - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | columnProtocol": { - "message": "Protocol", - "description": "Label for a column in a data table; entries in the column will be the HTTP Protocol used to make a network request." - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | description": { - "message": "HTTP/2 offers many benefits over HTTP/1.1, including binary headers, multiplexing, and server push. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should use HTTP/2. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/http2)" - } - } - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 request not served via HTTP/2}\n other {# requests not served via HTTP/2}\n }", - "description": "[ICU Syntax] Label identifying the number of network requests that were not served with HTTP/2." - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | failureTitle": { - "message": "Does not use HTTP/2 for all of its resources", - "description": "Title of a Lighthouse audit that provides detail on whether the webpage uses HTTP/2 for resources it requests over the network. This descriptive title is shown to users when the page does not use HTTP/2 for its requests." - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | title": { - "message": "Uses HTTP/2 for its own resources", - "description": "Title of a Lighthouse audit that provides detail on whether the webpage uses HTTP/2 for resources it requests over the network. This descriptive title is shown to users when the page uses HTTP/2 for its requests." - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description": { - "message": "Consider marking your touch and wheel event listeners as $MARKDOWN_SNIPPET_0$ to improve your page's scroll performance. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should use passive event listeners on the page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`passive`", - "example": "passive" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners)" - } - } - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | failureTitle": { - "message": "Does not use passive listeners to improve scrolling performance", - "description": "Title of a Lighthouse audit that provides detail on the page's use of passive event listeners used to improve the scrolling performance of the page. This descriptive title is shown to users when the page does not use passive listeners." - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { - "message": "Uses passive listeners to improve scrolling performance", - "description": "Title of a Lighthouse audit that provides detail on the page's use of passive event listeners used to improve the scrolling performance of the page. This descriptive title is shown to users when the page does use passive listeners." - }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Description", - "description": "Label for a column in a data table; entries in the column will be the descriptions of logged browser errors." - }, - "lighthouse-core/audits/errors-in-console.js | description": { - "message": "Errors logged to the console indicate unresolved problems. They can come from network request failures and other browser concerns.", - "description": "Description of a Lighthouse audit that tells the user why errors being logged to the devtools console are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits." - }, - "lighthouse-core/audits/errors-in-console.js | failureTitle": { - "message": "Browser errors were logged to the console", - "description": "Title of a Lighthouse audit that provides detail on browser errors. This descriptive title is shown to users when browser errors occurred and were logged into the devtools console." - }, - "lighthouse-core/audits/errors-in-console.js | title": { - "message": "No browser errors logged to the console", - "description": "Title of a Lighthouse audit that provides detail on browser errors. This descriptive title is shown to users when no browser errors were logged into the devtools console." - }, - "lighthouse-core/audits/font-display.js | description": { - "message": "Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should use the font-display CSS feature. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/updates/2016/02/font-display)" - } - } - }, - "lighthouse-core/audits/font-display.js | failureTitle": { - "message": "Ensure text remains visible during webfont load", - "description": "Title of a diagnostic audit that provides detail on the load of the page's webfonts. Often the text is invisible for seconds before the webfont resource is loaded. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/font-display.js | title": { - "message": "All text remains visible during webfont loads", - "description": "Title of a diagnostic audit that provides detail on if all the text on a webpage was visible while the page was loading its webfonts. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/font-display.js | undeclaredFontURLWarning": { - "message": "Lighthouse was unable to automatically check the font-display value for the following URL: $ICU_0$.", - "description": "A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it.", - "placeholders": { - "ICU_0": { - "content": "{fontURL}", - "example": "https://font.cdn.com/" - } - } - }, - "lighthouse-core/audits/image-aspect-ratio.js | columnActual": { - "message": "Aspect Ratio (Actual)", - "description": "Label for a column in a data table; entries in the column will be the numeric aspect ratio of the raw (actual) image." - }, - "lighthouse-core/audits/image-aspect-ratio.js | columnDisplayed": { - "message": "Aspect Ratio (Displayed)", - "description": "Label for a column in a data table; entries in the column will be the numeric aspect ratio of an image as displayed in a web page." - }, - "lighthouse-core/audits/image-aspect-ratio.js | description": { - "message": "Image display dimensions should match natural aspect ratio. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why they should maintain the correct aspect ratios for all images. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio)" - } - } - }, - "lighthouse-core/audits/image-aspect-ratio.js | failureTitle": { - "message": "Displays images with incorrect aspect ratio", - "description": "Title of a Lighthouse audit that provides detail on the aspect ratios of all images on the page. This descriptive title is shown to users when not all images use correct aspect ratios." - }, - "lighthouse-core/audits/image-aspect-ratio.js | title": { - "message": "Displays images with correct aspect ratio", - "description": "Title of a Lighthouse audit that provides detail on the aspect ratios of all images on the page. This descriptive title is shown to users when all images use correct aspect ratios." - }, - "lighthouse-core/audits/image-aspect-ratio.js | warningCompute": { - "message": "Invalid image sizing information $ICU_0$", - "description": "Warning that the size information for an image was nonsensical.", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://image.cdn.com/" - } - } - }, - "lighthouse-core/audits/is-on-https.js | columnInsecureURL": { - "message": "Insecure URL", - "description": "Label for a column in a data table; entries in the column will be the URLs of insecure (non-HTTPS) network requests." - }, - "lighthouse-core/audits/is-on-https.js | description": { - "message": "All sites should be protected with HTTPS, even ones that don't handle sensitive data. HTTPS prevents intruders from tampering with or passively listening in on the communications between your app and your users, and is a prerequisite for HTTP/2 and many new web platform APIs. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* HTTPS use is important. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/https)" - } - } - }, - "lighthouse-core/audits/is-on-https.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 insecure request found}\n other {# insecure requests found}\n }", - "description": "[ICU Syntax] Label identifying the number of insecure network requests found by an audit of a web page." - }, - "lighthouse-core/audits/is-on-https.js | failureTitle": { - "message": "Does not use HTTPS", - "description": "Title of a Lighthouse audit that provides detail on the useage of HTTPS on a page. This descriptive title is shown to users when some, or all, requests on the page use HTTP instead of HTTPS." - }, - "lighthouse-core/audits/is-on-https.js | title": { - "message": "Uses HTTPS", - "description": "Title of a Lighthouse audit that provides detail on the useage of HTTPS on a page. This descriptive title is shown to users when all requests on a page are fufilled using HTTPS." - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { - "message": "A fast page load over a cellular network ensures a good mobile user experience. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to load fast enough on mobile networks. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { - "message": "Interactive at $COMPLEX_ICU_0$ s", - "description": "Label for the audit identifying the time it took for the page to become interactive.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueTextWithOverride": { - "message": "Interactive on simulated mobile network at $COMPLEX_ICU_0$ s", - "description": "Label for the audit identifying the time it took for the page to become interactive on a mobile network.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": { - "message": "Page load is not fast enough on mobile networks", - "description": "Imperative title of a Lighthouse audit that tells the user that their page has loaded fast enough to be considered a Progressive Web App. This imperative title is shown to users when the web page has loaded too slowly to be considered a Progressive Web App." - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | title": { - "message": "Page load is fast enough on mobile networks", - "description": "Imperative title of a Lighthouse audit that tells the user that their page has loaded fast enough to be considered a Progressive Web App. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | columnCategory": { - "message": "Category", - "description": "Label for the Main Thread Category column in data tables, rows will have a main thread Category and main thread Task Name." - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | description": { - "message": "Consider reducing the time spent parsing, compiling and executing JS. You may find delivering smaller JS payloads helps with this.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce JS execution times. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | failureTitle": { - "message": "Minimize main-thread work", - "description": "Title of a diagnostic audit that provides detail on the main thread work the browser did to load the page. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | title": { - "message": "Minimizes main-thread work", - "description": "Title of a diagnostic audit that provides detail on the main thread work the browser did to load the page. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { - "message": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the Estimated Input Latency metric that estimates the amount of time, in milliseconds, that the app takes to respond to user input. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)" - } - } - }, - "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { - "message": "Estimated Input Latency", - "description": "The name of the metric that marks the estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { - "message": "First Contentful Paint marks the time at which the first text or image is painted. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the First Contentful Paint (FCP) metric, which marks the time at which the first text or image is painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)" - } - } - }, - "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { - "message": "First Contentful Paint", - "description": "The name of the metric that marks the time at which the first text or image is painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { - "message": "First CPU Idle marks the first time at which the page's main thread is quiet enough to handle input. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the First CPU Idle metric, which marks the time at which the page has displayed content and the CPU is not busy executing the page's scripts. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)" - } - } - }, - "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { - "message": "First CPU Idle", - "description": "The name of the metric that marks when the page has displayed content and the CPU is not busy executing the page's scripts. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { - "message": "First Meaningful Paint measures when the primary content of a page is visible. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the First Meaningful Paint (FMP) metric, which marks the time at which a majority of the content has been painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)" - } - } - }, - "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { - "message": "First Meaningful Paint", - "description": "The name of the metric that marks the time at which a majority of the content has been painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/interactive.js | description": { - "message": "Time to interactive is the amount of time it takes for the page to become fully interactive. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the Time to Interactive (TTI) metric, which evaluates when a page has completed its primary network activity and main thread work. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)" - } - } - }, - "lighthouse-core/audits/metrics/interactive.js | title": { - "message": "Time to Interactive", - "description": "The name of the metric that marks the time at which the page is fully loaded and is able to quickly respond to user input (clicks, taps, and keypresses feel responsive). Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/max-potential-fid.js | description": { - "message": "The maximum potential First Input Delay that your users could experience is the duration, in milliseconds, of the longest task. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the Maximum Potential First Input Delay metric that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/updates/2018/05/first-input-delay)" - } - } - }, - "lighthouse-core/audits/metrics/max-potential-fid.js | title": { - "message": "Max Potential First Input Delay", - "description": "The name of the metric \"Maximum Potential First Input Delay\" that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/metrics/speed-index.js | description": { - "message": "Speed Index shows how quickly the contents of a page are visibly populated. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the Speed Index metric, which summarizes how quickly the page looked visually complete. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/speed-index)" - } - } - }, - "lighthouse-core/audits/metrics/speed-index.js | title": { - "message": "Speed Index", - "description": "The name of the metric that summarizes how quickly the page looked visually complete. The name of this metric is largely abstract and can be loosely translated. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit." - }, - "lighthouse-core/audits/network-rtt.js | description": { - "message": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user that a high network round trip time (RTT) can effect their website's performance because the server is physically far away from them thus making the RTT high. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://hpbn.co/primer-on-latency-and-bandwidth/)" - } - } - }, - "lighthouse-core/audits/network-rtt.js | title": { - "message": "Network Round Trip Times", - "description": "Descriptive title of a Lighthouse audit that tells the user the round trip times to each origin the page connected to. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/network-server-latency.js | description": { - "message": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user that server latency can effect their website's performance negatively. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)" - } - } - }, - "lighthouse-core/audits/network-server-latency.js | title": { - "message": "Server Backend Latencies", - "description": "Descriptive title of a Lighthouse audit that tells the user the server latencies observed from each origin the page connected to. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/performance-budget.js | columnOverBudget": { - "message": "Over Budget", - "description": "Label for a column in a data table; entries will be how much the quantity or size of network requests exceeded a predetermined budget." - }, - "lighthouse-core/audits/performance-budget.js | description": { - "message": "Keep the quantity and size of network requests under the targets set by the provided performance budget. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit where a user sets budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" - } - } - }, - "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { - "message": "{count, plural,\n =1 {1 request}\n other {# requests}\n }", - "description": "[ICU Syntax] Entry in a data table identifying the number of network requests of a particular type. Count will be a whole number. String should be as short as possible to be able to fit well into the table." - }, - "lighthouse-core/audits/performance-budget.js | title": { - "message": "Performance budget", - "description": "Title of a Lighthouse audit that compares the size and quantity of page resources against targets set by the user. These targets are thought of as \"performance budgets\" because these metrics impact page performance (i.e. how quickly a page loads)." - }, - "lighthouse-core/audits/redirects.js | description": { - "message": "Redirects introduce additional delays before the page can be loaded. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells users why they should reduce the number of server-side redirects on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/redirects)" - } - } - }, - "lighthouse-core/audits/redirects.js | title": { - "message": "Avoid multiple page redirects", - "description": "Imperative title of a Lighthouse audit that tells the user to eliminate the redirects taken through multiple URLs to load the page. This is shown in a list of audits that Lighthouse generates." - }, - "lighthouse-core/audits/resource-summary.js | description": { - "message": "To set budgets for the quantity and size of page resources, add a budget.json file. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" - } - } - }, - "lighthouse-core/audits/resource-summary.js | displayValue": { - "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB", - "description": "[ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page." - }, - "lighthouse-core/audits/resource-summary.js | title": { - "message": "Keep request counts low and transfer sizes small", - "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." - }, - "lighthouse-core/audits/seo/canonical.js | description": { - "message": "Canonical links suggest which URL to show in search results. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/canonical)" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationConflict": { - "message": "Multiple conflicting URLs ($ICU_0$)", - "description": "Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other.", - "placeholders": { - "ICU_0": { - "content": "{urlList}", - "example": "https://example.com, https://example2.com" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain": { - "message": "Points to a different domain ($ICU_0$)", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain.", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationInvalid": { - "message": "Invalid URL ($ICU_0$)", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL being invalid.", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "Points to another $MARKDOWN_SNIPPET_0$ location ($ICU_0$)", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context.'hreflang' is an HTML attribute and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - }, - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationRelative": { - "message": "Relative URL ($ICU_0$)", - "description": "Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute.", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationRoot": { - "message": "Points to the domain's root URL (the homepage), instead of an equivalent page of content", - "description": "Explanatory message stating that the page's canonical URL was pointing to the domain's root URL, which is a common mistake. \"points\" refers to the action of the 'rel=canonical' referencing another link. \"root\" refers to the starting/home page of the website. \"domain\" refers to the registered domain name of the website." - }, - "lighthouse-core/audits/seo/canonical.js | failureTitle": { - "message": "Document does not have a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is invalid and should be fixed. \"rel=canonical\" is an HTML attribute and value and so should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=canonical`", - "example": "rel=canonical" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | title": { - "message": "Document has a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. \"rel=canonical\" is an HTML attribute and value and so should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=canonical`", - "example": "rel=canonical" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | description": { - "message": "Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to use a larger font size. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | displayValue": { - "message": "$COMPLEX_ICU_0$ legible text", - "description": "Label for the audit identifying font sizes that are too small.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | explanation": { - "message": "$COMPLEX_ICU_0$ of text is too small.", - "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. \"decimalProportion\" will be replaced by a percentage between 0 and 100%.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | explanationViewport": { - "message": "Text is illegible because there's no viewport meta tag optimized for mobile screens.", - "description": "Explanatory message stating that there was a failure in an audit caused by a missing page viewport meta tag configuration. \"viewport\" and \"meta\" are HTML terms and should not be translated." - }, - "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": { - "message": "$COMPLEX_ICU_0$ of text is too small (based on $COMPLEX_ICU_1$ sample).", - "description": "Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small, based on a sample size of text that was less than 100% of the text on the page. \"decimalProportion\" will be replaced by a percentage between 0 and 100%.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - }, - "COMPLEX_ICU_1": { - "content": "{decimalProportionVisited, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | failureTitle": { - "message": "Document doesn't use legible font sizes", - "description": "Title of a Lighthouse audit that provides detail on the font sizes used on the page. This descriptive title is shown to users when there is a font that may be too small to be read by users." - }, - "lighthouse-core/audits/seo/font-size.js | title": { - "message": "Document uses legible font sizes", - "description": "Title of a Lighthouse audit that provides detail on the font sizes used on the page. This descriptive title is shown to users when the fonts used on the page are large enough to be considered legible." - }, - "lighthouse-core/audits/seo/hreflang.js | description": { - "message": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. \"hreflang\" is an HTML attribute and should not be translated.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/hreflang)" - } - } - }, - "lighthouse-core/audits/seo/hreflang.js | failureTitle": { - "message": "Document doesn't have a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is not valid and needs to be fixed. \"hreflang\" is an HTML attribute and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - } - } - }, - "lighthouse-core/audits/seo/hreflang.js | title": { - "message": "Document has a valid $MARKDOWN_SNIPPET_0$", - "description": "Title of a Lighthouse audit that provides detail on the `hreflang` attribute on a page. This descriptive title is shown when the page's `hreflang` attribute is configured correctly. \"hreflang\" is an HTML attribute and should not be translated.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - } - } - }, - "lighthouse-core/audits/seo/http-status-code.js | description": { - "message": "Pages with unsuccessful HTTP status codes may not be indexed properly. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to serve pages with a valid HTTP status code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)" - } - } - }, - "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { - "message": "Page has unsuccessful HTTP status code", - "description": "Descriptive title of a Lighthouse audit that provides detail on the HTTP status code a page responds with. This descriptive title is shown when the page responds to requests with an HTTP status code that indicates the request was unsuccessful." - }, - "lighthouse-core/audits/seo/http-status-code.js | title": { - "message": "Page has successful HTTP status code", - "description": "Title of a Lighthouse audit that provides detail on the HTTP status code a page responds with. This descriptive title is shown when the page has responded with a valid HTTP status code." - }, - "lighthouse-core/audits/seo/is-crawlable.js | description": { - "message": "Search engines are unable to include your pages in search results if they don't have permission to crawl them. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* allowing search-engine crawling of their page is beneficial. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/indexing)" - } - } - }, - "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { - "message": "Page is blocked from indexing", - "description": "Title of a Lighthouse audit that provides detail on if search-engine crawlers are blocked from indexing the page. This title is shown when the page has been configured to block indexing and therefore cannot be indexed by search engines." - }, - "lighthouse-core/audits/seo/is-crawlable.js | title": { - "message": "Page isn’t blocked from indexing", - "description": "Title of a Lighthouse audit that provides detail on if search-engine crawlers are blocked from indexing the page. This title is shown when the page is not blocked from indexing and can be crawled." - }, - "lighthouse-core/audits/seo/link-text.js | description": { - "message": "Descriptive link text helps search engines understand your content. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have descriptive text on the links in their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)" - } - } - }, - "lighthouse-core/audits/seo/link-text.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 link found}\n other {# links found}\n }", - "description": "[ICU Syntax] Label for the audit identifying the number of links found. \"link\" here refers to the links in a web page to other web pages." - }, - "lighthouse-core/audits/seo/link-text.js | failureTitle": { - "message": "Links do not have descriptive text", - "description": "Title of a Lighthouse audit that tests if each link on a page contains a sufficient description of what a user will find when they click it. Generic, non-descriptive text like \"click here\" doesn't give an indication of what the link leads to. This descriptive title is shown when one or more links on the page contain generic, non-descriptive text." - }, - "lighthouse-core/audits/seo/link-text.js | title": { - "message": "Links have descriptive text", - "description": "Title of a Lighthouse audit that tests if each link on a page contains a sufficient description of what a user will find when they click it. Generic, non-descriptive text like \"click here\" doesn't give an indication of what the link leads to. This descriptive title is shown when all links on the page have sufficient textual descriptions." - }, - "lighthouse-core/audits/seo/manual/structured-data.js | description": { - "message": "Run the $LINK_START_0$Structured Data Testing Tool$LINK_END_0$ and the $LINK_START_1$Structured Data Linter$LINK_END_1$ to validate structured data. $LINK_START_2$Learn more$LINK_END_2$.", - "description": "Description of a Lighthouse audit that provides detail on the structured data in a page. \"Structured data\" is a standardized data format on a page that helps a search engine categorize and understand its contents. This description is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://search.google.com/structured-data/testing-tool/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](http://linter.structured-data.org/)" - }, - "LINK_START_2": { - "content": "[" - }, - "LINK_END_2": { - "content": "](https://developers.google.com/search/docs/guides/mark-up-content)" - } - } - }, - "lighthouse-core/audits/seo/manual/structured-data.js | title": { - "message": "Structured data is valid", - "description": "Title of a Lighthouse audit that prompts users to manually check their page for valid structured data. \"Structured data\" is a standardized data format on a page that helps a search engine categorize and understand its contents." - }, - "lighthouse-core/audits/seo/meta-description.js | description": { - "message": "Meta descriptions may be included in search results to concisely summarize page content. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have meta descriptions on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/description)" - } - } - }, - "lighthouse-core/audits/seo/meta-description.js | explanation": { - "message": "Description text is empty.", - "description": "Explanatory message stating that there was a failure in an audit caused by the page's meta description text being empty." - }, - "lighthouse-core/audits/seo/meta-description.js | failureTitle": { - "message": "Document does not have a meta description", - "description": "Title of a Lighthouse audit that provides detail on the web page's document meta description. This descriptive title is shown when the document does not have a meta description. \"meta\" should be left untranslated because it refers to an HTML element." - }, - "lighthouse-core/audits/seo/meta-description.js | title": { - "message": "Document has a meta description", - "description": "Title of a Lighthouse audit that provides detail on the web page's document meta description. This descriptive title is shown when the document has a meta description. \"meta\" should be left untranslated because it refers to an HTML element." - }, - "lighthouse-core/audits/seo/plugins.js | description": { - "message": "Search engines can't index plugin content, and many devices restrict plugins or don't support them. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to avoid using browser plugins in their content. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/plugins)" - } - } - }, - "lighthouse-core/audits/seo/plugins.js | failureTitle": { - "message": "Document uses plugins", - "description": "Descriptive title of a Lighthouse audit that provides detail on the browser plugins used by the page. This title is shown when there is plugin content on the page." - }, - "lighthouse-core/audits/seo/plugins.js | title": { - "message": "Document avoids plugins", - "description": "Title of a Lighthouse audit that provides detail on the browser plugins used by the page. This descriptive title is shown when there is no plugin content on the page that would restrict search indexing." - }, - "lighthouse-core/audits/seo/robots-txt.js | description": { - "message": "If your robots.txt file is malformed, crawlers may not be able to understand how you want your website to be crawled or indexed.", - "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid robots.txt file. Note: \"robots.txt\" is a canonical filename and should not be translated. This is displayed after a user expands the section to see more. No character length limits." - }, - "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": { - "message": "request for robots.txt returned HTTP status: $ICU_0$", - "description": "Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: \"robots.txt\" is a canonical filename and should not be translated.", - "placeholders": { - "ICU_0": { - "content": "{statusCode}", - "example": "500" - } - } - }, - "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": { - "message": "{itemCount, plural,\n =1 {1 error found}\n other {# errors found}\n }", - "description": "[ICU Syntax] Label for the audit identifying the number of errors that occured while validating the robots.txt file. \"itemCount\" will be replaced by the integer count of errors encountered." - }, - "lighthouse-core/audits/seo/robots-txt.js | explanation": { - "message": "Lighthouse was unable to download a robots.txt file", - "description": "Explanatory message stating that there was a failure in an audit caused by Lighthouse not being able to download the robots.txt file for the site. Note: \"robots.txt\" is a canonical filename and should not be translated." - }, - "lighthouse-core/audits/seo/robots-txt.js | failureTitle": { - "message": "robots.txt is not valid", - "description": "Title of a Lighthouse audit that provides detail on the site's robots.txt file. Note: \"robots.txt\" is a canonical filename and should not be translated. This descriptive title is shown when the robots.txt file is misconfigured, which makes the page hard or impossible to scan via web crawler." - }, - "lighthouse-core/audits/seo/robots-txt.js | title": { - "message": "robots.txt is valid", - "description": "Title of a Lighthouse audit that provides detail on the site's robots.txt file. Note: \"robots.txt\" is a canonical filename and should not be translated. This descriptive title is shown when the robots.txt file is present and configured correctly." - }, - "lighthouse-core/audits/seo/tap-targets.js | description": { - "message": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user why buttons and links need to be big enough and what 'big enough' means. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)" - } - } - }, - "lighthouse-core/audits/seo/tap-targets.js | displayValue": { - "message": "$COMPLEX_ICU_0$ appropriately sized tap targets", - "description": "Explanatory message stating that a certain percentage of the tap targets (like buttons and links) on the page are of an appropriately large size.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, percent}", - "example": "54.6%" - } - } - }, - "lighthouse-core/audits/seo/tap-targets.js | explanationViewportMetaNotOptimized": { - "message": "Tap targets are too small because there's no viewport meta tag optimized for mobile screens", - "description": "Explanatory message stating that there was a failure in an audit caused by the viewport meta tag not being optimized for mobile screens, which caused tap targets like buttons and links to be too small to tap on." - }, - "lighthouse-core/audits/seo/tap-targets.js | failureTitle": { - "message": "Tap targets are not sized appropriately", - "description": "Descriptive title of a Lighthouse audit that provides detail on whether tap targets (like buttons and links) on a page are big enough so they can easily be tapped on a mobile device. This descriptive title is shown when tap targets are not easy to tap on." - }, - "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": { - "message": "Overlapping Target", - "description": "Label of a table column that identifies a tap target (like a link or button) that overlaps with another tap target." - }, - "lighthouse-core/audits/seo/tap-targets.js | sizeHeader": { - "message": "Size", - "description": "Label of a table column that specifies the size of tap targets like buttons and links." - }, - "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": { - "message": "Tap Target", - "description": "Label of a table column that identifies tap targets (like buttons and links) that have failed the audit and aren't easy to tap on." - }, - "lighthouse-core/audits/seo/tap-targets.js | title": { - "message": "Tap targets are sized appropriately", - "description": "Title of a Lighthouse audit that provides detail on whether tap targets (like buttons and links) on a page are big enough so they can easily be tapped on a mobile device. This descriptive title is shown when tap targets are easy to tap on." - }, - "lighthouse-core/audits/third-party-summary.js | columnMainThreadTime": { - "message": "Main Thread Time", - "description": "Label for a table column that displays how much time each row spent executing on the main thread, entries will be the number of milliseconds spent." - }, - "lighthouse-core/audits/third-party-summary.js | columnThirdParty": { - "message": "Third-Party", - "description": "Label for a table column that displays the name of a third-party provider that potentially links to their website." - }, - "lighthouse-core/audits/third-party-summary.js | description": { - "message": "Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that identifies the code on the page that the user doesn't control. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)" - } - } - }, - "lighthouse-core/audits/third-party-summary.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 Third-Party Found}\n other {# Third-Parties Found}\n }", - "description": "Summary text for the result of a Lighthouse audit that identifies the code on the page that the user doesn't control. This text summarizes the number of distinct entities that were found on the page." - }, - "lighthouse-core/audits/third-party-summary.js | title": { - "message": "Third-Party Usage", - "description": "Title of a Lighthouse audit that identifies the code on the page that the user doesn't control. This is shown in a list of audits that Lighthouse generates." - }, - "lighthouse-core/audits/time-to-first-byte.js | description": { - "message": "Time To First Byte identifies the time at which your server sends a response. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should reduce the amount of time it takes their server to start responding to requests. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/ttfb)" - } - } - }, - "lighthouse-core/audits/time-to-first-byte.js | displayValue": { - "message": "Root document took $COMPLEX_ICU_0$ ms", - "description": "Used to summarize the total Time to First Byte duration for the primary HTML response. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 210 ms)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/audits/time-to-first-byte.js | failureTitle": { - "message": "Reduce server response times (TTFB)", - "description": "Title of a diagnostic audit that provides detail on how long it took from starting a request to when the server started responding. This imperative title is shown to users when there is a significant amount of execution time that could be reduced." - }, - "lighthouse-core/audits/time-to-first-byte.js | title": { - "message": "Server response times are low (TTFB)", - "description": "Title of a diagnostic audit that provides detail on how long it took from starting a request to when the server started responding. This descriptive title is shown to users when the amount is acceptable and no user action is required." - }, - "lighthouse-core/audits/user-timings.js | columnDuration": { - "message": "Duration", - "description": "Label for the Duration column in the User Timing event data table. User Timing API entries are added by the developer of the web page. Durations are only provided for 'Measure' entries. Durations are the number of total number milliseconds from Start Time to their ending point. e.g. '2,020.64 ms'" - }, - "lighthouse-core/audits/user-timings.js | columnName": { - "message": "Name", - "description": "Label for the Name column in the User Timing event data table. User Timing API entries are added by the developer of the web page. An example user timing event name: 'pageload_logoimage_done'" - }, - "lighthouse-core/audits/user-timings.js | columnStartTime": { - "message": "Start Time", - "description": "Label for the Start Time column in the User Timing event data table. User Timing API entries are added by the developer of the web page. Start Times are the number of milliseconds since the page started loading, e.g. '380.26 ms'" - }, - "lighthouse-core/audits/user-timings.js | columnType": { - "message": "Type", - "description": "Label for the Type column in the User Timing event data table. User Timing API entries are added by the developer of the web page. The only possible types are 'Mark' and Measure'." - }, - "lighthouse-core/audits/user-timings.js | description": { - "message": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user they may want to use the User Timing API to help measure the performance of aspects of their page load and interaction. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/user-timing)" - } - } - }, - "lighthouse-core/audits/user-timings.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 user timing}\n other {# user timings}\n }", - "description": "[ICU Syntax] Label for an audit identifying the number of User Timing timestamps present in the page." - }, - "lighthouse-core/audits/user-timings.js | title": { - "message": "User Timing marks and measures", - "description": "Descriptive title of a diagnostic audit that provides details on any timestamps generated by the page. User Timing refers to the 'User Timing API', which enables a website to record specific times as 'marks', or spans of time as 'measures'." - }, - "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": "A preconnect <link> was found for \"$ICU_0$\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", - "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`crossorigin`", - "example": "crossorigin" - }, - "ICU_0": { - "content": "{securityOrigin}", - "example": "<link rel=\"preconnect\" href=\"...\">" - } - } - }, - "lighthouse-core/audits/uses-rel-preconnect.js | description": { - "message": "Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user how to connect early to third-party domains that will be used to load page resources. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)" - } - } - }, - "lighthouse-core/audits/uses-rel-preconnect.js | title": { - "message": "Preconnect to required origins", - "description": "Imperative title of a Lighthouse audit that tells the user to connect early to internet domains that will be used to load page resources. Origin is the correct term, however 'domain name' could be used if neccsesary. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": "A preload <link> was found for \"$ICU_0$\" but was not used by the browser. Check that you are using the $MARKDOWN_SNIPPET_0$ attribute properly.", - "description": "A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`crossorigin`", - "example": "crossorigin" - }, - "ICU_0": { - "content": "{preloadURL}", - "example": "<link rel=\"preload\" href=\"...\">" - } - } - }, - "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of a Lighthouse audit that tells the user *why* they should preload important network requests. The associated network requests are started halfway through pageload (or later) but should be started at the beginning. This is displayed after a user expands the section to see more. No character length limits. '<link rel=preload>' is the html code the user would include in their page and shouldn't be translated. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/preload)" - } - } - }, - "lighthouse-core/audits/uses-rel-preload.js | title": { - "message": "Preload key requests", - "description": "Imperative title of a Lighthouse audit that tells the user to use <link rel=preload> to initiate important network requests earlier during page load. This is displayed in a list of audit titles that Lighthouse generates." - }, - "lighthouse-core/config/default-config.js | a11yAriaGroupDescription": { - "message": "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader.", - "description": "Description of the ARIA validity section within the Accessibility category. Within this section are audits with descriptive titles that highlight if whether all the aria- HTML attributes have been used properly." - }, - "lighthouse-core/config/default-config.js | a11yAriaGroupTitle": { - "message": "ARIA", - "description": "Title of the ARIA validity section within the Accessibility category. Within this section are audits with descriptive titles that highlight if whether all the aria- HTML attributes have been used properly." - }, - "lighthouse-core/config/default-config.js | a11yAudioVideoGroupDescription": { - "message": "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments.", - "description": "Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to provide alternative content for audio and video." - }, - "lighthouse-core/config/default-config.js | a11yAudioVideoGroupTitle": { - "message": "Audio and video", - "description": "Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to provide alternative content for audio and video." - }, - "lighthouse-core/config/default-config.js | a11yBestPracticesGroupDescription": { - "message": "These items highlight common accessibility best practices.", - "description": "Description of the best practices section within the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices." - }, - "lighthouse-core/config/default-config.js | a11yBestPracticesGroupTitle": { - "message": "Best practices", - "description": "Title of the best practices section of the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices." - }, - "lighthouse-core/config/default-config.js | a11yCategoryDescription": { - "message": "These checks highlight opportunities to $LINK_START_0$improve the accessibility of your web app$LINK_END_0$. Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.", - "description": "Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility)" - } - } - }, - "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { - "message": "These items address areas which an automated testing tool cannot cover. Learn more in our guide on $LINK_START_0$conducting an accessibility review$LINK_END_0$.", - "description": "Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility/how-to-review)" - } - } - }, - "lighthouse-core/config/default-config.js | a11yCategoryTitle": { - "message": "Accessibility", - "description": "Title of the Accessibility category of audits. This section contains audits focused on making web content accessible to all users. Also used as a label of a score gauge; try to limit to 20 characters." - }, - "lighthouse-core/config/default-config.js | a11yColorContrastGroupDescription": { - "message": "These are opportunities to improve the legibility of your content.", - "description": "Description of the color contrast section within the Accessibility category. Within this section are audits with descriptive titles that highlight the color and vision aspects of the page's accessibility that are passing or failing." - }, - "lighthouse-core/config/default-config.js | a11yColorContrastGroupTitle": { - "message": "Contrast", - "description": "Title of the color contrast section within the Accessibility category. Within this section are audits with descriptive titles that highlight the color and vision aspects of the page's accessibility that are passing or failing." - }, - "lighthouse-core/config/default-config.js | a11yLanguageGroupDescription": { - "message": "These are opportunities to improve the interpretation of your content by users in different locales.", - "description": "Description of the language section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the language has been annotated in the correct HTML attributes on the page." - }, - "lighthouse-core/config/default-config.js | a11yLanguageGroupTitle": { - "message": "Internationalization and localization", - "description": "Title of the language section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the language has been annotated in the correct HTML attributes on the page." - }, - "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupDescription": { - "message": "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader.", - "description": "Description of the HTML element naming section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the non-textual HTML elements on the page have names discernible by a screen reader." - }, - "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupTitle": { - "message": "Names and labels", - "description": "Title of the HTML element naming section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the non-textual HTML elements on the page have names discernible by a screen reader." - }, - "lighthouse-core/config/default-config.js | a11yNavigationGroupDescription": { - "message": "These are opportunities to improve keyboard navigation in your application.", - "description": "Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve keyboard navigation." - }, - "lighthouse-core/config/default-config.js | a11yNavigationGroupTitle": { - "message": "Navigation", - "description": "Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve keyboard navigation." - }, - "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupDescription": { - "message": "These are opportunities to to improve the experience of reading tabular or list data using assistive technology, like a screen reader.", - "description": "Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology." - }, - "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupTitle": { - "message": "Tables and lists", - "description": "Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology." - }, - "lighthouse-core/config/default-config.js | bestPracticesCategoryTitle": { - "message": "Best Practices", - "description": "Title of the Best Practices category of audits. This is displayed at the top of a list of audits focused on topics related to following web development best practices and accepted guidelines. Also used as a label of a score gauge; try to limit to 20 characters." - }, - "lighthouse-core/config/default-config.js | budgetsGroupDescription": { - "message": "Performance budgets set standards for the performance of your site.", - "description": "Description of the Budgets section of the Performance category. Within this section the budget results are displayed." - }, - "lighthouse-core/config/default-config.js | budgetsGroupTitle": { - "message": "Budgets", - "description": "Title of the Budgets section of the Performance Category. 'Budgets' refers to a budget (like a financial budget), but applied to the amount of resources on a page, rather than money." - }, - "lighthouse-core/config/default-config.js | diagnosticsGroupDescription": { - "message": "More information about the performance of your application.", - "description": "Description of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on the page's page load performance characteristics. Whereas the 'Opportunities' suggest an action along with expected time savings, diagnostics do not. Within this section, the user may read the details and deduce additional actions they could take." - }, - "lighthouse-core/config/default-config.js | diagnosticsGroupTitle": { - "message": "Diagnostics", - "description": "Title of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on the page's page load performance characteristics. Whereas the 'Opportunities' suggest an action along with expected time savings, diagnostics do not. Within this section, the user may read the details and deduce additional actions they could take." - }, - "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupDescription": { - "message": "The most critical aspect of performance is how quickly pixels are rendered onscreen. Key metrics: First Contentful Paint, First Meaningful Paint", - "description": "Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage." - }, - "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupTitle": { - "message": "First Paint Improvements", - "description": "Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage." - }, - "lighthouse-core/config/default-config.js | loadOpportunitiesGroupDescription": { - "message": "These optimizations can speed up your page load.", - "description": "Description of the opportunity section of the Performance category. 'Optimizations' could also be 'recommendations' or 'suggestions'. Within this section are audits with imperative titles that suggest actions the user can take to improve the loading performance of their web page." - }, - "lighthouse-core/config/default-config.js | loadOpportunitiesGroupTitle": { - "message": "Opportunities", - "description": "Title of the opportunity section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the loading performance of their web page. 'Suggestion'/'Optimization'/'Recommendation' are reasonable synonyms for 'opportunity' in this case." - }, - "lighthouse-core/config/default-config.js | metricGroupTitle": { - "message": "Metrics", - "description": "Title of the speed metrics section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds." - }, - "lighthouse-core/config/default-config.js | overallImprovementsGroupDescription": { - "message": "Enhance the overall loading experience, so the page is responsive and ready to use as soon as possible. Key metrics: Time to Interactive, Speed Index", - "description": "Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the overall loading performance of their web page." - }, - "lighthouse-core/config/default-config.js | overallImprovementsGroupTitle": { - "message": "Overall Improvements", - "description": "Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the overall loading performance of their web page." - }, - "lighthouse-core/config/default-config.js | performanceCategoryTitle": { - "message": "Performance", - "description": "Title of the Performance category of audits. Equivalent to 'Web performance', this term is inclusive of all web page speed and loading optimization topics. Also used as a label of a score gauge; try to limit to 20 characters." - }, - "lighthouse-core/config/default-config.js | pwaFastReliableGroupTitle": { - "message": "Fast and reliable", - "description": "Title of the Fast and Reliable section of the web app category. Within this section are audits that check if the web site loaded quickly and can reliably load even if the internet connection is very slow or goes offline." - }, - "lighthouse-core/config/default-config.js | pwaInstallableGroupTitle": { - "message": "Installable", - "description": "Title of the Installable section of the web app category. Within this section are audits that check if Chrome supports installing the web site as an app on their device." - }, - "lighthouse-core/config/default-config.js | pwaOptimizedGroupTitle": { - "message": "PWA Optimized", - "description": "Title of the \"PWA Optimized\" section of the web app category. Within this section are audits that check if the developer has taken advantage of features to make their web page more enjoyable and engaging for the user." - }, - "lighthouse-core/config/default-config.js | seoCategoryDescription": { - "message": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the Search Engine Optimization (SEO) category. This is displayed at the top of a list of audits focused on optimizing a website for indexing by search engines. No character length limits. 'Learn More' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://support.google.com/webmasters/answer/35769)" - } - } - }, - "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { - "message": "Run these additional validators on your site to check additional SEO best practices.", - "description": "Description of the Search Engine Optimization (SEO) manual checks category, the additional validators must be run by hand in order to check all SEO best practices. This is displayed at the top of a list of manually run audits focused on optimizing a website for indexing by search engines. No character length limits." - }, - "lighthouse-core/config/default-config.js | seoCategoryTitle": { - "message": "SEO", - "description": "Title of the Search Engine Optimization (SEO) category of audits. This is displayed at the top of a list of audits focused on topics related to optimizing a website for indexing by search engines. Also used as a label of a score gauge; try to limit to 20 characters." - }, - "lighthouse-core/config/default-config.js | seoContentGroupDescription": { - "message": "Format your HTML in a way that enables crawlers to better understand your app’s content.", - "description": "Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website content more easily understood by search engine crawler bots." - }, - "lighthouse-core/config/default-config.js | seoContentGroupTitle": { - "message": "Content Best Practices", - "description": "Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website content more easily understood by search engine crawler bots." - }, - "lighthouse-core/config/default-config.js | seoCrawlingGroupDescription": { - "message": "To appear in search results, crawlers need access to your app.", - "description": "Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website accessible to search engine crawlers." - }, - "lighthouse-core/config/default-config.js | seoCrawlingGroupTitle": { - "message": "Crawling and Indexing", - "description": "Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website accessible to search engine crawlers." - }, - "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { - "message": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. $LINK_START_0$Learn more$LINK_END_0$.", - "description": "Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/search/mobile-sites/)" - } - } - }, - "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { - "message": "Mobile Friendly", - "description": "Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices." - }, - "lighthouse-core/lib/i18n/i18n.js | columnCacheTTL": { - "message": "Cache TTL", - "description": "Label for a column in a data table; entries will be the time to live value of the cache header on a web resource." - }, - "lighthouse-core/lib/i18n/i18n.js | columnLocation": { - "message": "Location", - "description": "Label for a column in a data table; entries will be the location of a specific line of code in a file, in the format \"line: 102\"." - }, - "lighthouse-core/lib/i18n/i18n.js | columnRequests": { - "message": "Requests", - "description": "Label for a column in a data table; entries will be the number of network requests done by a webpage." - }, - "lighthouse-core/lib/i18n/i18n.js | columnResourceType": { - "message": "Resource Type", - "description": "Label for a column in a data table; entries will be types of resources loaded over the network, e.g. \"Scripts\", \"Third-Party\", \"Stylesheet\"." - }, - "lighthouse-core/lib/i18n/i18n.js | columnSize": { - "message": "Size", - "description": "Label for a column in a data table; entries will be the size of a web resource in kilobytes." - }, - "lighthouse-core/lib/i18n/i18n.js | columnTimeSpent": { - "message": "Time Spent", - "description": "Label for a column in a data table; entries will be the number of milliseconds spent during a particular activity." - }, - "lighthouse-core/lib/i18n/i18n.js | columnTransferSize": { - "message": "Transfer Size", - "description": "Label for a column in a data table; entries will be the number of kilobytes transferred to load a set of files." - }, - "lighthouse-core/lib/i18n/i18n.js | columnURL": { - "message": "URL", - "description": "Label for a column in a data table; entries will be the URL of a web resource" - }, - "lighthouse-core/lib/i18n/i18n.js | columnWastedBytes": { - "message": "Potential Savings", - "description": "Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions." - }, - "lighthouse-core/lib/i18n/i18n.js | columnWastedMs": { - "message": "Potential Savings", - "description": "Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions." - }, - "lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings": { - "message": "Potential savings of $COMPLEX_ICU_0$ KB", - "description": "Label shown per-audit to show how many bytes smaller the page could be if the user implemented the suggestions. The `{wastedBytes}` placeholder will be replaced with the number of bytes, shown in kilobytes (e.g. 148 KB)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{wastedBytes, number, bytes}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings": { - "message": "Potential savings of $COMPLEX_ICU_0$ ms", - "description": "Label shown per-audit to show how many milliseconds faster the page load could be if the user implemented the suggestions. The `{wastedMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 140 ms)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{wastedMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { - "message": "Document", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Document' resources loaded by a web page." - }, - "lighthouse-core/lib/i18n/i18n.js | fontResourceType": { - "message": "Font", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page." - }, - "lighthouse-core/lib/i18n/i18n.js | imageResourceType": { - "message": "Image", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page." - }, - "lighthouse-core/lib/i18n/i18n.js | mediaResourceType": { - "message": "Media", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page. 'Media' refers to audio and video files." - }, - "lighthouse-core/lib/i18n/i18n.js | ms": { - "message": "$COMPLEX_ICU_0$ ms", - "description": "Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { - "message": "Other", - "description": "Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font." - }, - "lighthouse-core/lib/i18n/i18n.js | scriptResourceType": { - "message": "Script", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. 'Script' refers to JavaScript or other files that are executable by a browser." - }, - "lighthouse-core/lib/i18n/i18n.js | seconds": { - "message": "$COMPLEX_ICU_0$ s", - "description": "Used to show the duration in seconds that something lasted. The {timeInMs} placeholder will be replaced with the time duration, shown in seconds (e.g. 5.2 s)", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { - "message": "Stylesheet", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. 'Stylesheet' refers to CSS stylesheets." - }, - "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": { - "message": "Third-party", - "description": "Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page." - }, - "lighthouse-core/lib/i18n/i18n.js | totalResourceType": { - "message": "Total", - "description": "Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page." - }, - "lighthouse-core/lib/lh-error.js | badTraceRecording": { - "message": "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ($ICU_0$)", - "description": "Error message explaining that the network trace was not able to be recorded for the Lighthouse run.", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "NO_TRACING_STARTED" - } - } - }, - "lighthouse-core/lib/lh-error.js | criTimeout": { - "message": "Timeout waiting for initial Debugger Protocol connection.", - "description": "Error message explaining that Lighthouse timed out while waiting for the initial connection to the Chrome Devtools protocol." - }, - "lighthouse-core/lib/lh-error.js | didntCollectScreenshots": { - "message": "Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ($ICU_0$)", - "description": "Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome.", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "NO_SPEEDLINE_FRAMES" - } - } - }, - "lighthouse-core/lib/lh-error.js | dnsFailure": { - "message": "DNS servers could not resolve the provided domain.", - "description": "Error message explaining that the requested page could not be resolved by the DNS server." - }, - "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "Required $ICU_0$ gatherer encountered an error: $ICU_1$", - "description": "Error message explaning that there was an error while trying to collect a resource that was required for testing. \"artifactName\" will be replaced with the name of the resource that wasn't collected; \"errorMessage\" will be replaced with a string description of the error that occurred.", - "placeholders": { - "ICU_0": { - "content": "{artifactName}", - "example": "Lighthouse Artifacts" - }, - "ICU_1": { - "content": "{errorMessage}", - "example": "ERRORED_REQUIRED_ARTIFACT" - } - } - }, - "lighthouse-core/lib/lh-error.js | internalChromeError": { - "message": "An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse.", - "description": "Error message explaining that Chrome has encountered an error during the Lighthouse run, and that Chrome should be restarted." - }, - "lighthouse-core/lib/lh-error.js | missingRequiredArtifact": { - "message": "Required $ICU_0$ gatherer did not run.", - "description": "Error message explaning that a resource that was required for testing was never collected. \"artifactName\" will be replaced with the name of the resource that wasn't collected.", - "placeholders": { - "ICU_0": { - "content": "{artifactName}", - "example": "MISSING_REQUIRED_ARTIFACT" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailed": { - "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests.", - "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedHung": { - "message": "Lighthouse was unable to reliably load the URL you requested because the page stopped responding.", - "description": "Error message explaining that Lighthouse couldn't complete because the page has stopped responding to its instructions." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedInsecure": { - "message": "The URL you have provided does not have a valid security certificate. $ICU_0$", - "description": "Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load.", - "placeholders": { - "ICU_0": { - "content": "{securityMessages}", - "example": "net::ERR_CERT_DATE_INVALID" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedInterstitial": { - "message": "Chrome prevented page load with an interstitial. Make sure you are testing the correct URL and that the server is properly responding to all requests.", - "description": "Error message explaining that Chrome prevented the page from loading and displayed an interstitial screen instead, so the URL cannot be accessed." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedWithDetails": { - "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: $ICU_0$)", - "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability.", - "placeholders": { - "ICU_0": { - "content": "{errorDetails}", - "example": "FAILED_DOCUMENT_REQUEST" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedWithStatusCode": { - "message": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: $ICU_0$)", - "description": "Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability.", - "placeholders": { - "ICU_0": { - "content": "{statusCode}", - "example": "404" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadTookTooLong": { - "message": "Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ($ICU_0$)", - "description": "Error message explaining that the page loaded too slowly to perform a Lighthouse run.", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "FMP_TOO_LATE_FOR_FCPUI" - } - } - }, - "lighthouse-core/lib/lh-error.js | protocolTimeout": { - "message": "Waiting for DevTools protocol response has exceeded the allotted time. (Method: $ICU_0$)", - "description": "Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed.", - "placeholders": { - "ICU_0": { - "content": "{protocolMethod}", - "example": "PROTOCOL_TIMEOUT" - } - } - }, - "lighthouse-core/lib/lh-error.js | requestContentTimeout": { - "message": "Fetching resource content has exceeded the allotted time", - "description": "Error message explaining that fetching the resources of the webpage has taken longer than the maximum time." - }, - "lighthouse-core/lib/lh-error.js | urlInvalid": { - "message": "The URL you have provided appears to be invalid.", - "description": "Error message explaining that the provided URL Lighthouse points to is not valid, and cannot be loaded." - }, - "lighthouse-core/report/html/renderer/util.js | auditGroupExpandTooltip": { - "message": "Show audits", - "description": "The tooltip text on an expandable chevron icon. Clicking the icon expands a section to reveal a list of audit results that was hidden by default." - }, - "lighthouse-core/report/html/renderer/util.js | crcInitialNavigation": { - "message": "Initial Navigation", - "description": "String of text shown in a graphical representation of the flow of network requests for the web page. This label represents the initial network request that fetches an HTML page. This navigation may be redirected (eg. Initial navigation to http://example.com redirects to https://www.example.com)." - }, - "lighthouse-core/report/html/renderer/util.js | crcLongestDurationLabel": { - "message": "Maximum critical path latency:", - "description": "Label of value shown in the summary of critical request chains. Refers to the total amount of time (milliseconds) of the longest critical path chain/sequence of network requests. Example value: 2310 ms" - }, - "lighthouse-core/report/html/renderer/util.js | errorLabel": { - "message": "Error!", - "description": "A label, shown next to an audit title or metric title, indicating that there was an error computing it. The user can hover on the label to reveal a tooltip with the extended error message. Translation should be short (< 20 characters)." - }, - "lighthouse-core/report/html/renderer/util.js | errorMissingAuditInfo": { - "message": "Report error: no audit information", - "description": "An error string displayed next to a particular audit when it has errored, but not provided any specific error message." - }, - "lighthouse-core/report/html/renderer/util.js | labDataTitle": { - "message": "Lab Data", - "description": "Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. \"Lab\" is an abbreviated form of \"laboratory\", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site." - }, - "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { - "message": "$LINK_START_0$Lighthouse$LINK_END_0$ analysis of the current page on an emulated mobile network. Values are estimated and may vary.", - "description": "Explanation shown to users below performance results to inform them that the test was done with a 4G network connection and to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. 'Lighthouse' becomes link text to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/)" - } - } - }, - "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { - "message": "Additional items to manually check", - "description": "Section heading shown above a list of audits that were not computed by Lighthouse. They serve as a list of suggestions for the user to go and manually check. For example, Lighthouse can't automate testing cross-browser compatibility, so that is listed within this section, so the user is reminded to test it themselves. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list." - }, - "lighthouse-core/report/html/renderer/util.js | notApplicableAuditsGroupTitle": { - "message": "Not applicable", - "description": "Section heading shown above a list of audits that do not apply to the page. For example, if an audit is 'Are images optimized?', but the page has no images on it, the audit will be marked as not applicable. This is neither passing or failing. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list." - }, - "lighthouse-core/report/html/renderer/util.js | opportunityResourceColumnLabel": { - "message": "Opportunity", - "description": "Column heading label for the listing of opportunity audits. Each audit title represents an opportunity. There are only 2 columns, so no strict character limit." - }, - "lighthouse-core/report/html/renderer/util.js | opportunitySavingsColumnLabel": { - "message": "Estimated Savings", - "description": "Column heading label for the estimated page load savings of opportunity audits. Estimated Savings is the total amount of time (in seconds) that Lighthouse computed could be reduced from the total page load time, if the suggested action is taken. There are only 2 columns, so no strict character limit." - }, - "lighthouse-core/report/html/renderer/util.js | passedAuditsGroupTitle": { - "message": "Passed audits", - "description": "Section heading shown above a list of audits that are passing. 'Passed' here refers to a passing grade. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list." - }, - "lighthouse-core/report/html/renderer/util.js | snippetCollapseButtonLabel": { - "message": "Collapse snippet", - "description": "Label for button that only shows a few lines of the snippet when clicked" - }, - "lighthouse-core/report/html/renderer/util.js | snippetExpandButtonLabel": { - "message": "Expand snippet", - "description": "Label for button that shows all lines of the snippet when clicked" - }, - "lighthouse-core/report/html/renderer/util.js | thirdPartyResourcesLabel": { - "message": "Show 3rd-party resources", - "description": "This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or \"3rd-party\") resources in the table, where \"third-party resources\" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page." - }, - "lighthouse-core/report/html/renderer/util.js | toplevelWarningsMessage": { - "message": "There were issues affecting this run of Lighthouse:", - "description": "Label shown preceding any important warnings that may have invalidated the entire report. For example, if the user has Chrome extensions installed, they may add enough performance overhead that Lighthouse's performance metrics are unreliable. If shown, this will be displayed at the top of the report UI." - }, - "lighthouse-core/report/html/renderer/util.js | varianceDisclaimer": { - "message": "Values are estimated and may vary.", - "description": "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." - }, - "lighthouse-core/report/html/renderer/util.js | warningAuditsGroupTitle": { - "message": "Passed audits but with warnings", - "description": "Section heading shown above a list of passed audits that contain warnings. Audits under this section do not negatively impact the score, but Lighthouse has generated some potentially actionable suggestions that should be reviewed. This section is expanded by default and displays after the failing audits." - }, - "lighthouse-core/report/html/renderer/util.js | warningHeader": { - "message": "Warnings: ", - "description": "This label is shown above a bulleted list of warnings. It is shown directly below an audit that produced warnings. Warnings describe situations the user should be aware of, as Lighthouse was unable to complete all the work required on this audit. For example, The 'Unable to decode image (biglogo.jpg)' warning may show up below an image encoding audit." - }, - "stack-packs/packs/wordpress.js | efficient_animated_content": { - "message": "Consider uploading your GIF to a service which will make it available to embed as an HTML5 video.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." - }, - "stack-packs/packs/wordpress.js | offscreen_images": { - "message": "Install a $LINK_START_0$lazy-load WordPress plugin$LINK_END_0$ that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using $LINK_START_1$the AMP plugin$LINK_END_1$.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/lazy+load/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://wordpress.org/plugins/amp/)" - } - } - }, - "stack-packs/packs/wordpress.js | render_blocking_resources": { - "message": "There are a number of WordPress plugins that can help you $LINK_START_0$inline critical assets$LINK_END_0$ or $LINK_START_1$defer less important resources$LINK_END_1$. Beware that optimizations provided by these plugins may break features of your theme or plugins, so you will likely need to make code changes.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/critical+css/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://wordpress.org/plugins/search/defer+css+javascript/)" - } - } - }, - "stack-packs/packs/wordpress.js | time_to_first_byte": { - "message": "Themes, plugins, and server specifications all contribute to server response time. Consider finding a more optimized theme, carefully selecting an optimization plugin, and/or upgrading your server.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." - }, - "stack-packs/packs/wordpress.js | total_byte_weight": { - "message": "Consider showing excerpts in your post lists (e.g. via the more tag), reducing the number of posts shown on a given page, breaking your long posts into multiple pages, or using a plugin to lazy-load comments.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." - }, - "stack-packs/packs/wordpress.js | unminified_css": { - "message": "A number of $LINK_START_0$WordPress plugins$LINK_END_0$ can speed up your site by concatenating, minifying, and compressing your styles. You may also want to use a build process to do this minification up-front if possible.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/minify+css/)" - } - } - }, - "stack-packs/packs/wordpress.js | unminified_javascript": { - "message": "A number of $LINK_START_0$WordPress plugins$LINK_END_0$ can speed up your site by concatenating, minifying, and compressing your scripts. You may also want to use a build process to do this minification up front if possible.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/minify+javascript/)" - } - } - }, - "stack-packs/packs/wordpress.js | unused_css_rules": { - "message": "Consider reducing, or switching, the number of $LINK_START_0$WordPress plugins$LINK_END_0$ loading unused CSS in your page. To identify plugins that are adding extraneous CSS, try running $LINK_START_1$code coverage$LINK_END_1$ in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage)" - } - } - }, - "stack-packs/packs/wordpress.js | unused_javascript": { - "message": "Consider reducing, or switching, the number of $LINK_START_0$WordPress plugins$LINK_END_0$ loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running $LINK_START_1$code coverage$LINK_END_1$ in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the script. Look out for plugins that have many scripts in the list which have a lot of red in code coverage. A plugin should only enqueue a script if it is actually used on the page.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage)" - } - } - }, - "stack-packs/packs/wordpress.js | uses_long_cache_ttl": { - "message": "Read about $LINK_START_0$Browser Caching in WordPress$LINK_END_0$.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching)" - } - } - }, - "stack-packs/packs/wordpress.js | uses_optimized_images": { - "message": "Consider using an $LINK_START_0$image optimization WordPress plugin$LINK_END_0$ that compresses your images while retaining quality.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/optimize+images/)" - } - } - }, - "stack-packs/packs/wordpress.js | uses_responsive_images": { - "message": "Upload images directly through the $LINK_START_0$media library$LINK_END_0$ to ensure that the required image sizes are available, and then insert them from the media library or use the image widget to ensure the optimal image sizes are used (including those for the responsive breakpoints). Avoid using $MARKDOWN_SNIPPET_0$ images unless the dimensions are adequate for their usage. $LINK_START_1$Learn More$LINK_END_1$.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`Full Size`", - "example": "Full Size" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://codex.wordpress.org/Media_Library_Screen)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://codex.wordpress.org/Inserting_Images_into_Posts_and_Pages#Image_Size)" - } - } - }, - "stack-packs/packs/wordpress.js | uses_text_compression": { - "message": "You can enable text compression in your web server configuration.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve performance via enabling text compression in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation." - }, - "stack-packs/packs/wordpress.js | uses_webp_images": { - "message": "Consider using a $LINK_START_0$plugin$LINK_END_0$ or service that will automatically convert your uploaded images to the optimal formats.", - "description": "Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. Links in (parenthesis) become link texts to additional documentation.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://wordpress.org/plugins/search/convert+webp/)" - } - } - } -} diff --git a/lighthouse-core/lib/i18n/pre-locale/en-XL.json b/lighthouse-core/lib/i18n/pre-locale/en-XL.json deleted file mode 100644 index abc7ef36f6a7..000000000000 --- a/lighthouse-core/lib/i18n/pre-locale/en-XL.json +++ /dev/null @@ -1,3106 +0,0 @@ -{ - "lighthouse-core/audits/accessibility/accesskeys.js | description": { - "message": "Âćĉéŝś k̂éŷś l̂ét̂ úŝér̂ś q̂úîćk̂ĺŷ f́ôćûś â ṕâŕt̂ óf̂ t́ĥé p̂áĝé. F̂ór̂ ṕr̂óp̂ér̂ ńâv́îǵât́îón̂, éâćĥ áĉćêśŝ ḱêý m̂úŝt́ b̂é ûńîq́ûé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/accesskeys?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/accesskeys.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ńôt́ ûńîq́ûé", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[accesskey]`", - "example": "[accesskey]" - } - } - }, - "lighthouse-core/audits/accessibility/accesskeys.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ún̂íq̂úê", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[accesskey]`", - "example": "[accesskey]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | description": { - "message": "Êáĉh́ ÂŔÎÁ $MARKDOWN_SNIPPET_0$ ŝúp̂ṕôŕt̂ś â śp̂éĉíf̂íĉ śûb́ŝét̂ óf̂ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂éŝ. Ḿîśm̂át̂ćĥín̂ǵ t̂h́êśê ín̂v́âĺîd́ât́êś t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`role`", - "example": "role" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`aria-*`", - "example": "aria-*" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`aria-*`", - "example": "aria-*" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-allowed-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ ḿât́ĉh́ t̂h́êír̂ ŕôĺêś", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-allowed-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś m̂át̂ćĥ t́ĥéîŕ r̂ól̂éŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ r̂ól̂éŝ h́âv́ê ŕêq́ûír̂éd̂ át̂t́r̂íb̂út̂éŝ t́ĥát̂ d́êśĉŕîb́ê t́ĥé ŝt́ât́ê óf̂ t́ĥé êĺêḿêńt̂ t́ô śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ŝ d́ô ńôt́ ĥáv̂é âĺl̂ ŕêq́ûír̂éd̂ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂éŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ŝ h́âv́ê ál̂ĺ r̂éq̂úîŕêd́ $MARKDOWN_SNIPPET_1$ ât́t̂ŕîb́ût́êś", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ p̂ár̂én̂t́ r̂ól̂éŝ ḿûśt̂ ćôńt̂áîń ŝṕêćîf́îć ĉh́îĺd̂ ŕôĺêś t̂ó p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-children?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | failureTitle": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ $MARKDOWN_SNIPPET_0$ t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ $MARKDOWN_SNIPPET_1$ś, âŕê ḿîśŝín̂ǵ.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-children.js | title": { - "message": "Êĺêḿêńt̂ś ŵít̂h́ $MARKDOWN_SNIPPET_0$ t̂h́ât́ r̂éq̂úîŕê śp̂éĉíf̂íĉ ćĥíl̂d́r̂én̂ $MARKDOWN_SNIPPET_1$ś, âŕê ṕr̂éŝén̂t́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | description": { - "message": "Ŝóm̂é ÂŔÎÁ ĉh́îĺd̂ ŕôĺêś m̂úŝt́ b̂é ĉón̂t́âín̂éd̂ b́ŷ śp̂éĉíf̂íĉ ṕâŕêńt̂ ŕôĺêś t̂ó p̂ŕôṕêŕl̂ý p̂ér̂f́ôŕm̂ t́ĥéîŕ îńt̂én̂d́êd́ âćĉéŝśîb́îĺît́ŷ f́ûńĉt́îón̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-required-parent?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ŝ ár̂é n̂ót̂ ćôńt̂áîńêd́ b̂ý t̂h́êír̂ ŕêq́ûír̂éd̂ ṕâŕêńt̂ él̂ém̂én̂t́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-required-parent.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ŝ ár̂é ĉón̂t́âín̂éd̂ b́ŷ t́ĥéîŕ r̂éq̂úîŕêd́ p̂ár̂én̂t́ êĺêḿêńt̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | description": { - "message": "ÂŔÎÁ r̂ól̂éŝ ḿûśt̂ h́âv́ê v́âĺîd́ v̂ál̂úêś îń ôŕd̂ér̂ t́ô ṕêŕf̂ór̂ḿ t̂h́êír̂ ín̂t́êńd̂éd̂ áĉćêśŝíb̂íl̂ít̂ý f̂ún̂ćt̂íôńŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-roles?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê ńôt́ v̂ál̂íd̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-roles.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ v̂ál̂úêś âŕê v́âĺîd́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[role]`", - "example": "[role]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ v̂ál̂úêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr-value?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê v́âĺîd́ v̂ál̂úêś", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr-value.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ĥáv̂é v̂ál̂íd̂ v́âĺûéŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | description": { - "message": "Âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś, ĉán̂'t́ îńt̂ér̂ṕr̂ét̂ ÁR̂Í át̂t́r̂íb̂út̂éŝ ẃît́ĥ ín̂v́âĺîd́ n̂ám̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/aria-valid-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś âŕê ńôt́ v̂ál̂íd̂ ór̂ ḿîśŝṕêĺl̂éd̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/aria-valid-attr.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś âŕê v́âĺîd́ âńd̂ ńôt́ m̂íŝśp̂él̂ĺêd́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[aria-*]`", - "example": "[aria-*]" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | description": { - "message": "Ĉáp̂t́îón̂ś m̂ák̂é âúd̂íô él̂ém̂én̂t́ŝ úŝáb̂ĺê f́ôŕ d̂éâf́ ôŕ ĥéâŕîńĝ-ím̂ṕâír̂éd̂ úŝér̂ś, p̂ŕôv́îd́îńĝ ćr̂ít̂íĉál̂ ín̂f́ôŕm̂át̂íôń ŝúĉh́ âś ŵh́ô íŝ t́âĺk̂ín̂ǵ, ŵh́ât́ t̂h́êý'r̂é ŝáŷín̂ǵ, âńd̂ ót̂h́êŕ n̂ón̂-śp̂éêćĥ ín̂f́ôŕm̂át̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/audio-caption?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âŕê ḿîśŝín̂ǵ â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<audio>`", - "example": "<audio>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/audio-caption.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<audio>`", - "example": "<audio>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": { - "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" - }, - "lighthouse-core/audits/accessibility/button-name.js | description": { - "message": "Ŵh́êń â b́ût́t̂ón̂ d́ôéŝń't̂ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê, śĉŕêén̂ ŕêád̂ér̂ś âńn̂óûńĉé ît́ âś \"b̂út̂t́ôń\", m̂ák̂ín̂ǵ ît́ ûńûśâb́l̂é f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/button-name?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/button-name.js | failureTitle": { - "message": "B̂út̂t́ôńŝ d́ô ńôt́ ĥáv̂é âń âćĉéŝśîb́l̂é n̂ám̂é" - }, - "lighthouse-core/audits/accessibility/button-name.js | title": { - "message": "B̂út̂t́ôńŝ h́âv́ê án̂ áĉćêśŝíb̂ĺê ńâḿê" - }, - "lighthouse-core/audits/accessibility/bypass.js | description": { - "message": "Âd́d̂ín̂ǵ ŵáŷś t̂ó b̂ýp̂áŝś r̂ép̂ét̂ít̂ív̂é ĉón̂t́êńt̂ ĺêt́ŝ ḱêýb̂óâŕd̂ úŝér̂ś n̂áv̂íĝát̂é t̂h́ê ṕâǵê ḿôŕê éf̂f́îćîén̂t́l̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/bypass?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/bypass.js | failureTitle": { - "message": "T̂h́ê ṕâǵê d́ôéŝ ńôt́ ĉón̂t́âín̂ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" - }, - "lighthouse-core/audits/accessibility/bypass.js | title": { - "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ á ĥéâd́îńĝ, śk̂íp̂ ĺîńk̂, ór̂ ĺâńd̂ḿâŕk̂ ŕêǵîón̂" - }, - "lighthouse-core/audits/accessibility/color-contrast.js | description": { - "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/color-contrast?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/color-contrast.js | failureTitle": { - "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ d́ô ńôt́ ĥáv̂é â śûf́f̂íĉíêńt̂ ćôńt̂ŕâśt̂ ŕât́îó." - }, - "lighthouse-core/audits/accessibility/color-contrast.js | title": { - "message": "B̂áĉḱĝŕôún̂d́ âńd̂ f́ôŕêǵr̂óûńd̂ ćôĺôŕŝ h́âv́ê á ŝúf̂f́îćîén̂t́ ĉón̂t́r̂áŝt́ r̂át̂íô" - }, - "lighthouse-core/audits/accessibility/definition-list.js | description": { - "message": "Ŵh́êń d̂éf̂ín̂ít̂íôń l̂íŝt́ŝ ár̂é n̂ót̂ ṕr̂óp̂ér̂ĺŷ ḿâŕk̂éd̂ úp̂, śĉŕêén̂ ŕêád̂ér̂ś m̂áŷ ṕr̂ód̂úĉé ĉón̂f́ûśîńĝ ór̂ ín̂áĉćûŕât́ê óût́p̂út̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/definition-list?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/definition-list.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$'ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ ṕr̂óp̂ér̂ĺŷ-ór̂d́êŕêd́ $MARKDOWN_SNIPPET_1$ âńd̂ $MARKDOWN_SNIPPET_2$ ǵr̂óûṕŝ, $MARKDOWN_SNIPPET_3$ ór̂ $MARKDOWN_SNIPPET_4$ él̂ém̂én̂t́ŝ.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_4": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/definition-list.js | title": { - "message": "$MARKDOWN_SNIPPET_0$'ŝ ćôńt̂áîń ôńl̂ý p̂ŕôṕêŕl̂ý-ôŕd̂ér̂éd̂ $MARKDOWN_SNIPPET_1$ án̂d́ $MARKDOWN_SNIPPET_2$ ĝŕôúp̂ś, $MARKDOWN_SNIPPET_3$ ôŕ $MARKDOWN_SNIPPET_4$ êĺêḿêńt̂ś.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_4": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | description": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$ án̂d́ $MARKDOWN_SNIPPET_1$) m̂úŝt́ b̂é ŵŕâṕp̂éd̂ ín̂ á p̂ár̂én̂t́ $MARKDOWN_SNIPPET_2$ êĺêḿêńt̂ t́ô én̂śûŕê t́ĥát̂ śĉŕêén̂ ŕêád̂ér̂ś ĉán̂ ṕr̂óp̂ér̂ĺŷ án̂ńôún̂ćê t́ĥém̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dt>`", - "example": "<dt>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<dd>`", - "example": "<dd>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<dl>`", - "example": "<dl>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/dlitem?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | failureTitle": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é n̂ót̂ ẃr̂áp̂ṕêd́ îń $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - } - } - }, - "lighthouse-core/audits/accessibility/dlitem.js | title": { - "message": "D̂éf̂ín̂ít̂íôń l̂íŝt́ ît́êḿŝ ár̂é ŵŕâṕp̂éd̂ ín̂ $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<dl>`", - "example": "<dl>" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | description": { - "message": "T̂h́ê t́ît́l̂é ĝív̂éŝ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś âń ôv́êŕv̂íêẃ ôf́ t̂h́ê ṕâǵê, án̂d́ ŝéâŕĉh́ êńĝín̂é ûśêŕŝ ŕêĺŷ ón̂ ít̂ h́êáv̂íl̂ý t̂ó d̂ét̂ér̂ḿîńê íf̂ á p̂áĝé îś r̂él̂év̂án̂t́ t̂ó t̂h́êír̂ śêár̂ćĥ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/title)" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<title>`", - "example": "<title>" - } - } - }, - "lighthouse-core/audits/accessibility/document-title.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<title>`", - "example": "<title>" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | description": { - "message": "T̂h́ê v́âĺûé ôf́ âń îd́ ât́t̂ŕîb́ût́ê ḿûśt̂ b́ê ún̂íq̂úê t́ô ṕr̂év̂én̂t́ ôt́ĥér̂ ín̂śt̂án̂ćêś f̂ŕôḿ b̂éîńĝ óv̂ér̂ĺôók̂éd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/duplicate-id?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é n̂ót̂ ún̂íq̂úê", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[id]`", - "example": "[id]" - } - } - }, - "lighthouse-core/audits/accessibility/duplicate-id.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ôń t̂h́ê ṕâǵê ár̂é ûńîq́ûé", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[id]`", - "example": "[id]" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ŕêĺŷ ón̂ f́r̂ám̂é t̂ít̂ĺêś t̂ó d̂éŝćr̂íb̂é t̂h́ê ćôńt̂én̂t́ŝ óf̂ f́r̂ám̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/frame-title?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ôŕ $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê á t̂ít̂ĺê", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<frame>`", - "example": "<frame>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<iframe>`", - "example": "<iframe>" - } - } - }, - "lighthouse-core/audits/accessibility/frame-title.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ôŕ $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ś ĥáv̂é â t́ît́l̂é", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<frame>`", - "example": "<frame>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<iframe>`", - "example": "<iframe>" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | description": { - "message": "Îf́ â ṕâǵê d́ôéŝń't̂ śp̂éĉíf̂ý â ĺâńĝ át̂t́r̂íb̂út̂é, â śĉŕêén̂ ŕêád̂ér̂ áŝśûḿêś t̂h́ât́ t̂h́ê ṕâǵê íŝ ín̂ t́ĥé d̂éf̂áûĺt̂ ĺâńĝúâǵê t́ĥát̂ t́ĥé ûśêŕ ĉh́ôśê ẃĥén̂ śêt́t̂ín̂ǵ ûṕ t̂h́ê śĉŕêén̂ ŕêád̂ér̂. Íf̂ t́ĥé p̂áĝé îśn̂'t́ âćt̂úâĺl̂ý îń t̂h́ê d́êf́âúl̂t́ l̂án̂ǵûáĝé, t̂h́êń t̂h́ê śĉŕêén̂ ŕêád̂ér̂ ḿîǵĥt́ n̂ót̂ án̂ńôún̂ćê t́ĥé p̂áĝé'ŝ t́êx́t̂ ćôŕr̂éĉt́l̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-has-lang.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ h́âś â $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ $LINK_START_0$B̂ĆP̂ 47 ĺâńĝúâǵê$LINK_END_0$ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ án̂ńôún̂ćê t́êx́t̂ ṕr̂óp̂ér̂ĺŷ. $LINK_START_1$Ĺêár̂ń m̂ór̂é$LINK_END_1$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/html-lang-valid.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ h́âś â v́âĺîd́ v̂ál̂úê f́ôŕ ît́ŝ $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<html>`", - "example": "<html>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | description": { - "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/image-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | failureTitle": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/image-alt.js | title": { - "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂éŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | description": { - "message": "Ŵh́êń âń îḿâǵê íŝ b́êín̂ǵ ûśêd́ âś âń $MARKDOWN_SNIPPET_0$ b̂út̂t́ôń, p̂ŕôv́îd́îńĝ ál̂t́êŕn̂át̂ív̂é t̂éx̂t́ ĉán̂ h́êĺp̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś ûńd̂ér̂śt̂án̂d́ t̂h́ê ṕûŕp̂óŝé ôf́ t̂h́ê b́ût́t̂ón̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input>`", - "example": "<input>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/input-image-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê $MARKDOWN_SNIPPET_1$ t́êx́t̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input type=\"image\">`", - "example": "<input type=\"image\">" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/input-image-alt.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĥáv̂é $MARKDOWN_SNIPPET_1$ t̂éx̂t́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<input type=\"image\">`", - "example": "<input type=\"image\">" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/label.js | description": { - "message": "L̂áb̂él̂ś êńŝúr̂é t̂h́ât́ f̂ór̂ḿ ĉón̂t́r̂ól̂ś âŕê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý b̂ý âśŝíŝt́îv́ê t́êćĥńôĺôǵîéŝ, ĺîḱê śĉŕêén̂ ŕêád̂ér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/label?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/label.js | failureTitle": { - "message": "F̂ór̂ḿ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê áŝśôćîát̂éd̂ ĺâb́êĺŝ" - }, - "lighthouse-core/audits/accessibility/label.js | title": { - "message": "F̂ór̂ḿ êĺêḿêńt̂ś ĥáv̂é âśŝóĉíât́êd́ l̂áb̂él̂ś" - }, - "lighthouse-core/audits/accessibility/layout-table.js | description": { - "message": " t́âb́l̂é b̂éîńĝ úŝéd̂ f́ôŕ l̂áŷóût́ p̂úr̂ṕôśêś ŝh́ôúl̂d́ n̂ót̂ ín̂ćl̂úd̂é d̂át̂á êĺêḿêńt̂ś, ŝúĉh́ âś t̂h́ê t́ĥ ór̂ ćâṕt̂íôń êĺêḿêńt̂ś ôŕ t̂h́ê śûḿm̂ár̂ý ât́t̂ŕîb́ût́ê, b́êćâúŝé t̂h́îś ĉán̂ ćr̂éât́ê á ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/layout-table?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/layout-table.js | failureTitle": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ áv̂óîd́ ûśîńĝ $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ ór̂ t́ĥé $MARKDOWN_SNIPPET_3$ ât́t̂ŕîb́ût́ê.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<caption>`", - "example": "<caption>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`[summary]`", - "example": "[summary]" - } - } - }, - "lighthouse-core/audits/accessibility/layout-table.js | title": { - "message": "P̂ŕêśêńt̂át̂íôńâĺ $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âv́ôíd̂ úŝín̂ǵ $MARKDOWN_SNIPPET_1$, $MARKDOWN_SNIPPET_2$ ôŕ t̂h́ê $MARKDOWN_SNIPPET_3$ át̂t́r̂íb̂út̂é.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<caption>`", - "example": "<caption>" - }, - "MARKDOWN_SNIPPET_3": { - "content": "`[summary]`", - "example": "[summary]" - } - } - }, - "lighthouse-core/audits/accessibility/link-name.js | description": { - "message": "L̂ín̂ḱ t̂éx̂t́ (âńd̂ ál̂t́êŕn̂át̂é t̂éx̂t́ f̂ór̂ ím̂áĝéŝ, ẃĥén̂ úŝéd̂ áŝ ĺîńk̂ś) t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê, ún̂íq̂úê, án̂d́ f̂óĉúŝáb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé n̂áv̂íĝát̂íôń êx́p̂ér̂íêńĉé f̂ór̂ śĉŕêén̂ ŕêád̂ér̂ úŝér̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/link-name?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/link-name.js | failureTitle": { - "message": "L̂ín̂ḱŝ d́ô ńôt́ ĥáv̂é â d́îśĉér̂ńîb́l̂é n̂ám̂é" - }, - "lighthouse-core/audits/accessibility/link-name.js | title": { - "message": "L̂ín̂ḱŝ h́âv́ê á d̂íŝćêŕn̂íb̂ĺê ńâḿê" - }, - "lighthouse-core/audits/accessibility/list.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê á ŝṕêćîf́îć ŵáŷ óf̂ án̂ńôún̂ćîńĝ ĺîśt̂ś. Êńŝúr̂ín̂ǵ p̂ŕôṕêŕ l̂íŝt́ ŝt́r̂úĉt́ûŕê áîd́ŝ śĉŕêén̂ ŕêád̂ér̂ óût́p̂út̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/list?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/list.js | failureTitle": { - "message": "L̂íŝt́ŝ d́ô ńôt́ ĉón̂t́âín̂ ón̂ĺŷ $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ án̂d́ ŝćr̂íp̂t́ ŝúp̂ṕôŕt̂ín̂ǵ êĺêḿêńt̂ś ($MARKDOWN_SNIPPET_1$ âńd̂ $MARKDOWN_SNIPPET_2$).", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/list.js | title": { - "message": "L̂íŝt́ŝ ćôńt̂áîń ôńl̂ý $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ śĉŕîṕt̂ śûṕp̂ór̂t́îńĝ él̂ém̂én̂t́ŝ ($MARKDOWN_SNIPPET_1$ án̂d́ $MARKDOWN_SNIPPET_2$).", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<script>`", - "example": "<script>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<template>`", - "example": "<template>" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ŕêq́ûír̂é l̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) t́ô b́ê ćôńt̂áîńêd́ ŵít̂h́îń â ṕâŕêńt̂ $MARKDOWN_SNIPPET_1$ ór̂ $MARKDOWN_SNIPPET_2$ t́ô b́ê án̂ńôún̂ćêd́ p̂ŕôṕêŕl̂ý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/listitem?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | failureTitle": { - "message": "L̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) ár̂é n̂ót̂ ćôńt̂áîńêd́ ŵít̂h́îń $MARKDOWN_SNIPPET_1$ ôŕ $MARKDOWN_SNIPPET_2$ p̂ár̂én̂t́ êĺêḿêńt̂ś.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - } - } - }, - "lighthouse-core/audits/accessibility/listitem.js | title": { - "message": "L̂íŝt́ ît́êḿŝ ($MARKDOWN_SNIPPET_0$) ár̂é ĉón̂t́âín̂éd̂ ẃît́ĥín̂ $MARKDOWN_SNIPPET_1$ ór̂ $MARKDOWN_SNIPPET_2$ ṕâŕêńt̂ él̂ém̂én̂t́ŝ", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<li>`", - "example": "<li>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<ul>`", - "example": "<ul>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`<ol>`", - "example": "<ol>" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | description": { - "message": "Ûśêŕŝ d́ô ńôt́ êx́p̂éĉt́ â ṕâǵê t́ô ŕêf́r̂éŝh́ âút̂óm̂át̂íĉál̂ĺŷ, án̂d́ d̂óîńĝ śô ẃîĺl̂ ḿôv́ê f́ôćûś b̂áĉḱ t̂ó t̂h́ê t́ôṕ ôf́ t̂h́ê ṕâǵê. T́ĥíŝ ḿâý ĉŕêát̂é â f́r̂úŝt́r̂át̂ín̂ǵ ôŕ ĉón̂f́ûśîńĝ éx̂ṕêŕîén̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-refresh?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | failureTitle": { - "message": "T̂h́ê d́ôćûḿêńt̂ úŝéŝ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<meta http-equiv=\"refresh\">`", - "example": "<meta http-equiv=\"refresh\">" - } - } - }, - "lighthouse-core/audits/accessibility/meta-refresh.js | title": { - "message": "T̂h́ê d́ôćûḿêńt̂ d́ôéŝ ńôt́ ûśê $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<meta http-equiv=\"refresh\">`", - "example": "<meta http-equiv=\"refresh\">" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | description": { - "message": "D̂íŝáb̂ĺîńĝ źôóm̂ín̂ǵ îś p̂ŕôb́l̂ém̂át̂íĉ f́ôŕ ûśêŕŝ ẃît́ĥ ĺôẃ v̂íŝíôń ŵh́ô ŕêĺŷ ón̂ śĉŕêén̂ ḿâǵn̂íf̂íĉát̂íôń t̂ó p̂ŕôṕêŕl̂ý ŝéê t́ĥé ĉón̂t́êńt̂ś ôf́ â ẃêb́ p̂áĝé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/meta-viewport?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ îś ûśêd́ îń t̂h́ê $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ôŕ t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂é îś l̂éŝś t̂h́âń 5.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[user-scalable=\"no\"]`", - "example": "[user-scalable=\"no\"]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<meta name=\"viewport\">`", - "example": "<meta name=\"viewport\">" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[maximum-scale]`", - "example": "[maximum-scale]" - } - } - }, - "lighthouse-core/audits/accessibility/meta-viewport.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ îś n̂ót̂ úŝéd̂ ín̂ t́ĥé $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ án̂d́ t̂h́ê $MARKDOWN_SNIPPET_2$ át̂t́r̂íb̂út̂é îś n̂ót̂ ĺêśŝ t́ĥán̂ 5.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[user-scalable=\"no\"]`", - "example": "[user-scalable=\"no\"]" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<meta name=\"viewport\">`", - "example": "<meta name=\"viewport\">" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[maximum-scale]`", - "example": "[maximum-scale]" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ ćâńn̂ót̂ t́r̂án̂śl̂át̂é n̂ón̂-t́êx́t̂ ćôńt̂én̂t́. Âd́d̂ín̂ǵ âĺt̂ t́êx́t̂ t́ô $MARKDOWN_SNIPPET_0$ él̂ém̂én̂t́ŝ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕŝ ćôńv̂éŷ ḿêán̂ín̂ǵ t̂ó ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/object-alt?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ h́âv́ê $MARKDOWN_SNIPPET_1$ t́êx́t̂", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/object-alt.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĥáv̂é $MARKDOWN_SNIPPET_1$ t̂éx̂t́", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<object>`", - "example": "<object>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[alt]`", - "example": "[alt]" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | description": { - "message": " v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0 ím̂ṕl̂íêś âń êx́p̂ĺîćît́ n̂áv̂íĝát̂íôń ôŕd̂ér̂ín̂ǵ. Âĺt̂h́ôúĝh́ t̂éĉh́n̂íĉál̂ĺŷ v́âĺîd́, t̂h́îś ôf́t̂én̂ ćr̂éât́êś f̂ŕûśt̂ŕât́îńĝ éx̂ṕêŕîén̂ćêś f̂ór̂ úŝér̂ś ŵh́ô ŕêĺŷ ón̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/tabindex?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | failureTitle": { - "message": "Ŝóm̂é êĺêḿêńt̂ś ĥáv̂é â $MARKDOWN_SNIPPET_0$ v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[tabindex]`", - "example": "[tabindex]" - } - } - }, - "lighthouse-core/audits/accessibility/tabindex.js | title": { - "message": "N̂ó êĺêḿêńt̂ h́âś â $MARKDOWN_SNIPPET_0$ v́âĺûé ĝŕêát̂ér̂ t́ĥán̂ 0", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[tabindex]`", - "example": "[tabindex]" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ $MARKDOWN_SNIPPET_0$ ćêĺl̂ś ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_1$ ât́t̂ŕîb́ût́ê ón̂ĺŷ ŕêf́êŕ t̂ó ôt́ĥér̂ ćêĺl̂ś îń t̂h́ê śâḿê t́âb́l̂é m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<td>`", - "example": "<td>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | failureTitle": { - "message": "Ĉél̂ĺŝ ín̂ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é r̂éf̂ér̂ś t̂ó ôt́ĥér̂ ćêĺl̂ś ôf́ t̂h́ât́ ŝám̂é t̂áb̂ĺê.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - } - } - }, - "lighthouse-core/audits/accessibility/td-headers-attr.js | title": { - "message": "Ĉél̂ĺŝ ín̂ á $MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ t́ĥát̂ úŝé t̂h́ê $MARKDOWN_SNIPPET_1$ át̂t́r̂íb̂út̂é ôńl̂ý r̂éf̂ér̂ t́ô ót̂h́êŕ ĉél̂ĺŝ óf̂ t́ĥát̂ śâḿê t́âb́l̂é.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<table>`", - "example": "<table>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[headers]`", - "example": "[headers]" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": { - "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́âb́l̂é ĥéâd́êŕŝ ál̂ẃâýŝ ŕêf́êŕ t̂ó ŝóm̂é ŝét̂ óf̂ ćêĺl̂ś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/th-has-data-cells?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ $MARKDOWN_SNIPPET_1$ d́ô ńôt́ ĥáv̂é d̂át̂á ĉél̂ĺŝ t́ĥéŷ d́êśĉŕîb́ê.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role=\"columnheader\"/\"rowheader\"]`", - "example": "[role=\"columnheader\"/\"rowheader\"]" - } - } - }, - "lighthouse-core/audits/accessibility/th-has-data-cells.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś âńd̂ él̂ém̂én̂t́ŝ ẃît́ĥ $MARKDOWN_SNIPPET_1$ h́âv́ê d́ât́â ćêĺl̂ś t̂h́êý d̂éŝćr̂íb̂é.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<th>`", - "example": "<th>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`[role=\"columnheader\"/\"rowheader\"]`", - "example": "[role=\"columnheader\"/\"rowheader\"]" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â v́âĺîd́ $LINK_START_0$B̂ĆP̂ 47 ĺâńĝúâǵê$LINK_END_0$ ón̂ él̂ém̂én̂t́ŝ h́êĺp̂ś êńŝúr̂é t̂h́ât́ t̂éx̂t́ îś p̂ŕôńôún̂ćêd́ ĉór̂ŕêćt̂ĺŷ b́ŷ á ŝćr̂éêń r̂éâd́êŕ. $LINK_START_1$L̂éâŕn̂ ḿôŕê$LINK_END_1$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.w3.org/International/questions/qa-choosing-language-tags#question)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/valid-lang?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś d̂ó n̂ót̂ h́âv́ê á v̂ál̂íd̂ v́âĺûé", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/valid-lang.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́êś ĥáv̂é â v́âĺîd́ v̂ál̂úê", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`[lang]`", - "example": "[lang]" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | description": { - "message": "Ŵh́êń â v́îd́êó p̂ŕôv́îd́êś â ćâṕt̂íôń ît́ îś êáŝíêŕ f̂ór̂ d́êáf̂ án̂d́ ĥéâŕîńĝ ím̂ṕâír̂éd̂ úŝér̂ś t̂ó âćĉéŝś ît́ŝ ín̂f́ôŕm̂át̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/video-caption?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-caption.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"captions\"]`", - "example": "[kind=\"captions\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | description": { - "message": "Âúd̂íô d́êśĉŕîṕt̂íôńŝ ṕr̂óv̂íd̂é r̂él̂év̂án̂t́ îńf̂ór̂ḿât́îón̂ f́ôŕ v̂íd̂éôś t̂h́ât́ d̂íâĺôǵûé ĉán̂ńôt́, ŝúĉh́ âś f̂áĉíâĺ êx́p̂ŕêśŝíôńŝ án̂d́ ŝćêńêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://dequeuniversity.com/rules/axe/3.1/video-description?application=lighthouse)" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | failureTitle": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś d̂ó n̂ót̂ ćôńt̂áîń â $MARKDOWN_SNIPPET_1$ él̂ém̂én̂t́ ŵít̂h́ $MARKDOWN_SNIPPET_2$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"description\"]`", - "example": "[kind=\"description\"]" - } - } - }, - "lighthouse-core/audits/accessibility/video-description.js | title": { - "message": "$MARKDOWN_SNIPPET_0$ êĺêḿêńt̂ś ĉón̂t́âín̂ á $MARKDOWN_SNIPPET_1$ êĺêḿêńt̂ ẃît́ĥ $MARKDOWN_SNIPPET_2$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`<video>`", - "example": "<video>" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`<track>`", - "example": "<track>" - }, - "MARKDOWN_SNIPPET_2": { - "content": "`[kind=\"description\"]`", - "example": "[kind=\"description\"]" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | description": { - "message": "F̂ór̂ íd̂éâĺ âṕp̂éâŕâńĉé ôń îÓŜ ẃĥén̂ úŝér̂ś âd́d̂ t́ô t́ĥé ĥóm̂é ŝćr̂éêń, d̂éf̂ín̂é âń âṕp̂ĺê-t́ôúĉh́-îćôń. Ît́ m̂úŝt́ p̂óîńt̂ t́ô á n̂ón̂-t́r̂án̂śp̂ár̂én̂t́ 192p̂x́ (ôŕ 180p̂x́) ŝq́ûár̂é P̂ŃĜ. $LINK_START_0$Ĺêár̂ń M̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | failureTitle": { - "message": "D̂óêś n̂ót̂ ṕr̂óv̂íd̂é â v́âĺîd́ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | precomposedWarning": { - "message": "$MARKDOWN_SNIPPET_0$ îś ôút̂ óf̂ d́ât́ê; $MARKDOWN_SNIPPET_1$ íŝ ṕr̂éf̂ér̂ŕêd́.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon-precomposed`", - "example": "apple-touch-icon-precomposed" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/apple-touch-icon.js | title": { - "message": "P̂ŕôv́îd́êś â v́âĺîd́ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`apple-touch-icon`", - "example": "apple-touch-icon" - } - } - }, - "lighthouse-core/audits/bootup-time.js | chromeExtensionsWarning": { - "message": "Ĉh́r̂óm̂é êx́t̂én̂śîón̂ś n̂éĝát̂ív̂él̂ý âf́f̂éĉt́êd́ t̂h́îś p̂áĝé'ŝ ĺôád̂ ṕêŕf̂ór̂ḿâńĉé. T̂ŕŷ áûd́ît́îńĝ t́ĥé p̂áĝé îń îńĉóĝńît́ô ḿôd́ê ór̂ f́r̂óm̂ á Ĉh́r̂óm̂é p̂ŕôf́îĺê ẃît́ĥóût́ êx́t̂én̂śîón̂ś." - }, - "lighthouse-core/audits/bootup-time.js | columnScriptEval": { - "message": "Ŝćr̂íp̂t́ Êv́âĺûát̂íôń" - }, - "lighthouse-core/audits/bootup-time.js | columnScriptParse": { - "message": "Ŝćr̂íp̂t́ P̂ár̂śê" - }, - "lighthouse-core/audits/bootup-time.js | columnTotal": { - "message": "T̂ót̂ál̂ ĆP̂Ú T̂ím̂é" - }, - "lighthouse-core/audits/bootup-time.js | description": { - "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ, âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/bootup)" - } - } - }, - "lighthouse-core/audits/bootup-time.js | failureTitle": { - "message": "R̂éd̂úĉé Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" - }, - "lighthouse-core/audits/bootup-time.js | title": { - "message": "Ĵáv̂áŜćr̂íp̂t́ êx́êćût́îón̂ t́îḿê" - }, - "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | description": { - "message": "L̂ár̂ǵê ǴÎF́ŝ ár̂é îńêf́f̂íĉíêńt̂ f́ôŕ d̂él̂ív̂ér̂ín̂ǵ âńîḿât́êd́ ĉón̂t́êńt̂. Ćôńŝíd̂ér̂ úŝín̂ǵ M̂ṔÊǴ4/Ŵéb̂Ḿ v̂íd̂éôś f̂ór̂ án̂ím̂át̂íôńŝ án̂d́ P̂ŃĜ/Ẃêb́P̂ f́ôŕ ŝt́ât́îć îḿâǵêś îńŝt́êád̂ óf̂ ǴÎF́ t̂ó ŝáv̂é n̂ét̂ẃôŕk̂ b́ŷt́êś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/efficient-animated-content.js | title": { - "message": "Ûśê v́îd́êó f̂ór̂ḿât́ŝ f́ôŕ âńîḿât́êd́ ĉón̂t́êńt̂" - }, - "lighthouse-core/audits/byte-efficiency/offscreen-images.js | description": { - "message": "Ĉón̂śîd́êŕ l̂áẑý-l̂óâd́îńĝ óf̂f́ŝćr̂éêń âńd̂ h́îd́d̂én̂ ím̂áĝéŝ áf̂t́êŕ âĺl̂ ćr̂ít̂íĉál̂ ŕêśôúr̂ćêś ĥáv̂é f̂ín̂íŝh́êd́ l̂óâd́îńĝ t́ô ĺôẃêŕ t̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/offscreen-images.js | title": { - "message": "D̂éf̂ér̂ óf̂f́ŝćr̂éêń îḿâǵêś" - }, - "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": { - "message": "R̂éŝóûŕĉéŝ ár̂é b̂ĺôćk̂ín̂ǵ t̂h́ê f́îŕŝt́ p̂áîńt̂ óf̂ ýôúr̂ ṕâǵê. Ćôńŝíd̂ér̂ d́êĺîv́êŕîńĝ ćr̂ít̂íĉál̂ J́Ŝ/ĆŜŚ îńl̂ín̂é âńd̂ d́êf́êŕr̂ín̂ǵ âĺl̂ ńôń-ĉŕît́îćâĺ ĴŚ/ŝt́ŷĺêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": { - "message": "Êĺîḿîńât́ê ŕêńd̂ér̂-b́l̂óĉḱîńĝ ŕêśôúr̂ćêś" - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | description": { - "message": "L̂ár̂ǵê ńêt́ŵór̂ḱ p̂áŷĺôád̂ś ĉóŝt́ ûśêŕŝ ŕêál̂ ḿôńêý âńd̂ ár̂é ĥíĝh́l̂ý ĉór̂ŕêĺât́êd́ ŵít̂h́ l̂ón̂ǵ l̂óâd́ t̂ím̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/network-payloads)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | displayValue": { - "message": "T̂ót̂ál̂ śîźê ẃâś $COMPLEX_ICU_0$ K̂B́", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{totalBytes, number, bytes}", - "example": "499" - } - } - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | failureTitle": { - "message": "Âv́ôíd̂ én̂ór̂ḿôúŝ ńêt́ŵór̂ḱ p̂áŷĺôád̂ś" - }, - "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | title": { - "message": "Âv́ôíd̂ś êńôŕm̂óûś n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ŝ" - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | description": { - "message": "M̂ín̂íf̂ýîńĝ ĆŜŚ f̂íl̂éŝ ćâń r̂éd̂úĉé n̂ét̂ẃôŕk̂ ṕâýl̂óâd́ ŝíẑéŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/minify-css)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-css.js | title": { - "message": "M̂ín̂íf̂ý ĈŚŜ" - }, - "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | description": { - "message": "M̂ín̂íf̂ýîńĝ J́âv́âŚĉŕîṕt̂ f́îĺêś ĉán̂ ŕêd́ûćê ṕâýl̂óâd́ ŝíẑéŝ án̂d́ ŝćr̂íp̂t́ p̂ár̂śê t́îḿê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/speed/docs/insights/MinifyResources)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unminified-javascript.js | title": { - "message": "M̂ín̂íf̂ý Ĵáv̂áŜćr̂íp̂t́" - }, - "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | description": { - "message": "R̂ém̂óv̂é d̂éâd́ r̂úl̂éŝ f́r̂óm̂ śt̂ýl̂éŝh́êét̂ś âńd̂ d́êf́êŕ t̂h́ê ĺôád̂ín̂ǵ ôf́ ĈŚŜ ńôt́ ûśêd́ f̂ór̂ áb̂óv̂é-t̂h́ê-f́ôĺd̂ ćôńt̂én̂t́ t̂ó r̂éd̂úĉé ûńn̂éĉéŝśâŕŷ b́ŷt́êś ĉón̂śûḿêd́ b̂ý n̂ét̂ẃôŕk̂ áĉt́îv́ît́ŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/unused-css)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/unused-css-rules.js | title": { - "message": "R̂ém̂óv̂é ûńûśêd́ ĈŚŜ" - }, - "lighthouse-core/audits/byte-efficiency/unused-javascript.js | description": { - "message": "R̂ém̂óv̂é ûńûśêd́ Ĵáv̂áŜćr̂íp̂t́ t̂ó r̂éd̂úĉé b̂ýt̂éŝ ćôńŝúm̂éd̂ b́ŷ ńêt́ŵór̂ḱ âćt̂ív̂ít̂ý." - }, - "lighthouse-core/audits/byte-efficiency/unused-javascript.js | title": { - "message": "R̂ém̂óv̂é ûńûśêd́ Ĵáv̂áŜćr̂íp̂t́" - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | description": { - "message": " ĺôńĝ ćâćĥé l̂íf̂ét̂ím̂é ĉán̂ śp̂éêd́ ûṕ r̂ép̂éât́ v̂íŝít̂ś t̂ó ŷóûŕ p̂áĝé. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/cache-policy)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 r̂éŝóûŕĉé f̂óûńd̂}\n other {# ŕêśôúr̂ćêś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | failureTitle": { - "message": "Ŝér̂v́ê śt̂át̂íĉ áŝśêt́ŝ ẃît́ĥ án̂ éf̂f́îćîén̂t́ ĉáĉh́ê ṕôĺîćŷ" - }, - "lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js | title": { - "message": "Ûśêś êf́f̂íĉíêńt̂ ćâćĥé p̂ól̂íĉý ôń ŝt́ât́îć âśŝét̂ś" - }, - "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | description": { - "message": "Ôṕt̂ím̂íẑéd̂ ím̂áĝéŝ ĺôád̂ f́âśt̂ér̂ án̂d́ ĉón̂śûḿê ĺêśŝ ćêĺl̂úl̂ár̂ d́ât́â. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-optimized-images.js | title": { - "message": "Êf́f̂íĉíêńt̂ĺŷ én̂ćôd́ê ím̂áĝéŝ" - }, - "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | description": { - "message": "Ŝér̂v́ê ím̂áĝéŝ t́ĥát̂ ár̂é âṕp̂ŕôṕr̂íât́êĺŷ-śîźêd́ t̂ó ŝáv̂é ĉél̂ĺûĺâŕ d̂át̂á âńd̂ ím̂ṕr̂óv̂é l̂óâd́ t̂ím̂é. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/oversized-images)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-responsive-images.js | title": { - "message": "P̂ŕôṕêŕl̂ý ŝíẑé îḿâǵêś" - }, - "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | description": { - "message": "T̂éx̂t́-b̂áŝéd̂ ŕêśôúr̂ćêś ŝh́ôúl̂d́ b̂é ŝér̂v́êd́ ŵít̂h́ ĉóm̂ṕr̂éŝśîón̂ (ǵẑíp̂, d́êf́l̂át̂é ôŕ b̂ŕôt́l̂í) t̂ó m̂ín̂ím̂íẑé t̂ót̂ál̂ ńêt́ŵór̂ḱ b̂ýt̂éŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/text-compression)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-text-compression.js | title": { - "message": "Êńâb́l̂é t̂éx̂t́ ĉóm̂ṕr̂éŝśîón̂" - }, - "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | description": { - "message": "Îḿâǵê f́ôŕm̂át̂ś l̂ík̂é ĴṔÊǴ 2000, ĴṔÊǴ X̂Ŕ, âńd̂ Ẃêb́P̂ óf̂t́êń p̂ŕôv́îd́ê b́êt́t̂ér̂ ćôḿp̂ŕêśŝíôń t̂h́âń P̂ŃĜ ór̂ J́P̂ÉĜ, ẃĥíĉh́ m̂éâńŝ f́âśt̂ér̂ d́ôẃn̂ĺôád̂ś âńd̂ ĺêśŝ d́ât́â ćôńŝúm̂ṕt̂íôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/webp)" - } - } - }, - "lighthouse-core/audits/byte-efficiency/uses-webp-images.js | title": { - "message": "Ŝér̂v́ê ím̂áĝéŝ ín̂ ńêx́t̂-ǵêń f̂ór̂ḿât́ŝ" - }, - "lighthouse-core/audits/critical-request-chains.js | description": { - "message": "T̂h́ê Ćr̂ít̂íĉál̂ Ŕêq́ûéŝt́ Ĉh́âín̂ś b̂él̂óŵ śĥóŵ ýôú ŵh́ât́ r̂éŝóûŕĉéŝ ár̂é l̂óâd́êd́ ŵít̂h́ â h́îǵĥ ṕr̂íôŕît́ŷ. Ćôńŝíd̂ér̂ ŕêd́ûćîńĝ t́ĥé l̂én̂ǵt̂h́ ôf́ ĉh́âín̂ś, r̂éd̂úĉín̂ǵ t̂h́ê d́ôẃn̂ĺôád̂ śîźê óf̂ ŕêśôúr̂ćêś, ôŕ d̂éf̂ér̂ŕîńĝ t́ĥé d̂óŵńl̂óâd́ ôf́ ûńn̂éĉéŝśâŕŷ ŕêśôúr̂ćêś t̂ó îḿp̂ŕôv́ê ṕâǵê ĺôád̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)" - } - } - }, - "lighthouse-core/audits/critical-request-chains.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 ĉh́âín̂ f́ôún̂d́}\n other {# ĉh́âín̂ś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/critical-request-chains.js | title": { - "message": "M̂ín̂ím̂íẑé Ĉŕît́îćâĺ R̂éq̂úêśt̂ś D̂ép̂t́ĥ" - }, - "lighthouse-core/audits/deprecations.js | columnDeprecate": { - "message": "D̂ép̂ŕêćât́îón̂ / Ẃâŕn̂ín̂ǵ" - }, - "lighthouse-core/audits/deprecations.js | columnLine": { - "message": "L̂ín̂é" - }, - "lighthouse-core/audits/deprecations.js | description": { - "message": "D̂ép̂ŕêćât́êd́ ÂṔÎś ŵíl̂ĺ êv́êńt̂úâĺl̂ý b̂é r̂ém̂óv̂éd̂ f́r̂óm̂ t́ĥé b̂ŕôẃŝér̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://www.chromestatus.com/features#deprecated)" - } - } - }, - "lighthouse-core/audits/deprecations.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 ŵár̂ńîńĝ f́ôún̂d́}\n other {# ŵár̂ńîńĝś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/deprecations.js | failureTitle": { - "message": "Ûśêś d̂ép̂ŕêćât́êd́ ÂṔÎś" - }, - "lighthouse-core/audits/deprecations.js | title": { - "message": "Âv́ôíd̂ś d̂ép̂ŕêćât́êd́ ÂṔÎś" - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | description": { - "message": "Âṕp̂ĺîćât́îón̂ Ćâćĥé îś d̂ép̂ŕêćât́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/appcache)" - } - } - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | displayValue": { - "message": "F̂óûńd̂ \"$ICU_0$\"", - "placeholders": { - "ICU_0": { - "content": "{AppCacheManifest}", - "example": "AppCacheManifest" - } - } - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | failureTitle": { - "message": "Ûśêś Âṕp̂ĺîćât́îón̂ Ćâćĥé" - }, - "lighthouse-core/audits/dobetterweb/appcache-manifest.js | title": { - "message": "Âv́ôíd̂ś Âṕp̂ĺîćât́îón̂ Ćâćĥé" - }, - "lighthouse-core/audits/dobetterweb/doctype.js | description": { - "message": "Ŝṕêćîf́ŷín̂ǵ â d́ôćt̂ýp̂é p̂ŕêv́êńt̂ś t̂h́ê b́r̂óŵśêŕ f̂ŕôḿ ŝẃît́ĉh́îńĝ t́ô q́ûír̂ḱŝ-ḿôd́ê. Ŕêád̂ ḿôŕê ón̂ t́ĥé $LINK_START_0$M̂D́N̂ Ẃêb́ D̂óĉś p̂áĝé$LINK_END_0$", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)" - } - } - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationBadDoctype": { - "message": "D̂óĉt́ŷṕê ńâḿê ḿûśt̂ b́ê t́ĥé l̂óŵér̂ćâśê śt̂ŕîńĝ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`html`", - "example": "html" - } - } - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationNoDoctype": { - "message": "D̂óĉúm̂én̂t́ m̂úŝt́ ĉón̂t́âín̂ á d̂óĉt́ŷṕê" - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationPublicId": { - "message": "Êx́p̂éĉt́êd́ p̂úb̂ĺîćÎd́ t̂ó b̂é âń êḿp̂t́ŷ śt̂ŕîńĝ" - }, - "lighthouse-core/audits/dobetterweb/doctype.js | explanationSystemId": { - "message": "Êx́p̂éĉt́êd́ ŝýŝt́êḿÎd́ t̂ó b̂é âń êḿp̂t́ŷ śt̂ŕîńĝ" - }, - "lighthouse-core/audits/dobetterweb/doctype.js | failureTitle": { - "message": "P̂áĝé l̂áĉḱŝ t́ĥé ĤT́M̂Ĺ d̂óĉt́ŷṕê, t́ĥúŝ t́r̂íĝǵêŕîńĝ q́ûír̂ḱŝ-ḿôd́ê" - }, - "lighthouse-core/audits/dobetterweb/doctype.js | title": { - "message": "P̂áĝé ĥáŝ t́ĥé ĤT́M̂Ĺ d̂óĉt́ŷṕê" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnElement": { - "message": "Êĺêḿêńt̂" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnStatistic": { - "message": "Ŝt́ât́îśt̂íĉ" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | columnValue": { - "message": "V̂ál̂úê" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | description": { - "message": "B̂ŕôẃŝér̂ én̂ǵîńêér̂ś r̂éĉóm̂ḿêńd̂ ṕâǵêś ĉón̂t́âín̂ f́êẃêŕ t̂h́âń ~1,500 D̂ÓM̂ él̂ém̂én̂t́ŝ. T́ĥé ŝẃêét̂ śp̂ót̂ íŝ á t̂ŕêé d̂ép̂t́ĥ < 32 él̂ém̂én̂t́ŝ án̂d́ f̂éŵér̂ t́ĥán̂ 60 ćĥíl̂d́r̂én̂/ṕâŕêńt̂ él̂ém̂én̂t́.  ĺâŕĝé D̂ÓM̂ ćâń îńĉŕêáŝé m̂ém̂ór̂ý ûśâǵê, ćâúŝé l̂ón̂ǵêŕ $LINK_START_0$ŝt́ŷĺê ćâĺĉúl̂át̂íôńŝ$LINK_END_0$, án̂d́ p̂ŕôd́ûćê ćôśt̂ĺŷ $LINK_START_1$ĺâýôút̂ ŕêf́l̂óŵś$LINK_END_1$. $LINK_START_2$L̂éâŕn̂ ḿôŕê$LINK_END_2$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](https://developers.google.com/speed/articles/reflow)" - }, - "LINK_START_2": { - "content": "[" - }, - "LINK_END_2": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/dom-size)" - } - } - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 êĺêḿêńt̂}\n other {# él̂ém̂én̂t́ŝ}\n }" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | failureTitle": { - "message": "Âv́ôíd̂ án̂ éx̂ćêśŝív̂é D̂ÓM̂ śîźê" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMDepth": { - "message": "M̂áx̂ím̂úm̂ D́ÔḾ D̂ép̂t́ĥ" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMElements": { - "message": "T̂ót̂ál̂ D́ÔḾ Êĺêḿêńt̂ś" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | statisticDOMWidth": { - "message": "M̂áx̂ím̂úm̂ Ćĥíl̂d́ Êĺêḿêńt̂ś" - }, - "lighthouse-core/audits/dobetterweb/dom-size.js | title": { - "message": "Âv́ôíd̂ś âń êx́ĉéŝśîv́ê D́ÔḾ ŝíẑé" - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnRel": { - "message": "R̂él̂" - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | columnTarget": { - "message": "T̂ár̂ǵêt́" - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | description": { - "message": "Âd́d̂ $MARKDOWN_SNIPPET_0$ ór̂ $MARKDOWN_SNIPPET_1$ t́ô án̂ý êx́t̂ér̂ńâĺ l̂ín̂ḱŝ t́ô ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê án̂d́ p̂ŕêv́êńt̂ śêćûŕît́ŷ v́ûĺn̂ér̂áb̂íl̂ít̂íêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=\"noopener\"`", - "example": "rel=\"noopener\"" - }, - "MARKDOWN_SNIPPET_1": { - "content": "`rel=\"noreferrer\"`", - "example": "rel=\"noreferrer\"" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/noopener)" - } - } - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | failureTitle": { - "message": "L̂ín̂ḱŝ t́ô ćr̂óŝś-ôŕîǵîń d̂éŝt́îńât́îón̂ś âŕê ún̂śâf́ê" - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | title": { - "message": "L̂ín̂ḱŝ t́ô ćr̂óŝś-ôŕîǵîń d̂éŝt́îńât́îón̂ś âŕê śâf́ê" - }, - "lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js | warning": { - "message": "Ûńâb́l̂é t̂ó d̂ét̂ér̂ḿîńê t́ĥé d̂éŝt́îńât́îón̂ f́ôŕ âńĉh́ôŕ ($ICU_0$). Îf́ n̂ót̂ úŝéd̂ áŝ á ĥýp̂ér̂ĺîńk̂, ćôńŝíd̂ér̂ ŕêḿôv́îńĝ t́âŕĝét̂=_b́l̂án̂ḱ.", - "placeholders": { - "ICU_0": { - "content": "{anchorHTML}", - "example": "<a>" - } - } - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ĥéîŕ l̂óĉát̂íôń ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô á ûśêŕ âćt̂íôń îńŝt́êád̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load)" - } - } - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | failureTitle": { - "message": "R̂éq̂úêśt̂ś t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" - }, - "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { - "message": "Âv́ôíd̂ś r̂éq̂úêśt̂ín̂ǵ t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnName": { - "message": "N̂ám̂é" - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { - "message": "V̂ér̂śîón̂" - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | description": { - "message": "Âĺl̂ f́r̂ón̂t́-êńd̂ J́âv́âŚĉŕîṕt̂ ĺîb́r̂ár̂íêś d̂ét̂éĉt́êd́ ôń t̂h́ê ṕâǵê." - }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | title": { - "message": "D̂ét̂éĉt́êd́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ" - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | description": { - "message": "F̂ór̂ úŝér̂ś ôń ŝĺôẃ ĉón̂ńêćt̂íôńŝ, éx̂t́êŕn̂ál̂ śĉŕîṕt̂ś d̂ýn̂ám̂íĉál̂ĺŷ ín̂j́êćt̂éd̂ v́îá $MARKDOWN_SNIPPET_0$ ĉán̂ d́êĺâý p̂áĝé l̂óâd́ b̂ý t̂én̂ś ôf́ ŝéĉón̂d́ŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/document-write)" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": { - "message": "Ûśêś $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-document-write.js | title": { - "message": "Âv́ôíd̂ś $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`document.write()`", - "example": "document.write()" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnSeverity": { - "message": "Ĥíĝh́êśt̂ Śêv́êŕît́ŷ" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnVersion": { - "message": "L̂íb̂ŕâŕŷ V́êŕŝíôń" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | columnVuln": { - "message": "V̂úl̂ńêŕâb́îĺît́ŷ Ćôún̂t́" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | description": { - "message": "Ŝóm̂é t̂h́îŕd̂-ṕâŕt̂ý ŝćr̂íp̂t́ŝ ḿâý ĉón̂t́âín̂ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ t́ĥát̂ ár̂é êáŝíl̂ý îd́êńt̂íf̂íêd́ âńd̂ éx̂ṕl̂óît́êd́ b̂ý ât́t̂áĉḱêŕŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/vulnerabilities)" - } - } - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 v̂úl̂ńêŕâb́îĺît́ŷ d́êt́êćt̂éd̂}\n other {# v́ûĺn̂ér̂áb̂íl̂ít̂íêś d̂ét̂éĉt́êd́}\n }" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | failureTitle": { - "message": "Îńĉĺûd́êś f̂ŕôńt̂-én̂d́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ ẃît́ĥ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityHigh": { - "message": "Ĥíĝh́" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityLow": { - "message": "L̂óŵ" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | rowSeverityMedium": { - "message": "M̂éd̂íûḿ" - }, - "lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js | title": { - "message": "Âv́ôíd̂ś f̂ŕôńt̂-én̂d́ Ĵáv̂áŜćr̂íp̂t́ l̂íb̂ŕâŕîéŝ ẃît́ĥ ḱn̂óŵń ŝéĉúr̂ít̂ý v̂úl̂ńêŕâb́îĺît́îéŝ" - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | description": { - "message": "Ûśêŕŝ ár̂é m̂íŝt́r̂úŝt́f̂úl̂ óf̂ ór̂ ćôńf̂úŝéd̂ b́ŷ śît́êś t̂h́ât́ r̂éq̂úêśt̂ t́ô śêńd̂ ńôt́îf́îćât́îón̂ś ŵít̂h́ôút̂ ćôńt̂éx̂t́. Ĉón̂śîd́êŕ t̂ýîńĝ t́ĥé r̂éq̂úêśt̂ t́ô úŝér̂ ǵêśt̂úr̂éŝ ín̂śt̂éâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load)" - } - } - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | failureTitle": { - "message": "R̂éq̂úêśt̂ś t̂h́ê ńôt́îf́îćât́îón̂ ṕêŕm̂íŝśîón̂ ón̂ ṕâǵê ĺôád̂" - }, - "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { - "message": "Âv́ôíd̂ś r̂éq̂úêśt̂ín̂ǵ t̂h́ê ńôt́îf́îćât́îón̂ ṕêŕm̂íŝśîón̂ ón̂ ṕâǵê ĺôád̂" - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { - "message": "P̂ŕêv́êńt̂ín̂ǵ p̂áŝśŵór̂d́ p̂áŝt́îńĝ ún̂d́êŕm̂ín̂éŝ ǵôód̂ śêćûŕît́ŷ ṕôĺîćŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/password-pasting)" - } - } - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | failureTitle": { - "message": "P̂ŕêv́êńt̂ś ûśêŕŝ t́ô ṕâśt̂é îńt̂ó p̂áŝśŵór̂d́ f̂íêĺd̂ś" - }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | title": { - "message": "Âĺl̂óŵś ûśêŕŝ t́ô ṕâśt̂é îńt̂ó p̂áŝśŵór̂d́ f̂íêĺd̂ś" - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | columnProtocol": { - "message": "P̂ŕôt́ôćôĺ" - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | description": { - "message": "ĤT́T̂Ṕ/2 ôf́f̂ér̂ś m̂án̂ý b̂én̂éf̂ít̂ś ôv́êŕ ĤT́T̂Ṕ/1.1, îńĉĺûd́îńĝ b́îńâŕŷ h́êád̂ér̂ś, m̂úl̂t́îṕl̂éx̂ín̂ǵ, âńd̂ śêŕv̂ér̂ ṕûśĥ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/http2)" - } - } - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 r̂éq̂úêśt̂ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n other {# ŕêq́ûéŝt́ŝ ńôt́ ŝér̂v́êd́ v̂íâ H́T̂T́P̂/2}\n }" - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | failureTitle": { - "message": "D̂óêś n̂ót̂ úŝé ĤT́T̂Ṕ/2 f̂ór̂ ál̂ĺ ôf́ ît́ŝ ŕêśôúr̂ćêś" - }, - "lighthouse-core/audits/dobetterweb/uses-http2.js | title": { - "message": "Ûśêś ĤT́T̂Ṕ/2 f̂ór̂ ít̂ś ôẃn̂ ŕêśôúr̂ćêś" - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | description": { - "message": "Ĉón̂śîd́êŕ m̂ár̂ḱîńĝ ýôúr̂ t́ôúĉh́ âńd̂ ẃĥéêĺ êv́êńt̂ ĺîśt̂én̂ér̂ś âś $MARKDOWN_SNIPPET_0$ t̂ó îḿp̂ŕôv́ê ýôúr̂ ṕâǵê'ś ŝćr̂ól̂ĺ p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`passive`", - "example": "passive" - }, - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners)" - } - } - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | failureTitle": { - "message": "D̂óêś n̂ót̂ úŝé p̂áŝśîv́ê ĺîśt̂én̂ér̂ś t̂ó îḿp̂ŕôv́ê śĉŕôĺl̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê" - }, - "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { - "message": "Ûśêś p̂áŝśîv́ê ĺîśt̂én̂ér̂ś t̂ó îḿp̂ŕôv́ê śĉŕôĺl̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê" - }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "D̂éŝćr̂íp̂t́îón̂" - }, - "lighthouse-core/audits/errors-in-console.js | description": { - "message": "Êŕr̂ór̂ś l̂óĝǵêd́ t̂ó t̂h́ê ćôńŝól̂é îńd̂íĉát̂é ûńr̂éŝól̂v́êd́ p̂ŕôb́l̂ém̂ś. T̂h́êý ĉán̂ ćôḿê f́r̂óm̂ ńêt́ŵór̂ḱ r̂éq̂úêśt̂ f́âíl̂úr̂éŝ án̂d́ ôt́ĥér̂ b́r̂óŵśêŕ ĉón̂ćêŕn̂ś." - }, - "lighthouse-core/audits/errors-in-console.js | failureTitle": { - "message": "B̂ŕôẃŝér̂ ér̂ŕôŕŝ ẃêŕê ĺôǵĝéd̂ t́ô t́ĥé ĉón̂śôĺê" - }, - "lighthouse-core/audits/errors-in-console.js | title": { - "message": "N̂ó b̂ŕôẃŝér̂ ér̂ŕôŕŝ ĺôǵĝéd̂ t́ô t́ĥé ĉón̂śôĺê" - }, - "lighthouse-core/audits/font-display.js | description": { - "message": "L̂év̂ér̂áĝé t̂h́ê f́ôńt̂-d́îśp̂ĺâý ĈŚŜ f́êát̂úr̂é t̂ó êńŝúr̂é t̂éx̂t́ îś ûśêŕ-v̂íŝíb̂ĺê ẃĥíl̂é ŵéb̂f́ôńt̂ś âŕê ĺôád̂ín̂ǵ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/updates/2016/02/font-display)" - } - } - }, - "lighthouse-core/audits/font-display.js | failureTitle": { - "message": "Êńŝúr̂é t̂éx̂t́ r̂ém̂áîńŝ v́îśîb́l̂é d̂úr̂ín̂ǵ ŵéb̂f́ôńt̂ ĺôád̂" - }, - "lighthouse-core/audits/font-display.js | title": { - "message": "Âĺl̂ t́êx́t̂ ŕêḿâín̂ś v̂íŝíb̂ĺê d́ûŕîńĝ ẃêb́f̂ón̂t́ l̂óâd́ŝ" - }, - "lighthouse-core/audits/font-display.js | undeclaredFontURLWarning": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô áût́ôḿât́îćâĺl̂ý ĉh́êćk̂ t́ĥé f̂ón̂t́-d̂íŝṕl̂áŷ v́âĺûé f̂ór̂ t́ĥé f̂ól̂ĺôẃîńĝ ÚR̂Ĺ: $ICU_0$.", - "placeholders": { - "ICU_0": { - "content": "{fontURL}", - "example": "https://font.cdn.com/" - } - } - }, - "lighthouse-core/audits/image-aspect-ratio.js | columnActual": { - "message": "Âśp̂éĉt́ R̂át̂íô (Áĉt́ûál̂)" - }, - "lighthouse-core/audits/image-aspect-ratio.js | columnDisplayed": { - "message": "Âśp̂éĉt́ R̂át̂íô (D́îśp̂ĺâýêd́)" - }, - "lighthouse-core/audits/image-aspect-ratio.js | description": { - "message": "Îḿâǵê d́îśp̂ĺâý d̂ím̂én̂śîón̂ś ŝh́ôúl̂d́ m̂át̂ćĥ ńât́ûŕâĺ âśp̂éĉt́ r̂át̂íô. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio)" - } - } - }, - "lighthouse-core/audits/image-aspect-ratio.js | failureTitle": { - "message": "D̂íŝṕl̂áŷś îḿâǵêś ŵít̂h́ îńĉór̂ŕêćt̂ áŝṕêćt̂ ŕât́îó" - }, - "lighthouse-core/audits/image-aspect-ratio.js | title": { - "message": "D̂íŝṕl̂áŷś îḿâǵêś ŵít̂h́ ĉór̂ŕêćt̂ áŝṕêćt̂ ŕât́îó" - }, - "lighthouse-core/audits/image-aspect-ratio.js | warningCompute": { - "message": "Îńv̂ál̂íd̂ ím̂áĝé ŝíẑín̂ǵ îńf̂ór̂ḿât́îón̂ $ICU_0$", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://image.cdn.com/" - } - } - }, - "lighthouse-core/audits/is-on-https.js | columnInsecureURL": { - "message": "Îńŝéĉúr̂é ÛŔL̂" - }, - "lighthouse-core/audits/is-on-https.js | description": { - "message": "Âĺl̂ śît́êś ŝh́ôúl̂d́ b̂é p̂ŕôt́êćt̂éd̂ ẃît́ĥ H́T̂T́P̂Ś, êv́êń ôńêś t̂h́ât́ d̂ón̂'t́ ĥán̂d́l̂é ŝén̂śît́îv́ê d́ât́â. H́T̂T́P̂Ś p̂ŕêv́êńt̂ś îńt̂ŕûd́êŕŝ f́r̂óm̂ t́âḿp̂ér̂ín̂ǵ ŵít̂h́ ôŕ p̂áŝśîv́êĺŷ ĺîśt̂én̂ín̂ǵ îń ôń t̂h́ê ćôḿm̂ún̂íĉát̂íôńŝ b́êt́ŵéêń ŷóûŕ âṕp̂ án̂d́ ŷóûŕ ûśêŕŝ, án̂d́ îś â ṕr̂ér̂éq̂úîśît́ê f́ôŕ ĤT́T̂Ṕ/2 âńd̂ ḿâńŷ ńêẃ ŵéb̂ ṕl̂át̂f́ôŕm̂ ÁP̂Íŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/https)" - } - } - }, - "lighthouse-core/audits/is-on-https.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 îńŝéĉúr̂é r̂éq̂úêśt̂ f́ôún̂d́}\n other {# îńŝéĉúr̂é r̂éq̂úêśt̂ś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/is-on-https.js | failureTitle": { - "message": "D̂óêś n̂ót̂ úŝé ĤT́T̂ṔŜ" - }, - "lighthouse-core/audits/is-on-https.js | title": { - "message": "Ûśêś ĤT́T̂ṔŜ" - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | description": { - "message": " f́âśt̂ ṕâǵê ĺôád̂ óv̂ér̂ á ĉél̂ĺûĺâŕ n̂ét̂ẃôŕk̂ én̂śûŕêś â ǵôód̂ ḿôb́îĺê úŝér̂ éx̂ṕêŕîén̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/fast-3g)" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueText": { - "message": "Îńt̂ér̂áĉt́îv́ê át̂ $COMPLEX_ICU_0$ ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | displayValueTextWithOverride": { - "message": "Îńt̂ér̂áĉt́îv́ê ón̂ śîḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂ át̂ $COMPLEX_ICU_0$ ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": { - "message": "P̂áĝé l̂óâd́ îś n̂ót̂ f́âśt̂ én̂óûǵĥ ón̂ ḿôb́îĺê ńêt́ŵór̂ḱŝ" - }, - "lighthouse-core/audits/load-fast-enough-for-pwa.js | title": { - "message": "P̂áĝé l̂óâd́ îś f̂áŝt́ êńôúĝh́ ôń m̂ób̂íl̂é n̂ét̂ẃôŕk̂ś" - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | columnCategory": { - "message": "Ĉát̂éĝór̂ý" - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | description": { - "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ t̂h́ê t́îḿê śp̂én̂t́ p̂ár̂śîńĝ, ćôḿp̂íl̂ín̂ǵ âńd̂ éx̂éĉút̂ín̂ǵ ĴŚ. Ŷóû ḿâý f̂ín̂d́ d̂él̂ív̂ér̂ín̂ǵ ŝḿâĺl̂ér̂ J́Ŝ ṕâýl̂óâd́ŝ h́êĺp̂ś ŵít̂h́ t̂h́îś." - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | failureTitle": { - "message": "M̂ín̂ím̂íẑé m̂áîń-t̂h́r̂éâd́ ŵór̂ḱ" - }, - "lighthouse-core/audits/mainthread-work-breakdown.js | title": { - "message": "M̂ín̂ím̂íẑéŝ ḿâín̂-t́ĥŕêád̂ ẃôŕk̂" - }, - "lighthouse-core/audits/metrics/estimated-input-latency.js | description": { - "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)" - } - } - }, - "lighthouse-core/audits/metrics/estimated-input-latency.js | title": { - "message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ" - }, - "lighthouse-core/audits/metrics/first-contentful-paint.js | description": { - "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́ m̂ár̂ḱŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ t́ĥé f̂ír̂śt̂ t́êx́t̂ ór̂ ím̂áĝé îś p̂áîńt̂éd̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)" - } - } - }, - "lighthouse-core/audits/metrics/first-contentful-paint.js | title": { - "message": "F̂ír̂śt̂ Ćôńt̂én̂t́f̂úl̂ Ṕâín̂t́" - }, - "lighthouse-core/audits/metrics/first-cpu-idle.js | description": { - "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é m̂ár̂ḱŝ t́ĥé f̂ír̂śt̂ t́îḿê át̂ ẃĥíĉh́ t̂h́ê ṕâǵê'ś m̂áîń t̂h́r̂éâd́ îś q̂úîét̂ én̂óûǵĥ t́ô h́âńd̂ĺê ín̂ṕût́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)" - } - } - }, - "lighthouse-core/audits/metrics/first-cpu-idle.js | title": { - "message": "F̂ír̂śt̂ ĆP̂Ú Îd́l̂é" - }, - "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": { - "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́ m̂éâśûŕêś ŵh́êń t̂h́ê ṕr̂ím̂ár̂ý ĉón̂t́êńt̂ óf̂ á p̂áĝé îś v̂íŝíb̂ĺê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)" - } - } - }, - "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": { - "message": "F̂ír̂śt̂ Ḿêán̂ín̂ǵf̂úl̂ Ṕâín̂t́" - }, - "lighthouse-core/audits/metrics/interactive.js | description": { - "message": "T̂ím̂é t̂ó îńt̂ér̂áĉt́îv́ê íŝ t́ĥé âḿôún̂t́ ôf́ t̂ím̂é ît́ t̂ák̂éŝ f́ôŕ t̂h́ê ṕâǵê t́ô b́êćôḿê f́ûĺl̂ý îńt̂ér̂áĉt́îv́ê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)" - } - } - }, - "lighthouse-core/audits/metrics/interactive.js | title": { - "message": "T̂ím̂é t̂ó Îńt̂ér̂áĉt́îv́ê" - }, - "lighthouse-core/audits/metrics/max-potential-fid.js | description": { - "message": "T̂h́ê ḿâx́îḿûḿ p̂ót̂én̂t́îál̂ F́îŕŝt́ Îńp̂út̂ D́êĺâý t̂h́ât́ ŷóûŕ ûśêŕŝ ćôúl̂d́ êx́p̂ér̂íêńĉé îś t̂h́ê d́ûŕât́îón̂, ín̂ ḿîĺl̂íŝéĉón̂d́ŝ, óf̂ t́ĥé l̂ón̂ǵêśt̂ t́âśk̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/updates/2018/05/first-input-delay)" - } - } - }, - "lighthouse-core/audits/metrics/max-potential-fid.js | title": { - "message": "M̂áx̂ Ṕôt́êńt̂íâĺ F̂ír̂śt̂ Ín̂ṕût́ D̂él̂áŷ" - }, - "lighthouse-core/audits/metrics/speed-index.js | description": { - "message": "Ŝṕêéd̂ Ín̂d́êx́ ŝh́ôẃŝ h́ôẃ q̂úîćk̂ĺŷ t́ĥé ĉón̂t́êńt̂ś ôf́ â ṕâǵê ár̂é v̂íŝíb̂ĺŷ ṕôṕûĺât́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/speed-index)" - } - } - }, - "lighthouse-core/audits/metrics/speed-index.js | title": { - "message": "Ŝṕêéd̂ Ín̂d́êx́" - }, - "lighthouse-core/audits/network-rtt.js | description": { - "message": "N̂ét̂ẃôŕk̂ ŕôún̂d́ t̂ŕîṕ t̂ím̂éŝ (ŔT̂T́) ĥáv̂é â ĺâŕĝé îḿp̂áĉt́ ôń p̂ér̂f́ôŕm̂án̂ćê. Íf̂ t́ĥé R̂T́T̂ t́ô án̂ ór̂íĝín̂ íŝ h́îǵĥ, ít̂'ś âń îńd̂íĉát̂íôń t̂h́ât́ ŝér̂v́êŕŝ ćl̂óŝér̂ t́ô t́ĥé ûśêŕ ĉóûĺd̂ ím̂ṕr̂óv̂é p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://hpbn.co/primer-on-latency-and-bandwidth/)" - } - } - }, - "lighthouse-core/audits/network-rtt.js | title": { - "message": "N̂ét̂ẃôŕk̂ Ŕôún̂d́ T̂ŕîṕ T̂ím̂éŝ" - }, - "lighthouse-core/audits/network-server-latency.js | description": { - "message": "Ŝér̂v́êŕ l̂át̂én̂ćîéŝ ćâń îḿp̂áĉt́ ŵéb̂ ṕêŕf̂ór̂ḿâńĉé. Îf́ t̂h́ê śêŕv̂ér̂ ĺât́êńĉý ôf́ âń ôŕîǵîń îś ĥíĝh́, ît́'ŝ án̂ ín̂d́îćât́îón̂ t́ĥé ŝér̂v́êŕ îś ôv́êŕl̂óâd́êd́ ôŕ ĥáŝ ṕôór̂ b́âćk̂én̂d́ p̂ér̂f́ôŕm̂án̂ćê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall)" - } - } - }, - "lighthouse-core/audits/network-server-latency.js | title": { - "message": "Ŝér̂v́êŕ B̂áĉḱêńd̂ Ĺât́êńĉíêś" - }, - "lighthouse-core/audits/performance-budget.js | columnOverBudget": { - "message": "Ôv́êŕ B̂úd̂ǵêt́" - }, - "lighthouse-core/audits/performance-budget.js | description": { - "message": "K̂éêṕ t̂h́ê q́ûán̂t́ît́ŷ án̂d́ ŝíẑé ôf́ n̂ét̂ẃôŕk̂ ŕêq́ûéŝt́ŝ ún̂d́êŕ t̂h́ê t́âŕĝét̂ś ŝét̂ b́ŷ t́ĥé p̂ŕôv́îd́êd́ p̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" - } - } - }, - "lighthouse-core/audits/performance-budget.js | requestCountOverBudget": { - "message": "{count, plural,\n =1 {1 r̂éq̂úêśt̂}\n other {# ŕêq́ûéŝt́ŝ}\n }" - }, - "lighthouse-core/audits/performance-budget.js | title": { - "message": "P̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂" - }, - "lighthouse-core/audits/redirects.js | description": { - "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/redirects)" - } - } - }, - "lighthouse-core/audits/redirects.js | title": { - "message": "Âv́ôíd̂ ḿûĺt̂íp̂ĺê ṕâǵê ŕêd́îŕêćt̂ś" - }, - "lighthouse-core/audits/resource-summary.js | description": { - "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/budgets)" - } - } - }, - "lighthouse-core/audits/resource-summary.js | displayValue": { - "message": "{requestCount, plural, =1 {1 r̂éq̂úêśt̂} other {# ŕêq́ûéŝt́ŝ}} • { byteCount, number, bytes } ḰB̂" - }, - "lighthouse-core/audits/resource-summary.js | title": { - "message": "K̂éêṕ r̂éq̂úêśt̂ ćôún̂t́ŝ ĺôẃ âńd̂ t́r̂án̂śf̂ér̂ śîźêś ŝḿâĺl̂" - }, - "lighthouse-core/audits/seo/canonical.js | description": { - "message": "Ĉán̂ón̂íĉál̂ ĺîńk̂ś ŝúĝǵêśt̂ ẃĥíĉh́ ÛŔL̂ t́ô śĥóŵ ín̂ śêár̂ćĥ ŕêśûĺt̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/canonical)" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationConflict": { - "message": "M̂úl̂t́îṕl̂é ĉón̂f́l̂íĉt́îńĝ ÚR̂Ĺŝ ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{urlList}", - "example": "https://example.com, https://example2.com" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain": { - "message": "P̂óîńt̂ś t̂ó â d́îf́f̂ér̂én̂t́ d̂óm̂áîń ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationInvalid": { - "message": "Îńv̂ál̂íd̂ ÚR̂Ĺ ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationPointsElsewhere": { - "message": "P̂óîńt̂ś t̂ó âńôt́ĥér̂ $MARKDOWN_SNIPPET_0$ ĺôćât́îón̂ ($ICU_0$)", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - }, - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationRelative": { - "message": "R̂él̂át̂ív̂é ÛŔL̂ ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{url}", - "example": "https://example.com/" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | explanationRoot": { - "message": "P̂óîńt̂ś t̂ó t̂h́ê d́ôḿâín̂'ś r̂óôt́ ÛŔL̂ (t́ĥé ĥóm̂ép̂áĝé), îńŝt́êád̂ óf̂ án̂ éq̂úîv́âĺêńt̂ ṕâǵê óf̂ ćôńt̂én̂t́" - }, - "lighthouse-core/audits/seo/canonical.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=canonical`", - "example": "rel=canonical" - } - } - }, - "lighthouse-core/audits/seo/canonical.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`rel=canonical`", - "example": "rel=canonical" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | description": { - "message": "F̂ón̂t́ ŝíẑéŝ ĺêśŝ t́ĥán̂ 12ṕx̂ ár̂é t̂óô śm̂ál̂ĺ t̂ó b̂é l̂éĝíb̂ĺê án̂d́ r̂éq̂úîŕê ḿôb́îĺê v́îśît́ôŕŝ t́ô “ṕîńĉh́ t̂ó ẑóôḿ” îń ôŕd̂ér̂ t́ô ŕêád̂. Śt̂ŕîv́ê t́ô h́âv́ê >60% óf̂ ṕâǵê t́êx́t̂ ≥12ṕx̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/font-sizes)" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | displayValue": { - "message": "$COMPLEX_ICU_0$ l̂éĝíb̂ĺê t́êx́t̂", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | explanation": { - "message": "$COMPLEX_ICU_0$ ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ.", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | explanationViewport": { - "message": "T̂éx̂t́ îś îĺl̂éĝíb̂ĺê b́êćâúŝé t̂h́êŕê'ś n̂ó v̂íêẃp̂ór̂t́ m̂ét̂á t̂áĝ óp̂t́îḿîźêd́ f̂ór̂ ḿôb́îĺê śĉŕêén̂ś." - }, - "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": { - "message": "$COMPLEX_ICU_0$ ôf́ t̂éx̂t́ îś t̂óô śm̂ál̂ĺ (b̂áŝéd̂ ón̂ $COMPLEX_ICU_1$ śâḿp̂ĺê).", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, extendedPercent}", - "example": "37.92%" - }, - "COMPLEX_ICU_1": { - "content": "{decimalProportionVisited, number, extendedPercent}", - "example": "37.92%" - } - } - }, - "lighthouse-core/audits/seo/font-size.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ûśê ĺêǵîb́l̂é f̂ón̂t́ ŝíẑéŝ" - }, - "lighthouse-core/audits/seo/font-size.js | title": { - "message": "D̂óĉúm̂én̂t́ ûśêś l̂éĝíb̂ĺê f́ôńt̂ śîźêś" - }, - "lighthouse-core/audits/seo/hreflang.js | description": { - "message": "ĥŕêf́l̂án̂ǵ l̂ín̂ḱŝ t́êĺl̂ śêár̂ćĥ én̂ǵîńêś ŵh́ât́ v̂ér̂śîón̂ óf̂ á p̂áĝé t̂h́êý ŝh́ôúl̂d́ l̂íŝt́ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ f́ôŕ â ǵîv́êń l̂án̂ǵûáĝé ôŕ r̂éĝíôń. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/hreflang)" - } - } - }, - "lighthouse-core/audits/seo/hreflang.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêśn̂'t́ ĥáv̂é â v́âĺîd́ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - } - } - }, - "lighthouse-core/audits/seo/hreflang.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á v̂ál̂íd̂ $MARKDOWN_SNIPPET_0$", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`hreflang`", - "example": "hreflang" - } - } - }, - "lighthouse-core/audits/seo/http-status-code.js | description": { - "message": "P̂áĝéŝ ẃît́ĥ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́êś m̂áŷ ńôt́ b̂é îńd̂éx̂éd̂ ṕr̂óp̂ér̂ĺŷ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/successful-http-code)" - } - } - }, - "lighthouse-core/audits/seo/http-status-code.js | failureTitle": { - "message": "P̂áĝé ĥáŝ ún̂śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" - }, - "lighthouse-core/audits/seo/http-status-code.js | title": { - "message": "P̂áĝé ĥáŝ śûćĉéŝśf̂úl̂ H́T̂T́P̂ śt̂át̂úŝ ćôd́ê" - }, - "lighthouse-core/audits/seo/is-crawlable.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ár̂é ûńâb́l̂é t̂ó îńĉĺûd́ê ýôúr̂ ṕâǵêś îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ íf̂ t́ĥéŷ d́ôń't̂ h́âv́ê ṕêŕm̂íŝśîón̂ t́ô ćr̂áŵĺ t̂h́êḿ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/indexing)" - } - } - }, - "lighthouse-core/audits/seo/is-crawlable.js | failureTitle": { - "message": "P̂áĝé îś b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" - }, - "lighthouse-core/audits/seo/is-crawlable.js | title": { - "message": "P̂áĝé îśn̂’t́ b̂ĺôćk̂éd̂ f́r̂óm̂ ín̂d́êx́îńĝ" - }, - "lighthouse-core/audits/seo/link-text.js | description": { - "message": "D̂éŝćr̂íp̂t́îv́ê ĺîńk̂ t́êx́t̂ h́êĺp̂ś ŝéâŕĉh́ êńĝín̂éŝ ún̂d́êŕŝt́âńd̂ ýôúr̂ ćôńt̂én̂t́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text)" - } - } - }, - "lighthouse-core/audits/seo/link-text.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 l̂ín̂ḱ f̂óûńd̂}\n other {# ĺîńk̂ś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/seo/link-text.js | failureTitle": { - "message": "L̂ín̂ḱŝ d́ô ńôt́ ĥáv̂é d̂éŝćr̂íp̂t́îv́ê t́êx́t̂" - }, - "lighthouse-core/audits/seo/link-text.js | title": { - "message": "L̂ín̂ḱŝ h́âv́ê d́êśĉŕîṕt̂ív̂é t̂éx̂t́" - }, - "lighthouse-core/audits/seo/manual/structured-data.js | description": { - "message": "R̂ún̂ t́ĥé $LINK_START_0$Ŝt́r̂úĉt́ûŕêd́ D̂át̂á T̂éŝt́îńĝ T́ôól̂$LINK_END_0$ án̂d́ t̂h́ê $LINK_START_1$Śt̂ŕûćt̂úr̂éd̂ D́ât́â Ĺîńt̂ér̂$LINK_END_1$ t́ô v́âĺîd́ât́ê śt̂ŕûćt̂úr̂éd̂ d́ât́â. $LINK_START_2$Ĺêár̂ń m̂ór̂é$LINK_END_2$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://search.google.com/structured-data/testing-tool/)" - }, - "LINK_START_1": { - "content": "[" - }, - "LINK_END_1": { - "content": "](http://linter.structured-data.org/)" - }, - "LINK_START_2": { - "content": "[" - }, - "LINK_END_2": { - "content": "](https://developers.google.com/search/docs/guides/mark-up-content)" - } - } - }, - "lighthouse-core/audits/seo/manual/structured-data.js | title": { - "message": "Ŝt́r̂úĉt́ûŕêd́ d̂át̂á îś v̂ál̂íd̂" - }, - "lighthouse-core/audits/seo/meta-description.js | description": { - "message": "M̂ét̂á d̂éŝćr̂íp̂t́îón̂ś m̂áŷ b́ê ín̂ćl̂úd̂éd̂ ín̂ śêár̂ćĥ ŕêśûĺt̂ś t̂ó ĉón̂ćîśêĺŷ śûḿm̂ár̂íẑé p̂áĝé ĉón̂t́êńt̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/description)" - } - } - }, - "lighthouse-core/audits/seo/meta-description.js | explanation": { - "message": "D̂éŝćr̂íp̂t́îón̂ t́êx́t̂ íŝ ém̂ṕt̂ý." - }, - "lighthouse-core/audits/seo/meta-description.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á m̂ét̂á d̂éŝćr̂íp̂t́îón̂" - }, - "lighthouse-core/audits/seo/meta-description.js | title": { - "message": "D̂óĉúm̂én̂t́ ĥáŝ á m̂ét̂á d̂éŝćr̂íp̂t́îón̂" - }, - "lighthouse-core/audits/seo/plugins.js | description": { - "message": "Ŝéâŕĉh́ êńĝín̂éŝ ćâń't̂ ín̂d́êx́ p̂ĺûǵîń ĉón̂t́êńt̂, án̂d́ m̂án̂ý d̂év̂íĉéŝ ŕêśt̂ŕîćt̂ ṕl̂úĝín̂ś ôŕ d̂ón̂'t́ ŝúp̂ṕôŕt̂ t́ĥém̂. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/plugins)" - } - } - }, - "lighthouse-core/audits/seo/plugins.js | failureTitle": { - "message": "D̂óĉúm̂én̂t́ ûśêś p̂ĺûǵîńŝ" - }, - "lighthouse-core/audits/seo/plugins.js | title": { - "message": "D̂óĉúm̂én̂t́ âv́ôíd̂ś p̂ĺûǵîńŝ" - }, - "lighthouse-core/audits/seo/robots-txt.js | description": { - "message": "Îf́ ŷóûŕ r̂ób̂ót̂ś.t̂x́t̂ f́îĺê íŝ ḿâĺf̂ór̂ḿêd́, ĉŕâẃl̂ér̂ś m̂áŷ ńôt́ b̂é âb́l̂é t̂ó ûńd̂ér̂śt̂án̂d́ ĥóŵ ýôú ŵán̂t́ ŷóûŕ ŵéb̂śît́ê t́ô b́ê ćr̂áŵĺêd́ ôŕ îńd̂éx̂éd̂." - }, - "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": { - "message": "r̂éq̂úêśt̂ f́ôŕ r̂ób̂ót̂ś.t̂x́t̂ ŕêt́ûŕn̂éd̂ H́T̂T́P̂ śt̂át̂úŝ: $ICU_0$", - "placeholders": { - "ICU_0": { - "content": "{statusCode}", - "example": "500" - } - } - }, - "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": { - "message": "{itemCount, plural,\n =1 {1 êŕr̂ór̂ f́ôún̂d́}\n other {# êŕr̂ór̂ś f̂óûńd̂}\n }" - }, - "lighthouse-core/audits/seo/robots-txt.js | explanation": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô d́ôẃn̂ĺôád̂ á r̂ób̂ót̂ś.t̂x́t̂ f́îĺê" - }, - "lighthouse-core/audits/seo/robots-txt.js | failureTitle": { - "message": "r̂ób̂ót̂ś.t̂x́t̂ íŝ ńôt́ v̂ál̂íd̂" - }, - "lighthouse-core/audits/seo/robots-txt.js | title": { - "message": "r̂ób̂ót̂ś.t̂x́t̂ íŝ v́âĺîd́" - }, - "lighthouse-core/audits/seo/tap-targets.js | description": { - "message": "Îńt̂ér̂áĉt́îv́ê él̂ém̂én̂t́ŝ ĺîḱê b́ût́t̂ón̂ś âńd̂ ĺîńk̂ś ŝh́ôúl̂d́ b̂é l̂ár̂ǵê én̂óûǵĥ (48x́48p̂x́), âńd̂ h́âv́ê én̂óûǵĥ śp̂áĉé âŕôún̂d́ t̂h́êḿ, t̂ó b̂é êáŝý êńôúĝh́ t̂ó t̂áp̂ ẃît́ĥóût́ ôv́êŕl̂áp̂ṕîńĝ ón̂t́ô ót̂h́êŕ êĺêḿêńt̂ś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design)" - } - } - }, - "lighthouse-core/audits/seo/tap-targets.js | displayValue": { - "message": "$COMPLEX_ICU_0$ âṕp̂ŕôṕr̂íât́êĺŷ śîźêd́ t̂áp̂ t́âŕĝét̂ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{decimalProportion, number, percent}", - "example": "54.6%" - } - } - }, - "lighthouse-core/audits/seo/tap-targets.js | explanationViewportMetaNotOptimized": { - "message": "T̂áp̂ t́âŕĝét̂ś âŕê t́ôó ŝḿâĺl̂ b́êćâúŝé t̂h́êŕê'ś n̂ó v̂íêẃp̂ór̂t́ m̂ét̂á t̂áĝ óp̂t́îḿîźêd́ f̂ór̂ ḿôb́îĺê śĉŕêén̂ś" - }, - "lighthouse-core/audits/seo/tap-targets.js | failureTitle": { - "message": "T̂áp̂ t́âŕĝét̂ś âŕê ńôt́ ŝíẑéd̂ áp̂ṕr̂óp̂ŕîát̂él̂ý" - }, - "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": { - "message": "Ôv́êŕl̂áp̂ṕîńĝ T́âŕĝét̂" - }, - "lighthouse-core/audits/seo/tap-targets.js | sizeHeader": { - "message": "Ŝíẑé" - }, - "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": { - "message": "T̂áp̂ T́âŕĝét̂" - }, - "lighthouse-core/audits/seo/tap-targets.js | title": { - "message": "T̂áp̂ t́âŕĝét̂ś âŕê śîźêd́ âṕp̂ŕôṕr̂íât́êĺŷ" - }, - "lighthouse-core/audits/third-party-summary.js | columnMainThreadTime": { - "message": "M̂áîń T̂h́r̂éâd́ T̂ím̂é" - }, - "lighthouse-core/audits/third-party-summary.js | columnThirdParty": { - "message": "T̂h́îŕd̂-Ṕâŕt̂ý" - }, - "lighthouse-core/audits/third-party-summary.js | description": { - "message": "T̂h́îŕd̂-ṕâŕt̂ý ĉód̂é ĉán̂ śîǵn̂íf̂íĉán̂t́l̂ý îḿp̂áĉt́ l̂óâd́ p̂ér̂f́ôŕm̂án̂ćê. Ĺîḿît́ t̂h́ê ńûḿb̂ér̂ óf̂ ŕêd́ûńd̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý p̂ŕôv́îd́êŕŝ án̂d́ t̂ŕŷ t́ô ĺôád̂ t́ĥír̂d́-p̂ár̂t́ŷ ćôd́ê áf̂t́êŕ ŷóûŕ p̂áĝé ĥáŝ ṕr̂ím̂ár̂íl̂ý f̂ín̂íŝh́êd́ l̂óâd́îńĝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)" - } - } - }, - "lighthouse-core/audits/third-party-summary.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 T̂h́îŕd̂-Ṕâŕt̂ý F̂óûńd̂}\n other {# T́ĥír̂d́-P̂ár̂t́îéŝ F́ôún̂d́}\n }" - }, - "lighthouse-core/audits/third-party-summary.js | title": { - "message": "T̂h́îŕd̂-Ṕâŕt̂ý Ûśâǵê" - }, - "lighthouse-core/audits/time-to-first-byte.js | description": { - "message": "T̂ím̂é T̂ó F̂ír̂śt̂ B́ŷt́ê íd̂én̂t́îf́îéŝ t́ĥé t̂ím̂é ât́ ŵh́îćĥ ýôúr̂ śêŕv̂ér̂ śêńd̂ś â ŕêśp̂ón̂śê. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/ttfb)" - } - } - }, - "lighthouse-core/audits/time-to-first-byte.js | displayValue": { - "message": "R̂óôt́ d̂óĉúm̂én̂t́ t̂óôḱ $COMPLEX_ICU_0$ m̂ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/audits/time-to-first-byte.js | failureTitle": { - "message": "R̂éd̂úĉé ŝér̂v́êŕ r̂éŝṕôńŝé t̂ím̂éŝ (T́T̂F́B̂)" - }, - "lighthouse-core/audits/time-to-first-byte.js | title": { - "message": "Ŝér̂v́êŕ r̂éŝṕôńŝé t̂ím̂éŝ ár̂é l̂óŵ (T́T̂F́B̂)" - }, - "lighthouse-core/audits/user-timings.js | columnDuration": { - "message": "D̂úr̂át̂íôń" - }, - "lighthouse-core/audits/user-timings.js | columnName": { - "message": "N̂ám̂é" - }, - "lighthouse-core/audits/user-timings.js | columnStartTime": { - "message": "Ŝt́âŕt̂ T́îḿê" - }, - "lighthouse-core/audits/user-timings.js | columnType": { - "message": "T̂ýp̂é" - }, - "lighthouse-core/audits/user-timings.js | description": { - "message": "Ĉón̂śîd́êŕ îńŝt́r̂úm̂én̂t́îńĝ ýôúr̂ áp̂ṕ ŵít̂h́ t̂h́ê Úŝér̂ T́îḿîńĝ ÁP̂Í t̂ó m̂éâśûŕê ýôúr̂ áp̂ṕ'ŝ ŕêál̂-ẃôŕl̂d́ p̂ér̂f́ôŕm̂án̂ćê d́ûŕîńĝ ḱêý ûśêŕ êx́p̂ér̂íêńĉéŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/user-timing)" - } - } - }, - "lighthouse-core/audits/user-timings.js | displayValue": { - "message": "{itemCount, plural,\n =1 {1 ûśêŕ t̂ím̂ín̂ǵ}\n other {# ûśêŕ t̂ím̂ín̂ǵŝ}\n }" - }, - "lighthouse-core/audits/user-timings.js | title": { - "message": "Ûśêŕ T̂ím̂ín̂ǵ m̂ár̂ḱŝ án̂d́ m̂éâśûŕêś" - }, - "lighthouse-core/audits/uses-rel-preconnect.js | crossoriginWarning": { - "message": " ṕr̂éĉón̂ńêćt̂ <ĺîńk̂> ẃâś f̂óûńd̂ f́ôŕ \"$ICU_0$\" b̂út̂ ẃâś n̂ót̂ úŝéd̂ b́ŷ t́ĥé b̂ŕôẃŝér̂. Ćĥéĉḱ t̂h́ât́ ŷóû ár̂é ûśîńĝ t́ĥé $MARKDOWN_SNIPPET_0$ ât́t̂ŕîb́ût́ê ṕr̂óp̂ér̂ĺŷ.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`crossorigin`", - "example": "crossorigin" - }, - "ICU_0": { - "content": "{securityOrigin}", - "example": "<link rel=\"preconnect\" href=\"...\">" - } - } - }, - "lighthouse-core/audits/uses-rel-preconnect.js | description": { - "message": "Ĉón̂śîd́êŕ âd́d̂ín̂ǵ p̂ŕêćôńn̂éĉt́ ôŕ d̂ńŝ-ṕr̂éf̂ét̂ćĥ ŕêśôúr̂ćê h́îńt̂ś t̂ó êśt̂áb̂ĺîśĥ éâŕl̂ý ĉón̂ńêćt̂íôńŝ t́ô ím̂ṕôŕt̂án̂t́ t̂h́îŕd̂-ṕâŕt̂ý ôŕîǵîńŝ. $LINK_START_0$Ĺêár̂ń m̂ór̂é$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)" - } - } - }, - "lighthouse-core/audits/uses-rel-preconnect.js | title": { - "message": "P̂ŕêćôńn̂éĉt́ t̂ó r̂éq̂úîŕêd́ ôŕîǵîńŝ" - }, - "lighthouse-core/audits/uses-rel-preload.js | crossoriginWarning": { - "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"$ICU_0$\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê $MARKDOWN_SNIPPET_0$ át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý.", - "placeholders": { - "MARKDOWN_SNIPPET_0": { - "content": "`crossorigin`", - "example": "crossorigin" - }, - "ICU_0": { - "content": "{preloadURL}", - "example": "<link rel=\"preload\" href=\"...\">" - } - } - }, - "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/audits/preload)" - } - } - }, - "lighthouse-core/audits/uses-rel-preload.js | title": { - "message": "P̂ŕêĺôád̂ ḱêý r̂éq̂úêśt̂ś" - }, - "lighthouse-core/config/default-config.js | a11yAriaGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ím̂ṕr̂óv̂é t̂h́ê úŝáĝé ôf́ ÂŔÎÁ îń ŷóûŕ âṕp̂ĺîćât́îón̂ ẃĥíĉh́ m̂áŷ én̂h́âńĉé t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ûśêŕŝ óf̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝý, l̂ík̂é â śĉŕêén̂ ŕêád̂ér̂." - }, - "lighthouse-core/config/default-config.js | a11yAriaGroupTitle": { - "message": "ÂŔÎÁ" - }, - "lighthouse-core/config/default-config.js | a11yAudioVideoGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ṕr̂óv̂íd̂é âĺt̂ér̂ńât́îv́ê ćôńt̂én̂t́ f̂ór̂ áûd́îó âńd̂ v́îd́êó. T̂h́îś m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ûśêŕŝ ẃît́ĥ h́êár̂ín̂ǵ ôŕ v̂íŝíôń îḿp̂áîŕm̂én̂t́ŝ." - }, - "lighthouse-core/config/default-config.js | a11yAudioVideoGroupTitle": { - "message": "Âúd̂íô án̂d́ v̂íd̂éô" - }, - "lighthouse-core/config/default-config.js | a11yBestPracticesGroupDescription": { - "message": "T̂h́êśê ít̂ém̂ś ĥíĝh́l̂íĝh́t̂ ćôḿm̂ón̂ áĉćêśŝíb̂íl̂ít̂ý b̂éŝt́ p̂ŕâćt̂íĉéŝ." - }, - "lighthouse-core/config/default-config.js | a11yBestPracticesGroupTitle": { - "message": "B̂éŝt́ p̂ŕâćt̂íĉéŝ" - }, - "lighthouse-core/config/default-config.js | a11yCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ h́îǵĥĺîǵĥt́ ôṕp̂ór̂t́ûńît́îéŝ t́ô $LINK_START_0$ím̂ṕr̂óv̂é t̂h́ê áĉćêśŝíb̂íl̂ít̂ý ôf́ ŷóûŕ ŵéb̂ áp̂ṕ$LINK_END_0$. Ôńl̂ý â śûb́ŝét̂ óf̂ áĉćêśŝíb̂íl̂ít̂ý îśŝúêś ĉán̂ b́ê áût́ôḿât́îćâĺl̂ý d̂ét̂éĉt́êd́ ŝó m̂án̂úâĺ t̂éŝt́îńĝ íŝ ál̂śô én̂ćôúr̂áĝéd̂.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility)" - } - } - }, - "lighthouse-core/config/default-config.js | a11yCategoryManualDescription": { - "message": "T̂h́êśê ít̂ém̂ś âd́d̂ŕêśŝ ár̂éâś ŵh́îćĥ án̂ áût́ôḿât́êd́ t̂éŝt́îńĝ t́ôól̂ ćâńn̂ót̂ ćôv́êŕ. L̂éâŕn̂ ḿôŕê ín̂ óûŕ ĝúîd́ê ón̂ $LINK_START_0$ćôńd̂úĉt́îńĝ án̂ áĉćêśŝíb̂íl̂ít̂ý r̂év̂íêẃ$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/fundamentals/accessibility/how-to-review)" - } - } - }, - "lighthouse-core/config/default-config.js | a11yCategoryTitle": { - "message": "Âćĉéŝśîb́îĺît́ŷ" - }, - "lighthouse-core/config/default-config.js | a11yColorContrastGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ím̂ṕr̂óv̂é t̂h́ê ĺêǵîb́îĺît́ŷ óf̂ ýôúr̂ ćôńt̂én̂t́." - }, - "lighthouse-core/config/default-config.js | a11yColorContrastGroupTitle": { - "message": "Ĉón̂t́r̂áŝt́" - }, - "lighthouse-core/config/default-config.js | a11yLanguageGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ím̂ṕr̂óv̂é t̂h́ê ín̂t́êŕp̂ŕêt́ât́îón̂ óf̂ ýôúr̂ ćôńt̂én̂t́ b̂ý ûśêŕŝ ín̂ d́îf́f̂ér̂én̂t́ l̂óĉál̂éŝ." - }, - "lighthouse-core/config/default-config.js | a11yLanguageGroupTitle": { - "message": "Îńt̂ér̂ńât́îón̂ál̂íẑát̂íôń âńd̂ ĺôćâĺîźât́îón̂" - }, - "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ím̂ṕr̂óv̂é t̂h́ê śêḿâńt̂íĉś ôf́ t̂h́ê ćôńt̂ŕôĺŝ ín̂ ýôúr̂ áp̂ṕl̂íĉát̂íôń. T̂h́îś m̂áŷ én̂h́âńĉé t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ûśêŕŝ óf̂ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝý, l̂ík̂é â śĉŕêén̂ ŕêád̂ér̂." - }, - "lighthouse-core/config/default-config.js | a11yNamesLabelsGroupTitle": { - "message": "N̂ám̂éŝ án̂d́ l̂áb̂él̂ś" - }, - "lighthouse-core/config/default-config.js | a11yNavigationGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô ím̂ṕr̂óv̂é k̂éŷb́ôár̂d́ n̂áv̂íĝát̂íôń îń ŷóûŕ âṕp̂ĺîćât́îón̂." - }, - "lighthouse-core/config/default-config.js | a11yNavigationGroupTitle": { - "message": "N̂áv̂íĝát̂íôń" - }, - "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupDescription": { - "message": "T̂h́êśê ár̂é ôṕp̂ór̂t́ûńît́îéŝ t́ô t́ô ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê óf̂ ŕêád̂ín̂ǵ t̂áb̂úl̂ár̂ ór̂ ĺîśt̂ d́ât́â úŝín̂ǵ âśŝíŝt́îv́ê t́êćĥńôĺôǵŷ, ĺîḱê á ŝćr̂éêń r̂éâd́êŕ." - }, - "lighthouse-core/config/default-config.js | a11yTablesListsVideoGroupTitle": { - "message": "T̂áb̂ĺêś âńd̂ ĺîśt̂ś" - }, - "lighthouse-core/config/default-config.js | bestPracticesCategoryTitle": { - "message": "B̂éŝt́ P̂ŕâćt̂íĉéŝ" - }, - "lighthouse-core/config/default-config.js | budgetsGroupDescription": { - "message": "P̂ér̂f́ôŕm̂án̂ćê b́ûd́ĝét̂ś ŝét̂ śt̂án̂d́âŕd̂ś f̂ór̂ t́ĥé p̂ér̂f́ôŕm̂án̂ćê óf̂ ýôúr̂ śît́ê." - }, - "lighthouse-core/config/default-config.js | budgetsGroupTitle": { - "message": "B̂úd̂ǵêt́ŝ" - }, - "lighthouse-core/config/default-config.js | diagnosticsGroupDescription": { - "message": "M̂ór̂é îńf̂ór̂ḿât́îón̂ áb̂óût́ t̂h́ê ṕêŕf̂ór̂ḿâńĉé ôf́ ŷóûŕ âṕp̂ĺîćât́îón̂." - }, - "lighthouse-core/config/default-config.js | diagnosticsGroupTitle": { - "message": "D̂íâǵn̂óŝt́îćŝ" - }, - "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupDescription": { - "message": "T̂h́ê ḿôśt̂ ćr̂ít̂íĉál̂ áŝṕêćt̂ óf̂ ṕêŕf̂ór̂ḿâńĉé îś ĥóŵ q́ûíĉḱl̂ý p̂íx̂él̂ś âŕê ŕêńd̂ér̂éd̂ ón̂śĉŕêén̂. Ḱêý m̂ét̂ŕîćŝ: F́îŕŝt́ Ĉón̂t́êńt̂f́ûĺ P̂áîńt̂, F́îŕŝt́ M̂éâńîńĝf́ûĺ P̂áîńt̂" - }, - "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupTitle": { - "message": "F̂ír̂śt̂ Ṕâín̂t́ Îḿp̂ŕôv́êḿêńt̂ś" - }, - "lighthouse-core/config/default-config.js | loadOpportunitiesGroupDescription": { - "message": "T̂h́êśê óp̂t́îḿîźât́îón̂ś ĉán̂ śp̂éêd́ ûṕ ŷóûŕ p̂áĝé l̂óâd́." - }, - "lighthouse-core/config/default-config.js | loadOpportunitiesGroupTitle": { - "message": "Ôṕp̂ór̂t́ûńît́îéŝ" - }, - "lighthouse-core/config/default-config.js | metricGroupTitle": { - "message": "M̂ét̂ŕîćŝ" - }, - "lighthouse-core/config/default-config.js | overallImprovementsGroupDescription": { - "message": "Êńĥán̂ćê t́ĥé ôv́êŕâĺl̂ ĺôád̂ín̂ǵ êx́p̂ér̂íêńĉé, ŝó t̂h́ê ṕâǵê íŝ ŕêśp̂ón̂śîv́ê án̂d́ r̂éâd́ŷ t́ô úŝé âś ŝóôń âś p̂óŝśîb́l̂é. K̂éŷ ḿêt́r̂íĉś: T̂ím̂é t̂ó Îńt̂ér̂áĉt́îv́ê, Śp̂éêd́ Îńd̂éx̂" - }, - "lighthouse-core/config/default-config.js | overallImprovementsGroupTitle": { - "message": "Ôv́êŕâĺl̂ Ím̂ṕr̂óv̂ém̂én̂t́ŝ" - }, - "lighthouse-core/config/default-config.js | performanceCategoryTitle": { - "message": "P̂ér̂f́ôŕm̂án̂ćê" - }, - "lighthouse-core/config/default-config.js | pwaFastReliableGroupTitle": { - "message": "F̂áŝt́ âńd̂ ŕêĺîáb̂ĺê" - }, - "lighthouse-core/config/default-config.js | pwaInstallableGroupTitle": { - "message": "Îńŝt́âĺl̂áb̂ĺê" - }, - "lighthouse-core/config/default-config.js | pwaOptimizedGroupTitle": { - "message": "P̂Ẃ Óp̂t́îḿîźêd́" - }, - "lighthouse-core/config/default-config.js | seoCategoryDescription": { - "message": "T̂h́êśê ćĥéĉḱŝ én̂śûŕê t́ĥát̂ ýôúr̂ ṕâǵê íŝ óp̂t́îḿîźêd́ f̂ór̂ śêár̂ćĥ én̂ǵîńê ŕêśûĺt̂ś r̂án̂ḱîńĝ. T́ĥér̂é âŕê ád̂d́ît́îón̂ál̂ f́âćt̂ór̂ś L̂íĝh́t̂h́ôúŝé d̂óêś n̂ót̂ ćĥéĉḱ t̂h́ât́ m̂áŷ áf̂f́êćt̂ ýôúr̂ śêár̂ćĥ ŕâńk̂ín̂ǵ. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://support.google.com/webmasters/answer/35769)" - } - } - }, - "lighthouse-core/config/default-config.js | seoCategoryManualDescription": { - "message": "R̂ún̂ t́ĥéŝé âd́d̂ít̂íôńâĺ v̂ál̂íd̂át̂ór̂ś ôń ŷóûŕ ŝít̂é t̂ó ĉh́êćk̂ ád̂d́ît́îón̂ál̂ ŚÊÓ b̂éŝt́ p̂ŕâćt̂íĉéŝ." - }, - "lighthouse-core/config/default-config.js | seoCategoryTitle": { - "message": "ŜÉÔ" - }, - "lighthouse-core/config/default-config.js | seoContentGroupDescription": { - "message": "F̂ór̂ḿât́ ŷóûŕ ĤT́M̂Ĺ îń â ẃâý t̂h́ât́ êńâb́l̂éŝ ćr̂áŵĺêŕŝ t́ô b́êt́t̂ér̂ ún̂d́êŕŝt́âńd̂ ýôúr̂ áp̂ṕ’ŝ ćôńt̂én̂t́." - }, - "lighthouse-core/config/default-config.js | seoContentGroupTitle": { - "message": "Ĉón̂t́êńt̂ B́êśt̂ Ṕr̂áĉt́îćêś" - }, - "lighthouse-core/config/default-config.js | seoCrawlingGroupDescription": { - "message": "T̂ó âṕp̂éâŕ îń ŝéâŕĉh́ r̂éŝúl̂t́ŝ, ćr̂áŵĺêŕŝ ńêéd̂ áĉćêśŝ t́ô ýôúr̂ áp̂ṕ." - }, - "lighthouse-core/config/default-config.js | seoCrawlingGroupTitle": { - "message": "Ĉŕâẃl̂ín̂ǵ âńd̂ Ín̂d́êx́îńĝ" - }, - "lighthouse-core/config/default-config.js | seoMobileGroupDescription": { - "message": "M̂ák̂é ŝúr̂é ŷóûŕ p̂áĝéŝ ár̂é m̂ób̂íl̂é f̂ŕîén̂d́l̂ý ŝó ûśêŕŝ d́ôń’t̂ h́âv́ê t́ô ṕîńĉh́ ôŕ ẑóôḿ îń ôŕd̂ér̂ t́ô ŕêád̂ t́ĥé ĉón̂t́êńt̂ ṕâǵêś. $LINK_START_0$L̂éâŕn̂ ḿôŕê$LINK_END_0$.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/search/mobile-sites/)" - } - } - }, - "lighthouse-core/config/default-config.js | seoMobileGroupTitle": { - "message": "M̂ób̂íl̂é F̂ŕîén̂d́l̂ý" - }, - "lighthouse-core/lib/i18n/i18n.js | columnCacheTTL": { - "message": "Ĉáĉh́ê T́T̂Ĺ" - }, - "lighthouse-core/lib/i18n/i18n.js | columnLocation": { - "message": "L̂óĉát̂íôń" - }, - "lighthouse-core/lib/i18n/i18n.js | columnRequests": { - "message": "R̂éq̂úêśt̂ś" - }, - "lighthouse-core/lib/i18n/i18n.js | columnResourceType": { - "message": "R̂éŝóûŕĉé T̂ýp̂é" - }, - "lighthouse-core/lib/i18n/i18n.js | columnSize": { - "message": "Ŝíẑé" - }, - "lighthouse-core/lib/i18n/i18n.js | columnTimeSpent": { - "message": "T̂ím̂é Ŝṕêńt̂" - }, - "lighthouse-core/lib/i18n/i18n.js | columnTransferSize": { - "message": "T̂ŕâńŝf́êŕ Ŝíẑé" - }, - "lighthouse-core/lib/i18n/i18n.js | columnURL": { - "message": "ÛŔL̂" - }, - "lighthouse-core/lib/i18n/i18n.js | columnWastedBytes": { - "message": "P̂ót̂én̂t́îál̂ Śâv́îńĝś" - }, - "lighthouse-core/lib/i18n/i18n.js | columnWastedMs": { - "message": "P̂ót̂én̂t́îál̂ Śâv́îńĝś" - }, - "lighthouse-core/lib/i18n/i18n.js | displayValueByteSavings": { - "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ $COMPLEX_ICU_0$ K̂B́", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{wastedBytes, number, bytes}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | displayValueMsSavings": { - "message": "P̂ót̂én̂t́îál̂ śâv́îńĝś ôf́ $COMPLEX_ICU_0$ m̂ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{wastedMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { - "message": "D̂óĉúm̂én̂t́" - }, - "lighthouse-core/lib/i18n/i18n.js | fontResourceType": { - "message": "F̂ón̂t́" - }, - "lighthouse-core/lib/i18n/i18n.js | imageResourceType": { - "message": "Îḿâǵê" - }, - "lighthouse-core/lib/i18n/i18n.js | mediaResourceType": { - "message": "M̂éd̂íâ" - }, - "lighthouse-core/lib/i18n/i18n.js | ms": { - "message": "$COMPLEX_ICU_0$ m̂ś", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, milliseconds}", - "example": "499" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { - "message": "Ôt́ĥér̂" - }, - "lighthouse-core/lib/i18n/i18n.js | scriptResourceType": { - "message": "Ŝćr̂íp̂t́" - }, - "lighthouse-core/lib/i18n/i18n.js | seconds": { - "message": "$COMPLEX_ICU_0$ ŝ", - "placeholders": { - "COMPLEX_ICU_0": { - "content": "{timeInMs, number, seconds}", - "example": "2.4" - } - } - }, - "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { - "message": "Ŝt́ŷĺêśĥéêt́" - }, - "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": { - "message": "T̂h́îŕd̂-ṕâŕt̂ý" - }, - "lighthouse-core/lib/i18n/i18n.js | totalResourceType": { - "message": "T̂ót̂ál̂" - }, - "lighthouse-core/lib/lh-error.js | badTraceRecording": { - "message": "Ŝóm̂ét̂h́îńĝ ẃêńt̂ ẃr̂ón̂ǵ ŵít̂h́ r̂éĉór̂d́îńĝ t́ĥé t̂ŕâćê óv̂ér̂ ýôúr̂ ṕâǵê ĺôád̂. Ṕl̂éâśê ŕûń L̂íĝh́t̂h́ôúŝé âǵâín̂. ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "NO_TRACING_STARTED" - } - } - }, - "lighthouse-core/lib/lh-error.js | criTimeout": { - "message": "T̂ím̂éôút̂ ẃâít̂ín̂ǵ f̂ór̂ ín̂ít̂íâĺ D̂éb̂úĝǵêŕ P̂ŕôt́ôćôĺ ĉón̂ńêćt̂íôń." - }, - "lighthouse-core/lib/lh-error.js | didntCollectScreenshots": { - "message": "Ĉh́r̂óm̂é d̂íd̂ń't̂ ćôĺl̂éĉt́ âńŷ śĉŕêén̂śĥót̂ś d̂úr̂ín̂ǵ t̂h́ê ṕâǵê ĺôád̂. Ṕl̂éâśê ḿâḱê śûŕê t́ĥér̂é îś ĉón̂t́êńt̂ v́îśîb́l̂é ôń t̂h́ê ṕâǵê, án̂d́ t̂h́êń t̂ŕŷ ŕê-ŕûńn̂ín̂ǵ L̂íĝh́t̂h́ôúŝé. ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "NO_SPEEDLINE_FRAMES" - } - } - }, - "lighthouse-core/lib/lh-error.js | dnsFailure": { - "message": "D̂ŃŜ śêŕv̂ér̂ś ĉóûĺd̂ ńôt́ r̂éŝól̂v́ê t́ĥé p̂ŕôv́îd́êd́ d̂óm̂áîń." - }, - "lighthouse-core/lib/lh-error.js | erroredRequiredArtifact": { - "message": "R̂éq̂úîŕêd́ $ICU_0$ ĝát̂h́êŕêŕ êńĉóûńt̂ér̂éd̂ án̂ ér̂ŕôŕ: $ICU_1$", - "placeholders": { - "ICU_0": { - "content": "{artifactName}", - "example": "Lighthouse Artifacts" - }, - "ICU_1": { - "content": "{errorMessage}", - "example": "ERRORED_REQUIRED_ARTIFACT" - } - } - }, - "lighthouse-core/lib/lh-error.js | internalChromeError": { - "message": "Âń îńt̂ér̂ńâĺ Ĉh́r̂óm̂é êŕr̂ór̂ óĉćûŕr̂éd̂. Ṕl̂éâśê ŕêśt̂ár̂t́ Ĉh́r̂óm̂é âńd̂ t́r̂ý r̂é-r̂ún̂ńîńĝ Ĺîǵĥt́ĥóûśê." - }, - "lighthouse-core/lib/lh-error.js | missingRequiredArtifact": { - "message": "R̂éq̂úîŕêd́ $ICU_0$ ĝát̂h́êŕêŕ d̂íd̂ ńôt́ r̂ún̂.", - "placeholders": { - "ICU_0": { - "content": "{artifactName}", - "example": "MISSING_REQUIRED_ARTIFACT" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailed": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedHung": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé ÛŔL̂ ýôú r̂éq̂úêśt̂éd̂ b́êćâúŝé t̂h́ê ṕâǵê śt̂óp̂ṕêd́ r̂éŝṕôńd̂ín̂ǵ." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedInsecure": { - "message": "T̂h́ê ÚR̂Ĺ ŷóû h́âv́ê ṕr̂óv̂íd̂éd̂ d́ôéŝ ńôt́ ĥáv̂é â v́âĺîd́ ŝéĉúr̂ít̂ý ĉér̂t́îf́îćât́ê. $ICU_0$", - "placeholders": { - "ICU_0": { - "content": "{securityMessages}", - "example": "net::ERR_CERT_DATE_INVALID" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedInterstitial": { - "message": "Ĉh́r̂óm̂é p̂ŕêv́êńt̂éd̂ ṕâǵê ĺôád̂ ẃît́ĥ án̂ ín̂t́êŕŝt́ît́îál̂. Ḿâḱê śûŕê ýôú âŕê t́êśt̂ín̂ǵ t̂h́ê ćôŕr̂éĉt́ ÛŔL̂ án̂d́ t̂h́ât́ t̂h́ê śêŕv̂ér̂ íŝ ṕr̂óp̂ér̂ĺŷ ŕêśp̂ón̂d́îńĝ t́ô ál̂ĺ r̂éq̂úêśt̂ś." - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedWithDetails": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (D́êt́âíl̂ś: $ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{errorDetails}", - "example": "FAILED_DOCUMENT_REQUEST" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadFailedWithStatusCode": { - "message": "L̂íĝh́t̂h́ôúŝé ŵáŝ ún̂áb̂ĺê t́ô ŕêĺîáb̂ĺŷ ĺôád̂ t́ĥé p̂áĝé ŷóû ŕêq́ûéŝt́êd́. M̂ák̂é ŝúr̂é ŷóû ár̂é t̂éŝt́îńĝ t́ĥé ĉór̂ŕêćt̂ ÚR̂Ĺ âńd̂ t́ĥát̂ t́ĥé ŝér̂v́êŕ îś p̂ŕôṕêŕl̂ý r̂éŝṕôńd̂ín̂ǵ t̂ó âĺl̂ ŕêq́ûéŝt́ŝ. (Śt̂át̂úŝ ćôd́ê: $ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{statusCode}", - "example": "404" - } - } - }, - "lighthouse-core/lib/lh-error.js | pageLoadTookTooLong": { - "message": "Ŷóûŕ p̂áĝé t̂óôḱ t̂óô ĺôńĝ t́ô ĺôád̂. Ṕl̂éâśê f́ôĺl̂óŵ t́ĥé ôṕp̂ór̂t́ûńît́îéŝ ín̂ t́ĥé r̂ép̂ór̂t́ t̂ó r̂éd̂úĉé ŷóûŕ p̂áĝé l̂óâd́ t̂ím̂é, âńd̂ t́ĥén̂ t́r̂ý r̂é-r̂ún̂ńîńĝ Ĺîǵĥt́ĥóûśê. ($ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{errorCode}", - "example": "FMP_TOO_LATE_FOR_FCPUI" - } - } - }, - "lighthouse-core/lib/lh-error.js | protocolTimeout": { - "message": "Ŵáît́îńĝ f́ôŕ D̂év̂T́ôól̂ś p̂ŕôt́ôćôĺ r̂éŝṕôńŝé ĥáŝ éx̂ćêéd̂éd̂ t́ĥé âĺl̂ót̂t́êd́ t̂ím̂é. (M̂ét̂h́ôd́: $ICU_0$)", - "placeholders": { - "ICU_0": { - "content": "{protocolMethod}", - "example": "PROTOCOL_TIMEOUT" - } - } - }, - "lighthouse-core/lib/lh-error.js | requestContentTimeout": { - "message": "F̂ét̂ćĥín̂ǵ r̂éŝóûŕĉé ĉón̂t́êńt̂ h́âś êx́ĉéêd́êd́ t̂h́ê ál̂ĺôt́t̂éd̂ t́îḿê" - }, - "lighthouse-core/lib/lh-error.js | urlInvalid": { - "message": "T̂h́ê ÚR̂Ĺ ŷóû h́âv́ê ṕr̂óv̂íd̂éd̂ áp̂ṕêár̂ś t̂ó b̂é îńv̂ál̂íd̂." - }, - "lighthouse-core/report/html/renderer/util.js | auditGroupExpandTooltip": { - "message": "Ŝh́ôẃ âúd̂ít̂ś" - }, - "lighthouse-core/report/html/renderer/util.js | crcInitialNavigation": { - "message": "Îńît́îál̂ Ńâv́îǵât́îón̂" - }, - "lighthouse-core/report/html/renderer/util.js | crcLongestDurationLabel": { - "message": "M̂áx̂ím̂úm̂ ćr̂ít̂íĉál̂ ṕât́ĥ ĺât́êńĉý:" - }, - "lighthouse-core/report/html/renderer/util.js | errorLabel": { - "message": "Êŕr̂ór̂!" - }, - "lighthouse-core/report/html/renderer/util.js | errorMissingAuditInfo": { - "message": "R̂ép̂ór̂t́ êŕr̂ór̂: ńô áûd́ît́ îńf̂ór̂ḿât́îón̂" - }, - "lighthouse-core/report/html/renderer/util.js | labDataTitle": { - "message": "L̂áb̂ D́ât́â" - }, - "lighthouse-core/report/html/renderer/util.js | lsPerformanceCategoryDescription": { - "message": "$LINK_START_0$L̂íĝh́t̂h́ôúŝé$LINK_END_0$ âńâĺŷśîś ôf́ t̂h́ê ćûŕr̂én̂t́ p̂áĝé ôń âń êḿûĺât́êd́ m̂ób̂íl̂é n̂ét̂ẃôŕk̂. V́âĺûéŝ ár̂é êśt̂ím̂át̂éd̂ án̂d́ m̂áŷ v́âŕŷ.", - "placeholders": { - "LINK_START_0": { - "content": "[" - }, - "LINK_END_0": { - "content": "](https://developers.google.com/web/tools/lighthouse/)" - } - } - }, - "lighthouse-core/report/html/renderer/util.js | manualAuditsGroupTitle": { - "message": "Âd́d̂ít̂íôńâĺ ît́êḿŝ t́ô ḿâńûál̂ĺŷ ćĥéĉḱ" - }, - "lighthouse-core/report/html/renderer/util.js | notApplicableAuditsGroupTitle": { - "message": "N̂ót̂ áp̂ṕl̂íĉáb̂ĺê" - }, - "lighthouse-core/report/html/renderer/util.js | opportunityResourceColumnLabel": { - "message": "Ôṕp̂ór̂t́ûńît́ŷ" - }, - "lighthouse-core/report/html/renderer/util.js | opportunitySavingsColumnLabel": { - "message": "Êśt̂ím̂át̂éd̂ Śâv́îńĝś" - }, - "lighthouse-core/report/html/renderer/util.js | passedAuditsGroupTitle": { - "message": "P̂áŝśêd́ âúd̂ít̂ś" - }, - "lighthouse-core/report/html/renderer/util.js | snippetCollapseButtonLabel": { - "message": "Ĉól̂ĺâṕŝé ŝńîṕp̂ét̂" - }, - "lighthouse-core/report/html/renderer/util.js | snippetExpandButtonLabel": { - "message": "Êx́p̂án̂d́ ŝńîṕp̂ét̂" - }, - "lighthouse-core/report/html/renderer/util.js | thirdPartyResourcesLabel": { - "message": "Ŝh́ôẃ 3r̂d́-p̂ár̂t́ŷ ŕêśôúr̂ćêś" - }, - "lighthouse-core/report/html/renderer/util.js | toplevelWarningsMessage": { - "message": "T̂h́êŕê ẃêŕê íŝśûéŝ áf̂f́êćt̂ín̂ǵ t̂h́îś r̂ún̂ óf̂ Ĺîǵĥt́ĥóûśê:" - }, - "lighthouse-core/report/html/renderer/util.js | varianceDisclaimer": { - "message": "V̂ál̂úêś âŕê éŝt́îḿât́êd́ âńd̂ ḿâý v̂ár̂ý." - }, - "lighthouse-core/report/html/renderer/util.js | warningAuditsGroupTitle": { - "message": "P̂áŝśêd́ âúd̂ít̂ś b̂út̂ ẃît́ĥ ẃâŕn̂ín̂ǵŝ" - }, - "lighthouse-core/report/html/renderer/util.js | warningHeader": { - "message": "Ŵár̂ńîńĝś: " - } -} diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 695d5212f0db..92057d4016fc 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -125,6 +125,9 @@ console.log('Collected from LH core!'); collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); console.log('Collected from Stack Packs!'); +// Make sure pre-locales exists since it is git-ignored +fs.mkdirSync('lighthouse-core/lib/i18n/pre-locale'); + writeStringsToLocaleFormat('pre-locale/en-US', strings); // Generate local pseudolocalized files for debugging while translating writeStringsToLocaleFormat('pre-locale/en-XL', psuedoLocalizedStrings); From 588f574a08c90dcd54f94f07cb102cd679dcd721 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 11 Jul 2019 11:17:52 -0700 Subject: [PATCH 36/71] reorganized collect and correct --- .../scripts/i18n/collect-strings.js | 344 ++++++++++++++- .../scripts/i18n/collection-util.js | 394 ------------------ .../scripts/i18n/correct-strings.js | 71 +++- ...n-util-test.js => collect-strings-test.js} | 63 +-- .../test/scripts/i18n/correct-strings-test.js | 71 ++++ 5 files changed, 471 insertions(+), 472 deletions(-) delete mode 100644 lighthouse-core/scripts/i18n/collection-util.js rename lighthouse-core/test/scripts/i18n/{collection-util-test.js => collect-strings-test.js} (89%) create mode 100644 lighthouse-core/test/scripts/i18n/correct-strings-test.js diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 92057d4016fc..933bdf69033d 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -11,7 +11,6 @@ const fs = require('fs'); const path = require('path'); const esprima = require('esprima'); -const collectionUtil = require('./collection-util.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; @@ -38,6 +37,314 @@ const ignoredPathComponents = [ '-renderer.js', ]; + +// @ts-ignore - @types/esprima lacks all of these +function computeDescription(ast, property, value, startRange) { + const endRange = property.range[0]; + const findIcu = /\{(\w+)\}/g; + for (const comment of ast.comments || []) { + if (comment.range[0] < startRange) continue; + if (comment.range[0] > endRange) continue; + if (comment.value.includes('@')) { + // This is a complex description with description and examples. + let description = ''; + /** @type {Record<string, string>} */ + const examples = {}; + + const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; + let matches; + while ((matches = r.exec(comment.value)) !== null) { + const tagName = matches[1]; + const placeholder = matches[2]; + const message = matches[3].trim(); + + if (tagName === 'description') { + description = message; + } else if (tagName === 'example') { + // Make sure the ICU var exists in string + if (!value.includes(placeholder)) { + throw Error(`Example missing ICU replacement in message "${message}"`); + } + examples[placeholder.substring(1, placeholder.length - 1)] = message; + } + } + // Make sure all ICU vars have examples + while ((matches = findIcu.exec(value)) !== null) { + const varName = matches[1]; + if (!examples[varName]) { + throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); + } + } + + // Make sure description is not empty + if (description.length === 0) throw Error(`Empty @description for message "${value}"`); + return {description, examples}; + } + + const description = comment.value.replace('*', '').trim(); + + // Make sure all ICU vars have examples + if (value.match(findIcu)) { + throw Error(`Variable '${value.match(/.*\{(\w+)\}.*/)[1]}' ` + + `is missing example comment in message "${value}"`); + } + + // Make sure description is not empty + if (description.length === 0) throw Error(`Empty description for message "${value}"`); + + // The entire comment is the description, so return everything. + return {description}; + } + throw Error(`No Description for message "${value}"`); +} + +/** + * Take a series of lighthouse-i18n-json format ICU messages and converts them + * to messages.json format by replacing {ICU} and `markdown` with + * $placeholders$. Functional opposite of `bakePlaceholders`. This is commonly + * called as one of the first steps in translation, via collect-strings.js. + * + * Converts this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ({url})", + * }, + * }, + * } + * + * Into this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ($ICU_0$)", + * "placeholders": { + * "ICU_0": { + * "content": "{url}", + * "example": "https://example.com/" + * }, + * }, + * }, + * } + * + * Throws if the message violates some basic sanity checking. + * + * @param {string} message + * @param {Record<string, string>} examples + * @returns {ICUMessageDefn} + */ +function convertMessageToPlaceholders(message, examples = {}) { + // Basically the same as markdown parsing in dom.js + const icu = { + message, + placeholders: {}, + }; + + // Process each placeholder type + _processPlaceholderMarkdownCode(icu); + + _processPlaceholderMarkdownLink(icu); + + _processPlaceholderComplexIcu(icu); + + _processPlaceholderDirectIcu(icu, examples); + + return icu; +} + +/** + * Convert markdown code blocks into placeholders with examples. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderMarkdownCode(icu) { + // Check that number of backticks is even. + if ((icu.message.split('`').length - 1) % 2 !== 0) { + throw Error(`Open backtick in message "${icu.message}"`); + } + + // Split on markdown code slashes + const parts = icu.message.split(/`(.*?)`/g); + icu.message = ''; + let idx = 0; + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, codeText] = parts.splice(0, 2); + icu.message += preambleText; + if (codeText) { + const pName = `MARKDOWN_SNIPPET_${idx++}`; + // Backtick replacement looks unreadable here, so .join() instead. + icu.message += ['$', pName, '$'].join(''); + icu.placeholders[pName] = { + content: ['`', codeText, '`'].join(''), + example: codeText, + }; + } + } +} + +/** + * Convert markdown html links into placeholders. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderMarkdownLink(icu) { + // Check that link markdown is not slightly off. + if (icu.message.match(/\[.*\] \(.*\)/)) { + throw Error(`Bad Link syntax in message "${icu.message}"`); + } + + // Split on markdown links (e.g. [some link](https://...)). + const parts = icu.message.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); + icu.message = ''; + let idx = 0; + + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, linkText, linkHref] = parts.splice(0, 3); + icu.message += preambleText; + + // Append link if there are any. + if (linkText && linkHref) { + const ls = `LINK_START_${idx}`; + const le = `LINK_END_${idx++}`; + const repr = `$${ls}$${linkText}$${le}$`; + icu.message += repr; + icu.placeholders[ls] = { + content: '[', + }; + icu.placeholders[le] = { + content: `](${linkHref})`, + }; + } + } +} + +/** + * Convert complex ICU syntax into placeholders with examples. + * + * @param {ICUMessageDefn} icu + */ +function _processPlaceholderComplexIcu(icu) { + // Check that complex ICU not using non-supported format + if (icu.message.match( + /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { + throw Error(`Unsupported ICU format in message "${icu.message}"`); + } + + // Split on complex ICU: {var, number, type} + const parts = icu.message.split( + /\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); + icu.message = ''; + let idx = 0; + + while (parts.length) { + // Pop off the same number of elements as there are capture groups. + const [preambleText, varName, icuType] = parts.splice(0, 3); + icu.message += preambleText; + + // Append link if there are any. + if (varName && icuType) { + const iName = `COMPLEX_ICU_${idx++}`; + icu.message += `$${iName}$`; + let example = '0'; + + // Make some good examples. + switch (icuType) { + case 'seconds': + example = '2.4'; + break; + case 'percent': + example = '54.6%'; + break; + case 'extendedPercent': + example = '37.92%'; + break; + default: + // Random (but constant) number for examples. + example = '499'; + } + + icu.placeholders[iName] = { + content: `{${varName}, number, ${icuType}}`, + example: example, + }; + } + } +} + +/** + * Add examples for direct ICU replacement. + * + * @param {ICUMessageDefn} icu + * @param {Record<string, string>} examples + */ +function _processPlaceholderDirectIcu(icu, examples) { + let tempMessage = icu.message; + let idx = 0; + for (const [key, value] of Object.entries(examples)) { + if (!icu.message.includes(`{${key}}`)) continue; + const eName = `ICU_${idx++}`; + tempMessage = tempMessage.replace(`{${key}}`, `$${eName}$`); + + icu.placeholders[eName] = { + content: `{${key}}`, + example: value, + }; + } + icu.message = tempMessage; +} + +/** + * Take a series of messages and apply ĥât̂ markers to the translatable portions + * of the text. Used to generate `en-XL` locale to debug i18n strings. + * + * @param {Record<string, ICUMessageDefn>} messages + */ +function createPsuedoLocaleStrings(messages) { + /** @type {Record<string, ICUMessageDefn>} */ + const psuedoLocalizedStrings = {}; + for (const [key, defn] of Object.entries(messages)) { + const message = defn.message; + const psuedoLocalizedString = []; + let braceCount = 0; + let inPlaceholder = false; + let useHatForAccentMark = true; + for (const char of message) { + psuedoLocalizedString.push(char); + if (char === '$') { + inPlaceholder = !inPlaceholder; + continue; + } + if (inPlaceholder) { + continue; + } + + if (char === '{') { + braceCount++; + } else if (char === '}') { + braceCount--; + } + + // Hack to not change {plural{ICU}braces} nested an odd number of times. + // ex: "{itemCount, plural, =1 {1 link found} other {# links found}}" + // becomes "{itemCount, plural, =1 {1 l̂ín̂ḱ f̂óûńd̂} other {# ĺîńk̂ś f̂óûńd̂}}" + // ex: "{itemCount, plural, =1 {1 link {nested_replacement} found} other {# links {nested_replacement} found}}" + // becomes: "{itemCount, plural, =1 {1 l̂ín̂ḱ {nested_replacement} f̂óûńd̂} other {# ĺîńk̂ś {nested_replacement} f̂óûńd̂}}" + if (braceCount % 2 === 1) continue; + + // Add diacritical marks to the preceding letter, alternating between a hat ( ̂ ) and an acute (´). + if (/[a-z]/i.test(char)) { + psuedoLocalizedString.push(useHatForAccentMark ? `\u0302` : `\u0301`); + useHatForAccentMark = !useHatForAccentMark; + } + } + psuedoLocalizedStrings[key] = { + message: psuedoLocalizedString.join(''), + placeholders: defn.placeholders, + }; + } + return psuedoLocalizedStrings; +} + /** * @param {string} dir * @param {Record<string, ICUMessageDefn>} strings @@ -81,9 +388,9 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - const {description, examples} = collectionUtil.computeDescription(ast, property, val, lastPropertyEndIndex); + const {description, examples} = computeDescription(ast, property, val, lastPropertyEndIndex); - const converted = collectionUtil.convertMessageToPlaceholders(val, examples); + const converted = convertMessageToPlaceholders(val, examples); const messageKey = `${relativePath} | ${key}`; @@ -118,17 +425,26 @@ function writeStringsToLocaleFormat(locale, strings) { fs.writeFileSync(fullPath, JSON.stringify(output, null, 2) + '\n'); } -const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core')); -const psuedoLocalizedStrings = collectionUtil.createPsuedoLocaleStrings(strings); -console.log('Collected from LH core!'); +// @ts-ignore Test if called from the CLI or as a module. +if (require.main === module) { + const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core')); + const psuedoLocalizedStrings = createPsuedoLocaleStrings(strings); + console.log('Collected from LH core!'); -collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); -console.log('Collected from Stack Packs!'); + collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); + console.log('Collected from Stack Packs!'); -// Make sure pre-locales exists since it is git-ignored -fs.mkdirSync('lighthouse-core/lib/i18n/pre-locale'); + // Make sure pre-locales exists since it is git-ignored + fs.mkdirSync('lighthouse-core/lib/i18n/pre-locale'); + + writeStringsToLocaleFormat('pre-locale/en-US', strings); + // Generate local pseudolocalized files for debugging while translating + writeStringsToLocaleFormat('pre-locale/en-XL', psuedoLocalizedStrings); + console.log('Written to disk!'); +} -writeStringsToLocaleFormat('pre-locale/en-US', strings); -// Generate local pseudolocalized files for debugging while translating -writeStringsToLocaleFormat('pre-locale/en-XL', psuedoLocalizedStrings); -console.log('Written to disk!'); +module.exports = { + computeDescription, + createPsuedoLocaleStrings, + convertMessageToPlaceholders, +}; diff --git a/lighthouse-core/scripts/i18n/collection-util.js b/lighthouse-core/scripts/i18n/collection-util.js deleted file mode 100644 index 29c836f04d38..000000000000 --- a/lighthouse-core/scripts/i18n/collection-util.js +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/env node -/** -* @license Copyright 2019 Google Inc. All Rights Reserved. -* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ -'use strict'; - -/** - * @typedef ICUMessageDefn - * @property {string} message - * @property {string} [description] - * @property {Record<string, ICUPlaceholderDefn>} [placeholders] - */ - -/** - * @typedef ICUPlaceholderDefn - * @property {string} content - * @property {string} [example] - */ - -// @ts-ignore - @types/esprima lacks all of these -function computeDescription(ast, property, value, startRange) { - const endRange = property.range[0]; - const findIcu = /\{(\w+)\}/g; - for (const comment of ast.comments || []) { - if (comment.range[0] < startRange) continue; - if (comment.range[0] > endRange) continue; - if (comment.value.includes('@')) { - // This is a complex description with description and examples. - let description = ''; - /** @type {Record<string, string>} */ - const examples = {}; - - const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; - let matches; - while ((matches = r.exec(comment.value)) !== null) { - const tagName = matches[1]; - const placeholder = matches[2]; - const message = matches[3].trim(); - - if (tagName === 'description') { - description = message; - } else if (tagName === 'example') { - // Make sure the ICU var exists in string - if (!value.includes(placeholder)) { - throw Error(`Example missing ICU replacement in message "${message}"`); - } - examples[placeholder.substring(1, placeholder.length - 1)] = message; - } - } - // Make sure all ICU vars have examples - while ((matches = findIcu.exec(value)) !== null) { - const varName = matches[1]; - if (!examples[varName]) { - throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); - } - } - - // Make sure description is not empty - if (description.length === 0) throw Error(`Empty @description for message "${value}"`); - return {description, examples}; - } - - const description = comment.value.replace('*', '').trim(); - - // Make sure all ICU vars have examples - if (value.match(findIcu)) { - throw Error(`Variable '${value.match(/.*\{(\w+)\}.*/)[1]}' ` + - `is missing example comment in message "${value}"`); - } - - // Make sure description is not empty - if (description.length === 0) throw Error(`Empty description for message "${value}"`); - - // The entire comment is the description, so return everything. - return {description}; - } - throw Error(`No Description for message "${value}"`); -} - -/** - * Take a series of lighthouse-i18n-json format ICU messages and converts them - * to messages.json format by replacing {ICU} and `markdown` with - * $placeholders$. Functional opposite of `bakePlaceholders`. This is commonly - * called as one of the first steps in translation, via collect-strings.js. - * - * Converts this: - * messages: { - * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { - * "message": "Points to a different domain ({url})", - * }, - * }, - * } - * - * Into this: - * messages: { - * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { - * "message": "Points to a different domain ($ICU_0$)", - * "placeholders": { - * "ICU_0": { - * "content": "{url}", - * "example": "https://example.com/" - * }, - * }, - * }, - * } - * - * Throws if the message violates some basic sanity checking. - * - * @param {string} message - * @param {Record<string, string>} examples - * @returns {ICUMessageDefn} - */ -function convertMessageToPlaceholders(message, examples = {}) { - // Basically the same as markdown parsing in dom.js - const icu = { - message, - placeholders: {}, - }; - - // Process each placeholder type - _processPlaceholderMarkdownCode(icu); - - _processPlaceholderMarkdownLink(icu); - - _processPlaceholderComplexIcu(icu); - - _processPlaceholderDirectIcu(icu, examples); - - return icu; -} - -/** - * Convert markdown code blocks into placeholders with examples. - * - * @param {ICUMessageDefn} icu - */ -function _processPlaceholderMarkdownCode(icu) { - // Check that number of backticks is even. - if ((icu.message.split('`').length - 1) % 2 !== 0) { - throw Error(`Open backtick in message "${icu.message}"`); - } - - // Split on markdown code slashes - const parts = icu.message.split(/`(.*?)`/g); - icu.message = ''; - let idx = 0; - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, codeText] = parts.splice(0, 2); - icu.message += preambleText; - if (codeText) { - const pName = `MARKDOWN_SNIPPET_${idx++}`; - // Backtick replacement looks unreadable here, so .join() instead. - icu.message += ['$', pName, '$'].join(''); - icu.placeholders[pName] = { - content: ['`', codeText, '`'].join(''), - example: codeText, - }; - } - } -} - -/** - * Convert markdown html links into placeholders. - * - * @param {ICUMessageDefn} icu - */ -function _processPlaceholderMarkdownLink(icu) { - // Check that link markdown is not slightly off. - if (icu.message.match(/\[.*\] \(.*\)/)) { - throw Error(`Bad Link syntax in message "${icu.message}"`); - } - - // Split on markdown links (e.g. [some link](https://...)). - const parts = icu.message.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g); - icu.message = ''; - let idx = 0; - - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, linkText, linkHref] = parts.splice(0, 3); - icu.message += preambleText; - - // Append link if there are any. - if (linkText && linkHref) { - const ls = `LINK_START_${idx}`; - const le = `LINK_END_${idx++}`; - const repr = `$${ls}$${linkText}$${le}$`; - icu.message += repr; - icu.placeholders[ls] = { - content: '[', - }; - icu.placeholders[le] = { - content: `](${linkHref})`, - }; - } - } -} - -/** - * Convert complex ICU syntax into placeholders with examples. - * - * @param {ICUMessageDefn} icu - */ -function _processPlaceholderComplexIcu(icu) { - // Check that complex ICU not using non-supported format - if (icu.message.match( - /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { - throw Error(`Unsupported ICU format in message "${icu.message}"`); - } - - // Split on complex ICU: {var, number, type} - const parts = icu.message.split( - /\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); - icu.message = ''; - let idx = 0; - - while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, varName, icuType] = parts.splice(0, 3); - icu.message += preambleText; - - // Append link if there are any. - if (varName && icuType) { - const iName = `COMPLEX_ICU_${idx++}`; - icu.message += `$${iName}$`; - let example = '0'; - - // Make some good examples. - switch (icuType) { - case 'seconds': - example = '2.4'; - break; - case 'percent': - example = '54.6%'; - break; - case 'extendedPercent': - example = '37.92%'; - break; - default: - // Random (but constant) number for examples. - example = '499'; - } - - icu.placeholders[iName] = { - content: `{${varName}, number, ${icuType}}`, - example: example, - }; - } - } -} - -/** - * Add examples for direct ICU replacement. - * - * @param {ICUMessageDefn} icu - * @param {Record<string, string>} examples - */ -function _processPlaceholderDirectIcu(icu, examples) { - let tempMessage = icu.message; - let idx = 0; - for (const [key, value] of Object.entries(examples)) { - if (!icu.message.includes(`{${key}}`)) continue; - const eName = `ICU_${idx++}`; - tempMessage = tempMessage.replace(`{${key}}`, `$${eName}$`); - - icu.placeholders[eName] = { - content: `{${key}}`, - example: value, - }; - } - icu.message = tempMessage; -} - -/** - * Take a series of messages and apply ĥât̂ markers to the translatable portions - * of the text. Used to generate `en-XL` locale to debug i18n strings. - * - * @param {Record<string, ICUMessageDefn>} messages - */ -function createPsuedoLocaleStrings(messages) { - /** @type {Record<string, ICUMessageDefn>} */ - const psuedoLocalizedStrings = {}; - for (const [key, defn] of Object.entries(messages)) { - const message = defn.message; - const psuedoLocalizedString = []; - let braceCount = 0; - let inPlaceholder = false; - let useHatForAccentMark = true; - for (const char of message) { - psuedoLocalizedString.push(char); - if (char === '$') { - inPlaceholder = !inPlaceholder; - continue; - } - if (inPlaceholder) { - continue; - } - - if (char === '{') { - braceCount++; - } else if (char === '}') { - braceCount--; - } - - // Hack to not change {plural{ICU}braces} nested an odd number of times. - // ex: "{itemCount, plural, =1 {1 link found} other {# links found}}" - // becomes "{itemCount, plural, =1 {1 l̂ín̂ḱ f̂óûńd̂} other {# ĺîńk̂ś f̂óûńd̂}}" - // ex: "{itemCount, plural, =1 {1 link {nested_replacement} found} other {# links {nested_replacement} found}}" - // becomes: "{itemCount, plural, =1 {1 l̂ín̂ḱ {nested_replacement} f̂óûńd̂} other {# ĺîńk̂ś {nested_replacement} f̂óûńd̂}}" - if (braceCount % 2 === 1) continue; - - // Add diacritical marks to the preceding letter, alternating between a hat ( ̂ ) and an acute (´). - if (/[a-z]/i.test(char)) { - psuedoLocalizedString.push(useHatForAccentMark ? `\u0302` : `\u0301`); - useHatForAccentMark = !useHatForAccentMark; - } - } - psuedoLocalizedStrings[key] = { - message: psuedoLocalizedString.join(''), - placeholders: defn.placeholders, - }; - } - return psuedoLocalizedStrings; -} - -/** - * Take a series of messages.json format ICU messages and converts them to - * lighthouse-i18n-json format by replacing $placeholders$ with their {ICU} - * values. Functional opposite of `convertMessageToPlaceholders`. This is - * commonly called as the last step in translation, via correct-strings.js. - * - * Converts this: - * messages: { - * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { - * "message": "Points to a different domain ($ICU_0$)", - * "placeholders": { - * "ICU_0": { - * "content": "{url}", - * "example": "https://example.com/" - * }, - * }, - * }, - * } - * - * Into this: - * messages: { - * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { - * "message": "Points to a different domain ({url})", - * }, - * }, - * } - * - * Throws if there is a $placeholder$ in the message that has no corresponding - * value in the placeholders object, or vice versa. - * - * @param {Record<string, ICUMessageDefn>} messages - * @returns {Record<string, ICUMessageDefn>} - */ -function bakePlaceholders(messages) { - for (const [_, defn] of Object.entries(messages)) { - delete defn['description']; - - let message = defn['message']; - const placeholders = defn['placeholders']; - - for (const placeholder in placeholders) { - if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; - - const content = placeholders[placeholder]['content']; - if (!message.includes(`$${placeholder}$`)) { - throw Error(`Message "${message}" has extra placeholder "${placeholder}"`); - } - message = message.replace(`$${placeholder}$`, content); - } - - // Sanity check that all placeholders are gone - if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); - - defn['message'] = message; - - delete defn['placeholders']; - } - return messages; -} - -module.exports = { - computeDescription, - convertMessageToPlaceholders, - createPsuedoLocaleStrings, - bakePlaceholders, -}; diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/correct-strings.js index fcac5c81c270..a00608940238 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/correct-strings.js @@ -10,12 +10,18 @@ const fs = require('fs'); const path = require('path'); -const collUtil = require('./collection-util.js'); /** * @typedef ICUMessageDefn * @property {string} message * @property {string} [description] + * @property {Record<string, ICUPlaceholderDefn>} [placeholders] + */ + +/** + * @typedef ICUPlaceholderDefn + * @property {string} content + * @property {string} [example] */ const ignoredPathComponents = [ @@ -27,6 +33,66 @@ const ignoredPathComponents = [ '-renderer.js', ]; +/** + * Take a series of messages.json format ICU messages and converts them to + * lighthouse-i18n-json format by replacing $placeholders$ with their {ICU} + * values. Functional opposite of `convertMessageToPlaceholders`. This is + * commonly called as the last step in translation, via correct-strings.js. + * + * Converts this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ($ICU_0$)", + * "placeholders": { + * "ICU_0": { + * "content": "{url}", + * "example": "https://example.com/" + * }, + * }, + * }, + * } + * + * Into this: + * messages: { + * "lighthouse-core/audits/seo/canonical.js | explanationDifferentDomain" { + * "message": "Points to a different domain ({url})", + * }, + * }, + * } + * + * Throws if there is a $placeholder$ in the message that has no corresponding + * value in the placeholders object, or vice versa. + * + * @param {Record<string, ICUMessageDefn>} messages + * @returns {Record<string, ICUMessageDefn>} + */ +function bakePlaceholders(messages) { + for (const [_, defn] of Object.entries(messages)) { + delete defn['description']; + + let message = defn['message']; + const placeholders = defn['placeholders']; + + for (const placeholder in placeholders) { + if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; + + const content = placeholders[placeholder]['content']; + if (!message.includes(`$${placeholder}$`)) { + throw Error(`Message "${message}" has extra placeholder "${placeholder}"`); + } + message = message.replace(`$${placeholder}$`, content); + } + + // Sanity check that all placeholders are gone + if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); + + defn['message'] = message; + + delete defn['placeholders']; + } + return messages; +} + /** * @param {*} file */ @@ -57,7 +123,7 @@ function collectAllPreLocaleStrings(dir, output) { if (name.endsWith('.json')) { if (!process.env.CI) console.log('Correcting from', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); - const strings = collUtil.bakePlaceholders(preLocaleStrings); + const strings = bakePlaceholders(preLocaleStrings); saveLocaleStrings(output + path.basename(name), strings); } } @@ -65,4 +131,5 @@ function collectAllPreLocaleStrings(dir, output) { module.exports = { collectAllPreLocaleStrings, + bakePlaceholders, }; diff --git a/lighthouse-core/test/scripts/i18n/collection-util-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js similarity index 89% rename from lighthouse-core/test/scripts/i18n/collection-util-test.js rename to lighthouse-core/test/scripts/i18n/collect-strings-test.js index 5730b4e07c71..41966bd7675c 100644 --- a/lighthouse-core/test/scripts/i18n/collection-util-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -7,7 +7,7 @@ /* eslint-env jest */ -const collect = require('../../../scripts/i18n/collection-util.js'); +const collect = require('../../../scripts/i18n/collect-strings.js'); const esprima = require('esprima'); describe('Compute Description', () => { @@ -386,64 +386,3 @@ describe('PseudoLocalizer', () => { }); }); }); - -describe('Baking Placeholders', () => { - it('passthroughs a basic message unchanged', () => { - const strings = { - hello: { - message: 'world', - }, - }; - const res = collect.bakePlaceholders(strings); - expect(res).toEqual({ - hello: { - message: 'world', - }, - }); - }); - - it('bakes a placeholder into the output string', () => { - const strings = { - hello: { - message: '$MARKDOWN_SNIPPET_0$', - placeholders: { - MARKDOWN_SNIPPET_0: { - content: '`World`', - }, - }, - }, - }; - const res = collect.bakePlaceholders(strings); - expect(res).toEqual({ - hello: { - message: '`World`', - placeholders: undefined, - }, - }); - }); - - it('throws when a placeholder cannot be found', () => { - const strings = { - hello: { - message: '$MARKDOWN_SNIPPET_0$', - }, - }; - expect(() => collect.bakePlaceholders(strings)) - .toThrow(/Message "\$MARKDOWN_SNIPPET_0\$" is missing placeholder/); - }); - - it('throws when a placeholder is not in string', () => { - const strings = { - hello: { - message: 'World', - placeholders: { - MARKDOWN_SNIPPET_0: { - content: '`World`', - }, - }, - }, - }; - expect(() => collect.bakePlaceholders(strings)) - .toThrow(/Message "World" has extra placeholder "MARKDOWN_SNIPPET_0"/); - }); -}); diff --git a/lighthouse-core/test/scripts/i18n/correct-strings-test.js b/lighthouse-core/test/scripts/i18n/correct-strings-test.js new file mode 100644 index 000000000000..0fafa8150b20 --- /dev/null +++ b/lighthouse-core/test/scripts/i18n/correct-strings-test.js @@ -0,0 +1,71 @@ +/** + * @license Copyright 2019 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +/* eslint-env jest */ + +const correct = require('../../../scripts/i18n/correct-strings.js'); + +describe('Baking Placeholders', () => { + it('passthroughs a basic message unchanged', () => { + const strings = { + hello: { + message: 'world', + }, + }; + const res = correct.bakePlaceholders(strings); + expect(res).toEqual({ + hello: { + message: 'world', + }, + }); + }); + + it('bakes a placeholder into the output string', () => { + const strings = { + hello: { + message: '$MARKDOWN_SNIPPET_0$', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + }, + }, + }, + }; + const res = correct.bakePlaceholders(strings); + expect(res).toEqual({ + hello: { + message: '`World`', + placeholders: undefined, + }, + }); + }); + + it('throws when a placeholder cannot be found', () => { + const strings = { + hello: { + message: '$MARKDOWN_SNIPPET_0$', + }, + }; + expect(() => correct.bakePlaceholders(strings)) + .toThrow(/Message "\$MARKDOWN_SNIPPET_0\$" is missing placeholder/); + }); + + it('throws when a placeholder is not in string', () => { + const strings = { + hello: { + message: 'World', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + }, + }, + }, + }; + expect(() => correct.bakePlaceholders(strings)) + .toThrow(/Message "World" has extra placeholder "MARKDOWN_SNIPPET_0"/); + }); +}); From 2b171308f897d73069d3e2e3f5e1f2cde8c5a362 Mon Sep 17 00:00:00 2001 From: Paul Irish <paulirish@google.com> Date: Thu, 11 Jul 2019 11:56:47 -0700 Subject: [PATCH 37/71] fixup collect-string output --- lighthouse-core/scripts/i18n/collect-strings.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 933bdf69033d..08511bbca017 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -9,6 +9,7 @@ /* eslint-disable no-console, max-len */ const fs = require('fs'); +const mkdirp = require('mkdirp').sync; const path = require('path'); const esprima = require('esprima'); @@ -359,7 +360,7 @@ function collectAllStringsInDir(dir, strings = {}) { collectAllStringsInDir(fullPath, strings); } else { if (name.endsWith('.js')) { - if (!process.env.CI) console.log('Collecting from', relativePath); + if (!process.env.CI) console.log('- Collecting from', relativePath); const content = fs.readFileSync(fullPath, 'utf8'); const exportVars = require(fullPath); const regexMatches = !!UISTRINGS_REGEX.test(content); @@ -428,19 +429,19 @@ function writeStringsToLocaleFormat(locale, strings) { // @ts-ignore Test if called from the CLI or as a module. if (require.main === module) { const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core')); - const psuedoLocalizedStrings = createPsuedoLocaleStrings(strings); console.log('Collected from LH core!'); collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); console.log('Collected from Stack Packs!'); // Make sure pre-locales exists since it is git-ignored - fs.mkdirSync('lighthouse-core/lib/i18n/pre-locale'); + mkdirp('lighthouse-core/lib/i18n/pre-locale'); writeStringsToLocaleFormat('pre-locale/en-US', strings); + console.log('Written to disk!', 'pre-locale/en-US'); // Generate local pseudolocalized files for debugging while translating - writeStringsToLocaleFormat('pre-locale/en-XL', psuedoLocalizedStrings); - console.log('Written to disk!'); + writeStringsToLocaleFormat('pre-locale/en-XL', createPsuedoLocaleStrings(strings)); + console.log('Written to disk!', 'pre-locale/en-XL'); } module.exports = { From 570a6cc6f4d39b5b582418f393783c792286f267 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 12 Jul 2019 11:02:20 -0700 Subject: [PATCH 38/71] Paul foodback. Readme updates, updated yarn cmds, updated ctc naming part 1, updated baking script. en-XL has WP strings now. --- .gitignore | 2 +- lighthouse-core/lib/i18n/README.md | 63 ++++++++++++++----- lighthouse-core/lib/i18n/locales/en-XL.json | 42 +++++++++++++ .../{correct-strings.js => bake-strings.js} | 13 ++-- .../scripts/i18n/collect-strings.js | 20 ++++-- .../scripts/i18n/pseudolocalize.js | 15 ----- ...t-strings-test.js => bake-strings-test.js} | 10 +-- package.json | 4 +- 8 files changed, 120 insertions(+), 49 deletions(-) rename lighthouse-core/scripts/i18n/{correct-strings.js => bake-strings.js} (89%) delete mode 100644 lighthouse-core/scripts/i18n/pseudolocalize.js rename lighthouse-core/test/scripts/i18n/{correct-strings-test.js => bake-strings-test.js} (87%) diff --git a/.gitignore b/.gitignore index b3cfc46c0428..02f265f28640 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,8 @@ last-run-results.html *.report.csv *.report.pretty *.artifacts.log +*.ctc.json -lighthouse-core/lib/i18n/pre-locale !lighthouse-core/test/results/artifacts/*.trace.json !lighthouse-core/test/results/artifacts/*.devtoolslog.json !lighthouse-core/test/fixtures/artifacts/**/*.trace.json diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index b0cbebed7f28..63bca2c90224 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -41,7 +41,7 @@ displayValue: `{pronoun, select, ### Why we use message.json -It is the [Chrome Standard](https://developer.chrome.com/extensions/i18n-messages) for i18n messages. +We needed a JS-friendly format supported by Google's Translation Console (TC). The [Chrome extension & Chrome app i18n format](https://developer.chrome.com/extensions/i18n-messages) checks those boxes. ### Parts of a message.json message @@ -166,32 +166,65 @@ The translation pipeline has 2 distinct stages, the collection and translation i #### Translation Pipeline (build time) -1. `file_with_UIStrings.js` this is where strings start. Optimized for programmer ease of use and not for machine parsing. Uses ICU syntax and markdown control characters inline. +To a typical developer the pipeline looks like this: -2. `yarn i18n:collect-strings` collects all UIStrings, and generates the pre-locale files. Does some parsing to make sure that common mistakes are avoided. +* LH contributor makes any changes to strings. They run yarn i18n, They can now use the en-XL locale to verify things work as intended. -3. `pre-locale/en-US.json` this is the well formatted _machine parsable_ fileset that is uploaded to be translated, i.e. they use $placeholder$ syntax instead of ICU. These aren't used by Lighthouse's i18n system, they are solely used to send to translators. +* Googler is ready to kick off the TC pipeline again. They run yarn i18n and then on the google-side: import-source-from-github.sh, submit CL. Wait ~two weeks... + + * They run export-tc-dump-to-github.sh, and opens a LH PR. - 1. Googlers will take the `pre-locale/` files to translators and have the files translated and returned to be consumed by `correct-strings` -4. `yarn i18n:correct-strings` collects all pre-locale files, or returned .json files of all languages if you're a Googler importing strings (see 3.1), and converts them back to Lighthouse json format and puts them into `locales/`. +Paul Irish's ASCII explanation: -5. `locales/{locale}.json` the Lighthouse json files. Used by the i18n.js system to localize strings. Uses ICU and not $placeholder$ syntax. +``` + Source files: Locale files: ++---------------------------+ +---------------------------------------------- +| ++ | lighthouse-core/lib/i18n/locales/en-US.json | +| const UIStrings = { ... };|-+ +---> | lighthouse-core/lib/i18n/locales/en-XL.json | +| |-| | +----------------------------------------------+ ++-----------------------------| | | || + +----------------------------| | | lighthouse-core/lib/i18n/locales/*.json |-<+ + +---------------------------+ | | || | + | | +----------------------------------------------| | + | | +---------------------------------------------+ | + $ yarn i18n +--------------------+ | + | | + v ▐ ▐ +---------------+ | + +------------+------+ ▐ Google TC Pipeline ▐ +->| *.ctc.json |---+ + | en-US.ctc.json | +--------------> ▐ (~2 weeks) ▐ +---------------+ + +-------------------+ $ g3/import….sh ▐ ▐ $ g3/export….sh +``` + +LH Contirbutor commands: + +```shell +# collect UIStrings and bake the en-US & en-XL locales +$ yarn i18n -This pipeline is best seen with its component commands: +# Test to see that the new translations are valid and apply to all strings +$ node lighthouse-cli https://example.com/ --view --locale=en-XL +``` + +i18n'ing Googler commands: ```shell -# collect UIStrings into pre-locale files -$ yarn i18n:collect-strings +# collect UIStrings and bake the en-US & en-XL locales +# (to make sure everything is up to date) +$ yarn i18n + +# Extract the CTC format files to translation console +$ sh google_export_script.sh -# make the final en-US and en-XL files -$ yarn i18n:correct-strings +# Wait ~2 weeks for translations -# Send off to translators, and the i18n:correct-strings again -# once those .json's are done. -$ sh google_import_script_that_calls_correct_strings +# Import the CTC format files to locales/ and bake them +$ sh google_import_script.sh ``` +Note: Why do `en-US` and `en-XL` get baked early? We write all our strings in `en-US` by default, so they do not need to be translated, so it can be immediately baked without going to the translators. Similarly, `en-XL` is a debugging language, it is an automated version of `en-US` that simply adds markers to `en` strings in order to make it obvious that something has or hasn't been translated. So neither of these files need to go to translators to be used, and both can be used at develop-time to help developer i18n workflow. + + #### String Replacement Pipeline (runtime) 1. String called in `.js` file, converted to i18n id. diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 4d52b82056a6..ca5ecafc447f 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -1348,5 +1348,47 @@ }, "lighthouse-core/report/html/renderer/util.js | warningHeader": { "message": "Ŵár̂ńîńĝś: " + }, + "stack-packs/packs/wordpress.js | efficient_animated_content": { + "message": "Ĉón̂śîd́êŕ ûṕl̂óâd́îńĝ ýôúr̂ ǴÎF́ t̂ó â śêŕv̂íĉé ŵh́îćĥ ẃîĺl̂ ḿâḱê ít̂ áv̂áîĺâb́l̂é t̂ó êḿb̂éd̂ áŝ án̂ H́T̂ḾL̂5 v́îd́êó." + }, + "stack-packs/packs/wordpress.js | offscreen_images": { + "message": "Îńŝt́âĺl̂ á [l̂áẑý-l̂óâd́ Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂](https://wordpress.org/plugins/search/lazy+load/) t́ĥát̂ ṕr̂óv̂íd̂éŝ t́ĥé âb́îĺît́ŷ t́ô d́êf́êŕ âńŷ óf̂f́ŝćr̂éêń îḿâǵêś, ôŕ ŝẃît́ĉh́ t̂ó â t́ĥém̂é t̂h́ât́ p̂ŕôv́îd́êś t̂h́ât́ f̂ún̂ćt̂íôńâĺît́ŷ. Ál̂śô ćôńŝíd̂ér̂ úŝín̂ǵ [t̂h́ê ÁM̂Ṕ p̂ĺûǵîń](https://wordpress.org/plugins/amp/)." + }, + "stack-packs/packs/wordpress.js | render_blocking_resources": { + "message": "T̂h́êŕê ár̂é â ńûḿb̂ér̂ óf̂ Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ t́ĥát̂ ćâń ĥél̂ṕ ŷóû [ín̂ĺîńê ćr̂ít̂íĉál̂ áŝśêt́ŝ](https://wordpress.org/plugins/search/critical+css/) ór̂ [d́êf́êŕ l̂éŝś îḿp̂ór̂t́âńt̂ ŕêśôúr̂ćêś](https://wordpress.org/plugins/search/defer+css+javascript/). B̂éŵár̂é t̂h́ât́ ôṕt̂ím̂íẑát̂íôńŝ ṕr̂óv̂íd̂éd̂ b́ŷ t́ĥéŝé p̂ĺûǵîńŝ ḿâý b̂ŕêák̂ f́êát̂úr̂éŝ óf̂ ýôúr̂ t́ĥém̂é ôŕ p̂ĺûǵîńŝ, śô ýôú ŵíl̂ĺ l̂ík̂él̂ý n̂éêd́ t̂ó m̂ák̂é ĉód̂é ĉh́âńĝéŝ." + }, + "stack-packs/packs/wordpress.js | time_to_first_byte": { + "message": "T̂h́êḿêś, p̂ĺûǵîńŝ, án̂d́ ŝér̂v́êŕ ŝṕêćîf́îćât́îón̂ś âĺl̂ ćôńt̂ŕîb́ût́ê t́ô śêŕv̂ér̂ ŕêśp̂ón̂śê t́îḿê. Ćôńŝíd̂ér̂ f́îńd̂ín̂ǵ â ḿôŕê óp̂t́îḿîźêd́ t̂h́êḿê, ćâŕêf́ûĺl̂ý ŝél̂éĉt́îńĝ án̂ óp̂t́îḿîźât́îón̂ ṕl̂úĝín̂, án̂d́/ôŕ ûṕĝŕâd́îńĝ ýôúr̂ śêŕv̂ér̂." + }, + "stack-packs/packs/wordpress.js | total_byte_weight": { + "message": "Ĉón̂śîd́êŕ ŝh́ôẃîńĝ éx̂ćêŕp̂t́ŝ ín̂ ýôúr̂ ṕôśt̂ ĺîśt̂ś (ê.ǵ. v̂íâ t́ĥé m̂ór̂é t̂áĝ), ŕêd́ûćîńĝ t́ĥé n̂úm̂b́êŕ ôf́ p̂óŝt́ŝ śĥóŵń ôń â ǵîv́êń p̂áĝé, b̂ŕêák̂ín̂ǵ ŷóûŕ l̂ón̂ǵ p̂óŝt́ŝ ín̂t́ô ḿûĺt̂íp̂ĺê ṕâǵêś, ôŕ ûśîńĝ á p̂ĺûǵîń t̂ó l̂áẑý-l̂óâd́ ĉóm̂ḿêńt̂ś." + }, + "stack-packs/packs/wordpress.js | unminified_css": { + "message": " ńûḿb̂ér̂ óf̂ [Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ](https://wordpress.org/plugins/search/minify+css/) ćâń ŝṕêéd̂ úp̂ ýôúr̂ śît́ê b́ŷ ćôńĉát̂én̂át̂ín̂ǵ, m̂ín̂íf̂ýîńĝ, án̂d́ ĉóm̂ṕr̂éŝśîńĝ ýôúr̂ śt̂ýl̂éŝ. Ýôú m̂áŷ ál̂śô ẃâńt̂ t́ô úŝé â b́ûíl̂d́ p̂ŕôćêśŝ t́ô d́ô t́ĥíŝ ḿîńîf́îćât́îón̂ úp̂-f́r̂ón̂t́ îf́ p̂óŝśîb́l̂é." + }, + "stack-packs/packs/wordpress.js | unminified_javascript": { + "message": " ńûḿb̂ér̂ óf̂ [Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ](https://wordpress.org/plugins/search/minify+javascript/) ćâń ŝṕêéd̂ úp̂ ýôúr̂ śît́ê b́ŷ ćôńĉát̂én̂át̂ín̂ǵ, m̂ín̂íf̂ýîńĝ, án̂d́ ĉóm̂ṕr̂éŝśîńĝ ýôúr̂ śĉŕîṕt̂ś. Ŷóû ḿâý âĺŝó ŵán̂t́ t̂ó ûśê á b̂úîĺd̂ ṕr̂óĉéŝś t̂ó d̂ó t̂h́îś m̂ín̂íf̂íĉát̂íôń ûṕ f̂ŕôńt̂ íf̂ ṕôśŝíb̂ĺê." + }, + "stack-packs/packs/wordpress.js | unused_css_rules": { + "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ, ôŕ ŝẃît́ĉh́îńĝ, t́ĥé n̂úm̂b́êŕ ôf́ [Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂ś](https://wordpress.org/plugins/) l̂óâd́îńĝ ún̂úŝéd̂ ĆŜŚ îń ŷóûŕ p̂áĝé. T̂ó îd́êńt̂íf̂ý p̂ĺûǵîńŝ t́ĥát̂ ár̂é âd́d̂ín̂ǵ êx́t̂ŕâńêóûś ĈŚŜ, t́r̂ý r̂ún̂ńîńĝ [ćôd́ê ćôv́êŕâǵê](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) ín̂ Ćĥŕôḿê D́êv́T̂óôĺŝ. Ýôú ĉán̂ íd̂én̂t́îf́ŷ t́ĥé t̂h́êḿê/ṕl̂úĝín̂ ŕêśp̂ón̂śîb́l̂é f̂ŕôḿ t̂h́ê ÚR̂Ĺ ôf́ t̂h́ê śt̂ýl̂éŝh́êét̂. Ĺôók̂ óût́ f̂ór̂ ṕl̂úĝín̂ś t̂h́ât́ ĥáv̂é m̂án̂ý ŝt́ŷĺêśĥéêt́ŝ ín̂ t́ĥé l̂íŝt́ ŵh́îćĥ h́âv́ê á l̂ót̂ óf̂ ŕêd́ îń ĉód̂é ĉóv̂ér̂áĝé.  ṕl̂úĝín̂ śĥóûĺd̂ ón̂ĺŷ én̂q́ûéûé â śt̂ýl̂éŝh́êét̂ íf̂ ít̂ íŝ áĉt́ûál̂ĺŷ úŝéd̂ ón̂ t́ĥé p̂áĝé." + }, + "stack-packs/packs/wordpress.js | unused_javascript": { + "message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ, ôŕ ŝẃît́ĉh́îńĝ, t́ĥé n̂úm̂b́êŕ ôf́ [Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂ś](https://wordpress.org/plugins/) l̂óâd́îńĝ ún̂úŝéd̂ J́âv́âŚĉŕîṕt̂ ín̂ ýôúr̂ ṕâǵê. T́ô íd̂én̂t́îf́ŷ ṕl̂úĝín̂ś t̂h́ât́ âŕê ád̂d́îńĝ éx̂t́r̂án̂éôúŝ J́Ŝ, t́r̂ý r̂ún̂ńîńĝ [ćôd́ê ćôv́êŕâǵê](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) ín̂ Ćĥŕôḿê D́êv́T̂óôĺŝ. Ýôú ĉán̂ íd̂én̂t́îf́ŷ t́ĥé t̂h́êḿê/ṕl̂úĝín̂ ŕêśp̂ón̂śîb́l̂é f̂ŕôḿ t̂h́ê ÚR̂Ĺ ôf́ t̂h́ê śĉŕîṕt̂. Ĺôók̂ óût́ f̂ór̂ ṕl̂úĝín̂ś t̂h́ât́ ĥáv̂é m̂án̂ý ŝćr̂íp̂t́ŝ ín̂ t́ĥé l̂íŝt́ ŵh́îćĥ h́âv́ê á l̂ót̂ óf̂ ŕêd́ îń ĉód̂é ĉóv̂ér̂áĝé.  ṕl̂úĝín̂ śĥóûĺd̂ ón̂ĺŷ én̂q́ûéûé â śĉŕîṕt̂ íf̂ ít̂ íŝ áĉt́ûál̂ĺŷ úŝéd̂ ón̂ t́ĥé p̂áĝé." + }, + "stack-packs/packs/wordpress.js | uses_long_cache_ttl": { + "message": "R̂éâd́ âb́ôút̂ [B́r̂óŵśêŕ Ĉáĉh́îńĝ ín̂ Ẃôŕd̂Ṕr̂éŝś](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching)." + }, + "stack-packs/packs/wordpress.js | uses_optimized_images": { + "message": "Ĉón̂śîd́êŕ ûśîńĝ án̂ [ím̂áĝé ôṕt̂ím̂íẑát̂íôń Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂](https://wordpress.org/plugins/search/optimize+images/) t́ĥát̂ ćôḿp̂ŕêśŝéŝ ýôúr̂ ím̂áĝéŝ ẃĥíl̂é r̂ét̂áîńîńĝ q́ûál̂ít̂ý." + }, + "stack-packs/packs/wordpress.js | uses_responsive_images": { + "message": "Ûṕl̂óâd́ îḿâǵêś d̂ír̂éĉt́l̂ý t̂h́r̂óûǵĥ t́ĥé [m̂éd̂íâ ĺîb́r̂ár̂ý](https://codex.wordpress.org/Media_Library_Screen) t̂ó êńŝúr̂é t̂h́ât́ t̂h́ê ŕêq́ûír̂éd̂ ím̂áĝé ŝíẑéŝ ár̂é âv́âíl̂áb̂ĺê, án̂d́ t̂h́êń îńŝér̂t́ t̂h́êḿ f̂ŕôḿ t̂h́ê ḿêd́îá l̂íb̂ŕâŕŷ ór̂ úŝé t̂h́ê ím̂áĝé ŵíd̂ǵêt́ t̂ó êńŝúr̂é t̂h́ê óp̂t́îḿâĺ îḿâǵê śîźêś âŕê úŝéd̂ (ín̂ćl̂úd̂ín̂ǵ t̂h́ôśê f́ôŕ t̂h́ê ŕêśp̂ón̂śîv́ê b́r̂éâḱp̂óîńt̂ś). Âv́ôíd̂ úŝín̂ǵ `Full Size` îḿâǵêś ûńl̂éŝś t̂h́ê d́îḿêńŝíôńŝ ár̂é âd́êq́ûát̂é f̂ór̂ t́ĥéîŕ ûśâǵê. [Ĺêár̂ń M̂ór̂é](https://codex.wordpress.org/Inserting_Images_into_Posts_and_Pages#Image_Size)." + }, + "stack-packs/packs/wordpress.js | uses_text_compression": { + "message": "Ŷóû ćâń êńâb́l̂é t̂éx̂t́ ĉóm̂ṕr̂éŝśîón̂ ín̂ ýôúr̂ ẃêb́ ŝér̂v́êŕ ĉón̂f́îǵûŕât́îón̂." + }, + "stack-packs/packs/wordpress.js | uses_webp_images": { + "message": "Ĉón̂śîd́êŕ ûśîńĝ á [p̂ĺûǵîń](https://wordpress.org/plugins/search/convert+webp/) ôŕ ŝér̂v́îćê t́ĥát̂ ẃîĺl̂ áût́ôḿât́îćâĺl̂ý ĉón̂v́êŕt̂ ýôúr̂ úp̂ĺôád̂éd̂ ím̂áĝéŝ t́ô t́ĥé ôṕt̂ím̂ál̂ f́ôŕm̂át̂ś." } } diff --git a/lighthouse-core/scripts/i18n/correct-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js similarity index 89% rename from lighthouse-core/scripts/i18n/correct-strings.js rename to lighthouse-core/scripts/i18n/bake-strings.js index a00608940238..42a481a73817 100644 --- a/lighthouse-core/scripts/i18n/correct-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -113,23 +113,28 @@ function saveLocaleStrings(path, output) { /** * @param {string} dir * @param {string} output + * @param {string} extension the file extension of the CTC files, '.ctc.json' is LH default, but '.json' when importing from Translators + * @returns {Array<string>} */ -function collectAllPreLocaleStrings(dir, output) { +function collectAndBakeCtcStrings(dir, output, extension = '.ctc.json') { + const lhl = []; for (const name of fs.readdirSync(dir)) { const fullPath = path.join(dir, name); const relativePath = fullPath;// path.relative(LH_ROOT, fullPath); if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; - if (name.endsWith('.json')) { + if (name.endsWith(extension)) { if (!process.env.CI) console.log('Correcting from', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); const strings = bakePlaceholders(preLocaleStrings); - saveLocaleStrings(output + path.basename(name), strings); + saveLocaleStrings(output + path.basename(name).replace('.ctc', ''), strings); + lhl.push(path.basename(name)); } } + return lhl; } module.exports = { - collectAllPreLocaleStrings, + collectAndBakeCtcStrings, bakePlaceholders, }; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 08511bbca017..a35de6f497c6 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -12,6 +12,7 @@ const fs = require('fs'); const mkdirp = require('mkdirp').sync; const path = require('path'); const esprima = require('esprima'); +const bakery = require('./bake-strings.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; @@ -414,8 +415,8 @@ function collectAllStringsInDir(dir, strings = {}) { * @param {string} locale * @param {Record<string, ICUMessageDefn>} strings */ -function writeStringsToLocaleFormat(locale, strings) { - const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/${locale}.json`); +function writeStringsToCtcFiles(locale, strings) { + const fullPath = path.join(LH_ROOT, `lighthouse-core/lib/i18n/locales/${locale}.ctc.json`); /** @type {Record<string, ICUMessageDefn>} */ const output = {}; const sortedEntries = Object.entries(strings).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); @@ -437,11 +438,18 @@ if (require.main === module) { // Make sure pre-locales exists since it is git-ignored mkdirp('lighthouse-core/lib/i18n/pre-locale'); - writeStringsToLocaleFormat('pre-locale/en-US', strings); - console.log('Written to disk!', 'pre-locale/en-US'); + writeStringsToCtcFiles('en-US', strings); + console.log('Written to disk!', 'en-US.ctc.json'); // Generate local pseudolocalized files for debugging while translating - writeStringsToLocaleFormat('pre-locale/en-XL', createPsuedoLocaleStrings(strings)); - console.log('Written to disk!', 'pre-locale/en-XL'); + writeStringsToCtcFiles('en-XL', createPsuedoLocaleStrings(strings)); + console.log('Written to disk!', 'en-XL.ctc.json'); + + // Bake the ctc en-US and en-XL files into en-US and en-XL LHL format + const lhl = bakery.collectAndBakeCtcStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/'), + path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/')); + lhl.forEach(function(locale) { + console.log(`Baked ${locale} into LHL format.`); + }); } module.exports = { diff --git a/lighthouse-core/scripts/i18n/pseudolocalize.js b/lighthouse-core/scripts/i18n/pseudolocalize.js deleted file mode 100644 index 44229d38b5ec..000000000000 --- a/lighthouse-core/scripts/i18n/pseudolocalize.js +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node -/** - * @license Copyright 2019 Google Inc. All Rights Reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -'use strict'; - -const cs = require('./correct-strings.js'); -const path = require('path'); - -const LH_ROOT = path.join(__dirname, '../../../'); - -cs.collectAllPreLocaleStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/pre-locale/'), - path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/')); diff --git a/lighthouse-core/test/scripts/i18n/correct-strings-test.js b/lighthouse-core/test/scripts/i18n/bake-strings-test.js similarity index 87% rename from lighthouse-core/test/scripts/i18n/correct-strings-test.js rename to lighthouse-core/test/scripts/i18n/bake-strings-test.js index 0fafa8150b20..0186a7e3079e 100644 --- a/lighthouse-core/test/scripts/i18n/correct-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/bake-strings-test.js @@ -7,7 +7,7 @@ /* eslint-env jest */ -const correct = require('../../../scripts/i18n/correct-strings.js'); +const bakery = require('../../../scripts/i18n/bake-strings.js'); describe('Baking Placeholders', () => { it('passthroughs a basic message unchanged', () => { @@ -16,7 +16,7 @@ describe('Baking Placeholders', () => { message: 'world', }, }; - const res = correct.bakePlaceholders(strings); + const res = bakery.bakePlaceholders(strings); expect(res).toEqual({ hello: { message: 'world', @@ -35,7 +35,7 @@ describe('Baking Placeholders', () => { }, }, }; - const res = correct.bakePlaceholders(strings); + const res = bakery.bakePlaceholders(strings); expect(res).toEqual({ hello: { message: '`World`', @@ -50,7 +50,7 @@ describe('Baking Placeholders', () => { message: '$MARKDOWN_SNIPPET_0$', }, }; - expect(() => correct.bakePlaceholders(strings)) + expect(() => bakery.bakePlaceholders(strings)) .toThrow(/Message "\$MARKDOWN_SNIPPET_0\$" is missing placeholder/); }); @@ -65,7 +65,7 @@ describe('Baking Placeholders', () => { }, }, }; - expect(() => correct.bakePlaceholders(strings)) + expect(() => bakery.bakePlaceholders(strings)) .toThrow(/Message "World" has extra placeholder "MARKDOWN_SNIPPET_0"/); }); }); diff --git a/package.json b/package.json index fc6d54938346..6a3a556e5021 100644 --- a/package.json +++ b/package.json @@ -53,9 +53,7 @@ "changelog": "conventional-changelog --config ./build/changelog-generator/index.js --infile changelog.md --same-file", "type-check": "tsc -p . && tsc -p lighthouse-viewer/", "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", - "i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js", - "i18n:correct-strings": "node lighthouse-core/scripts/i18n/pseudolocalize.js", - "i18n:collect-and-correct": "yarn i18n:collect-strings && yarn i18n:correct-strings", + "i18n": "node lighthouse-core/scripts/i18n/collect-strings", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", From dcc7cc7efeaa3c82ee7d1fea4f814eed3586360b Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 12 Jul 2019 11:15:20 -0700 Subject: [PATCH 39/71] Wording of CTC and LHL in readme and docstrings. Removed mkdirp. Added .ctc.json to yarn clean. --- lighthouse-core/lib/i18n/README.md | 20 +++++++++++++------ lighthouse-core/scripts/i18n/bake-strings.js | 8 ++++---- .../scripts/i18n/collect-strings.js | 4 ---- package.json | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 63bca2c90224..29bf58f03cf8 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -37,7 +37,7 @@ displayValue: `{pronoun, select, }`, ``` -## message.json Syntax +## message.json Syntax (CTC) ### Why we use message.json @@ -62,7 +62,17 @@ We needed a JS-friendly format supported by Google's Translation Console (TC). T } ``` -## Our message system +### Why do we call it CTC? + +CTC is a name that is distinct and identifies this as the Chrome translation format. "message.json" is ambiguous in our opinion and so throughout the docs we will refer to files that follow the "message.json" format as being "CTC" files. + +## Our message system (LHL) + +TODO(exterkamp): explain all the comments and where they go/what they become. + +TODO(exterkamp): explain why we can't use some ICU like number formatting. + +TODO(exterkamp): example of plural and ordinal. We use UIStrings & i18n.js to extract strings from individual js files into locale.json files. This allows us to keep strings close to the code in which they are used so that developers can easily understand their context. It also comes with its own syntax. @@ -154,11 +164,9 @@ ICU syntax is used throughout Lighthouse strings, and they are specified directl }; ``` -TODO(exterkamp): explain all the comments and where they go/what they become. - -TODO(exterkamp): explain why we can't use some ICU like number formatting. +### Why do we call it LHL? -TODO(exterkamp): example of plural and ordinal. +LHL is a name that is distinct and identifies this as the LightHouse Locale format. Since both LHL and CTC use `.json` files it is ambiguous, so LHL is the given name for UIString and locale/ formatted json files that are used by the underlying Lighthouse i18n engine. ### The pipeline diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index 42a481a73817..94d04ad8f610 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -34,10 +34,10 @@ const ignoredPathComponents = [ ]; /** - * Take a series of messages.json format ICU messages and converts them to - * lighthouse-i18n-json format by replacing $placeholders$ with their {ICU} - * values. Functional opposite of `convertMessageToPlaceholders`. This is - * commonly called as the last step in translation, via correct-strings.js. + * Take a series of CTC format ICU messages and converts them to LHL format by + * replacing $placeholders$ with their {ICU} values. Functional opposite of + * `convertMessageToPlaceholders`. This is commonly called as the last step in + * translation. * * Converts this: * messages: { diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index a35de6f497c6..94834d79ba8a 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -9,7 +9,6 @@ /* eslint-disable no-console, max-len */ const fs = require('fs'); -const mkdirp = require('mkdirp').sync; const path = require('path'); const esprima = require('esprima'); const bakery = require('./bake-strings.js'); @@ -435,9 +434,6 @@ if (require.main === module) { collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); console.log('Collected from Stack Packs!'); - // Make sure pre-locales exists since it is git-ignored - mkdirp('lighthouse-core/lib/i18n/pre-locale'); - writeStringsToCtcFiles('en-US', strings); console.log('Written to disk!', 'en-US.ctc.json'); // Generate local pseudolocalized files for debugging while translating diff --git a/package.json b/package.json index 6a3a556e5021..7df8402c8a15 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "build-devtools": "node ./build/build-bundle.js clients/devtools-entry.js dist/lighthouse-dt-bundle.js && node ./build/build-dt-report-resources.js", "build-lr": "node ./build/build-lightrider-bundles.js", "build-viewer": "node ./build/build-viewer.js", - "clean": "rimraf dist proto/scripts/*.json proto/scripts/*_pb2.* proto/scripts/*_pb.* proto/scripts/__pycache__ proto/scripts/*.pyc *.report.html *.report.dom.html *.report.json *.devtoolslog.json *.trace.json || true", + "clean": "rimraf dist proto/scripts/*.json proto/scripts/*_pb2.* proto/scripts/*_pb.* proto/scripts/__pycache__ proto/scripts/*.pyc *.report.html *.report.dom.html *.report.json *.devtoolslog.json *.trace.json lighthouse-core/lib/i18n/locales/*.ctc.json || true", "lint": "[ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .", "smoke": "node lighthouse-cli/test/smokehouse/run-smoke.js", "debug": "node --inspect-brk ./lighthouse-cli/index.js", From 7743cda319c3392945e5a6887a5e67ed0dc91357 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 12 Jul 2019 13:03:35 -0700 Subject: [PATCH 40/71] rip my hopes and dreams, thanks linter. --- lighthouse-core/scripts/i18n/bake-strings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index 94d04ad8f610..a206de778c11 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -36,7 +36,7 @@ const ignoredPathComponents = [ /** * Take a series of CTC format ICU messages and converts them to LHL format by * replacing $placeholders$ with their {ICU} values. Functional opposite of - * `convertMessageToPlaceholders`. This is commonly called as the last step in + * `convertMessageToPlaceholders`. This is commonly called as the last step in * translation. * * Converts this: From ce01c755176f9e3626141567f0c3664496bb71ed Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 12 Jul 2019 13:10:39 -0700 Subject: [PATCH 41/71] polish to package and to collect-strings --- lighthouse-core/scripts/i18n/collect-strings.js | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 94834d79ba8a..c69db4edec9c 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -100,8 +100,8 @@ function computeDescription(ast, property, value, startRange) { } /** - * Take a series of lighthouse-i18n-json format ICU messages and converts them - * to messages.json format by replacing {ICU} and `markdown` with + * Take a series of LHL format ICU messages and converts them + * to CTC format by replacing {ICU} and `markdown` with * $placeholders$. Functional opposite of `bakePlaceholders`. This is commonly * called as one of the first steps in translation, via collect-strings.js. * @@ -360,7 +360,7 @@ function collectAllStringsInDir(dir, strings = {}) { collectAllStringsInDir(fullPath, strings); } else { if (name.endsWith('.js')) { - if (!process.env.CI) console.log('- Collecting from', relativePath); + if (!process.env.CI) console.log('Collecting from', relativePath); const content = fs.readFileSync(fullPath, 'utf8'); const exportVars = require(fullPath); const regexMatches = !!UISTRINGS_REGEX.test(content); diff --git a/package.json b/package.json index 7df8402c8a15..d350cc71fab8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "changelog": "conventional-changelog --config ./build/changelog-generator/index.js --infile changelog.md --same-file", "type-check": "tsc -p . && tsc -p lighthouse-viewer/", "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", - "i18n": "node lighthouse-core/scripts/i18n/collect-strings", + "i18n": "node lighthouse-core/scripts/i18n/collect-strings.js", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", From dea280abbd585f12785e20165fdf5820fa0faac7 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Fri, 12 Jul 2019 13:41:58 -0700 Subject: [PATCH 42/71] better examples! --- lighthouse-core/audits/dobetterweb/appcache-manifest.js | 2 +- .../dobetterweb/external-anchors-use-rel-noopener.js | 2 +- lighthouse-core/audits/uses-rel-preconnect.js | 2 +- lighthouse-core/audits/uses-rel-preload.js | 2 +- lighthouse-core/lib/lh-error.js | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/appcache-manifest.js b/lighthouse-core/audits/dobetterweb/appcache-manifest.js index 26efe635f67a..5ddca8648085 100644 --- a/lighthouse-core/audits/dobetterweb/appcache-manifest.js +++ b/lighthouse-core/audits/dobetterweb/appcache-manifest.js @@ -23,7 +23,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).', /** * @description Label for the audit identifying uses of the Application Cache. - * @example {AppCacheManifest} AppCacheManifest + * @example {AppCacheManifest} clock.appcache */ displayValue: 'Found "{AppCacheManifest}"', }; diff --git a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js index ab4c8ed383f0..d28fe8778efb 100644 --- a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +++ b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js @@ -20,7 +20,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/noopener).', /** * @description Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety. - * @example {anchorHTML} <a> + * @example {anchorHTML} <a target="_blank"> * */ warning: 'Unable to determine the destination for anchor ({anchorHTML}). ' + 'If not used as a hyperlink, consider removing target=_blank.', diff --git a/lighthouse-core/audits/uses-rel-preconnect.js b/lighthouse-core/audits/uses-rel-preconnect.js index 2ea08d3a0d3c..0171b644946e 100644 --- a/lighthouse-core/audits/uses-rel-preconnect.js +++ b/lighthouse-core/audits/uses-rel-preconnect.js @@ -31,7 +31,7 @@ const UIStrings = { `connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, /** * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links. - * @example {securityOrigin} <link rel="preconnect" href="..."> + * @example {securityOrigin} https://example.com * */ crossoriginWarning: 'A preconnect <link> was found for "{securityOrigin}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', diff --git a/lighthouse-core/audits/uses-rel-preload.js b/lighthouse-core/audits/uses-rel-preload.js index ccd6b56cb303..9e668a31352c 100644 --- a/lighthouse-core/audits/uses-rel-preload.js +++ b/lighthouse-core/audits/uses-rel-preload.js @@ -22,7 +22,7 @@ const UIStrings = { 'currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).', /** * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links. - * @example {preloadURL} <link rel="preload" href="..."> + * @example {preloadURL} https://example.com * */ crossoriginWarning: 'A preload <link> was found for "{preloadURL}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index 1f76253e1ba1..30e0ad0fa43a 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -52,7 +52,7 @@ const UIStrings = { urlInvalid: 'The URL you have provided appears to be invalid.', /** * @description Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed. - * @example {protocolMethod} PROTOCOL_TIMEOUT + * @example {protocolMethod} Network.enable * */ protocolTimeout: 'Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})', /** Error message explaining that the requested page could not be resolved by the DNS server. */ @@ -63,13 +63,13 @@ const UIStrings = { criTimeout: 'Timeout waiting for initial Debugger Protocol connection.', /** * @description Error message explaning that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected. - * @example {artifactName} MISSING_REQUIRED_ARTIFACT + * @example {artifactName} WebAppManifest * */ missingRequiredArtifact: 'Required {artifactName} gatherer did not run.', /** * @description Error message explaning that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. - * @example {artifactName} Lighthouse Artifacts - * @example {errorMessage} ERRORED_REQUIRED_ARTIFACT + * @example {artifactName} WebAppManifest + * @example {errorMessage} Manifest invalid * */ erroredRequiredArtifact: 'Required {artifactName} gatherer encountered an error: {errorMessage}', }; From 7f89ccf70f9d7bf8111bf6989f063847af8b86a9 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 15 Jul 2019 09:24:48 -0700 Subject: [PATCH 43/71] correct some complex ICU, add backticks. --- lighthouse-core/audits/resource-summary.js | 2 +- lighthouse-core/audits/uses-rel-preload.js | 2 +- lighthouse-core/lib/i18n/locales/en-US.json | 4 ++-- lighthouse-core/lib/i18n/locales/en-XL.json | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js index 18bbf9d03f09..1c45de7408ba 100644 --- a/lighthouse-core/audits/resource-summary.js +++ b/lighthouse-core/audits/resource-summary.js @@ -17,7 +17,7 @@ const UIStrings = { ' add a budget.json file. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets).', /** [ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page. */ displayValue: `{requestCount, plural, =1 {1 request} other {# requests}}` + - ` • { byteCount, number, bytes } KB`, + ` • {byteCount, number, bytes} KB`, }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); diff --git a/lighthouse-core/audits/uses-rel-preload.js b/lighthouse-core/audits/uses-rel-preload.js index 9e668a31352c..a1e4f7561755 100644 --- a/lighthouse-core/audits/uses-rel-preload.js +++ b/lighthouse-core/audits/uses-rel-preload.js @@ -18,7 +18,7 @@ const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to use <link rel=preload> to initiate important network requests earlier during page load. This is displayed in a list of audit titles that Lighthouse generates. */ title: 'Preload key requests', /** Description of a Lighthouse audit that tells the user *why* they should preload important network requests. The associated network requests are started halfway through pageload (or later) but should be started at the beginning. This is displayed after a user expands the section to see more. No character length limits. '<link rel=preload>' is the html code the user would include in their page and shouldn't be translated. 'Learn More' becomes link text to additional documentation. */ - description: 'Consider using <link rel=preload> to prioritize fetching resources that are ' + + description: 'Consider using `<link rel=preload>` to prioritize fetching resources that are ' + 'currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).', /** * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links. diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 11d20950f270..f8afc38d009a 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -813,7 +813,7 @@ "message": "To set budgets for the quantity and size of page resources, add a budget.json file. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets)." }, "lighthouse-core/audits/resource-summary.js | displayValue": { - "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB" + "message": "{requestCount, plural, =1 {1 request} other {# requests}} • {byteCount, number, bytes} KB" }, "lighthouse-core/audits/resource-summary.js | title": { "message": "Keep request counts low and transfer sizes small" @@ -1035,7 +1035,7 @@ "message": "A preload <link> was found for \"{preloadURL}\" but was not used by the browser. Check that you are using the `crossorigin` attribute properly." }, "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload)." + "message": "Consider using `<link rel=preload>` to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload)." }, "lighthouse-core/audits/uses-rel-preload.js | title": { "message": "Preload key requests" diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index ca5ecafc447f..5163f673b3ce 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -813,7 +813,7 @@ "message": "T̂ó ŝét̂ b́ûd́ĝét̂ś f̂ór̂ t́ĥé q̂úâńt̂ít̂ý âńd̂ śîźê óf̂ ṕâǵê ŕêśôúr̂ćêś, âd́d̂ á b̂úd̂ǵêt́.ĵśôń f̂íl̂é. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/budgets)." }, "lighthouse-core/audits/resource-summary.js | displayValue": { - "message": "{requestCount, plural, =1 {1 r̂éq̂úêśt̂} other {# ŕêq́ûéŝt́ŝ}} • { byteCount, number, bytes } ḰB̂" + "message": "{requestCount, plural, =1 {1 r̂éq̂úêśt̂} other {# ŕêq́ûéŝt́ŝ}} • {byteCount, number, bytes} ḰB̂" }, "lighthouse-core/audits/resource-summary.js | title": { "message": "K̂éêṕ r̂éq̂úêśt̂ ćôún̂t́ŝ ĺôẃ âńd̂ t́r̂án̂śf̂ér̂ śîźêś ŝḿâĺl̂" @@ -1035,7 +1035,7 @@ "message": " ṕr̂él̂óâd́ <l̂ín̂ḱ> ŵáŝ f́ôún̂d́ f̂ór̂ \"{preloadURL}\" b́ût́ ŵáŝ ńôt́ ûśêd́ b̂ý t̂h́ê b́r̂óŵśêŕ. Ĉh́êćk̂ t́ĥát̂ ýôú âŕê úŝín̂ǵ t̂h́ê `crossorigin` át̂t́r̂íb̂út̂é p̂ŕôṕêŕl̂ý." }, "lighthouse-core/audits/uses-rel-preload.js | description": { - "message": "Ĉón̂śîd́êŕ ûśîńĝ <ĺîńk̂ ŕêĺ=p̂ŕêĺôád̂> t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/preload)." + "message": "Ĉón̂śîd́êŕ ûśîńĝ `<link rel=preload>` t́ô ṕr̂íôŕît́îźê f́êt́ĉh́îńĝ ŕêśôúr̂ćêś t̂h́ât́ âŕê ćûŕr̂én̂t́l̂ý r̂éq̂úêśt̂éd̂ ĺât́êŕ îń p̂áĝé l̂óâd́. [L̂éâŕn̂ ḿôŕê](https://developers.google.com/web/tools/lighthouse/audits/preload)." }, "lighthouse-core/audits/uses-rel-preload.js | title": { "message": "P̂ŕêĺôád̂ ḱêý r̂éq̂úêśt̂ś" From d1567379f9b5617f230a847f68166eeaf2087f38 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 15 Jul 2019 13:10:16 -0700 Subject: [PATCH 44/71] Update 'yarn update:sample-json' and json itself --- lighthouse-core/test/results/sample_v2.json | 2 +- package.json | 2 +- proto/sample_v2_round_trip.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index ea1424095902..e08b04fa9f57 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -762,7 +762,7 @@ "uses-rel-preload": { "id": "uses-rel-preload", "title": "Preload key requests", - "description": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).", + "description": "Consider using `<link rel=preload>` to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).", "score": 1, "scoreDisplayMode": "numeric", "numericValue": 0, diff --git a/package.json b/package.json index eb3bb82ecc41..573ece8a6e00 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", "i18n": "node lighthouse-core/scripts/i18n/collect-strings.js", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", - "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", + "update:sample-json": "yarn i18n && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", "ultradumbBenchmark": "./lighthouse-core/scripts/benchmark.js", "mixed-content": "./lighthouse-cli/index.js --chrome-flags='--headless' --preset=mixed-content", diff --git a/proto/sample_v2_round_trip.json b/proto/sample_v2_round_trip.json index 0c03c90c9db3..701c294324cc 100644 --- a/proto/sample_v2_round_trip.json +++ b/proto/sample_v2_round_trip.json @@ -3044,7 +3044,7 @@ "warnings": [] }, "uses-rel-preload": { - "description": "Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).", + "description": "Consider using `<link rel=preload>` to prioritize fetching resources that are currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).", "details": { "headings": [], "items": [], From 89410f89ea87ad5f49d2bd6404dbea6eb2ab7591 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 15 Jul 2019 13:16:55 -0700 Subject: [PATCH 45/71] Handle the TODOs in readme. --- lighthouse-core/lib/i18n/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 8eff11d75e7c..f15db0d65d30 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -69,10 +69,6 @@ See [Appendix A: How runtime string replacement works](#appendix) # Writing UIStrings with LHL -❗TODO(exterkamp): explain all the comments and where they go/what they become. - -❗TODO(exterkamp): explain why we can't use some ICU like number formatting. - We want to keep strings close to the code in which they are used so that developers can easily understand their context. We use `i18n.js` to extract the `UIStrings` strings from individual js files. LHL strings in each module are defined in a `UIStrings` object with the strings as its properties. JSDoc is sometimes used to provide additional information about each string. @@ -143,6 +139,8 @@ displayValue: `{itemCount, plural, }`, ``` +Note: Why are direct ICU and complex ICU placeholdered out, but Ordinals are not? Direct and complex ICU should not contain elements that need to be translated (Direct ICU replaces universal proper nouns, and Complex ICU replaces number formatting), while ordinals do need to be translated. Ordinals and selects are therefore handled specially, and do not need to be placeholdered out. + ### Selects A select ICU message is used when the message should select a sub-message based on the value of a variable `pronoun` in this case. This is often used for gender based selections, but can be used for any enum. Lighthouse does not use selects very often. From ea3616b13689196d9df6c5a8d19c2c2701603a87 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 15 Jul 2019 15:49:04 -0700 Subject: [PATCH 46/71] Added @meanings for all duplicated strings. --- .../audits/accessibility/audio-caption.js | 5 +++- .../audits/accessibility/axe-audit.js | 5 +++- .../audits/accessibility/input-image-alt.js | 10 +++++-- .../audits/accessibility/object-alt.js | 10 +++++-- .../audits/accessibility/video-caption.js | 10 +++++-- .../audits/accessibility/video-description.js | 10 +++++-- .../audits/dobetterweb/js-libraries.js | 4 +-- .../password-inputs-can-be-pasted-into.js | 5 +++- lighthouse-core/audits/seo/canonical.js | 5 +++- lighthouse-core/audits/seo/tap-targets.js | 4 +-- lighthouse-core/audits/user-timings.js | 4 +-- lighthouse-core/lib/i18n/i18n.js | 12 ++++++-- lighthouse-core/lib/i18n/locales/en-US.json | 12 ++------ lighthouse-core/lib/i18n/locales/en-XL.json | 12 ++------ lighthouse-core/scripts/i18n/bake-strings.js | 3 ++ .../scripts/i18n/collect-strings.js | 30 +++++++++++++++---- 16 files changed, 94 insertions(+), 47 deletions(-) diff --git a/lighthouse-core/audits/accessibility/audio-caption.js b/lighthouse-core/audits/accessibility/audio-caption.js index f3d265a2d262..f43e96c278b3 100644 --- a/lighthouse-core/audits/accessibility/audio-caption.js +++ b/lighthouse-core/audits/accessibility/audio-caption.js @@ -14,7 +14,10 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required. */ + /** + * @description Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required. + * @meaning 727144 + * */ title: '`<audio>` elements contain a `<track>` element with `[kind="captions"]`', /** Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<audio>` elements are missing a `<track>` element with ' + diff --git a/lighthouse-core/audits/accessibility/axe-audit.js b/lighthouse-core/audits/accessibility/axe-audit.js index bba59545af5a..ec849c5cb688 100644 --- a/lighthouse-core/audits/accessibility/axe-audit.js +++ b/lighthouse-core/audits/accessibility/axe-audit.js @@ -14,7 +14,10 @@ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Label of a table column that identifies HTML elements that have failed an audit. */ + /** + * @description Label of a table column that identifies HTML elements that have failed an audit. + * @meaning 1014809 + * */ failingElementsHeader: 'Failing Elements', }; diff --git a/lighthouse-core/audits/accessibility/input-image-alt.js b/lighthouse-core/audits/accessibility/input-image-alt.js index 3714e6f839cf..1a65f1a3b951 100644 --- a/lighthouse-core/audits/accessibility/input-image-alt.js +++ b/lighthouse-core/audits/accessibility/input-image-alt.js @@ -14,9 +14,15 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required. */ + /** + * @description Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required. + * @meaning 785503 + * */ title: '`<input type="image">` elements have `[alt]` text', - /** Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ + /** + * @description Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. + * @meaning 927328 + * */ failureTitle: '`<input type="image">` elements do not have `[alt]` text', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'When an image is being used as an `<input>` button, providing alternative ' + diff --git a/lighthouse-core/audits/accessibility/object-alt.js b/lighthouse-core/audits/accessibility/object-alt.js index ed78b6150d97..c94eaeffea97 100644 --- a/lighthouse-core/audits/accessibility/object-alt.js +++ b/lighthouse-core/audits/accessibility/object-alt.js @@ -14,9 +14,15 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required. */ + /** + * @description Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required. + * @meaning 471992 + * */ title: '`<object>` elements have `[alt]` text', - /** Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ + /** + * @description Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. + * @meaning 939038 + * */ failureTitle: '`<object>` elements do not have `[alt]` text', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Screen readers cannot translate non-text content. Adding alt text to ' + diff --git a/lighthouse-core/audits/accessibility/video-caption.js b/lighthouse-core/audits/accessibility/video-caption.js index d6aa0c72a873..c6ed117aa150 100644 --- a/lighthouse-core/audits/accessibility/video-caption.js +++ b/lighthouse-core/audits/accessibility/video-caption.js @@ -14,9 +14,15 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required. */ + /** + * @description Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required. + * @meaning 201662 + * */ title: '`<video>` elements contain a `<track>` element with `[kind="captions"]`', - /** Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ + /** + * @description Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. + * @meaning 140411 + * */ failureTitle: '`<video>` elements do not contain a `<track>` element ' + 'with `[kind="captions"]`.', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/accessibility/video-description.js b/lighthouse-core/audits/accessibility/video-description.js index 036aaaf86352..58b50fa1feb3 100644 --- a/lighthouse-core/audits/accessibility/video-description.js +++ b/lighthouse-core/audits/accessibility/video-description.js @@ -14,9 +14,15 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required. */ + /** + * @description Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required. + * @meaning 449684 + * */ title: '`<video>` elements contain a `<track>` element with `[kind="description"]`', - /** Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ + /** + * @description Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. + * @meaning 23134 + * */ failureTitle: '`<video>` elements do not contain a `<track>` element with ' + '`[kind="description"]`.', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/dobetterweb/js-libraries.js b/lighthouse-core/audits/dobetterweb/js-libraries.js index 684feb7192bd..7a30e9f8dd10 100644 --- a/lighthouse-core/audits/dobetterweb/js-libraries.js +++ b/lighthouse-core/audits/dobetterweb/js-libraries.js @@ -18,8 +18,6 @@ const UIStrings = { title: 'Detected JavaScript libraries', /** Description of a Lighthouse audit that tells the user what this audit is detecting. This is displayed after a user expands the section to see more. No character length limits. */ description: 'All front-end JavaScript libraries detected on the page.', - /** Label for a column in a data table; entries will be the names of the detected Javascript libraries. */ - columnName: 'Name', /** Label for a column in a data table; entries will be the version numbers of the detected Javascript libraries. */ columnVersion: 'Version', }; @@ -54,7 +52,7 @@ class JsLibrariesAudit extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'name', itemType: 'text', text: str_(UIStrings.columnName)}, + {key: 'name', itemType: 'text', text: str_(i18n.UIStrings.columnName)}, {key: 'version', itemType: 'text', text: str_(UIStrings.columnVersion)}, ]; const details = Audit.makeTableDetails(headings, libDetails, {}); diff --git a/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js b/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js index b417988ca634..f0304fda7025 100644 --- a/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js +++ b/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js @@ -16,7 +16,10 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Preventing password pasting undermines good security policy. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/password-pasting).', - /** Table column header for the HTML elements that do not allow pasting of content. */ + /** + * @description Table column header for the HTML elements that do not allow pasting of content. + * @meaning 979624 + * */ columnFailingElem: 'Failing Elements', }; diff --git a/lighthouse-core/audits/seo/canonical.js b/lighthouse-core/audits/seo/canonical.js index 0f44bfb8bc56..e80cc2b7d680 100644 --- a/lighthouse-core/audits/seo/canonical.js +++ b/lighthouse-core/audits/seo/canonical.js @@ -11,7 +11,10 @@ const MainResource = require('../../computed/main-resource.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. "rel=canonical" is an HTML attribute and value and so should not be translated. */ + /** + * @description Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. "rel=canonical" is an HTML attribute and value and so should not be translated. + * @meaning 665744 + * */ title: 'Document has a valid `rel=canonical`', /** Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is invalid and should be fixed. "rel=canonical" is an HTML attribute and value and so should not be translated. */ failureTitle: 'Document does not have a valid `rel=canonical`', diff --git a/lighthouse-core/audits/seo/tap-targets.js b/lighthouse-core/audits/seo/tap-targets.js index 125c2ba91fbf..ebe56de00326 100644 --- a/lighthouse-core/audits/seo/tap-targets.js +++ b/lighthouse-core/audits/seo/tap-targets.js @@ -31,8 +31,6 @@ const UIStrings = { description: 'Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. [Learn more](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design).', /** Label of a table column that identifies tap targets (like buttons and links) that have failed the audit and aren't easy to tap on. */ tapTargetHeader: 'Tap Target', - /** Label of a table column that specifies the size of tap targets like buttons and links. */ - sizeHeader: 'Size', /** Label of a table column that identifies a tap target (like a link or button) that overlaps with another tap target. */ overlappingTargetHeader: 'Overlapping Target', /** Explanatory message stating that there was a failure in an audit caused by the viewport meta tag not being optimized for mobile screens, which caused tap targets like buttons and links to be too small to tap on. */ @@ -303,7 +301,7 @@ class TapTargets extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'tapTarget', itemType: 'node', text: str_(UIStrings.tapTargetHeader)}, - {key: 'size', itemType: 'text', text: str_(UIStrings.sizeHeader)}, + {key: 'size', itemType: 'text', text: str_(i18n.UIStrings.columnSize)}, {key: 'overlappingTarget', itemType: 'node', text: str_(UIStrings.overlappingTargetHeader)}, ]; diff --git a/lighthouse-core/audits/user-timings.js b/lighthouse-core/audits/user-timings.js index 902c346381d2..9967e99e54c2 100644 --- a/lighthouse-core/audits/user-timings.js +++ b/lighthouse-core/audits/user-timings.js @@ -21,8 +21,6 @@ const UIStrings = { =1 {1 user timing} other {# user timings} }`, - /** Label for the Name column in the User Timing event data table. User Timing API entries are added by the developer of the web page. An example user timing event name: 'pageload_logoimage_done' */ - columnName: 'Name', /** Label for the Type column in the User Timing event data table. User Timing API entries are added by the developer of the web page. The only possible types are 'Mark' and Measure'. */ columnType: 'Type', /** Label for the Start Time column in the User Timing event data table. User Timing API entries are added by the developer of the web page. Start Times are the number of milliseconds since the page started loading, e.g. '380.26 ms' */ @@ -96,7 +94,7 @@ class UserTimings extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'name', itemType: 'text', text: str_(UIStrings.columnName)}, + {key: 'name', itemType: 'text', text: str_(i18n.UIStrings.columnName)}, {key: 'timingType', itemType: 'text', text: str_(UIStrings.columnType)}, {key: 'startTime', itemType: 'ms', granularity: 0.01, text: str_(UIStrings.columnStartTime)}, diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 868e72bcd18f..28300ac7e016 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -50,9 +50,15 @@ const UIStrings = { columnSize: 'Size', /** Label for a column in a data table; entries will be the time to live value of the cache header on a web resource. */ columnCacheTTL: 'Cache TTL', - /** Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions. */ + /** + * @description Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions. + * @meaning 601610 + * */ columnWastedBytes: 'Potential Savings', - /** Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. */ + /** + * @description Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. + * @meaning 449166 + * */ columnWastedMs: 'Potential Savings', /** Label for a column in a data table; entries will be the number of milliseconds spent during a particular activity. */ columnTimeSpent: 'Time Spent', @@ -64,6 +70,8 @@ const UIStrings = { columnRequests: 'Requests', /** Label for a column in a data table; entries will be the number of kilobytes transferred to load a set of files. */ columnTransferSize: 'Transfer Size', + /** Label for the Name column in the User Timing event data table. User Timing API entries are added by the developer of the web page. An example user timing event name: 'pageload_logoimage_done' */ + columnName: 'Name', /** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page. */ totalResourceType: 'Total', /** Label for a row in a data table; entries will be the total number and byte size of all 'Document' resources loaded by a web page. */ diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index f8afc38d009a..fdb2407426b3 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -557,9 +557,6 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Avoids requesting the geolocation permission on page load" }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnName": { - "message": "Name" - }, "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { "message": "Version" }, @@ -965,9 +962,6 @@ "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": { "message": "Overlapping Target" }, - "lighthouse-core/audits/seo/tap-targets.js | sizeHeader": { - "message": "Size" - }, "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": { "message": "Tap Target" }, @@ -1004,9 +998,6 @@ "lighthouse-core/audits/user-timings.js | columnDuration": { "message": "Duration" }, - "lighthouse-core/audits/user-timings.js | columnName": { - "message": "Name" - }, "lighthouse-core/audits/user-timings.js | columnStartTime": { "message": "Start Time" }, @@ -1178,6 +1169,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnLocation": { "message": "Location" }, + "lighthouse-core/lib/i18n/i18n.js | columnName": { + "message": "Name" + }, "lighthouse-core/lib/i18n/i18n.js | columnRequests": { "message": "Requests" }, diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 5163f673b3ce..199f7922eb20 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -557,9 +557,6 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Âv́ôíd̂ś r̂éq̂úêśt̂ín̂ǵ t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" }, - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnName": { - "message": "N̂ám̂é" - }, "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { "message": "V̂ér̂śîón̂" }, @@ -965,9 +962,6 @@ "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": { "message": "Ôv́êŕl̂áp̂ṕîńĝ T́âŕĝét̂" }, - "lighthouse-core/audits/seo/tap-targets.js | sizeHeader": { - "message": "Ŝíẑé" - }, "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": { "message": "T̂áp̂ T́âŕĝét̂" }, @@ -1004,9 +998,6 @@ "lighthouse-core/audits/user-timings.js | columnDuration": { "message": "D̂úr̂át̂íôń" }, - "lighthouse-core/audits/user-timings.js | columnName": { - "message": "N̂ám̂é" - }, "lighthouse-core/audits/user-timings.js | columnStartTime": { "message": "Ŝt́âŕt̂ T́îḿê" }, @@ -1178,6 +1169,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnLocation": { "message": "L̂óĉát̂íôń" }, + "lighthouse-core/lib/i18n/i18n.js | columnName": { + "message": "N̂ám̂é" + }, "lighthouse-core/lib/i18n/i18n.js | columnRequests": { "message": "R̂éq̂úêśt̂ś" }, diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index a206de778c11..021cfd90886e 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -15,6 +15,7 @@ const path = require('path'); * @typedef ICUMessageDefn * @property {string} message * @property {string} [description] + * @property {string} [meaning] * @property {Record<string, ICUPlaceholderDefn>} [placeholders] */ @@ -68,7 +69,9 @@ const ignoredPathComponents = [ */ function bakePlaceholders(messages) { for (const [_, defn] of Object.entries(messages)) { + // Don't need descriptions or meanings anymore. delete defn['description']; + delete defn['meaning']; let message = defn['message']; const placeholders = defn['placeholders']; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index c69db4edec9c..4bd5e8c81009 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -20,6 +20,7 @@ const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; * @typedef ICUMessageDefn * @property {string} message * @property {string} [description] + * @property {string} [meaning] * @property {Record<string, ICUPlaceholderDefn>} [placeholders] */ @@ -52,6 +53,9 @@ function computeDescription(ast, property, value, startRange) { /** @type {Record<string, string>} */ const examples = {}; + /** @type {string | undefined} */ + let meaning = undefined; + const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; let matches; while ((matches = r.exec(comment.value)) !== null) { @@ -67,6 +71,8 @@ function computeDescription(ast, property, value, startRange) { throw Error(`Example missing ICU replacement in message "${message}"`); } examples[placeholder.substring(1, placeholder.length - 1)] = message; + } else if (tagName === 'meaning') { + meaning = message; } } // Make sure all ICU vars have examples @@ -79,7 +85,7 @@ function computeDescription(ast, property, value, startRange) { // Make sure description is not empty if (description.length === 0) throw Error(`Empty @description for message "${value}"`); - return {description, examples}; + return {description, examples, meaning}; } const description = comment.value.replace('*', '').trim(); @@ -389,17 +395,29 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - const {description, examples} = computeDescription(ast, property, val, lastPropertyEndIndex); + const {description, examples, meaning} = computeDescription(ast, property, val, lastPropertyEndIndex); const converted = convertMessageToPlaceholders(val, examples); const messageKey = `${relativePath} | ${key}`; - if (Object.entries(converted.placeholders).length === 0 && converted.placeholders.constructor === Object) { - strings[messageKey] = {message: converted.message, description}; - } else { - strings[messageKey] = {message: converted.message, description, placeholders: converted.placeholders}; + /** @type {ICUMessageDefn} */ + const msg = { + message: converted.message, + description, + }; + + if (Object.entries(converted.placeholders).length > 0 && + converted.placeholders.constructor === Object) { + msg.placeholders = converted.placeholders; + } + + if (meaning) { + msg.meaning = meaning; } + + strings[messageKey] = msg; + lastPropertyEndIndex = property.range[1]; } } From 3d40437e51e77758916e88aaac1c33ea1bb66ec2 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 15 Jul 2019 15:50:12 -0700 Subject: [PATCH 47/71] update sample json --- lighthouse-core/test/results/sample_v2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index e08b04fa9f57..f097b4519abb 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -6017,7 +6017,7 @@ "lighthouse-core/audits/dobetterweb/js-libraries.js | description": [ "audits[js-libraries].description" ], - "lighthouse-core/audits/dobetterweb/js-libraries.js | columnName": [ + "lighthouse-core/lib/i18n/i18n.js | columnName": [ "audits[js-libraries].details.headings[0].text" ], "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": [ From bc2b8f3724f6a5557509059efa2ead59034db612 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 16 Jul 2019 15:01:19 -0700 Subject: [PATCH 48/71] remove from UIStrings, add autofilled meanings + warning log. --- .../audits/accessibility/audio-caption.js | 5 +-- .../audits/accessibility/axe-audit.js | 5 +-- .../audits/accessibility/input-image-alt.js | 10 ++---- .../audits/accessibility/object-alt.js | 10 ++---- .../audits/accessibility/video-caption.js | 10 ++---- .../audits/accessibility/video-description.js | 10 ++---- .../password-inputs-can-be-pasted-into.js | 5 +-- lighthouse-core/audits/seo/canonical.js | 5 +-- lighthouse-core/lib/i18n/i18n.js | 10 ++---- .../scripts/i18n/collect-strings.js | 34 ++++++++++++++----- 10 files changed, 39 insertions(+), 65 deletions(-) diff --git a/lighthouse-core/audits/accessibility/audio-caption.js b/lighthouse-core/audits/accessibility/audio-caption.js index f43e96c278b3..f3d265a2d262 100644 --- a/lighthouse-core/audits/accessibility/audio-caption.js +++ b/lighthouse-core/audits/accessibility/audio-caption.js @@ -14,10 +14,7 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required. - * @meaning 727144 - * */ + /** Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the successful state and is shown to users when no user action is required. */ title: '`<audio>` elements contain a `<track>` element with `[kind="captions"]`', /** Title of an accesibility audit that evaluates if all audio elements have a track element that has captions for screen readers. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<audio>` elements are missing a `<track>` element with ' + diff --git a/lighthouse-core/audits/accessibility/axe-audit.js b/lighthouse-core/audits/accessibility/axe-audit.js index ec849c5cb688..bba59545af5a 100644 --- a/lighthouse-core/audits/accessibility/axe-audit.js +++ b/lighthouse-core/audits/accessibility/axe-audit.js @@ -14,10 +14,7 @@ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Label of a table column that identifies HTML elements that have failed an audit. - * @meaning 1014809 - * */ + /** Label of a table column that identifies HTML elements that have failed an audit. */ failingElementsHeader: 'Failing Elements', }; diff --git a/lighthouse-core/audits/accessibility/input-image-alt.js b/lighthouse-core/audits/accessibility/input-image-alt.js index 1a65f1a3b951..3714e6f839cf 100644 --- a/lighthouse-core/audits/accessibility/input-image-alt.js +++ b/lighthouse-core/audits/accessibility/input-image-alt.js @@ -14,15 +14,9 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required. - * @meaning 785503 - * */ + /** Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the successful state and is shown to users when no user action is required. */ title: '`<input type="image">` elements have `[alt]` text', - /** - * @description Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. - * @meaning 927328 - * */ + /** Title of an accesibility audit that evaluates if all input elements of type image have an alt HTML attribute to describe their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<input type="image">` elements do not have `[alt]` text', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'When an image is being used as an `<input>` button, providing alternative ' + diff --git a/lighthouse-core/audits/accessibility/object-alt.js b/lighthouse-core/audits/accessibility/object-alt.js index c94eaeffea97..ed78b6150d97 100644 --- a/lighthouse-core/audits/accessibility/object-alt.js +++ b/lighthouse-core/audits/accessibility/object-alt.js @@ -14,15 +14,9 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required. - * @meaning 471992 - * */ + /** Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the successful state and is shown to users when no user action is required. */ title: '`<object>` elements have `[alt]` text', - /** - * @description Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. - * @meaning 939038 - * */ + /** Title of an accesibility audit that evaluates if all object elements have an alt HTML attribute that describes their contents. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<object>` elements do not have `[alt]` text', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Screen readers cannot translate non-text content. Adding alt text to ' + diff --git a/lighthouse-core/audits/accessibility/video-caption.js b/lighthouse-core/audits/accessibility/video-caption.js index c6ed117aa150..d6aa0c72a873 100644 --- a/lighthouse-core/audits/accessibility/video-caption.js +++ b/lighthouse-core/audits/accessibility/video-caption.js @@ -14,15 +14,9 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required. - * @meaning 201662 - * */ + /** Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required. */ title: '`<video>` elements contain a `<track>` element with `[kind="captions"]`', - /** - * @description Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. - * @meaning 140411 - * */ + /** Title of an accesibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<video>` elements do not contain a `<track>` element ' + 'with `[kind="captions"]`.', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/accessibility/video-description.js b/lighthouse-core/audits/accessibility/video-description.js index 58b50fa1feb3..036aaaf86352 100644 --- a/lighthouse-core/audits/accessibility/video-description.js +++ b/lighthouse-core/audits/accessibility/video-description.js @@ -14,15 +14,9 @@ const AxeAudit = require('./axe-audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required. - * @meaning 449684 - * */ + /** Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the successful state and is shown to users when no user action is required. */ title: '`<video>` elements contain a `<track>` element with `[kind="description"]`', - /** - * @description Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. - * @meaning 23134 - * */ + /** Title of an accesibility audit that evaluates if all video elements have child track elements that contain a description of the video content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */ failureTitle: '`<video>` elements do not contain a `<track>` element with ' + '`[kind="description"]`.', /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ diff --git a/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js b/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js index f0304fda7025..b417988ca634 100644 --- a/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js +++ b/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js @@ -16,10 +16,7 @@ const UIStrings = { /** Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ description: 'Preventing password pasting undermines good security policy. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/password-pasting).', - /** - * @description Table column header for the HTML elements that do not allow pasting of content. - * @meaning 979624 - * */ + /** Table column header for the HTML elements that do not allow pasting of content. */ columnFailingElem: 'Failing Elements', }; diff --git a/lighthouse-core/audits/seo/canonical.js b/lighthouse-core/audits/seo/canonical.js index e80cc2b7d680..0f44bfb8bc56 100644 --- a/lighthouse-core/audits/seo/canonical.js +++ b/lighthouse-core/audits/seo/canonical.js @@ -11,10 +11,7 @@ const MainResource = require('../../computed/main-resource.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** - * @description Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. "rel=canonical" is an HTML attribute and value and so should not be translated. - * @meaning 665744 - * */ + /** Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is valid. "rel=canonical" is an HTML attribute and value and so should not be translated. */ title: 'Document has a valid `rel=canonical`', /** Title of a Lighthouse audit that provides detail on a page's rel=canonical link. This descriptive title is shown to users when the rel=canonical link is invalid and should be fixed. "rel=canonical" is an HTML attribute and value and so should not be translated. */ failureTitle: 'Document does not have a valid `rel=canonical`', diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 28300ac7e016..5cd1e6df80a4 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -50,15 +50,9 @@ const UIStrings = { columnSize: 'Size', /** Label for a column in a data table; entries will be the time to live value of the cache header on a web resource. */ columnCacheTTL: 'Cache TTL', - /** - * @description Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions. - * @meaning 601610 - * */ + /** Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions. */ columnWastedBytes: 'Potential Savings', - /** - * @description Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. - * @meaning 449166 - * */ + /** Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. */ columnWastedMs: 'Potential Savings', /** Label for a column in a data table; entries will be the number of milliseconds spent during a particular activity. */ columnTimeSpent: 'Time Spent', diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 4bd5e8c81009..69f4d1988068 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -53,9 +53,6 @@ function computeDescription(ast, property, value, startRange) { /** @type {Record<string, string>} */ const examples = {}; - /** @type {string | undefined} */ - let meaning = undefined; - const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; let matches; while ((matches = r.exec(comment.value)) !== null) { @@ -71,8 +68,6 @@ function computeDescription(ast, property, value, startRange) { throw Error(`Example missing ICU replacement in message "${message}"`); } examples[placeholder.substring(1, placeholder.length - 1)] = message; - } else if (tagName === 'meaning') { - meaning = message; } } // Make sure all ICU vars have examples @@ -85,7 +80,7 @@ function computeDescription(ast, property, value, startRange) { // Make sure description is not empty if (description.length === 0) throw Error(`Empty @description for message "${value}"`); - return {description, examples, meaning}; + return {description, examples}; } const description = comment.value.replace('*', '').trim(); @@ -352,6 +347,12 @@ function createPsuedoLocaleStrings(messages) { return psuedoLocalizedStrings; } +/** @type {Map<string, string>} */ +const seenStrings = new Map(); + +/** @type {number} */ +let collisions = 0; + /** * @param {string} dir * @param {Record<string, ICUMessageDefn>} strings @@ -395,7 +396,7 @@ function collectAllStringsInDir(dir, strings = {}) { for (const property of stmt.declarations[0].init.properties) { const key = property.key.name; const val = exportVars.UIStrings[key]; - const {description, examples, meaning} = computeDescription(ast, property, val, lastPropertyEndIndex); + const {description, examples} = computeDescription(ast, property, val, lastPropertyEndIndex); const converted = convertMessageToPlaceholders(val, examples); @@ -412,10 +413,21 @@ function collectAllStringsInDir(dir, strings = {}) { msg.placeholders = converted.placeholders; } - if (meaning) { - msg.meaning = meaning; + // check for duplicates, if duplicate, add description as meaning to both + if (seenStrings.has(msg.message)) { + msg.meaning = msg.description; + const id = seenStrings.get(msg.message); + if (!id) throw new Error('Message has collision, but collision not recorded.'); + if (!strings[id].meaning) { + strings[id].meaning = strings[id].description; + collisions++; + } + collisions++; } + seenStrings.set(msg.message, messageKey); + + strings[messageKey] = msg; lastPropertyEndIndex = property.range[1]; @@ -452,6 +464,10 @@ if (require.main === module) { collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings); console.log('Collected from Stack Packs!'); + if ((collisions) > 0) { + console.log(`MEANING COLLISION: ${collisions} string(s) have the same content.`); + } + writeStringsToCtcFiles('en-US', strings); console.log('Written to disk!', 'en-US.ctc.json'); // Generate local pseudolocalized files for debugging while translating From 92cafeb412873b6635106c03d30782e2f708ea93 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 16 Jul 2019 15:05:48 -0700 Subject: [PATCH 49/71] Some comments --- lighthouse-core/scripts/i18n/collect-strings.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 69f4d1988068..911f844a4720 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -413,11 +413,12 @@ function collectAllStringsInDir(dir, strings = {}) { msg.placeholders = converted.placeholders; } - // check for duplicates, if duplicate, add description as meaning to both + // check for duplicates, if duplicate, add @description as @meaning to both if (seenStrings.has(msg.message)) { msg.meaning = msg.description; const id = seenStrings.get(msg.message); - if (!id) throw new Error('Message has collision, but collision not recorded.'); + // Shouldn't be able to get here, but ts wants a check. + if (!id) throw new Error('Message has collision, but collision not recorded in seen.'); if (!strings[id].meaning) { strings[id].meaning = strings[id].description; collisions++; From 3d746d62666147fa023300b515596b71f0ac9406 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 16 Jul 2019 15:07:04 -0700 Subject: [PATCH 50/71] added TODO to collect-strings --- lighthouse-core/scripts/i18n/collect-strings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 911f844a4720..17595cfbd753 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -466,6 +466,7 @@ if (require.main === module) { console.log('Collected from Stack Packs!'); if ((collisions) > 0) { + // TODO(exterkamp): assert that this number is constant to prevent unexpected dupes. console.log(`MEANING COLLISION: ${collisions} string(s) have the same content.`); } From c2e4ce5a13e38148511433b5ff176c7cc8526010 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 17 Jul 2019 16:44:36 -0700 Subject: [PATCH 51/71] Paul foodback. --- lighthouse-core/lib/i18n/i18n.js | 2 +- lighthouse-core/scripts/i18n/bake-strings.js | 11 ++++++----- lighthouse-core/scripts/i18n/collect-strings.js | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index ed70ba0ea6f7..ec1406f309bc 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -195,7 +195,7 @@ function _formatIcuMessage(locale, icuMessageId, uiStringMessage, values) { // Warn the user that the UIString message != the `en` message ∴ they should update the strings if (LOCALES['en'][icuMessageId] && localeMessage !== LOCALES['en'][icuMessageId].message) { log.warn('i18n', `Message "${icuMessageId}" does not match its 'en' counterpart. ` + - `Run 'collect-and-correct' to update.`); + `Run 'i18n' to update.`); } } // At this point, there is no reasonable string to show to the user, so throw. diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index 021cfd90886e..d97c1914b02e 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -11,6 +11,8 @@ const fs = require('fs'); const path = require('path'); +const LH_ROOT = path.join(__dirname, '../../../'); + /** * @typedef ICUMessageDefn * @property {string} message @@ -116,18 +118,17 @@ function saveLocaleStrings(path, output) { /** * @param {string} dir * @param {string} output - * @param {string} extension the file extension of the CTC files, '.ctc.json' is LH default, but '.json' when importing from Translators * @returns {Array<string>} */ -function collectAndBakeCtcStrings(dir, output, extension = '.ctc.json') { +function collectAndBakeCtcStrings(dir, output) { const lhl = []; for (const name of fs.readdirSync(dir)) { const fullPath = path.join(dir, name); - const relativePath = fullPath;// path.relative(LH_ROOT, fullPath); + const relativePath = path.relative(LH_ROOT, fullPath); if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; - if (name.endsWith(extension)) { - if (!process.env.CI) console.log('Correcting from', relativePath); + if (name.endsWith('.ctc.json')) { + if (!process.env.CI) console.log('Baking', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); const strings = bakePlaceholders(preLocaleStrings); saveLocaleStrings(output + path.basename(name).replace('.ctc', ''), strings); diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 17595cfbd753..c5d7084c3934 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -159,7 +159,8 @@ function convertMessageToPlaceholders(message, examples = {}) { */ function _processPlaceholderMarkdownCode(icu) { // Check that number of backticks is even. - if ((icu.message.split('`').length - 1) % 2 !== 0) { + const match = icu.message.match(/`/g); + if (match && match.length % 2 !== 0) { throw Error(`Open backtick in message "${icu.message}"`); } From 5dd3e07c5eb373b6fc3a1e17ef84763b82bad30e Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Wed, 17 Jul 2019 23:46:17 -0700 Subject: [PATCH 52/71] Brendan baking foodback part 1. --- lighthouse-core/scripts/i18n/bake-strings.js | 63 +++++++------------ .../scripts/i18n/collect-strings.js | 7 +++ 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index d97c1914b02e..0308637d5fd0 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -6,7 +6,7 @@ */ 'use strict'; -/* eslint-disable no-console, max-len */ +/* eslint-disable no-console */ const fs = require('fs'); const path = require('path'); @@ -27,15 +27,6 @@ const LH_ROOT = path.join(__dirname, '../../../'); * @property {string} [example] */ -const ignoredPathComponents = [ - '/.git', - '/scripts', - '/node_modules', - '/test/', - '-test.js', - '-renderer.js', -]; - /** * Take a series of CTC format ICU messages and converts them to LHL format by * replacing $placeholders$ with their {ICU} values. Functional opposite of @@ -67,23 +58,20 @@ const ignoredPathComponents = [ * value in the placeholders object, or vice versa. * * @param {Record<string, ICUMessageDefn>} messages - * @returns {Record<string, ICUMessageDefn>} + * @returns {Record<string, {message: string}>} */ function bakePlaceholders(messages) { - for (const [_, defn] of Object.entries(messages)) { - // Don't need descriptions or meanings anymore. - delete defn['description']; - delete defn['meaning']; - - let message = defn['message']; - const placeholders = defn['placeholders']; + /** @type {Record<string, ICUMessageDefn>} */ + const bakedMessages = {}; - for (const placeholder in placeholders) { - if (!Object.prototype.hasOwnProperty.call(placeholders, placeholder)) continue; + for (const [key, defn] of Object.entries(messages)) { + let message = defn.message; + const placeholders = defn.placeholders; - const content = placeholders[placeholder]['content']; + if (!placeholders) continue; + for (const [placeholder, {content}] of Object.entries(placeholders)) { if (!message.includes(`$${placeholder}$`)) { - throw Error(`Message "${message}" has extra placeholder "${placeholder}"`); + throw Error(`Provided placeholder "${placeholder}" not found in message "${message}".`); } message = message.replace(`$${placeholder}$`, content); } @@ -91,15 +79,13 @@ function bakePlaceholders(messages) { // Sanity check that all placeholders are gone if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); - defn['message'] = message; - - delete defn['placeholders']; + bakedMessages[key] = {message}; } - return messages; + return bakedMessages; } /** - * @param {*} file + * @param {string} file */ function collectPreLocaleStrings(file) { const rawdata = fs.readFileSync(file, 'utf8'); @@ -108,31 +94,30 @@ function collectPreLocaleStrings(file) { } /** - * @param {*} path - * @param {*} output + * @param {string} path + * @param {Record<string, ICUMessageDefn>} localeStrings */ -function saveLocaleStrings(path, output) { - fs.writeFileSync(path, JSON.stringify(output, null, 2) + '\n'); +function saveLocaleStrings(path, localeStrings) { + fs.writeFileSync(path, JSON.stringify(localeStrings, null, 2) + '\n'); } /** * @param {string} dir - * @param {string} output + * @param {string} outputDir * @returns {Array<string>} */ -function collectAndBakeCtcStrings(dir, output) { +function collectAndBakeCtcStrings(dir, outputDir) { const lhl = []; - for (const name of fs.readdirSync(dir)) { - const fullPath = path.join(dir, name); + for (const filename of fs.readdirSync(dir)) { + const fullPath = path.join(dir, filename); const relativePath = path.relative(LH_ROOT, fullPath); - if (ignoredPathComponents.some(p => fullPath.includes(p))) continue; - if (name.endsWith('.ctc.json')) { + if (filename.endsWith('.ctc.json')) { if (!process.env.CI) console.log('Baking', relativePath); const preLocaleStrings = collectPreLocaleStrings(relativePath); const strings = bakePlaceholders(preLocaleStrings); - saveLocaleStrings(output + path.basename(name).replace('.ctc', ''), strings); - lhl.push(path.basename(name)); + saveLocaleStrings(outputDir + path.basename(filename).replace('.ctc', ''), strings); + lhl.push(path.basename(filename)); } } return lhl; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index c5d7084c3934..26a2f527111a 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -37,6 +37,13 @@ const ignoredPathComponents = [ '/test/', '-test.js', '-renderer.js', + // Windows + '\\.git', + '\\scripts', + '\\node_modules', + '\\test\\', + '-test.js', + '-renderer.js', ]; From 6eef366e41d499a0d7e52c69f741ffe4147865da Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 00:02:21 -0700 Subject: [PATCH 53/71] update bakery, and tests. Remove space from yarn clean. --- lighthouse-core/scripts/i18n/bake-strings.js | 13 ++++++++----- .../test/scripts/i18n/bake-strings-test.js | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index 0308637d5fd0..61b4cef5bd9f 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -65,15 +65,17 @@ function bakePlaceholders(messages) { const bakedMessages = {}; for (const [key, defn] of Object.entries(messages)) { + let message = defn.message; const placeholders = defn.placeholders; - if (!placeholders) continue; - for (const [placeholder, {content}] of Object.entries(placeholders)) { - if (!message.includes(`$${placeholder}$`)) { - throw Error(`Provided placeholder "${placeholder}" not found in message "${message}".`); + if (placeholders) { + for (const [placeholder, {content}] of Object.entries(placeholders)) { + if (!message.includes(`$${placeholder}$`)) { + throw Error(`Provided placeholder "${placeholder}" not found in message "${message}".`); + } + message = message.replace(`$${placeholder}$`, content); } - message = message.replace(`$${placeholder}$`, content); } // Sanity check that all placeholders are gone @@ -81,6 +83,7 @@ function bakePlaceholders(messages) { bakedMessages[key] = {message}; } + return bakedMessages; } diff --git a/lighthouse-core/test/scripts/i18n/bake-strings-test.js b/lighthouse-core/test/scripts/i18n/bake-strings-test.js index 0186a7e3079e..5433e7d747a0 100644 --- a/lighthouse-core/test/scripts/i18n/bake-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/bake-strings-test.js @@ -66,6 +66,6 @@ describe('Baking Placeholders', () => { }, }; expect(() => bakery.bakePlaceholders(strings)) - .toThrow(/Message "World" has extra placeholder "MARKDOWN_SNIPPET_0"/); + .toThrow(/Provided placeholder "MARKDOWN_SNIPPET_0" not found in message "World"./); }); }); diff --git a/package.json b/package.json index d00b32a6497f..af1a4ecaa42e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "build-devtools": "node ./build/build-bundle.js clients/devtools-entry.js dist/lighthouse-dt-bundle.js && node ./build/build-dt-report-resources.js", "build-lr": "node ./build/build-lightrider-bundles.js", "build-viewer": "node ./build/build-viewer.js", - "clean": "rimraf dist proto/scripts/*.json proto/scripts/*_pb2.* proto/scripts/*_pb.* proto/scripts/__pycache__ proto/scripts/*.pyc *.report.html *.report.dom.html *.report.json *.devtoolslog.json *.trace.json lighthouse-core/lib/i18n/locales/*.ctc.json || true", + "clean": "rimraf dist proto/scripts/*.json proto/scripts/*_pb2.* proto/scripts/*_pb.* proto/scripts/__pycache__ proto/scripts/*.pyc *.report.html *.report.dom.html *.report.json *.devtoolslog.json *.trace.json lighthouse-core/lib/i18n/locales/*.ctc.json || true", "lint": "[ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .", "smoke": "node lighthouse-cli/test/smokehouse/run-smoke.js", "debug": "node --inspect-brk ./lighthouse-cli/index.js", From a35a45e2b068347f66e7f02cf9ce7c3f468d91b2 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 00:13:10 -0700 Subject: [PATCH 54/71] lint --- lighthouse-core/scripts/i18n/bake-strings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-strings.js index 61b4cef5bd9f..83a0aa0cfc68 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-strings.js @@ -65,7 +65,6 @@ function bakePlaceholders(messages) { const bakedMessages = {}; for (const [key, defn] of Object.entries(messages)) { - let message = defn.message; const placeholders = defn.placeholders; From 13d0f02dc73116c93ec2c8dc29db103bbf166f51 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 11:45:22 -0700 Subject: [PATCH 55/71] foodback round 2, renaming party. --- .../i18n/{bake-strings.js => bake-ctc-to-lhl.js} | 13 ++++++++----- lighthouse-core/scripts/i18n/collect-strings.js | 16 ++-------------- ...e-strings-test.js => bake-ctc-to-lhl-test.js} | 8 ++++---- 3 files changed, 14 insertions(+), 23 deletions(-) rename lighthouse-core/scripts/i18n/{bake-strings.js => bake-ctc-to-lhl.js} (89%) rename lighthouse-core/test/scripts/i18n/{bake-strings-test.js => bake-ctc-to-lhl-test.js} (83%) diff --git a/lighthouse-core/scripts/i18n/bake-strings.js b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js similarity index 89% rename from lighthouse-core/scripts/i18n/bake-strings.js rename to lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js index 83a0aa0cfc68..34c5118c03c4 100644 --- a/lighthouse-core/scripts/i18n/bake-strings.js +++ b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js @@ -78,7 +78,9 @@ function bakePlaceholders(messages) { } // Sanity check that all placeholders are gone - if (message.match(/\$\w+\$/)) throw Error(`Message "${message}" is missing placeholder`); + if (message.match(/\$\w+\$/)) { + throw Error(`Message "${message}" is missing placeholder(s): ${message.match(/\$\w+\$/g)}`); + } bakedMessages[key] = {message}; } @@ -89,7 +91,7 @@ function bakePlaceholders(messages) { /** * @param {string} file */ -function collectPreLocaleStrings(file) { +function collectCtcStrings(file) { const rawdata = fs.readFileSync(file, 'utf8'); const messages = JSON.parse(rawdata); return messages; @@ -116,9 +118,10 @@ function collectAndBakeCtcStrings(dir, outputDir) { if (filename.endsWith('.ctc.json')) { if (!process.env.CI) console.log('Baking', relativePath); - const preLocaleStrings = collectPreLocaleStrings(relativePath); - const strings = bakePlaceholders(preLocaleStrings); - saveLocaleStrings(outputDir + path.basename(filename).replace('.ctc', ''), strings); + const ctcStrings = collectCtcStrings(relativePath); + const strings = bakePlaceholders(ctcStrings); + const outputFile = outputDir + path.basename(filename).replace('.ctc', ''); + saveLocaleStrings(outputFile, strings); lhl.push(path.basename(filename)); } } diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 26a2f527111a..f6f55ad4f98f 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -11,24 +11,12 @@ const fs = require('fs'); const path = require('path'); const esprima = require('esprima'); -const bakery = require('./bake-strings.js'); +const bakery = require('./bake-ctc-to-lhl.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; -/** - * @typedef ICUMessageDefn - * @property {string} message - * @property {string} [description] - * @property {string} [meaning] - * @property {Record<string, ICUPlaceholderDefn>} [placeholders] - */ - -/** - * @typedef ICUPlaceholderDefn - * @property {string} content - * @property {string} [example] - */ +/** @typedef {import('./bake-ctc-to-lhl.js').ICUMessageDefn} ICUMessageDefn */ const ignoredPathComponents = [ '/.git', diff --git a/lighthouse-core/test/scripts/i18n/bake-strings-test.js b/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js similarity index 83% rename from lighthouse-core/test/scripts/i18n/bake-strings-test.js rename to lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js index 5433e7d747a0..9632f1cfe41d 100644 --- a/lighthouse-core/test/scripts/i18n/bake-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js @@ -7,7 +7,7 @@ /* eslint-env jest */ -const bakery = require('../../../scripts/i18n/bake-strings.js'); +const bakery = require('../../../scripts/i18n/bake-ctc-to-lhl.js'); describe('Baking Placeholders', () => { it('passthroughs a basic message unchanged', () => { @@ -47,11 +47,11 @@ describe('Baking Placeholders', () => { it('throws when a placeholder cannot be found', () => { const strings = { hello: { - message: '$MARKDOWN_SNIPPET_0$', + message: 'Hello $MARKDOWN_SNIPPET_0$ $MARKDOWN_SNIPPET_1$', }, }; - expect(() => bakery.bakePlaceholders(strings)) - .toThrow(/Message "\$MARKDOWN_SNIPPET_0\$" is missing placeholder/); + // eslint-disable-next-line max-len + expect(() => bakery.bakePlaceholders(strings)).toThrow(/Message "Hello \$MARKDOWN_SNIPPET_0\$ \$MARKDOWN_SNIPPET_1\$" is missing placeholder\(s\): \$MARKDOWN_SNIPPET_0\$,\$MARKDOWN_SNIPPET_1\$/); }); it('throws when a placeholder is not in string', () => { From b34ef9551978de2b45d4fa51a9a760a32bbf5bf8 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 12:01:28 -0700 Subject: [PATCH 56/71] Last part of feedback --- lighthouse-core/lib/i18n/README.md | 10 +++++----- lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js | 13 +++++++------ package.json | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index f15db0d65d30..65c4ca2cada0 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -19,8 +19,8 @@ The collection and translation pipeline: +----------------------------| | | lighthouse-core/lib/i18n/locales/*.json |-<+ +---------------------------+ | | || | | | +----------------------------------------------| | - | | +---------------------------------------------+ | - $ yarn i18n +--------------------+ | + $ yarn | | +---------------------------------------------+ | + i18n:collect-strings +--------------------+ | | | v ▐ ▐ +---------------+ | +------------+------+ ▐ Google TC Pipeline ▐ +->| *.ctc.json |---+ @@ -36,7 +36,7 @@ To a typical developer, the pipeline looks like this: ```shell # collect UIStrings and bake the en-US & en-XL locales -$ yarn i18n +$ yarn i18n:collect-strings # Test to see that the new translations are valid and apply to all strings $ node lighthouse-core/scripts/build-report-for-autodeployment.js && open dist/xl-accented/index.html @@ -50,7 +50,7 @@ Note: Why do `en-US` and `en-XL` get baked early? We write all our strings in ` ```shell # collect UIStrings (to make sure everything is up to date) -$ yarn i18n +$ yarn i18n:collect-strings # Extract the CTC format files to translation console $ sh import-source-from-github.sh @@ -119,7 +119,7 @@ const UIStrings = { `{timeInMs, number, milliseconds}` is called _Complex ICU_ since the replacement is for numbers and other complex replacements that use the custom formatters in Lighthouse. The supported complex ICU formats are: `milliseconds`, `seconds`, `bytes`, `percent`, and `extendedPercent`. -These complex ICU formats are automatically given @example values during `yarn i18n`. Therefore, a normal description string can be used: +These complex ICU formats are automatically given @example values during `yarn i18n:collect-strings`. Therefore, a normal description string can be used: ```javascript const UIStrings = { diff --git a/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js index 34c5118c03c4..50da0e1c7eb3 100644 --- a/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js +++ b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js @@ -70,10 +70,11 @@ function bakePlaceholders(messages) { if (placeholders) { for (const [placeholder, {content}] of Object.entries(placeholders)) { - if (!message.includes(`$${placeholder}$`)) { + const escapedPlaceholder = '$' + placeholder + '$'; + if (!message.includes(escapedPlaceholder)) { throw Error(`Provided placeholder "${placeholder}" not found in message "${message}".`); } - message = message.replace(`$${placeholder}$`, content); + message = message.replace(escapedPlaceholder, content); } } @@ -91,7 +92,7 @@ function bakePlaceholders(messages) { /** * @param {string} file */ -function collectCtcStrings(file) { +function loadCtcStrings(file) { const rawdata = fs.readFileSync(file, 'utf8'); const messages = JSON.parse(rawdata); return messages; @@ -101,7 +102,7 @@ function collectCtcStrings(file) { * @param {string} path * @param {Record<string, ICUMessageDefn>} localeStrings */ -function saveLocaleStrings(path, localeStrings) { +function saveLhlStrings(path, localeStrings) { fs.writeFileSync(path, JSON.stringify(localeStrings, null, 2) + '\n'); } @@ -118,10 +119,10 @@ function collectAndBakeCtcStrings(dir, outputDir) { if (filename.endsWith('.ctc.json')) { if (!process.env.CI) console.log('Baking', relativePath); - const ctcStrings = collectCtcStrings(relativePath); + const ctcStrings = loadCtcStrings(relativePath); const strings = bakePlaceholders(ctcStrings); const outputFile = outputDir + path.basename(filename).replace('.ctc', ''); - saveLocaleStrings(outputFile, strings); + saveLhlStrings(outputFile, strings); lhl.push(path.basename(filename)); } } diff --git a/package.json b/package.json index af1a4ecaa42e..e749a973d37f 100644 --- a/package.json +++ b/package.json @@ -53,9 +53,9 @@ "changelog": "conventional-changelog --config ./build/changelog-generator/index.js --infile changelog.md --same-file", "type-check": "tsc -p . && tsc -p lighthouse-viewer/", "i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh", - "i18n": "node lighthouse-core/scripts/i18n/collect-strings.js", + "i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js", "update:sample-artifacts": "node lighthouse-core/scripts/update-report-fixtures.js", - "update:sample-json": "yarn i18n && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", + "update:sample-json": "yarn i18n:collect-strings && node ./lighthouse-cli -A=./lighthouse-core/test/results/artifacts --config-path=./lighthouse-core/test/results/sample-config.js --output=json --output-path=./lighthouse-core/test/results/sample_v2.json && node lighthouse-core/scripts/cleanup-LHR-for-diff.js ./lighthouse-core/test/results/sample_v2.json --only-remove-timing && yarn compile-proto && yarn build-proto-roundtrip", "diff:sample-json": "yarn i18n:checks && bash lighthouse-core/scripts/assert-golden-lhr-unchanged.sh", "ultradumbBenchmark": "./lighthouse-core/scripts/benchmark.js", "mixed-content": "./lighthouse-cli/index.js --chrome-flags='--headless' --preset=mixed-content", From 48283f407ef5c98078323a1694ac4e1017591cb5 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 12:02:29 -0700 Subject: [PATCH 57/71] windows compat collect-strings handled in appropriate PR. --- lighthouse-core/scripts/i18n/collect-strings.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index f6f55ad4f98f..99eaac7b914a 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -25,13 +25,6 @@ const ignoredPathComponents = [ '/test/', '-test.js', '-renderer.js', - // Windows - '\\.git', - '\\scripts', - '\\node_modules', - '\\test\\', - '-test.js', - '-renderer.js', ]; From 95527d5c8922af6196498fa4dca8e1d8c1f4e2a2 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 23:24:22 -0700 Subject: [PATCH 58/71] Brendan foodback part 2. --- lighthouse-core/lib/i18n/i18n.js | 4 ++-- lighthouse-core/lib/lh-error.js | 1 - lighthouse-core/scripts/i18n/collect-strings.js | 7 ++++--- .../test/scripts/i18n/bake-ctc-to-lhl-test.js | 10 +++++++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index ec1406f309bc..631b5e5b79dc 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -64,7 +64,7 @@ const UIStrings = { columnRequests: 'Requests', /** Label for a column in a data table; entries will be the number of kilobytes transferred to load a set of files. */ columnTransferSize: 'Transfer Size', - /** Label for the Name column in the User Timing event data table. User Timing API entries are added by the developer of the web page. An example user timing event name: 'pageload_logoimage_done' */ + /** Label for a column in a data table; entries will be the names of arbitrary objects. */ columnName: 'Name', /** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page. */ totalResourceType: 'Total', @@ -193,7 +193,7 @@ function _formatIcuMessage(locale, icuMessageId, uiStringMessage, values) { localeMessage = uiStringMessage; // Warn the user that the UIString message != the `en` message ∴ they should update the strings - if (LOCALES['en'][icuMessageId] && localeMessage !== LOCALES['en'][icuMessageId].message) { + if (!LOCALES['en'][icuMessageId] || localeMessage !== LOCALES['en'][icuMessageId].message) { log.warn('i18n', `Message "${icuMessageId}" does not match its 'en' counterpart. ` + `Run 'i18n' to update.`); } diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index 30e0ad0fa43a..7ce048e7a98b 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -7,7 +7,6 @@ const i18n = require('./i18n/i18n.js'); -// TODO(exterkamp): Get better examples. /* eslint-disable max-len */ const UIStrings = { /** diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 99eaac7b914a..00515716f168 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -10,8 +10,9 @@ const fs = require('fs'); const path = require('path'); +var assert = require('assert'); const esprima = require('esprima'); -const bakery = require('./bake-ctc-to-lhl.js'); +const collectAndBakeCtcStrings = require('./bake-ctc-to-lhl.js'); const LH_ROOT = path.join(__dirname, '../../../'); const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im; @@ -455,7 +456,7 @@ if (require.main === module) { console.log('Collected from Stack Packs!'); if ((collisions) > 0) { - // TODO(exterkamp): assert that this number is constant to prevent unexpected dupes. + assert.equal(collisions, 15, 'The number of duplicate strings have changed, update this assertion if that is expected, or reword strings.'); console.log(`MEANING COLLISION: ${collisions} string(s) have the same content.`); } @@ -466,7 +467,7 @@ if (require.main === module) { console.log('Written to disk!', 'en-XL.ctc.json'); // Bake the ctc en-US and en-XL files into en-US and en-XL LHL format - const lhl = bakery.collectAndBakeCtcStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/'), + const lhl = collectAndBakeCtcStrings.collectAndBakeCtcStrings(path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/'), path.join(LH_ROOT, 'lighthouse-core/lib/i18n/locales/')); lhl.forEach(function(locale) { console.log(`Baked ${locale} into LHL format.`); diff --git a/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js b/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js index 9632f1cfe41d..cbc2b34b3219 100644 --- a/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js +++ b/lighthouse-core/test/scripts/i18n/bake-ctc-to-lhl-test.js @@ -36,10 +36,9 @@ describe('Baking Placeholders', () => { }, }; const res = bakery.bakePlaceholders(strings); - expect(res).toEqual({ + expect(res).toStrictEqual({ hello: { message: '`World`', - placeholders: undefined, }, }); }); @@ -48,10 +47,15 @@ describe('Baking Placeholders', () => { const strings = { hello: { message: 'Hello $MARKDOWN_SNIPPET_0$ $MARKDOWN_SNIPPET_1$', + placeholders: { + MARKDOWN_SNIPPET_0: { + content: '`World`', + }, + }, }, }; // eslint-disable-next-line max-len - expect(() => bakery.bakePlaceholders(strings)).toThrow(/Message "Hello \$MARKDOWN_SNIPPET_0\$ \$MARKDOWN_SNIPPET_1\$" is missing placeholder\(s\): \$MARKDOWN_SNIPPET_0\$,\$MARKDOWN_SNIPPET_1\$/); + expect(() => bakery.bakePlaceholders(strings)).toThrow(/Message "Hello `World` \$MARKDOWN_SNIPPET_1\$" is missing placeholder\(s\): \$MARKDOWN_SNIPPET_1\$/); }); it('throws when a placeholder is not in string', () => { From 327c7dba7f9916c26ffb70f6de0f6b4bfd98b498 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Thu, 18 Jul 2019 23:29:06 -0700 Subject: [PATCH 59/71] How'd that var get there. --- lighthouse-core/scripts/i18n/collect-strings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 00515716f168..01ef43916ab4 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -10,7 +10,7 @@ const fs = require('fs'); const path = require('path'); -var assert = require('assert'); +const assert = require('assert'); const esprima = require('esprima'); const collectAndBakeCtcStrings = require('./bake-ctc-to-lhl.js'); From b006cf7181ed4264fffade014d20769c874aaddd Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Sun, 21 Jul 2019 12:04:22 -0700 Subject: [PATCH 60/71] Brendan feedback v3 --- .../scripts/i18n/bake-ctc-to-lhl.js | 20 +-- .../scripts/i18n/collect-strings.js | 155 ++++++++++-------- .../test/scripts/i18n/collect-strings-test.js | 46 +++++- 3 files changed, 141 insertions(+), 80 deletions(-) diff --git a/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js index 50da0e1c7eb3..435dec7960fa 100644 --- a/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js +++ b/lighthouse-core/scripts/i18n/bake-ctc-to-lhl.js @@ -15,16 +15,16 @@ const LH_ROOT = path.join(__dirname, '../../../'); /** * @typedef ICUMessageDefn - * @property {string} message - * @property {string} [description] - * @property {string} [meaning] - * @property {Record<string, ICUPlaceholderDefn>} [placeholders] + * @property {string} message the message that is being translated + * @property {string} [description] a string used by translators to give context to the message + * @property {string} [meaning] an arbitrary strings used by translators to differentiate messages that have the same message + * @property {Record<string, ICUPlaceholderDefn>} [placeholders] a set of values that are to be replaced in a message */ /** * @typedef ICUPlaceholderDefn - * @property {string} content - * @property {string} [example] + * @property {string} content the string that will be substituted into a message + * @property {string} [example] an example (to assist translators) of what the content may be in the final string */ /** @@ -58,10 +58,10 @@ const LH_ROOT = path.join(__dirname, '../../../'); * value in the placeholders object, or vice versa. * * @param {Record<string, ICUMessageDefn>} messages - * @returns {Record<string, {message: string}>} + * @return {Record<string, {message: string}>} */ function bakePlaceholders(messages) { - /** @type {Record<string, ICUMessageDefn>} */ + /** @type {Record<string, {message: string}>} */ const bakedMessages = {}; for (const [key, defn] of Object.entries(messages)) { @@ -100,7 +100,7 @@ function loadCtcStrings(file) { /** * @param {string} path - * @param {Record<string, ICUMessageDefn>} localeStrings + * @param {Record<string, {message: string}>} localeStrings */ function saveLhlStrings(path, localeStrings) { fs.writeFileSync(path, JSON.stringify(localeStrings, null, 2) + '\n'); @@ -109,7 +109,7 @@ function saveLhlStrings(path, localeStrings) { /** * @param {string} dir * @param {string} outputDir - * @returns {Array<string>} + * @return {Array<string>} */ function collectAndBakeCtcStrings(dir, outputDir) { const lhl = []; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 01ef43916ab4..265a5502e369 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -120,29 +120,28 @@ function computeDescription(ast, property, value, startRange) { * * @param {string} message * @param {Record<string, string>} examples - * @returns {ICUMessageDefn} + * @return {ICUMessageDefn} */ function convertMessageToPlaceholders(message, examples = {}) { - // Basically the same as markdown parsing in dom.js - const icu = { + const icuDefn = { message, placeholders: {}, }; // Process each placeholder type - _processPlaceholderMarkdownCode(icu); + _processPlaceholderMarkdownCode(icuDefn); - _processPlaceholderMarkdownLink(icu); + _processPlaceholderMarkdownLink(icuDefn); - _processPlaceholderComplexIcu(icu); + _processPlaceholderComplexIcu(icuDefn); - _processPlaceholderDirectIcu(icu, examples); + _processPlaceholderDirectIcu(icuDefn, examples); - return icu; + return icuDefn; } /** - * Convert markdown code blocks into placeholders with examples. + * Convert code spans into placeholders with examples. * * @param {ICUMessageDefn} icu */ @@ -153,7 +152,7 @@ function _processPlaceholderMarkdownCode(icu) { throw Error(`Open backtick in message "${icu.message}"`); } - // Split on markdown code slashes + // Split on backticked code spans const parts = icu.message.split(/`(.*?)`/g); icu.message = ''; let idx = 0; @@ -162,11 +161,11 @@ function _processPlaceholderMarkdownCode(icu) { const [preambleText, codeText] = parts.splice(0, 2); icu.message += preambleText; if (codeText) { - const pName = `MARKDOWN_SNIPPET_${idx++}`; + const placeholderName = `MARKDOWN_SNIPPET_${idx++}`; // Backtick replacement looks unreadable here, so .join() instead. - icu.message += ['$', pName, '$'].join(''); - icu.placeholders[pName] = { - content: ['`', codeText, '`'].join(''), + icu.message += '$' + placeholderName + '$'; + icu.placeholders[placeholderName] = { + content: '`' + codeText + '`', example: codeText, }; } @@ -179,7 +178,8 @@ function _processPlaceholderMarkdownCode(icu) { * @param {ICUMessageDefn} icu */ function _processPlaceholderMarkdownLink(icu) { - // Check that link markdown is not slightly off. + // Check for markdown link common errors, ex: + // * [extra] (space between brackets and parens) if (icu.message.match(/\[.*\] \(.*\)/)) { throw Error(`Bad Link syntax in message "${icu.message}"`); } @@ -196,14 +196,14 @@ function _processPlaceholderMarkdownLink(icu) { // Append link if there are any. if (linkText && linkHref) { - const ls = `LINK_START_${idx}`; - const le = `LINK_END_${idx++}`; - const repr = `$${ls}$${linkText}$${le}$`; - icu.message += repr; - icu.placeholders[ls] = { + const startPlaceholder = `LINK_START_${idx}`; + const endPlaceholder = `LINK_END_${idx}`; + icu.message += '$' + startPlaceholder + '$' + linkText + '$' + endPlaceholder + '$'; + idx++; + icu.placeholders[startPlaceholder] = { content: '[', }; - icu.placeholders[le] = { + icu.placeholders[endPlaceholder] = { content: `](${linkHref})`, }; } @@ -212,54 +212,72 @@ function _processPlaceholderMarkdownLink(icu) { /** * Convert complex ICU syntax into placeholders with examples. + * Custom formats defined in i18n.js in "format" object. + * + * Before: + * icu: 'This audit took {timeInMs, number, milliseconds} ms.' + * After: + * icu: 'This audit took $COMPLEX_ICU_0' ms. + * placeholders: { + * COMPLEX_IXU_0 { + * content: {timeInMs, number, milliseconds}, + * example: 499, + * } + * } * * @param {ICUMessageDefn} icu */ function _processPlaceholderComplexIcu(icu) { - // Check that complex ICU not using non-supported format - if (icu.message.match( - /\{(\w{2,50}), number, (?!milliseconds|seconds|bytes|percent|extendedPercent).*\}/)) { - throw Error(`Unsupported ICU format in message "${icu.message}"`); - } - // Split on complex ICU: {var, number, type} const parts = icu.message.split( - /\{(\w{2,50}), number, (milliseconds|seconds|bytes|percent|extendedPercent)\}/g); + /\{(\w+), (\w+), (\w+)\}/g); icu.message = ''; let idx = 0; while (parts.length) { - // Pop off the same number of elements as there are capture groups. - const [preambleText, varName, icuType] = parts.splice(0, 3); + // Seperate out the match into parts. + const [preambleText, rawName, format, formatType] = parts.splice(0, 4); icu.message += preambleText; - // Append link if there are any. - if (varName && icuType) { - const iName = `COMPLEX_ICU_${idx++}`; - icu.message += `$${iName}$`; - let example = '0'; - - // Make some good examples. - switch (icuType) { - case 'seconds': - example = '2.4'; - break; - case 'percent': - example = '54.6%'; - break; - case 'extendedPercent': - example = '37.92%'; - break; - default: - // Random (but constant) number for examples. - example = '499'; - } + if (!rawName || !format || !formatType) continue; + // Check that complex ICU not using non-supported format ex: + // * using a second arg anything other than "number" + // * using a third arg that is not millis, secs, bytes, %, or extended % + if (!format.match(/^number$/)) { + throw Error(`Unsupported Complex ICU format var "${format}" in message "${icu.message}"`); + } + if (!formatType.match(/milliseconds|seconds|bytes|percent|extendedPercent/)) { + throw Error(`Unsupported Complex ICU type var "${formatType}" in message "${icu.message}"`); + } - icu.placeholders[iName] = { - content: `{${varName}, number, ${icuType}}`, - example: example, - }; + // Append ICU replacements if there are any. + const placeholderName = `COMPLEX_ICU_${idx++}`; + icu.message += `$${placeholderName}$`; + let example; + + // Make some good examples. + switch (formatType) { + case 'seconds': + example = '2.4'; + break; + case 'percent': + example = '54.6%'; + break; + case 'extendedPercent': + example = '37.92%'; + break; + case 'milliseconds': + case 'bytes': + example = '499'; + break; + default: + throw Error('Unknown formatType'); } + + icu.placeholders[placeholderName] = { + content: `{${rawName}, number, ${formatType}}`, + example, + }; } } @@ -393,33 +411,32 @@ function collectAllStringsInDir(dir, strings = {}) { const messageKey = `${relativePath} | ${key}`; /** @type {ICUMessageDefn} */ - const msg = { + const icuDefn = { message: converted.message, description, }; - if (Object.entries(converted.placeholders).length > 0 && - converted.placeholders.constructor === Object) { - msg.placeholders = converted.placeholders; + if (converted.placeholders.constructor === Object) { + icuDefn.placeholders = converted.placeholders; } // check for duplicates, if duplicate, add @description as @meaning to both - if (seenStrings.has(msg.message)) { - msg.meaning = msg.description; - const id = seenStrings.get(msg.message); - // Shouldn't be able to get here, but ts wants a check. - if (!id) throw new Error('Message has collision, but collision not recorded in seen.'); - if (!strings[id].meaning) { - strings[id].meaning = strings[id].description; + if (seenStrings.has(icuDefn.message)) { + icuDefn.meaning = icuDefn.description; + const seenId = seenStrings.get(icuDefn.message); + if (seenId) { + if (!strings[seenId].meaning) { + strings[seenId].meaning = strings[seenId].description; + collisions++; + } collisions++; } - collisions++; } - seenStrings.set(msg.message, messageKey); + seenStrings.set(icuDefn.message, messageKey); - strings[messageKey] = msg; + strings[messageKey] = icuDefn; lastPropertyEndIndex = property.range[1]; } diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 41966bd7675c..0b66486e6a24 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -186,6 +186,21 @@ describe('Convert Message to Placeholder', () => { expect(res).toEqual({message, placeholders: {}}); }); + it('passthroughs an ICU plural unchanged', () => { + const message = '{var, select, male{Hello Mr. Programmer.} ' + + 'female{Hello Ms. Programmer} other{Hello Programmer.}}'; + const res = collect.convertMessageToPlaceholders(message, undefined); + expect(res).toEqual({message, placeholders: {}}); + }); + + // TODO(exterkamp): more strict parsing for this case + it.skip('passthroughs an ICU plural, with commas (Complex ICU parsing test), unchanged', () => { + const message = '{var, select, male{Hello, Mr, Programmer.} ' + + 'female{Hello, Ms, Programmer} other{Hello, Programmer.}}'; + const res = collect.convertMessageToPlaceholders(message, undefined); + expect(res).toEqual({message, placeholders: {}}); + }); + it('converts code block to placeholder', () => { const message = 'Hello `World`.'; const res = collect.convertMessageToPlaceholders(message, undefined); @@ -290,10 +305,39 @@ describe('Convert Message to Placeholder', () => { }); }); + it('replaces within ICU plural', () => { + const message = '{var, select, male{time: {timeInSec, number, seconds}} ' + + 'female{time: {timeInSec, number, seconds}} other{time: {timeInSec, number, seconds}}}'; + const expectation = '{var, select, male{time: $COMPLEX_ICU_0$} ' + + 'female{time: $COMPLEX_ICU_1$} other{time: $COMPLEX_ICU_2$}}'; + const res = collect.convertMessageToPlaceholders(message, undefined); + expect(res.message).toEqual(expectation); + expect(res.placeholders).toEqual({ + COMPLEX_ICU_0: { + content: '{timeInSec, number, seconds}', + example: '2.4', + }, + COMPLEX_ICU_1: { + content: '{timeInSec, number, seconds}', + example: '2.4', + }, + COMPLEX_ICU_2: { + content: '{timeInSec, number, seconds}', + example: '2.4', + }, + }); + }); + it('errors when using non-supported complex ICU format', () => { + const message = 'Hello World took {var, badFormat, milliseconds}.'; + expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( + /Unsupported Complex ICU format var "badFormat" in message "Hello World took "/); + }); + + it('errors when using non-supported complex ICU type', () => { const message = 'Hello World took {var, number, global_int}.'; expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( - /Unsupported ICU format in message "Hello World took {var, number, global_int}\."/); + /Unsupported Complex ICU type var "global_int" in message "Hello World took "/); }); it('converts direct ICU with examples to placeholders', () => { From 51cbb78845492a33038f7f8cfc57fa16888d290e Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 11:38:28 -0700 Subject: [PATCH 61/71] added comment to example fallback. --- lighthouse-core/scripts/i18n/collect-strings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 265a5502e369..c9ea1e95edb6 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -271,6 +271,7 @@ function _processPlaceholderComplexIcu(icu) { example = '499'; break; default: + // This shouldn't be possible, but if the above formatType regex fails, this is fallback. throw Error('Unknown formatType'); } From d2a83267de8ee214148b3c47b216b953b1aac763 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 13:30:35 -0700 Subject: [PATCH 62/71] complex ICU -> custom-formatted ICU --- .../scripts/i18n/collect-strings.js | 20 +++++------ .../test/scripts/i18n/collect-strings-test.js | 36 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index c9ea1e95edb6..5c90dc714a90 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -133,7 +133,7 @@ function convertMessageToPlaceholders(message, examples = {}) { _processPlaceholderMarkdownLink(icuDefn); - _processPlaceholderComplexIcu(icuDefn); + _processPlaceholderCustomFormattedIcu(icuDefn); _processPlaceholderDirectIcu(icuDefn, examples); @@ -211,15 +211,15 @@ function _processPlaceholderMarkdownLink(icu) { } /** - * Convert complex ICU syntax into placeholders with examples. + * Convert custom-formatted ICU syntax into placeholders with examples. * Custom formats defined in i18n.js in "format" object. * * Before: * icu: 'This audit took {timeInMs, number, milliseconds} ms.' * After: - * icu: 'This audit took $COMPLEX_ICU_0' ms. + * icu: 'This audit took $CUSTOM_ICU_0' ms. * placeholders: { - * COMPLEX_IXU_0 { + * CUSTOM_ICU_0 { * content: {timeInMs, number, milliseconds}, * example: 499, * } @@ -227,8 +227,8 @@ function _processPlaceholderMarkdownLink(icu) { * * @param {ICUMessageDefn} icu */ -function _processPlaceholderComplexIcu(icu) { - // Split on complex ICU: {var, number, type} +function _processPlaceholderCustomFormattedIcu(icu) { + // Split on custom-formatted ICU: {var, number, type} const parts = icu.message.split( /\{(\w+), (\w+), (\w+)\}/g); icu.message = ''; @@ -240,18 +240,18 @@ function _processPlaceholderComplexIcu(icu) { icu.message += preambleText; if (!rawName || !format || !formatType) continue; - // Check that complex ICU not using non-supported format ex: + // Check that custom-formatted ICU not using non-supported format ex: // * using a second arg anything other than "number" // * using a third arg that is not millis, secs, bytes, %, or extended % if (!format.match(/^number$/)) { - throw Error(`Unsupported Complex ICU format var "${format}" in message "${icu.message}"`); + throw Error(`Unsupported custom-formatted ICU format var "${format}" in message "${icu.message}"`); } if (!formatType.match(/milliseconds|seconds|bytes|percent|extendedPercent/)) { - throw Error(`Unsupported Complex ICU type var "${formatType}" in message "${icu.message}"`); + throw Error(`Unsupported custom-formatted ICU type var "${formatType}" in message "${icu.message}"`); } // Append ICU replacements if there are any. - const placeholderName = `COMPLEX_ICU_${idx++}`; + const placeholderName = `CUSTOM_ICU_${idx++}`; icu.message += `$${placeholderName}$`; let example; diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 0b66486e6a24..136da9b16f5f 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -271,34 +271,34 @@ describe('Convert Message to Placeholder', () => { .toThrow(/Bad Link syntax in message "Hello \[World\] \(https:\/\/google\.com\/\)\."/); }); - it('converts complex ICU to placholders', () => { + it('converts custom-formatted ICU to placholders', () => { const message = 'Hello World took {timeInMs, number, milliseconds} ms, ' + '{timeInSec, number, seconds} s, used {bytes, number, bytes} KB, ' + '{perc, number, percent} of {percEx, number, extendedPercent}.'; const res = collect.convertMessageToPlaceholders(message, undefined); - const expectation = 'Hello World took $COMPLEX_ICU_0$ ms, ' + - '$COMPLEX_ICU_1$ s, used $COMPLEX_ICU_2$ KB, ' + - '$COMPLEX_ICU_3$ of $COMPLEX_ICU_4$.'; + const expectation = 'Hello World took $CUSTOM_ICU_0$ ms, ' + + '$CUSTOM_ICU_1$ s, used $CUSTOM_ICU_2$ KB, ' + + '$CUSTOM_ICU_3$ of $CUSTOM_ICU_4$.'; expect(res.message).toBe(expectation); expect(res.placeholders).toEqual({ - COMPLEX_ICU_0: { + CUSTOM_ICU_0: { content: '{timeInMs, number, milliseconds}', example: '499', }, - COMPLEX_ICU_1: { + CUSTOM_ICU_1: { content: '{timeInSec, number, seconds}', example: '2.4', }, - COMPLEX_ICU_2: { + CUSTOM_ICU_2: { content: '{bytes, number, bytes}', example: '499', }, - COMPLEX_ICU_3: { + CUSTOM_ICU_3: { content: '{perc, number, percent}', example: '54.6%', }, - COMPLEX_ICU_4: { + CUSTOM_ICU_4: { content: '{percEx, number, extendedPercent}', example: '37.92%', }, @@ -308,36 +308,36 @@ describe('Convert Message to Placeholder', () => { it('replaces within ICU plural', () => { const message = '{var, select, male{time: {timeInSec, number, seconds}} ' + 'female{time: {timeInSec, number, seconds}} other{time: {timeInSec, number, seconds}}}'; - const expectation = '{var, select, male{time: $COMPLEX_ICU_0$} ' + - 'female{time: $COMPLEX_ICU_1$} other{time: $COMPLEX_ICU_2$}}'; + const expectation = '{var, select, male{time: $CUSTOM_ICU_0$} ' + + 'female{time: $CUSTOM_ICU_1$} other{time: $CUSTOM_ICU_2$}}'; const res = collect.convertMessageToPlaceholders(message, undefined); expect(res.message).toEqual(expectation); expect(res.placeholders).toEqual({ - COMPLEX_ICU_0: { + CUSTOM_ICU_0: { content: '{timeInSec, number, seconds}', example: '2.4', }, - COMPLEX_ICU_1: { + CUSTOM_ICU_1: { content: '{timeInSec, number, seconds}', example: '2.4', }, - COMPLEX_ICU_2: { + CUSTOM_ICU_2: { content: '{timeInSec, number, seconds}', example: '2.4', }, }); }); - it('errors when using non-supported complex ICU format', () => { + it('errors when using non-supported custom-formatted ICU format', () => { const message = 'Hello World took {var, badFormat, milliseconds}.'; expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( - /Unsupported Complex ICU format var "badFormat" in message "Hello World took "/); + /Unsupported custom-formatted ICU format var "badFormat" in message "Hello World took "/); }); - it('errors when using non-supported complex ICU type', () => { + it('errors when using non-supported custom-formatted ICU type', () => { const message = 'Hello World took {var, number, global_int}.'; expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( - /Unsupported Complex ICU type var "global_int" in message "Hello World took "/); + /Unsupported custom-formatted ICU type var "global_int" in message "Hello World took "/); }); it('converts direct ICU with examples to placeholders', () => { From be426b8a2f7c7d95f5d193adb0f5cf20fedc4693 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 13:55:58 -0700 Subject: [PATCH 63/71] reorg example logic to directIcu replacement. --- .../scripts/i18n/collect-strings.js | 35 +++++++------- .../test/scripts/i18n/collect-strings-test.js | 47 +++++++++---------- 2 files changed, 37 insertions(+), 45 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 5c90dc714a90..b0178c6af087 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -32,7 +32,7 @@ const ignoredPathComponents = [ // @ts-ignore - @types/esprima lacks all of these function computeDescription(ast, property, value, startRange) { const endRange = property.range[0]; - const findIcu = /\{(\w+)\}/g; + for (const comment of ast.comments || []) { if (comment.range[0] < startRange) continue; if (comment.range[0] > endRange) continue; @@ -52,20 +52,9 @@ function computeDescription(ast, property, value, startRange) { if (tagName === 'description') { description = message; } else if (tagName === 'example') { - // Make sure the ICU var exists in string - if (!value.includes(placeholder)) { - throw Error(`Example missing ICU replacement in message "${message}"`); - } examples[placeholder.substring(1, placeholder.length - 1)] = message; } } - // Make sure all ICU vars have examples - while ((matches = findIcu.exec(value)) !== null) { - const varName = matches[1]; - if (!examples[varName]) { - throw Error(`Variable '${varName}' is missing example comment in message "${value}"`); - } - } // Make sure description is not empty if (description.length === 0) throw Error(`Empty @description for message "${value}"`); @@ -74,12 +63,6 @@ function computeDescription(ast, property, value, startRange) { const description = comment.value.replace('*', '').trim(); - // Make sure all ICU vars have examples - if (value.match(findIcu)) { - throw Error(`Variable '${value.match(/.*\{(\w+)\}.*/)[1]}' ` + - `is missing example comment in message "${value}"`); - } - // Make sure description is not empty if (description.length === 0) throw Error(`Empty description for message "${value}"`); @@ -291,8 +274,22 @@ function _processPlaceholderCustomFormattedIcu(icu) { function _processPlaceholderDirectIcu(icu, examples) { let tempMessage = icu.message; let idx = 0; + const findIcu = /\{(\w+)\}/g; + + let matches; + // Make sure all ICU vars have examples + while ((matches = findIcu.exec(tempMessage)) !== null) { + const varName = matches[1]; + if (!examples[varName]) { + throw Error(`Variable '${varName}' is missing example comment in message "${tempMessage}"`); + } + } + for (const [key, value] of Object.entries(examples)) { - if (!icu.message.includes(`{${key}}`)) continue; + // Make sure all examples have ICU vars + if (!icu.message.includes(`{${key}}`)) { + throw Error(`Example '${key}' provided, but has not corresponding ICU replacement in message "${icu.message}"`); + } const eName = `ICU_${idx++}`; tempMessage = tempMessage.replace(`{${key}}`, `$${eName}$`); diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 136da9b16f5f..b66247001e77 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -128,25 +128,28 @@ describe('Compute Description', () => { expect(res.examples['variable']).toBe('Variable example.'); }); - it('errors when example given without variable', () => { + it('collects complex description with multiple examples', () => { const justUIStrings = `const UIStrings = { /** * @description Tagged description for Hello World. * @example {variable} Variable example. + * @example {variable2} Variable2 example. */ - message: 'Hello World', + message: 'Hello World {variable} {variable2}', };`; const ast = esprima.parse(justUIStrings, {comment: true, range: true}); const stmt = ast.body[0]; const prop = stmt.declarations[0].init.properties[0]; - expect(() => collect.computeDescription(ast, prop, 'Hello World', 0)) - .toThrow(/Example missing ICU replacement in message "Variable example."/); + const res = collect.computeDescription(ast, prop, 'Hello World {variable} {variable2}', 0); + expect(res.description).toBe('Tagged description for Hello World.'); + expect(res.examples['variable']).toBe('Variable example.'); + expect(res.examples['variable2']).toBe('Variable2 example.'); }); - it('errors when variable has no example', () => { + it('does not throw when no example for ICU', () => { const justUIStrings = `const UIStrings = { /** @@ -159,23 +162,9 @@ describe('Compute Description', () => { const stmt = ast.body[0]; const prop = stmt.declarations[0].init.properties[0]; - expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)).toThrow( - /Variable 'variable' is missing example comment in message "Hello World {variable}"/); - }); - - it('errors when variable has no example, with basic description', () => { - const justUIStrings = - `const UIStrings = { - /** Tagged description for Hello World. */ - message: 'Hello World {variable}', - };`; - - const ast = esprima.parse(justUIStrings, {comment: true, range: true}); - - const stmt = ast.body[0]; - const prop = stmt.declarations[0].init.properties[0]; - expect(() => collect.computeDescription(ast, prop, 'Hello World {variable}', 0)).toThrow( - /Variable 'variable' is missing example comment in message "Hello World {variable}"/); + const res = collect.computeDescription(ast, prop, 'Hello World {variable}', 0); + expect(res.description).toBe('Tagged description for Hello World.'); + expect(res.examples).toEqual({}); }); }); @@ -353,11 +342,17 @@ describe('Convert Message to Placeholder', () => { }); }); - it('ignores direct ICU with no examples', () => { + it('errors when example given without variable', () => { + const message = 'Hello name.'; + expect(() => collect.convertMessageToPlaceholders(message, {name: 'Mary'})) + // eslint-disable-next-line max-len + .toThrow(/Example 'name' provided, but has not corresponding ICU replacement in message "Hello name."/); + }); + + it('errors when direct ICU has no examples', () => { const message = 'Hello {name}.'; - const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res.message).toBe(message); - expect(res.placeholders).toEqual({}); + expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( + /Variable 'name' is missing example comment in message "Hello {name}."/); }); }); From 125cb1d4f76d8739d21c2bda694e393d6273967c Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 14:48:20 -0700 Subject: [PATCH 64/71] stop empty plcaeholders from being added to every message. Stricter check to prevent regression. --- lighthouse-core/scripts/i18n/collect-strings.js | 3 ++- lighthouse-core/test/scripts/i18n/collect-strings-test.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index b0178c6af087..a10110968f74 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -414,7 +414,8 @@ function collectAllStringsInDir(dir, strings = {}) { description, }; - if (converted.placeholders.constructor === Object) { + // Stop empty placeholders from being added to every message + if (Object.entries(converted.placeholders).length > 0) { icuDefn.placeholders = converted.placeholders; } diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index b66247001e77..fb258ec56a8c 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -172,14 +172,14 @@ describe('Convert Message to Placeholder', () => { it('passthroughs a basic message unchanged', () => { const message = 'Hello World.'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: {}}); + expect(res).toEqual({message, placeholders: undefined}); }); it('passthroughs an ICU plural unchanged', () => { const message = '{var, select, male{Hello Mr. Programmer.} ' + 'female{Hello Ms. Programmer} other{Hello Programmer.}}'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: {}}); + expect(res).toEqual({message, placeholders: undefined}); }); // TODO(exterkamp): more strict parsing for this case From b95b96b1bc37333aee13210111ad4fc818d6cbf5 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 14:57:17 -0700 Subject: [PATCH 65/71] updated columnName description --- lighthouse-core/lib/i18n/i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 631b5e5b79dc..2d0e4440646d 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -64,7 +64,7 @@ const UIStrings = { columnRequests: 'Requests', /** Label for a column in a data table; entries will be the number of kilobytes transferred to load a set of files. */ columnTransferSize: 'Transfer Size', - /** Label for a column in a data table; entries will be the names of arbitrary objects. */ + /** Label for a column in a data table; entries will be the names of arbitrary objects, e.g. the name of a Javascript library, or the name of a user defined timing event. */ columnName: 'Name', /** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page. */ totalResourceType: 'Total', From 90efcffe2cef2313cacd2781036ca59428193f96 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 16:07:57 -0700 Subject: [PATCH 66/71] actually can't assert that in the tests. The undefined part is done after :( --- lighthouse-core/test/scripts/i18n/collect-strings-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index fb258ec56a8c..b66247001e77 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -172,14 +172,14 @@ describe('Convert Message to Placeholder', () => { it('passthroughs a basic message unchanged', () => { const message = 'Hello World.'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: undefined}); + expect(res).toEqual({message, placeholders: {}}); }); it('passthroughs an ICU plural unchanged', () => { const message = '{var, select, male{Hello Mr. Programmer.} ' + 'female{Hello Ms. Programmer} other{Hello Programmer.}}'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: undefined}); + expect(res).toEqual({message, placeholders: {}}); }); // TODO(exterkamp): more strict parsing for this case From 6e6ef2420e20abe6e66d9ffbdb6550953fba3c57 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Mon, 22 Jul 2019 18:30:32 -0700 Subject: [PATCH 67/71] @example {example} varName --- .../audits/dobetterweb/appcache-manifest.js | 2 +- .../external-anchors-use-rel-noopener.js | 2 +- lighthouse-core/audits/font-display.js | 2 +- lighthouse-core/audits/image-aspect-ratio.js | 2 +- lighthouse-core/audits/seo/canonical.js | 10 +++++----- lighthouse-core/audits/seo/robots-txt.js | 2 +- lighthouse-core/audits/uses-rel-preconnect.js | 2 +- lighthouse-core/audits/uses-rel-preload.js | 2 +- lighthouse-core/lib/lh-error.js | 20 +++++++++---------- .../scripts/i18n/collect-strings.js | 10 +++++----- .../test/scripts/i18n/collect-strings-test.js | 7 ++++--- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/appcache-manifest.js b/lighthouse-core/audits/dobetterweb/appcache-manifest.js index 5ddca8648085..c525a7ed953a 100644 --- a/lighthouse-core/audits/dobetterweb/appcache-manifest.js +++ b/lighthouse-core/audits/dobetterweb/appcache-manifest.js @@ -23,7 +23,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).', /** * @description Label for the audit identifying uses of the Application Cache. - * @example {AppCacheManifest} clock.appcache + * @example {clock.appcache} AppCacheManifest */ displayValue: 'Found "{AppCacheManifest}"', }; diff --git a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js index d28fe8778efb..a5e9cf9cbd11 100644 --- a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +++ b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js @@ -20,7 +20,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/noopener).', /** * @description Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety. - * @example {anchorHTML} <a target="_blank"> + * @example {<a target="_blank">} anchorHTML * */ warning: 'Unable to determine the destination for anchor ({anchorHTML}). ' + 'If not used as a hyperlink, consider removing target=_blank.', diff --git a/lighthouse-core/audits/font-display.js b/lighthouse-core/audits/font-display.js index ce3743043513..29f3b3c129c1 100644 --- a/lighthouse-core/audits/font-display.js +++ b/lighthouse-core/audits/font-display.js @@ -26,7 +26,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/updates/2016/02/font-display).', /** * @description A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts and that the user will need to manually check it. - * @example {fontURL} https://font.cdn.com/ + * @example {https://font.cdn.com/} fontURL */ undeclaredFontURLWarning: 'Lighthouse was unable to automatically check the font-display value ' + 'for the following URL: {fontURL}.', diff --git a/lighthouse-core/audits/image-aspect-ratio.js b/lighthouse-core/audits/image-aspect-ratio.js index cb3d0481d360..b736977dfc5e 100644 --- a/lighthouse-core/audits/image-aspect-ratio.js +++ b/lighthouse-core/audits/image-aspect-ratio.js @@ -25,7 +25,7 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/aspect-ratio).', /** * @description Warning that the size information for an image was nonsensical. - * @example {url} https://image.cdn.com/ + * @example {https://image.cdn.com/} url */ warningCompute: 'Invalid image sizing information {url}', /** Label for a column in a data table; entries in the column will be the numeric aspect ratio of an image as displayed in a web page. */ diff --git a/lighthouse-core/audits/seo/canonical.js b/lighthouse-core/audits/seo/canonical.js index 0f44bfb8bc56..fe3032bf892d 100644 --- a/lighthouse-core/audits/seo/canonical.js +++ b/lighthouse-core/audits/seo/canonical.js @@ -20,27 +20,27 @@ const UIStrings = { '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).', /** * @description Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. - * @example {urlList} https://example.com, https://example2.com + * @example {https://example.com, https://example2.com} urlList * */ explanationConflict: 'Multiple conflicting URLs ({urlList})', /** * @description Explanatory message stating that there was a failure in an audit caused by a URL being invalid. - * @example {url} https://example.com/ + * @example {https://example.com/} url * */ explanationInvalid: 'Invalid URL ({url})', /** * @description Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute. - * @example {url} https://example.com/ + * @example {https://example.com/} url * */ explanationRelative: 'Relative URL ({url})', /** * @description Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context.'hreflang' is an HTML attribute and should not be translated. - * @example {url} https://example.com/ + * @example {https://example.com/} url */ explanationPointsElsewhere: 'Points to another `hreflang` location ({url})', /** * @description Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. - * @example {url} https://example.com/ + * @example {https://example.com/} url * */ explanationDifferentDomain: 'Points to a different domain ({url})', /** Explanatory message stating that the page's canonical URL was pointing to the domain's root URL, which is a common mistake. "points" refers to the action of the 'rel=canonical' referencing another link. "root" refers to the starting/home page of the website. "domain" refers to the registered domain name of the website. */ diff --git a/lighthouse-core/audits/seo/robots-txt.js b/lighthouse-core/audits/seo/robots-txt.js index c9e919c64d2c..1367308c367e 100644 --- a/lighthouse-core/audits/seo/robots-txt.js +++ b/lighthouse-core/audits/seo/robots-txt.js @@ -43,7 +43,7 @@ const UIStrings = { 'how you want your website to be crawled or indexed.', /** * @description Label for the audit identifying that the robots.txt request has returned a specific HTTP status code. Note: "robots.txt" is a canonical filename and should not be translated. - * @example {statusCode} 500 + * @example {500} statusCode * */ displayValueHttpBadCode: 'request for robots.txt returned HTTP status: {statusCode}', /** [ICU Syntax] Label for the audit identifying the number of errors that occured while validating the robots.txt file. "itemCount" will be replaced by the integer count of errors encountered. */ diff --git a/lighthouse-core/audits/uses-rel-preconnect.js b/lighthouse-core/audits/uses-rel-preconnect.js index 0171b644946e..52db3743a922 100644 --- a/lighthouse-core/audits/uses-rel-preconnect.js +++ b/lighthouse-core/audits/uses-rel-preconnect.js @@ -31,7 +31,7 @@ const UIStrings = { `connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, /** * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links. - * @example {securityOrigin} https://example.com + * @example {https://example.com} securityOrigin * */ crossoriginWarning: 'A preconnect <link> was found for "{securityOrigin}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', diff --git a/lighthouse-core/audits/uses-rel-preload.js b/lighthouse-core/audits/uses-rel-preload.js index a1e4f7561755..767232e9b91f 100644 --- a/lighthouse-core/audits/uses-rel-preload.js +++ b/lighthouse-core/audits/uses-rel-preload.js @@ -22,7 +22,7 @@ const UIStrings = { 'currently requested later in page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/preload).', /** * @description A warning message that is shown when the user tried to follow the advice of the audit, but it's not working as expected. Forgetting to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preload links. - * @example {preloadURL} https://example.com + * @example {https://example.com} preloadURL * */ crossoriginWarning: 'A preload <link> was found for "{preloadURL}" but was not used ' + 'by the browser. Check that you are using the `crossorigin` attribute properly.', diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js index e635f2074bfd..f1809ff15105 100644 --- a/lighthouse-core/lib/lh-error.js +++ b/lighthouse-core/lib/lh-error.js @@ -11,34 +11,34 @@ const i18n = require('./i18n/i18n.js'); const UIStrings = { /** * @description Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome. - * @example {errorCode} NO_SPEEDLINE_FRAMES + * @example {NO_SPEEDLINE_FRAMES} errorCode * */ didntCollectScreenshots: `Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})`, /** * @description Error message explaining that the network trace was not able to be recorded for the Lighthouse run. - * @example {errorCode} NO_TRACING_STARTED + * @example {NO_TRACING_STARTED} errorCode * */ badTraceRecording: 'Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})', /** * @description Error message explaining that the page loaded too slowly to perform a Lighthouse run. - * @example {errorCode} FMP_TOO_LATE_FOR_FCPUI + * @example {FMP_TOO_LATE_FOR_FCPUI} errorCode * */ pageLoadTookTooLong: 'Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ({errorCode})', /** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ pageLoadFailed: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests.', /** * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. - * @example {statusCode} 404 + * @example {404} statusCode * */ pageLoadFailedWithStatusCode: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: {statusCode})', /** * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. - * @example {errorDetails} FAILED_DOCUMENT_REQUEST + * @example {FAILED_DOCUMENT_REQUEST} errorDetails * */ pageLoadFailedWithDetails: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})', /** * @description Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load. - * @example {securityMessages} net::ERR_CERT_DATE_INVALID + * @example {net::ERR_CERT_DATE_INVALID} securityMessages * */ pageLoadFailedInsecure: 'The URL you have provided does not have a valid security certificate. {securityMessages}', /** Error message explaining that Chrome prevented the page from loading and displayed an interstitial screen instead, so the URL cannot be accessed. */ @@ -51,7 +51,7 @@ const UIStrings = { urlInvalid: 'The URL you have provided appears to be invalid.', /** * @description Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed. - * @example {protocolMethod} Network.enable + * @example {Network.enable} protocolMethod * */ protocolTimeout: 'Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})', /** Error message explaining that the requested page could not be resolved by the DNS server. */ @@ -62,13 +62,13 @@ const UIStrings = { criTimeout: 'Timeout waiting for initial Debugger Protocol connection.', /** * @description Error message explaning that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected. - * @example {artifactName} WebAppManifest + * @example {WebAppManifest} artifactName * */ missingRequiredArtifact: 'Required {artifactName} gatherer did not run.', /** * @description Error message explaning that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. - * @example {artifactName} WebAppManifest - * @example {errorMessage} Manifest invalid + * @example {WebAppManifest} artifactName + * @example {Manifest invalid} errorMessage * */ erroredRequiredArtifact: 'Required {artifactName} gatherer encountered an error: {errorMessage}', }; diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index a10110968f74..457d61769fee 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -42,17 +42,17 @@ function computeDescription(ast, property, value, startRange) { /** @type {Record<string, string>} */ const examples = {}; - const r = /@(\w+) ({\w+})?(.*)(\n|$)/g; + const r = /@(\w+) ({.+})?(.*)(\n|$)/g; let matches; while ((matches = r.exec(comment.value)) !== null) { const tagName = matches[1]; - const placeholder = matches[2]; - const message = matches[3].trim(); + const example = matches[2]; + const messageOrPlaceholder = matches[3].trim(); if (tagName === 'description') { - description = message; + description = messageOrPlaceholder; } else if (tagName === 'example') { - examples[placeholder.substring(1, placeholder.length - 1)] = message; + examples[messageOrPlaceholder] = example.substring(1, example.length - 1); } } diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index b66247001e77..6605e0d59e8b 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -114,7 +114,7 @@ describe('Compute Description', () => { `const UIStrings = { /** * @description Tagged description for Hello World. - * @example {variable} Variable example. + * @example {Variable example.} variable */ message: 'Hello World {variable}', };`; @@ -125,6 +125,7 @@ describe('Compute Description', () => { const prop = stmt.declarations[0].init.properties[0]; const res = collect.computeDescription(ast, prop, 'Hello World {variable}', 0); expect(res.description).toBe('Tagged description for Hello World.'); + console.log(res) expect(res.examples['variable']).toBe('Variable example.'); }); @@ -133,8 +134,8 @@ describe('Compute Description', () => { `const UIStrings = { /** * @description Tagged description for Hello World. - * @example {variable} Variable example. - * @example {variable2} Variable2 example. + * @example {Variable example.} variable + * @example {Variable2 example.} variable2 */ message: 'Hello World {variable} {variable2}', };`; From 6a9ef287d7c761fb5ef73ae36ad4ba81af3df8e9 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 23 Jul 2019 07:57:27 -0700 Subject: [PATCH 68/71] whoops. console log left in --- lighthouse-core/test/scripts/i18n/collect-strings-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 6605e0d59e8b..69cbc870da72 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -125,7 +125,6 @@ describe('Compute Description', () => { const prop = stmt.declarations[0].init.properties[0]; const res = collect.computeDescription(ast, prop, 'Hello World {variable}', 0); expect(res.description).toBe('Tagged description for Hello World.'); - console.log(res) expect(res.examples['variable']).toBe('Variable example.'); }); From 7762381760873dab70965e309ab4a625e95cc56d Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 23 Jul 2019 16:05:13 -0700 Subject: [PATCH 69/71] brendan feedback --- .../external-anchors-use-rel-noopener.js | 2 +- lighthouse-core/lib/i18n/README.md | 4 ++-- lighthouse-core/lib/i18n/i18n.js | 2 +- .../scripts/i18n/collect-strings.js | 21 +++++++++++-------- .../test/scripts/i18n/collect-strings-test.js | 4 ++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js index a5e9cf9cbd11..f8ccee8ffee2 100644 --- a/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +++ b/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js @@ -21,7 +21,7 @@ const UIStrings = { /** * @description Warning that some links' destinations cannot be determined and therefore the audit cannot evaluate the link's safety. * @example {<a target="_blank">} anchorHTML - * */ + */ warning: 'Unable to determine the destination for anchor ({anchorHTML}). ' + 'If not used as a hyperlink, consider removing target=_blank.', /** Label for a column in a data table; entries will be the target attribute of a link. Each entry is either an empty string or a string like `_blank`. */ diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md index 65c4ca2cada0..35c61af0a711 100644 --- a/lighthouse-core/lib/i18n/README.md +++ b/lighthouse-core/lib/i18n/README.md @@ -103,13 +103,13 @@ ICU replacements must use a JSDoc-like syntax to specify an example for direct I * To specify the description, use `@description …`: * `@description Label string used to…` * To specify an example for an ICU replacement, use `@example {…} …`: - * `@example {variableName} This is an example ICU replacement` + * `@example {This is an example ICU replacement} variableName` ```javascript const UIStrings = { /** * @description Error message explaining ... - * @example {errorCode} NO_SPEEDLINE_FRAMES + * @example {NO_SPEEDLINE_FRAMES} errorCode */ didntCollectScreenshots: `Chrome didn't .... ({errorCode})`, }; diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 2d0e4440646d..4ebd6c4fa885 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -193,7 +193,7 @@ function _formatIcuMessage(locale, icuMessageId, uiStringMessage, values) { localeMessage = uiStringMessage; // Warn the user that the UIString message != the `en` message ∴ they should update the strings - if (!LOCALES['en'][icuMessageId] || localeMessage !== LOCALES['en'][icuMessageId].message) { + if (!LOCALES.en[icuMessageId] || localeMessage !== LOCALES.en[icuMessageId].message) { log.warn('i18n', `Message "${icuMessageId}" does not match its 'en' counterpart. ` + `Run 'i18n' to update.`); } diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 457d61769fee..8ade074c76cd 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -105,7 +105,7 @@ function computeDescription(ast, property, value, startRange) { * @param {Record<string, string>} examples * @return {ICUMessageDefn} */ -function convertMessageToPlaceholders(message, examples = {}) { +function convertMessageToCtc(message, examples = {}) { const icuDefn = { message, placeholders: {}, @@ -120,6 +120,11 @@ function convertMessageToPlaceholders(message, examples = {}) { _processPlaceholderDirectIcu(icuDefn, examples); + if (Object.entries(icuDefn.placeholders).length === 0) { + // @ts-ignore - if this is empty then force undefined so that it does not appear in the JSON + icuDefn.placeholders = undefined; + } + return icuDefn; } @@ -303,7 +308,9 @@ function _processPlaceholderDirectIcu(icu, examples) { /** * Take a series of messages and apply ĥât̂ markers to the translatable portions - * of the text. Used to generate `en-XL` locale to debug i18n strings. + * of the text. Used to generate `en-XL` locale to debug i18n strings. This is + * done while messages are in `ctc` format, and therefore modifies only the + * messages themselves while leaving placeholders untouched. * * @param {Record<string, ICUMessageDefn>} messages */ @@ -404,7 +411,7 @@ function collectAllStringsInDir(dir, strings = {}) { const val = exportVars.UIStrings[key]; const {description, examples} = computeDescription(ast, property, val, lastPropertyEndIndex); - const converted = convertMessageToPlaceholders(val, examples); + const converted = convertMessageToCtc(val, examples); const messageKey = `${relativePath} | ${key}`; @@ -412,13 +419,9 @@ function collectAllStringsInDir(dir, strings = {}) { const icuDefn = { message: converted.message, description, + placeholders: converted.placeholders, }; - // Stop empty placeholders from being added to every message - if (Object.entries(converted.placeholders).length > 0) { - icuDefn.placeholders = converted.placeholders; - } - // check for duplicates, if duplicate, add @description as @meaning to both if (seenStrings.has(icuDefn.message)) { icuDefn.meaning = icuDefn.description; @@ -493,5 +496,5 @@ if (require.main === module) { module.exports = { computeDescription, createPsuedoLocaleStrings, - convertMessageToPlaceholders, + convertMessageToPlaceholders: convertMessageToCtc, }; diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 69cbc870da72..943b9a4d247a 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -172,14 +172,14 @@ describe('Convert Message to Placeholder', () => { it('passthroughs a basic message unchanged', () => { const message = 'Hello World.'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: {}}); + expect(res).toEqual({message, placeholders: undefined}); }); it('passthroughs an ICU plural unchanged', () => { const message = '{var, select, male{Hello Mr. Programmer.} ' + 'female{Hello Ms. Programmer} other{Hello Programmer.}}'; const res = collect.convertMessageToPlaceholders(message, undefined); - expect(res).toEqual({message, placeholders: {}}); + expect(res).toEqual({message, placeholders: undefined}); }); // TODO(exterkamp): more strict parsing for this case From be34f7ec5dd3041dc9efa02f251329336b847609 Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 23 Jul 2019 17:34:03 -0700 Subject: [PATCH 70/71] Add sanity check for ctc files --- lighthouse-core/scripts/i18n/collect-strings.js | 15 +++++++++++++++ .../test/scripts/i18n/collect-strings-test.js | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lighthouse-core/scripts/i18n/collect-strings.js b/lighthouse-core/scripts/i18n/collect-strings.js index 8ade074c76cd..8a5cb147d817 100644 --- a/lighthouse-core/scripts/i18n/collect-strings.js +++ b/lighthouse-core/scripts/i18n/collect-strings.js @@ -120,6 +120,8 @@ function convertMessageToCtc(message, examples = {}) { _processPlaceholderDirectIcu(icuDefn, examples); + _ctcSanityChecks(icuDefn); + if (Object.entries(icuDefn.placeholders).length === 0) { // @ts-ignore - if this is empty then force undefined so that it does not appear in the JSON icuDefn.placeholders = undefined; @@ -306,6 +308,19 @@ function _processPlaceholderDirectIcu(icu, examples) { icu.message = tempMessage; } +/** + * Do some basic sanity checks to a ctc object to confirm that it is valid. Future + * ctc regression catching should go here. + * + * @param {ICUMessageDefn} icu the ctc output message to verify + */ +function _ctcSanityChecks(icu) { + // '$$' i.e. "Double Dollar" is always invalid in ctc. + if (icu.message.match(/\$\$/)) { + throw new Error(`Ctc messages cannot contain double dollar: ${icu.message}`); + } +} + /** * Take a series of messages and apply ĥât̂ markers to the translatable portions * of the text. Used to generate `en-XL` locale to debug i18n strings. This is diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index 943b9a4d247a..e39584dbaabd 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -354,6 +354,19 @@ describe('Convert Message to Placeholder', () => { expect(() => collect.convertMessageToPlaceholders(message, undefined)).toThrow( /Variable 'name' is missing example comment in message "Hello {name}."/); }); + + it('throws when message contains double dollar', () => { + const message = 'Hello World$$'; + expect(() => collect.convertMessageToPlaceholders(message)). + toThrow(/Ctc messages cannot contain double dollar: Hello World\$\$/); + }); + + it('throws when message contains double dollar, less obvious edition', () => { + const message = 'Hello ${name}'; + expect(() => collect.convertMessageToPlaceholders(message, {name: 'Mary'})). + toThrow(/Ctc messages cannot contain double dollar: Hello \$\$ICU_0\$/); + }); + }); describe('PseudoLocalizer', () => { From 23a68d505ee42b24f163777247ce1895de1eb83c Mon Sep 17 00:00:00 2001 From: Shane Exterkamp <shaneexterkamp5@gmail.com> Date: Tue, 23 Jul 2019 17:37:43 -0700 Subject: [PATCH 71/71] I feel like my linter is turned off --- lighthouse-core/test/scripts/i18n/collect-strings-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lighthouse-core/test/scripts/i18n/collect-strings-test.js b/lighthouse-core/test/scripts/i18n/collect-strings-test.js index e39584dbaabd..575d3e21f23f 100644 --- a/lighthouse-core/test/scripts/i18n/collect-strings-test.js +++ b/lighthouse-core/test/scripts/i18n/collect-strings-test.js @@ -366,7 +366,6 @@ describe('Convert Message to Placeholder', () => { expect(() => collect.convertMessageToPlaceholders(message, {name: 'Mary'})). toThrow(/Ctc messages cannot contain double dollar: Hello \$\$ICU_0\$/); }); - }); describe('PseudoLocalizer', () => {