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 b262e5ba6545..89ca318ce907 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,8 +16,6 @@ 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://web.dev/password-inputs-can-be-pasted-into/).', - /** Table column header for the HTML elements that do not allow pasting of content. */ - columnFailingElem: 'Failing Elements', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -53,7 +51,7 @@ class PasswordInputsCanBePastedIntoAudit extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'node', itemType: 'node', text: str_(UIStrings.columnFailingElem)}, + {key: 'node', itemType: 'node', text: str_(i18n.UIStrings.columnFailingElem)}, ]; return { diff --git a/lighthouse-core/audits/unsized-images.js b/lighthouse-core/audits/unsized-images.js new file mode 100644 index 000000000000..1036b0b62b1f --- /dev/null +++ b/lighthouse-core/audits/unsized-images.js @@ -0,0 +1,124 @@ +/** + * @license Copyright 2020 The Lighthouse Authors. 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. + */ +/** + * @fileoverview + * Audit that checks whether all images have explicit width and height. + */ + +'use strict'; + +const Audit = require('./audit.js'); +const i18n = require('./../lib/i18n/i18n.js'); +const URL = require('./../lib/url-shim.js'); + +const UIStrings = { + /** Title of a Lighthouse audit that provides detail on whether all images have explicit width and height. This descriptive title is shown to users when every image has explicit width and height */ + title: 'Image elements have explicit `width` and `height`', + /** Title of a Lighthouse audit that provides detail on whether all images have explicit width and height. This descriptive title is shown to users when one or more images does not have explicit width and height */ + failureTitle: 'Image elements do not have explicit `width` and `height`', + /** Description of a Lighthouse audit that tells the user why they should include explicit width and height 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: 'Always include explicit width and height on image elements to reduce layout shifts and improve CLS. [Learn more](https://web.dev/optimize-cls/#images-without-dimensions)', +}; + +const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + +class SizedImages extends Audit { + /** + * @return {LH.Audit.Meta} + */ + static get meta() { + return { + id: 'unsized-images', + title: str_(UIStrings.title), + failureTitle: str_(UIStrings.failureTitle), + description: str_(UIStrings.description), + requiredArtifacts: ['ImageElements'], + }; + } + + /** + * An img size attribute is valid for preventing CLS + * if it is a non-negative, non-zero integer. + * @param {string} attr + * @return {boolean} + */ + static isValidAttr(attr) { + const NON_NEGATIVE_INT_REGEX = /^\d+$/; + const ZERO_REGEX = /^0+$/; + return NON_NEGATIVE_INT_REGEX.test(attr) && !ZERO_REGEX.test(attr); + } + + /** + * An img css size property is valid for preventing CLS + * if it is defined, not empty, and not equal to 'auto'. + * @param {string | undefined} property + * @return {boolean} + */ + static isValidCss(property) { + if (!property) return false; + return property !== 'auto'; + } + + /** + * Images are considered sized if they have defined & valid values. + * @param {LH.Artifacts.ImageElement} image + * @return {boolean} + */ + static isUnsizedImage(image) { + const attrWidth = image.attributeWidth; + const attrHeight = image.attributeHeight; + const cssWidth = image.cssWidth; + const cssHeight = image.cssHeight; + const widthIsValidAttribute = SizedImages.isValidAttr(attrWidth); + const widthIsValidCss = SizedImages.isValidCss(cssWidth); + const heightIsValidAttribute = SizedImages.isValidAttr(attrHeight); + const heightIsValidCss = SizedImages.isValidCss(cssHeight); + const validWidth = widthIsValidAttribute || widthIsValidCss; + const validHeight = heightIsValidAttribute || heightIsValidCss; + return !validWidth || !validHeight; + } + + /** + * @param {LH.Artifacts} artifacts + * @return {Promise} + */ + static async audit(artifacts) { + // CSS background-images are ignored for this audit. + const images = artifacts.ImageElements.filter(el => !el.isCss); + const unsizedImages = []; + + for (const image of images) { + if (!SizedImages.isUnsizedImage(image)) continue; + const url = URL.elideDataURI(image.src); + unsizedImages.push({ + url, + node: /** @type {LH.Audit.Details.NodeValue} */ ({ + type: 'node', + path: image.devtoolsNodePath, + selector: image.selector, + nodeLabel: image.nodeLabel, + snippet: image.snippet, + }), + }); + } + + /** @type {LH.Audit.Details.Table['headings']} */ + const headings = [ + {key: 'url', itemType: 'thumbnail', text: ''}, + {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, + {key: 'node', itemType: 'node', text: str_(i18n.UIStrings.columnFailingElem)}, + ]; + + return { + score: unsizedImages.length > 0 ? 0 : 1, + notApplicable: images.length === 0, + details: Audit.makeTableDetails(headings, unsizedImages), + }; + } +} + +module.exports = SizedImages; +module.exports.UIStrings = UIStrings; diff --git a/lighthouse-core/config/experimental-config.js b/lighthouse-core/config/experimental-config.js index 644f0d483a09..a9ba9327eb5c 100644 --- a/lighthouse-core/config/experimental-config.js +++ b/lighthouse-core/config/experimental-config.js @@ -14,6 +14,7 @@ const config = { extends: 'lighthouse:default', audits: [ + 'unsized-images', 'full-page-screenshot', ], passes: [{ @@ -23,6 +24,13 @@ const config = { ], }], categories: { + // @ts-ignore: `title` is required in CategoryJson. setting to the same value as the default + // config is awkward - easier to omit the property here. Will defer to default config. + 'best-practices': { + auditRefs: [ + {id: 'unsized-images', weight: 1, group: 'best-practices-ux'}, + ], + }, }, }; diff --git a/lighthouse-core/gather/gatherers/image-elements.js b/lighthouse-core/gather/gatherers/image-elements.js index 82917df670b1..e136f38704b4 100644 --- a/lighthouse-core/gather/gatherers/image-elements.js +++ b/lighthouse-core/gather/gatherers/image-elements.js @@ -13,7 +13,7 @@ const Gatherer = require('./gatherer.js'); const pageFunctions = require('../../lib/page-functions.js'); const Driver = require('../driver.js'); // eslint-disable-line no-unused-vars -/* global window, getElementsInDocument, Image */ +/* global window, getElementsInDocument, Image, getNodePath, getNodeSelector, getNodeLabel, getOuterHTMLSnippet */ /** @param {Element} element */ @@ -51,6 +51,8 @@ function getHTMLImages(allElements) { clientRect: getClientRect(element), naturalWidth: element.naturalWidth, naturalHeight: element.naturalHeight, + attributeWidth: element.getAttribute('width') || '', + attributeHeight: element.getAttribute('height') || '', isCss: false, // @ts-expect-error: loading attribute not yet added to HTMLImageElement definition. loading: element.loading, @@ -64,6 +66,14 @@ function getHTMLImages(allElements) { ), // https://html.spec.whatwg.org/multipage/images.html#pixel-density-descriptor usesSrcSetDensityDescriptor: / \d+(\.\d+)?x/.test(element.srcset), + // @ts-ignore - getNodePath put into scope via stringification + devtoolsNodePath: getNodePath(element), + // @ts-ignore - put into scope via stringification + selector: getNodeSelector(element), + // @ts-ignore - put into scope via stringification + nodeLabel: getNodeLabel(element), + // @ts-ignore - put into scope via stringification + snippet: getOuterHTMLSnippet(element), }; }); } @@ -99,6 +109,8 @@ function getCSSImages(allElements) { // CSS Images do not expose natural size, we'll determine the size later naturalWidth: 0, naturalHeight: 0, + attributeWidth: '', + attributeHeight: '', isCss: true, isPicture: false, usesObjectFit: false, @@ -107,6 +119,14 @@ function getCSSImages(allElements) { ), usesSrcSetDensityDescriptor: false, resourceSize: 0, // this will get overwritten below + // @ts-ignore - getNodePath put into scope via stringification + devtoolsNodePath: getNodePath(element), + // @ts-ignore - put into scope via stringification + selector: getNodeSelector(element), + // @ts-ignore - put into scope via stringification + nodeLabel: getNodeLabel(element), + // @ts-ignore - put into scope via stringification + snippet: getOuterHTMLSnippet(element), }); } @@ -192,6 +212,10 @@ class ImageElements extends Gatherer { const expression = `(function() { ${pageFunctions.getElementsInDocumentString}; // define function on page + ${pageFunctions.getNodePathString}; + ${pageFunctions.getNodeSelectorString}; + ${pageFunctions.getNodeLabelString}; + ${pageFunctions.getOuterHTMLSnippetString}; ${getClientRect.toString()}; ${getHTMLImages.toString()}; ${getCSSImages.toString()}; diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index c621b317cfaf..21368f19223b 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -88,6 +88,8 @@ const UIStrings = { columnStartTime: 'Start Time', /** Label for a column in a data table; entries will be the total number of milliseconds from the start time until the end time. */ columnDuration: 'Duration', + /** Label for a column in a data table; entries will be a representation of a DOM element that did not meet certain suggestions. */ + columnFailingElem: 'Failing Elements', /** 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/ar-XB.json b/lighthouse-core/lib/i18n/locales/ar-XB.json index 8a0a049655f8..4b0cde7c319a 100644 --- a/lighthouse-core/lib/i18n/locales/ar-XB.json +++ b/lighthouse-core/lib/i18n/locales/ar-XB.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "‏‮Avoids‬‏ ‏‮requesting‬‏ ‏‮the‬‏ ‏‮notification‬‏ ‏‮permission‬‏ ‏‮on‬‏ ‏‮page‬‏ ‏‮load‬‏" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "‏‮Failing‬‏ ‏‮Elements‬‏" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "‏‮Preventing‬‏ ‏‮password‬‏ ‏‮pasting‬‏ ‏‮undermines‬‏ ‏‮good‬‏ ‏‮security‬‏ ‏‮policy‬‏. [‏‮Learn‬‏ ‏‮more‬‏](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ar.json b/lighthouse-core/lib/i18n/locales/ar.json index d6586172643e..9ec0de614af4 100644 --- a/lighthouse-core/lib/i18n/locales/ar.json +++ b/lighthouse-core/lib/i18n/locales/ar.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "يتم تجنُّب طلب إذن الإشعار عند تحميل الصفحة" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "العناصر التي لا تسمح بلصق المحتوى" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "يؤدي منع لصق كلمة المرور إلى تقويض سياسة الأمان الجيدة. [مزيد من المعلومات](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/bg.json b/lighthouse-core/lib/i18n/locales/bg.json index 1a4c1b93ca68..49f2b700c626 100644 --- a/lighthouse-core/lib/i18n/locales/bg.json +++ b/lighthouse-core/lib/i18n/locales/bg.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Избягва да иска разрешение за известяване при зареждането на страницата" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Елементи с грешки" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Забраната на поставянето на пароли неутрализира добра практика за сигурност. [Научете повече](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ca.json b/lighthouse-core/lib/i18n/locales/ca.json index 17867fbeaa34..7f1e4f7aa57e 100644 --- a/lighthouse-core/lib/i18n/locales/ca.json +++ b/lighthouse-core/lib/i18n/locales/ca.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita sol·licitar el permís de notificació en carregar la pàgina" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elements amb errors" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Impedir enganxar la contrasenya va en detriment d'una bona política de seguretat. [Obtén més informació](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/cs.json b/lighthouse-core/lib/i18n/locales/cs.json index cf16d7dbbaf8..7cebad909af0 100644 --- a/lighthouse-core/lib/i18n/locales/cs.json +++ b/lighthouse-core/lib/i18n/locales/cs.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Nežádá při načtení stránky o oprávnění zobrazovat oznámení" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Prvky, které neprošly" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Blokování vkládání hesel je v rozporu s dobrými bezpečnostními zásadami. [Další informace](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/da.json b/lighthouse-core/lib/i18n/locales/da.json index b673f4d8c097..4b4734d359fe 100644 --- a/lighthouse-core/lib/i18n/locales/da.json +++ b/lighthouse-core/lib/i18n/locales/da.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Undgår at anmode om tilladelse til notifikationer ved indlæsning af siden" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementer, der ikke bestod gennemgangen" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "En god sikkerhedspolitik undermineres ved at forhindre indsættelse af adgangskoder. [Få flere oplysninger](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index 88c0047aad30..958af8de89a3 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Fordert während des Seitenaufbaus keine Benachrichtigungsberechtigung an" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Fehlerhafte Elemente" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Das Einfügen von Passwörtern sollte entsprechend guten Sicherheitsrichtlinien zulässig sein. [Weitere Informationen.](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/el.json b/lighthouse-core/lib/i18n/locales/el.json index bdac897c0d45..699d60bac68c 100644 --- a/lighthouse-core/lib/i18n/locales/el.json +++ b/lighthouse-core/lib/i18n/locales/el.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Αποφυγή αιτήματος για άδεια ειδοποίησης κατά τη φόρτωση σελίδων" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Στοιχεία που απέτυχαν" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Η απαγόρευση της επικόλλησης κωδικών πρόσβασης υπονομεύει την ορθή πολιτική ασφάλειας. [Μάθετε περισσότερα](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/en-GB.json b/lighthouse-core/lib/i18n/locales/en-GB.json index 2d2b1ee0610a..4a127dedafa9 100644 --- a/lighthouse-core/lib/i18n/locales/en-GB.json +++ b/lighthouse-core/lib/i18n/locales/en-GB.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Avoids requesting the notification permission on page load" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Failing Elements" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Preventing password pasting undermines good security policy. [Learn more](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 8324e14952cd..2576cf8287f2 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -695,9 +695,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Avoids requesting the notification permission on page load" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Failing Elements" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Preventing password pasting undermines good security policy. [Learn more](https://web.dev/password-inputs-can-be-pasted-into/)." }, @@ -1259,6 +1256,15 @@ "lighthouse-core/audits/timing-budget.js | title": { "message": "Timing budget" }, + "lighthouse-core/audits/unsized-images.js | description": { + "message": "Always include explicit width and height on image elements to reduce layout shifts and improve CLS. [Learn more](https://web.dev/optimize-cls/#images-without-dimensions)" + }, + "lighthouse-core/audits/unsized-images.js | failureTitle": { + "message": "Image elements do not have explicit `width` and `height`" + }, + "lighthouse-core/audits/unsized-images.js | title": { + "message": "Image elements have explicit `width` and `height`" + }, "lighthouse-core/audits/user-timings.js | columnType": { "message": "Type" }, @@ -1496,6 +1502,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnElement": { "message": "Element" }, + "lighthouse-core/lib/i18n/i18n.js | columnFailingElem": { + "message": "Failing Elements" + }, "lighthouse-core/lib/i18n/i18n.js | columnLocation": { "message": "Location" }, diff --git a/lighthouse-core/lib/i18n/locales/en-XA.json b/lighthouse-core/lib/i18n/locales/en-XA.json index 0e0a309c0ea3..9838c8039fd6 100644 --- a/lighthouse-core/lib/i18n/locales/en-XA.json +++ b/lighthouse-core/lib/i18n/locales/en-XA.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "[Åvöîðš ŕéqûéšţîñĝ ţĥé ñöţîƒîçåţîöñ þéŕmîššîöñ öñ þåĝé ļöåð one two three four five six seven eight nine ten eleven twelve]" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "[Fåîļîñĝ Éļéméñţš one two]" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "[Þŕévéñţîñĝ þåššŵöŕð þåšţîñĝ ûñðéŕmîñéš ĝööð šéçûŕîţý þöļîçý. ᐅ[ᐊĻéåŕñ möŕéᐅ](https://web.dev/password-inputs-can-be-pasted-into/)ᐊ. one two three four five six seven eight nine ten eleven twelve thirteen fourteen]" }, diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 36cdf7e095cb..acce4a0dab86 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -695,9 +695,6 @@ "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́ŷ ṕôĺîćŷ. [Ĺêár̂ń m̂ór̂é](https://web.dev/password-inputs-can-be-pasted-into/)." }, @@ -1259,6 +1256,15 @@ "lighthouse-core/audits/timing-budget.js | title": { "message": "T̂ím̂ín̂ǵ b̂úd̂ǵêt́" }, + "lighthouse-core/audits/unsized-images.js | description": { + "message": "Âĺŵáŷś îńĉĺûd́ê éx̂ṕl̂íĉít̂ ẃîd́t̂h́ âńd̂ h́êíĝh́t̂ ón̂ ím̂áĝé êĺêḿêńt̂ś t̂ó r̂éd̂úĉé l̂áŷóût́ ŝh́îf́t̂ś âńd̂ ím̂ṕr̂óv̂é ĈĹŜ. [Ĺêár̂ń m̂ór̂é](https://web.dev/optimize-cls/#images-without-dimensions)" + }, + "lighthouse-core/audits/unsized-images.js | failureTitle": { + "message": "Îḿâǵê él̂ém̂én̂t́ŝ d́ô ńôt́ ĥáv̂é êx́p̂ĺîćît́ `width` âńd̂ `height`" + }, + "lighthouse-core/audits/unsized-images.js | title": { + "message": "Îḿâǵê él̂ém̂én̂t́ŝ h́âv́ê éx̂ṕl̂íĉít̂ `width` án̂d́ `height`" + }, "lighthouse-core/audits/user-timings.js | columnType": { "message": "T̂ýp̂é" }, @@ -1496,6 +1502,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnElement": { "message": "Êĺêḿêńt̂" }, + "lighthouse-core/lib/i18n/i18n.js | columnFailingElem": { + "message": "F̂áîĺîńĝ Él̂ém̂én̂t́ŝ" + }, "lighthouse-core/lib/i18n/i18n.js | columnLocation": { "message": "L̂óĉát̂íôń" }, diff --git a/lighthouse-core/lib/i18n/locales/es-419.json b/lighthouse-core/lib/i18n/locales/es-419.json index 19e97541a2d6..dbfac9d0d9ba 100644 --- a/lighthouse-core/lib/i18n/locales/es-419.json +++ b/lighthouse-core/lib/i18n/locales/es-419.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita solicitar el permiso de notificaciones al cargar la página" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementos con errores" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Evitar el pegado de contraseñas debilita las buenas políticas de seguridad. [Obtén más información](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/es.json b/lighthouse-core/lib/i18n/locales/es.json index 37ac2f413249..4ec50243ee28 100644 --- a/lighthouse-core/lib/i18n/locales/es.json +++ b/lighthouse-core/lib/i18n/locales/es.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita solicitar el permiso de notificación al cargar la página" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementos con errores" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Evitar que se pueda pegar texto en el campo de contraseña debilita una buena política de seguridad. [Más información](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/fi.json b/lighthouse-core/lib/i18n/locales/fi.json index 0071bf948297..3aa993b850ab 100644 --- a/lighthouse-core/lib/i18n/locales/fi.json +++ b/lighthouse-core/lib/i18n/locales/fi.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Välttää ilmoitusten käyttöoikeuden pyytämistä sivun latauksessa" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Hylätyt elementit" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Salasanan liittämisen estäminen on hyvän tietoturvakäytännön vastaista. [Lue lisää](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/fil.json b/lighthouse-core/lib/i18n/locales/fil.json index 4d7eac318183..5e5fe0373a43 100644 --- a/lighthouse-core/lib/i18n/locales/fil.json +++ b/lighthouse-core/lib/i18n/locales/fil.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Iniiwasan ang paghiling ng pahintulot sa notification sa pag-load ng page" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Mga Hindi Nakapasang Element" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Pinapahina ng paghadlang sa pag-paste ng password ang magandang patakarang panseguridad. [Matuto pa](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/fr.json b/lighthouse-core/lib/i18n/locales/fr.json index 403db4dbeed9..dc78d0549353 100644 --- a/lighthouse-core/lib/i18n/locales/fr.json +++ b/lighthouse-core/lib/i18n/locales/fr.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Aucune autorisation d'envoi de notifications n'est demandée au chargement de la page" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Éléments non conformes" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Empêcher la copie de contenu dans les champs de mot de passe nuit aux règles de sécurité. [En savoir plus](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/he.json b/lighthouse-core/lib/i18n/locales/he.json index 9e1cce08ee4b..9e827bb15d0a 100644 --- a/lighthouse-core/lib/i18n/locales/he.json +++ b/lighthouse-core/lib/i18n/locales/he.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "הדף לא מבקש הרשאה להתראות במהלך טעינת הדף" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "רכיבים שנכשלו בבדיקה" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "מניעה של הדבקת סיסמאות פוגעת ביכולת לקיים מדיניות אבטחה טובה. [מידע נוסף](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/hi.json b/lighthouse-core/lib/i18n/locales/hi.json index ca4338c5b0d1..f8b34af568aa 100644 --- a/lighthouse-core/lib/i18n/locales/hi.json +++ b/lighthouse-core/lib/i18n/locales/hi.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "पेज लोड पर सूचना भेजने की मंज़ूरी का अनुरोध नहीं किया जाता" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "फ़ेल होने वाले एलिमेंट" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "पासवर्ड वाले फ़ील्ड में कुछ कॉपी करके चिपकाने की सुविधा न लागू करने का मतलब है एक अच्छी सुरक्षा नीति को कमज़ोर समझना. [ज़्यादा जानें](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/hr.json b/lighthouse-core/lib/i18n/locales/hr.json index b49455281476..17a74ee3ac92 100644 --- a/lighthouse-core/lib/i18n/locales/hr.json +++ b/lighthouse-core/lib/i18n/locales/hr.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Izbjegava traženje dopuštenja za obavještavanje pri učitavanju stranice" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementi koji nisu prošli provjeru" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Sprječavanje lijepljenja zaporke narušava kvalitetu dobrih sigurnosnih pravila. [Saznajte više](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/hu.json b/lighthouse-core/lib/i18n/locales/hu.json index 9fbf515869cc..2875d151b753 100644 --- a/lighthouse-core/lib/i18n/locales/hu.json +++ b/lighthouse-core/lib/i18n/locales/hu.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Kerüli az értesítésekre vonatkozó engedély kérését oldalbetöltéskor" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Hibás elemek" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "A jelszóbeillesztés megakadályozása rossz biztonsági gyakorlat. [További információ](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/id.json b/lighthouse-core/lib/i18n/locales/id.json index 6a34c17e2f40..e90ffd6f0719 100644 --- a/lighthouse-core/lib/i18n/locales/id.json +++ b/lighthouse-core/lib/i18n/locales/id.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Menghindari meminta izin notifikasi pada pemuatan halaman" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elemen yang Gagal" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Mencegah menempelkan sandi akan merusak kebijakan keamanan yang baik. [Pelajari lebih lanjut](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/it.json b/lighthouse-core/lib/i18n/locales/it.json index 8896a99dadee..22d0f7fa04f0 100644 --- a/lighthouse-core/lib/i18n/locales/it.json +++ b/lighthouse-core/lib/i18n/locales/it.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita di chiedere l'autorizzazione di accesso alle notifiche durante il caricamento della pagina" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementi che non consentono di incollare" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Impedire di incollare le password pregiudica l'efficacia delle norme di sicurezza. [Ulteriori informazioni](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ja.json b/lighthouse-core/lib/i18n/locales/ja.json index ae68b937e6d4..22c9103849b7 100644 --- a/lighthouse-core/lib/i18n/locales/ja.json +++ b/lighthouse-core/lib/i18n/locales/ja.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "ページの読み込み時に通知の許可はリクエストされません" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "問題のある要素" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "パスワードの貼り付けを禁止すると、良好なセキュリティ ポリシーが損なわれます。[詳細](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ko.json b/lighthouse-core/lib/i18n/locales/ko.json index 21e435c6dff9..d9b1a06d3fab 100644 --- a/lighthouse-core/lib/i18n/locales/ko.json +++ b/lighthouse-core/lib/i18n/locales/ko.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "페이지 로드 시 알림 권한 요청 방지하기" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "통과하지 못한 요소" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "비밀번호 붙여넣기 방지로 인해 타당한 보안 정책이 저해됩니다. [자세히 알아보기](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/lt.json b/lighthouse-core/lib/i18n/locales/lt.json index 4298a15e14a7..5a0e44676521 100644 --- a/lighthouse-core/lib/i18n/locales/lt.json +++ b/lighthouse-core/lib/i18n/locales/lt.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Įkeliant puslapį vengiama pateikti užklausą dėl pranešimų leidimo" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Netinkami elementai" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Neleidžiant įklijuoti slaptažodžių, pažeidžiama tinkamos saugos politika. [Sužinokite daugiau](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/lv.json b/lighthouse-core/lib/i18n/locales/lv.json index 4a2665056d76..423d70df3b05 100644 --- a/lighthouse-core/lib/i18n/locales/lv.json +++ b/lighthouse-core/lib/i18n/locales/lv.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Netiek pieprasīta paziņojumu atļauja lapas ielādei" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Nederīgi elementi" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Paroles ielīmēšanas novēršana neatbilst labai drošības politikai. [Uzziniet vairāk](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/nl.json b/lighthouse-core/lib/i18n/locales/nl.json index aa17944ec73b..0d19391fae4a 100644 --- a/lighthouse-core/lib/i18n/locales/nl.json +++ b/lighthouse-core/lib/i18n/locales/nl.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Vermijdt verzoeken om de meldingsrechten bij laden van pagina" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Mislukte elementen" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Verhindering van het plakken van wachtwoorden ondermijnt een goed beveiligingsbeleid. [Meer informatie](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/no.json b/lighthouse-core/lib/i18n/locales/no.json index af53abb1a129..25760d03f36f 100644 --- a/lighthouse-core/lib/i18n/locales/no.json +++ b/lighthouse-core/lib/i18n/locales/no.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Unngår å spørre om varseltillatelsen ved sideinnlasting" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementer som ikke besto kontrollen" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Å hindre brukere i å lime inn passord underminerer gode retningslinjer for sikkerhet. [Finn ut mer](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/pl.json b/lighthouse-core/lib/i18n/locales/pl.json index a89a6cd25e0b..bae13d159f98 100644 --- a/lighthouse-core/lib/i18n/locales/pl.json +++ b/lighthouse-core/lib/i18n/locales/pl.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Nie pyta o zgodę na wyświetlanie powiadomień podczas wczytywania strony" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Nieprawidłowe elementy" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Uniemożliwianie wklejania haseł jest sprzeczne z dobrymi zasadami bezpieczeństwa. [Więcej informacji](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/pt-PT.json b/lighthouse-core/lib/i18n/locales/pt-PT.json index 98117a441ba6..b4420929fa26 100644 --- a/lighthouse-core/lib/i18n/locales/pt-PT.json +++ b/lighthouse-core/lib/i18n/locales/pt-PT.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita a solicitação da autorização de notificações no carregamento da página" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementos reprovados" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Impedir a colagem de palavras-passe compromete o cumprimento de uma política de segurança adequada. [Saiba mais](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/pt.json b/lighthouse-core/lib/i18n/locales/pt.json index c1037eb91b99..6b879c6ab76f 100644 --- a/lighthouse-core/lib/i18n/locales/pt.json +++ b/lighthouse-core/lib/i18n/locales/pt.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evita o pedido da permissão de notificação no carregamento de página" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementos com falha" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Impedir a colagem da senha prejudica a política de boa segurança. [Saiba mais](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ro.json b/lighthouse-core/lib/i18n/locales/ro.json index f949a5510ddb..69f993929d34 100644 --- a/lighthouse-core/lib/i18n/locales/ro.json +++ b/lighthouse-core/lib/i18n/locales/ro.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Evită solicitarea permisiunii de notificare la încărcarea paginii" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elemente cu probleme" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Împiedicarea inserării parolelor subminează buna politică de securitate. [Află mai multe](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ru.json b/lighthouse-core/lib/i18n/locales/ru.json index cc8f90bdd6b0..dcffb7b36103 100644 --- a/lighthouse-core/lib/i18n/locales/ru.json +++ b/lighthouse-core/lib/i18n/locales/ru.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Разрешение на отправку уведомлений не запрашивается при загрузке страницы" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Элементы, запрещающие вставку из буфера обмена" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Запрет на вставку пароля из буфера обмена отрицательно сказывается на безопасности пользователей. [Подробнее…](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sk.json b/lighthouse-core/lib/i18n/locales/sk.json index 604684695ffa..b294e9a5744b 100644 --- a/lighthouse-core/lib/i18n/locales/sk.json +++ b/lighthouse-core/lib/i18n/locales/sk.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Nepožaduje povolenie na upozornenie pri načítaní stránky" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Prvky s chybami" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Ak zakážete prilepovanie hesiel, zhoršíte kvalitu zabezpečenia. [Ďalšie informácie](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sl.json b/lighthouse-core/lib/i18n/locales/sl.json index 4b72972d5176..5094fe157c34 100644 --- a/lighthouse-core/lib/i18n/locales/sl.json +++ b/lighthouse-core/lib/i18n/locales/sl.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Ne zahteva dovoljenja za obvestila pri nalaganju strani" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Neuspešni elementi" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Preprečevanje lepljenja gesel omeji dober pravilnik o varnosti. [Več o tem](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/sr-Latn.json b/lighthouse-core/lib/i18n/locales/sr-Latn.json index 165f22d1dc8a..ca6fe54a939c 100644 --- a/lighthouse-core/lib/i18n/locales/sr-Latn.json +++ b/lighthouse-core/lib/i18n/locales/sr-Latn.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Izbegavajte traženje dozvole za obaveštenja pri učitavanju stranice" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Elementi koji nisu prošli proveru" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Sprečavanje lepljenja lozinke narušava dobre smernice za bezbednost. [Saznajte više](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/sr.json b/lighthouse-core/lib/i18n/locales/sr.json index da2dcbaac56a..81101ab7fe43 100644 --- a/lighthouse-core/lib/i18n/locales/sr.json +++ b/lighthouse-core/lib/i18n/locales/sr.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Избегавајте тражење дозволе за обавештења при учитавању странице" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Елементи који нису прошли проверу" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Спречавање лепљења лозинке нарушава добре смернице за безбедност. [Сазнајте више](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/sv.json b/lighthouse-core/lib/i18n/locales/sv.json index 3346444f2fd1..5829bc1987f6 100644 --- a/lighthouse-core/lib/i18n/locales/sv.json +++ b/lighthouse-core/lib/i18n/locales/sv.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Undviker att begära aviseringsbehörighet vid sidinläsning" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Element med fel" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Att förhindra att lösenord klistras in underminerar en bra säkerhetspolicy. [Läs mer](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/ta.json b/lighthouse-core/lib/i18n/locales/ta.json index dd1216bf094b..990c7bf3e419 100644 --- a/lighthouse-core/lib/i18n/locales/ta.json +++ b/lighthouse-core/lib/i18n/locales/ta.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "பக்கம் ஏற்றப்படும்போது அதுகுறித்த அறிவிப்பைத் தெரிந்துகொள்வதற்கான அனுமதியைக் கோராது" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "தோல்வியுறும் உறுப்புகள்" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "கடவுச்சொல்லை ஒட்டுவதைத் தடுப்பதால் நல்ல பாதுகாப்புக் கொள்கை பாதிக்கப்படுகிறது. [மேலும் அறிக](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/te.json b/lighthouse-core/lib/i18n/locales/te.json index 8278f3899d39..a04b94b92000 100644 --- a/lighthouse-core/lib/i18n/locales/te.json +++ b/lighthouse-core/lib/i18n/locales/te.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "పేజీ లోడ్ సమయంలో నోటిఫికేషన్ అనుమతిని అభ్యర్థించడం నివారిస్తుంది" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "విఫలం అవుతున్న మూలకాలు" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "పాస్‌వర్డ్‌లో అతికించే చర్యను నిరోధించడం వలన మంచి భద్రతా విధానానికి ఆటంకం ఏర్పడుతుంది. [మరింత తెలుసుకోండి](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/th.json b/lighthouse-core/lib/i18n/locales/th.json index 0ed755f59e1b..afad3c096b7b 100644 --- a/lighthouse-core/lib/i18n/locales/th.json +++ b/lighthouse-core/lib/i18n/locales/th.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "หลีกเลี่ยงการขอสิทธิ์การแจ้งเตือนในการโหลดหน้าเว็บ" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "องค์ประกอบที่ไม่ผ่านการตรวจสอบ" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "การป้องกันการวางรหัสผ่านทำให้นโยบายความปลอดภัยที่ดีอ่อนแอลง [ดูข้อมูลเพิ่มเติม](https://web.dev/password-inputs-can-be-pasted-into/)" }, diff --git a/lighthouse-core/lib/i18n/locales/tr.json b/lighthouse-core/lib/i18n/locales/tr.json index caacf3cbfd27..625acedc23ce 100644 --- a/lighthouse-core/lib/i18n/locales/tr.json +++ b/lighthouse-core/lib/i18n/locales/tr.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Sayfa yüklemede bildirim izni istemiyor" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Başarısız Öğeler" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Şifre yapıştırmanın engellenmesi, iyi güvenlik politikasına zarar verir. [Daha fazla bilgi](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/uk.json b/lighthouse-core/lib/i18n/locales/uk.json index 291322de58d1..2225b7ed08be 100644 --- a/lighthouse-core/lib/i18n/locales/uk.json +++ b/lighthouse-core/lib/i18n/locales/uk.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Уникає надсилання запитів на показ сповіщень під час завантаження сторінки" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Відхилені елементи" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Якщо заборонити вставляти пароль, це порушить правила щодо високого рівня безпеки. [Докладніше](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/vi.json b/lighthouse-core/lib/i18n/locales/vi.json index 71b41df978c9..9d587e0ad819 100644 --- a/lighthouse-core/lib/i18n/locales/vi.json +++ b/lighthouse-core/lib/i18n/locales/vi.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "Tránh yêu cầu quyền truy cập thông báo khi tải trang" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "Các phần tử không đạt" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "Việc ngăn dán mật khẩu sẽ làm giảm tác dụng của chính sách bảo mật hiệu quả. [Tìm hiểu thêm](https://web.dev/password-inputs-can-be-pasted-into/)." }, diff --git a/lighthouse-core/lib/i18n/locales/zh-HK.json b/lighthouse-core/lib/i18n/locales/zh-HK.json index d802ca38a5ae..34800ff237eb 100644 --- a/lighthouse-core/lib/i18n/locales/zh-HK.json +++ b/lighthouse-core/lib/i18n/locales/zh-HK.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "避免在載入網頁時要求使用者允許網站顯示通知" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "審核失敗的元素" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "禁止貼上密碼會對安全政策造成不良影響。[瞭解詳情](https://web.dev/password-inputs-can-be-pasted-into/)。" }, diff --git a/lighthouse-core/lib/i18n/locales/zh-TW.json b/lighthouse-core/lib/i18n/locales/zh-TW.json index 39084ed49249..531efb947203 100644 --- a/lighthouse-core/lib/i18n/locales/zh-TW.json +++ b/lighthouse-core/lib/i18n/locales/zh-TW.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "避免在載入網頁時要求使用者允許網站顯示通知" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "未通過稽核的元素" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "禁止貼上密碼會對安全性政策造成不良影響[瞭解詳情](https://web.dev/password-inputs-can-be-pasted-into/)。" }, diff --git a/lighthouse-core/lib/i18n/locales/zh.json b/lighthouse-core/lib/i18n/locales/zh.json index 7ffa516e1daa..318dd532415f 100644 --- a/lighthouse-core/lib/i18n/locales/zh.json +++ b/lighthouse-core/lib/i18n/locales/zh.json @@ -689,9 +689,6 @@ "lighthouse-core/audits/dobetterweb/notification-on-start.js | title": { "message": "避免在网页加载时请求通知权限" }, - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": { - "message": "失败的元素" - }, "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": { "message": "阻止密码粘贴,会破坏良好的安全政策。[了解详情](https://web.dev/password-inputs-can-be-pasted-into/)。" }, diff --git a/lighthouse-core/test/audits/unsized-images-test.js b/lighthouse-core/test/audits/unsized-images-test.js new file mode 100644 index 000000000000..4ee5eab63534 --- /dev/null +++ b/lighthouse-core/test/audits/unsized-images-test.js @@ -0,0 +1,418 @@ +/** + * @license Copyright 2020 The Lighthouse Authors. 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 UnSizedImagesAudit = require('../../audits/unsized-images.js'); + +/* eslint-env jest */ + +function generateImage(props, src = 'https://google.com/logo.png', isCss = false) { + const image = {src, isCss}; + Object.assign(image, props); + return image; +} + +describe('Sized images audit', () => { + function runAudit(props) { + const result = UnSizedImagesAudit.audit({ + ImageElements: [ + generateImage(props), + ], + }); + return result; + } + + it('passes when an image is a css image', async () => { + const result = await runAudit({ + isCss: true, + attributeWidth: '', + attributeHeight: '', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(1); + }); + + describe('has empty width', () => { + it('fails when an image only has attribute height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '100', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image only has css height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: '', + cssHeight: '100', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image only has attribute height & css height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '100', + cssWidth: '', + cssHeight: '100', + }); + expect(result.score).toEqual(0); + }); + }); + + describe('has empty height', () => { + it('fails when an image only has attribute width', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image only has css width', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: '100', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image only has attribute width & css width', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '', + cssWidth: '100', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + }); + + it('fails when an image has empty width and height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + describe('has valid width and height', () => { + it('passes when an image has attribute width and css height', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '', + cssWidth: '', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has attribute width and attribute height', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '100', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css width and attribute height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '100', + cssWidth: '100', + cssHeight: '', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css width and css height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: '100', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css & attribute width and css height', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '', + cssWidth: '100', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css & attribute width and attribute height', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '100', + cssWidth: '100', + cssHeight: '', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css & attribute height and css width', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '100', + cssWidth: '100', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css & attribute height and attribute width', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '100', + cssWidth: '', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has css & attribute height and css & attribute width', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '100', + cssWidth: '100', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + }); + + describe('has invalid width', () => { + it('fails when an image has invalid width attribute', async () => { + const result = await runAudit({ + attributeWidth: '-200', + attributeHeight: '100', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image has invalid height attribute', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '-200', + cssWidth: '', + cssHeight: '', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image has invalid css width', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: 'auto', + cssHeight: '100', + }); + expect(result.score).toEqual(0); + }); + + it('fails when an image has invalid css height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '', + cssWidth: '100', + cssHeight: 'auto', + }); + expect(result.score).toEqual(0); + }); + + it('passes when an image has invalid width attribute, and valid css width', async () => { + const result = await runAudit({ + attributeWidth: '-200', + attributeHeight: '100', + cssWidth: '100', + cssHeight: '', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has invalid height attribute, and valid css height', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '-200', + cssWidth: '', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has invalid css width, and valid attribute width', async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '', + cssWidth: 'auto', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has invalid css height, and valid attribute height', async () => { + const result = await runAudit({ + attributeWidth: '', + attributeHeight: '100', + cssWidth: '100', + cssHeight: 'auto', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has invalid css width & height, and valid attribute width & height', + async () => { + const result = await runAudit({ + attributeWidth: '100', + attributeHeight: '100', + cssWidth: 'auto', + cssHeight: 'auto', + }); + expect(result.score).toEqual(1); + }); + + it('passes when an image has invalid attribute width & height, and valid css width & height', + async () => { + const result = await runAudit({ + attributeWidth: '-200', + attributeHeight: '-200', + cssWidth: '100', + cssHeight: '100', + }); + expect(result.score).toEqual(1); + }); + + it('fails when an image has invalid attribute width & height, and invalid css width & height', + async () => { + const result = await runAudit({ + attributeWidth: '-200', + attributeHeight: '-200', + cssWidth: 'auto', + cssHeight: 'auto', + }); + expect(result.score).toEqual(0); + }); + }); + + it('is not applicable when there are no images', async () => { + const result = await UnSizedImagesAudit.audit({ + ImageElements: [], + }); + expect(result.notApplicable).toEqual(true); + expect(result.score).toEqual(1); + }); + + it('can return multiple unsized images', async () => { + const result = await UnSizedImagesAudit.audit({ + ImageElements: [ + generateImage( + { + attributeWidth: '', + attributeHeight: '', + cssWidth: '', + cssHeight: '', + }, + 'image1.png' + ), + generateImage( + { + attributeWidth: '100', + attributeHeight: '150', + }, + 'image2.png' + ), + generateImage( + { + attributeWidth: '', + attributeHeight: '', + cssWidth: '', + cssHeight: '', + }, + 'image3.png' + ), + ], + }); + expect(result.score).toEqual(0); + expect(result.details.items).toHaveLength(2); + const srcs = result.details.items.map(item => item.url); + expect(srcs).toEqual(['image1.png', 'image3.png']); + }); +}); + +describe('Size attribute validity check', () => { + it('fails if it is empty', () => { + expect(UnSizedImagesAudit.isValidAttr('')).toEqual(false); + }); + + it('fails on non-numeric characters', () => { + expect(UnSizedImagesAudit.isValidAttr('zero')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('1002$')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('s-5')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('3,000')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('100.0')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('2/3')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('-2020')).toEqual(false); + expect(UnSizedImagesAudit.isValidAttr('+2020')).toEqual(false); + }); + + it('fails on zero input', () => { + expect(UnSizedImagesAudit.isValidAttr('0')).toEqual(false); + }); + + it('passes on non-zero non-negative integer input', () => { + expect(UnSizedImagesAudit.isValidAttr('1')).toEqual(true); + expect(UnSizedImagesAudit.isValidAttr('250')).toEqual(true); + expect(UnSizedImagesAudit.isValidAttr('4000000')).toEqual(true); + }); +}); + +describe('CSS size property validity check', () => { + it('fails if it was never defined', () => { + expect(UnSizedImagesAudit.isValidCss(undefined)).toEqual(false); + }); + + it('fails if it is empty', () => { + expect(UnSizedImagesAudit.isValidCss('')).toEqual(false); + }); + + it('fails if it is auto', () => { + expect(UnSizedImagesAudit.isValidCss('auto')).toEqual(false); + }); + + it('passes if it is defined and not auto', () => { + expect(UnSizedImagesAudit.isValidCss('200')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('300.5')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('150px')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('80%')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('5cm')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('20rem')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('7vw')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('-20')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('0')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('three')).toEqual(true); + expect(UnSizedImagesAudit.isValidCss('-20')).toEqual(true); + }); +}); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index 1b3b3c903b5f..686c0255c53c 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -6891,13 +6891,14 @@ "lighthouse-core/audits/accessibility/color-contrast.js | description": [ "audits[color-contrast].description" ], - "lighthouse-core/audits/accessibility/axe-audit.js | failingElementsHeader": [ + "lighthouse-core/lib/i18n/i18n.js | columnFailingElem": [ "audits[color-contrast].details.headings[0].text", "audits[html-has-lang].details.headings[0].text", "audits[image-alt].details.headings[0].text", "audits.label.details.headings[0].text", "audits[link-name].details.headings[0].text", - "audits[object-alt].details.headings[0].text" + "audits[object-alt].details.headings[0].text", + "audits[password-inputs-can-be-pasted-into].details.headings[0].text" ], "lighthouse-core/audits/accessibility/definition-list.js | title": [ "audits[definition-list].title" @@ -7348,9 +7349,6 @@ "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | description": [ "audits[password-inputs-can-be-pasted-into].description" ], - "lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js | columnFailingElem": [ - "audits[password-inputs-can-be-pasted-into].details.headings[0].text" - ], "lighthouse-core/audits/dobetterweb/uses-http2.js | title": [ "audits[uses-http2].title" ], diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index ba7ef38daa8d..3851373ae865 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -410,6 +410,14 @@ declare global { naturalWidth: number; /** The natural height of the underlying image, uses img.naturalHeight. See https://codepen.io/patrickhulce/pen/PXvQbM for examples. */ naturalHeight: number; + /** The raw width attribute of the image element. CSS images will be set to the empty string. */ + attributeWidth: string; + /** The raw height attribute of the image element. CSS images will be set to the empty string. */ + attributeHeight: string; + /** The CSS width property of the image element. */ + cssWidth?: string | undefined; + /** The CSS height property of the image element. */ + cssHeight?: string | undefined; /** The BoundingClientRect of the element. */ clientRect: { top: number; @@ -434,6 +442,11 @@ declare global { usesSrcSetDensityDescriptor: boolean; /** The size of the underlying image file in bytes. 0 if the file could not be identified. */ resourceSize: number; + /** Path that uniquely identifies the node in the DOM */ + devtoolsNodePath: string; + snippet: string; + selector: string; + nodeLabel: string; /** The MIME type of the underlying image file. */ mimeType?: string; /** The loading attribute of the image. */