lighthouse 9.5.0-dev.20220404 → 9.5.0-dev.20220407

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4999,7 +4999,7 @@ function computeWindowNameSuffix(json) {
4999
4999
  // @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
5000
5000
  const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
5001
5001
  const fetchTime = json.fetchTime || fallbackFetchTime;
5002
- return `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
5002
+ return `${json.lighthouseVersion}-${json.finalUrl}-${fetchTime}`;
5003
5003
  }
5004
5004
 
5005
5005
  /**
@@ -5081,7 +5081,6 @@ function openTreemap(json) {
5081
5081
  /** @type {LH.Treemap.Options} */
5082
5082
  const treemapOptions = {
5083
5083
  lhr: {
5084
- requestedUrl: json.requestedUrl,
5085
5084
  finalUrl: json.finalUrl,
5086
5085
  audits: {
5087
5086
  'script-treemap-data': json.audits['script-treemap-data'],
@@ -188,7 +188,7 @@ class ja{constructor(e,a){this._document=e,this._lighthouseChannel="unknown",thi
188
188
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
189
  * See the License for the specific language governing permissions and
190
190
  * limitations under the License.
191
- */function cn(){const e=window.location.host.endsWith(".vercel.app"),a=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:a?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function dn(e){const a=e.generatedTime,n=e.fetchTime||a;return`${e.lighthouseVersion}-${e.requestedUrl}-${n}`}async function mn(e,a,n){const t=new URL(a),i=Boolean(window.CompressionStream);t.hash=await un.toBase64(JSON.stringify(e),{gzip:i}),i&&t.searchParams.set("gzip","1"),window.open(t.toString(),n)}async function hn(e){const a="viewer-"+dn(e);!function(e,a,n){const t=new URL(a).origin;window.addEventListener("message",(function a(n){n.origin===t&&i&&n.data.opened&&(i.postMessage(e,t),window.removeEventListener("message",a))}));const i=window.open(a,n)}({lhr:e},cn()+"/viewer/",a)}
191
+ */function cn(){const e=window.location.host.endsWith(".vercel.app"),a=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:a?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function dn(e){const a=e.generatedTime,n=e.fetchTime||a;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function mn(e,a,n){const t=new URL(a),i=Boolean(window.CompressionStream);t.hash=await un.toBase64(JSON.stringify(e),{gzip:i}),i&&t.searchParams.set("gzip","1"),window.open(t.toString(),n)}async function hn(e){const a="viewer-"+dn(e);!function(e,a,n){const t=new URL(a).origin;window.addEventListener("message",(function a(n){n.origin===t&&i&&n.data.opened&&(i.postMessage(e,t),window.removeEventListener("message",a))}));const i=window.open(a,n)}({lhr:e},cn()+"/viewer/",a)}
192
192
  /**
193
193
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
194
194
  * 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
@@ -220,7 +220,7 @@ class gn{constructor(e){this._dom=e,this._toggleEl,this._menuEl,this.onDocumentK
220
220
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
221
221
  * See the License for the specific language governing permissions and
222
222
  * limitations under the License.
223
- */class yn{constructor(e,a={}){this.json,this._dom=e,this._opts=a,this._topbar=a.omitTopbar?null:new vn(this,e),this.onMediaQueryChange=this.onMediaQueryChange.bind(this)}initFeatures(e){this.json=e,this._topbar&&(this._topbar.enable(e),this._topbar.resetUIState()),this._setupMediaQueryListeners(),this._setupThirdPartyFilter(),this._setupElementScreenshotOverlay(this._dom.rootEl);const a=this._dom.isDevTools()||this._opts.disableDarkMode||this._opts.disableAutoDarkModeAndFireworks;!a&&window.matchMedia("(prefers-color-scheme: dark)").matches&&sn(this._dom,!0);const n=["performance","accessibility","best-practices","seo"].every((a=>{const n=e.categories[a];return n&&1===n.score})),t=this._opts.disableFireworks||this._opts.disableAutoDarkModeAndFireworks;n&&!t&&(this._enableFireworks(),a||sn(this._dom,!0));if(e.categories.performance&&e.categories.performance.auditRefs.some((a=>Boolean("metrics"===a.group&&e.audits[a.id].errorMessage)))){this._dom.find("input.lh-metrics-toggle__input",this._dom.rootEl).checked=!0}this.json.audits["script-treemap-data"]&&this.json.audits["script-treemap-data"].details&&this.addButton({text:de.i18n.strings.viewTreemapLabel,icon:"treemap",onClick:()=>function(e){if(!e.audits["script-treemap-data"].details)throw new Error("no script treemap data found");mn({lhr:{requestedUrl:e.requestedUrl,finalUrl:e.finalUrl,audits:{"script-treemap-data":e.audits["script-treemap-data"]},configSettings:{locale:e.configSettings.locale}}},cn()+"/treemap/","treemap-"+dn(e))}(this.json)}),this._opts.onViewTrace&&this.addButton({text:"simulate"===e.configSettings.throttlingMethod?de.i18n.strings.viewOriginalTraceLabel:de.i18n.strings.viewTraceLabel,onClick:()=>this._opts.onViewTrace?.()}),this._opts.getStandaloneReportHTML&&this._dom.find('a[data-action="save-html"]',this._dom.rootEl).classList.remove("lh-hidden");for(const e of this._dom.findAll("[data-i18n]",this._dom.rootEl)){const a=e.getAttribute("data-i18n");e.textContent=de.i18n.strings[a]}}addButton(e){const a=this._dom.rootEl.querySelector(".lh-audit-group--metrics");if(!a)return;let n=a.querySelector(".lh-buttons");n||(n=this._dom.createChildOf(a,"div","lh-buttons"));const t=["lh-button"];e.icon&&(t.push("lh-report-icon"),t.push(`lh-report-icon--${e.icon}`));const i=this._dom.createChildOf(n,"button",t.join(" "));return i.textContent=e.text,i.addEventListener("click",e.onClick),i}resetUIState(){this._topbar&&this._topbar.resetUIState()}getReportHtml(){if(!this._opts.getStandaloneReportHTML)throw new Error("`getStandaloneReportHTML` is not set");return this.resetUIState(),this._opts.getStandaloneReportHTML()}saveAsGist(){throw new Error("Cannot save as gist from base report")}_enableFireworks(){this._dom.find(".lh-scores-container",this._dom.rootEl).classList.add("lh-score100")}_setupMediaQueryListeners(){const e=self.matchMedia("(max-width: 500px)");e.addListener(this.onMediaQueryChange),this.onMediaQueryChange(e)}_resetUIState(){this._topbar&&this._topbar.resetUIState()}onMediaQueryChange(e){this._dom.rootEl.classList.toggle("lh-narrow",e.matches)}_setupThirdPartyFilter(){const e=["uses-rel-preconnect","third-party-facades"],a=["legacy-javascript"];Array.from(this._dom.rootEl.querySelectorAll("table.lh-table")).filter((e=>e.querySelector("td.lh-table-column--url, td.lh-table-column--source-location"))).filter((a=>{const n=a.closest(".lh-audit");if(!n)throw new Error(".lh-table not within audit");return!e.includes(n.id)})).forEach((e=>{const n=function(e){return Array.from(e.tBodies[0].rows)}(e),t=this._getThirdPartyRows(n,this.json.finalUrl),i=this._dom.createComponent("3pFilter"),o=this._dom.find("input",i);o.addEventListener("change",(e=>{const a=e.target instanceof HTMLInputElement&&!e.target.checked;let i=!0,o=n[0];for(;o;){const e=a&&t.includes(o);do{o.classList.toggle("lh-row--hidden",e),o.classList.toggle("lh-row--even",!e&&i),o.classList.toggle("lh-row--odd",!e&&!i),o=o.nextElementSibling}while(o&&o.classList.contains("lh-sub-item-row"));e||(i=!i)}})),this._dom.find(".lh-3p-filter-count",i).textContent=`${t.length}`,this._dom.find(".lh-3p-ui-string",i).textContent=de.i18n.strings.thirdPartyResourcesLabel;const r=t.length===n.length,s=!t.length;if((r||s)&&(this._dom.find("div.lh-3p-filter",i).hidden=!0),!e.parentNode)return;e.parentNode.insertBefore(i,e);const l=e.closest(".lh-audit");if(!l)throw new Error(".lh-table not within audit");a.includes(l.id)&&!r&&o.click()}))}_setupElementScreenshotOverlay(e){const a=this.json.audits["full-page-screenshot"]&&this.json.audits["full-page-screenshot"].details&&"full-page-screenshot"===this.json.audits["full-page-screenshot"].details.type&&this.json.audits["full-page-screenshot"].details;a&&en.installOverlayFeature({dom:this._dom,rootEl:e,overlayContainerEl:e,fullPageScreenshot:a})}_getThirdPartyRows(e,a){const n=[],t=de.getRootDomain(a);for(const a of e){if(a.classList.contains("lh-sub-item-row"))continue;const e=a.querySelector("div.lh-text__url");if(!e)continue;const i=e.dataset.url;if(!i)continue;de.getRootDomain(i)!==t&&n.push(a)}return n}_saveFile(e){const a=e.type.match("json")?".json":".html",n=bn.getLhrFilenamePrefix(this.json)+a;this._opts.onSaveFileOverride?this._opts.onSaveFileOverride(e,n):this._dom.saveFile(e,n)}}
223
+ */class yn{constructor(e,a={}){this.json,this._dom=e,this._opts=a,this._topbar=a.omitTopbar?null:new vn(this,e),this.onMediaQueryChange=this.onMediaQueryChange.bind(this)}initFeatures(e){this.json=e,this._topbar&&(this._topbar.enable(e),this._topbar.resetUIState()),this._setupMediaQueryListeners(),this._setupThirdPartyFilter(),this._setupElementScreenshotOverlay(this._dom.rootEl);const a=this._dom.isDevTools()||this._opts.disableDarkMode||this._opts.disableAutoDarkModeAndFireworks;!a&&window.matchMedia("(prefers-color-scheme: dark)").matches&&sn(this._dom,!0);const n=["performance","accessibility","best-practices","seo"].every((a=>{const n=e.categories[a];return n&&1===n.score})),t=this._opts.disableFireworks||this._opts.disableAutoDarkModeAndFireworks;n&&!t&&(this._enableFireworks(),a||sn(this._dom,!0));if(e.categories.performance&&e.categories.performance.auditRefs.some((a=>Boolean("metrics"===a.group&&e.audits[a.id].errorMessage)))){this._dom.find("input.lh-metrics-toggle__input",this._dom.rootEl).checked=!0}this.json.audits["script-treemap-data"]&&this.json.audits["script-treemap-data"].details&&this.addButton({text:de.i18n.strings.viewTreemapLabel,icon:"treemap",onClick:()=>function(e){if(!e.audits["script-treemap-data"].details)throw new Error("no script treemap data found");mn({lhr:{finalUrl:e.finalUrl,audits:{"script-treemap-data":e.audits["script-treemap-data"]},configSettings:{locale:e.configSettings.locale}}},cn()+"/treemap/","treemap-"+dn(e))}(this.json)}),this._opts.onViewTrace&&this.addButton({text:"simulate"===e.configSettings.throttlingMethod?de.i18n.strings.viewOriginalTraceLabel:de.i18n.strings.viewTraceLabel,onClick:()=>this._opts.onViewTrace?.()}),this._opts.getStandaloneReportHTML&&this._dom.find('a[data-action="save-html"]',this._dom.rootEl).classList.remove("lh-hidden");for(const e of this._dom.findAll("[data-i18n]",this._dom.rootEl)){const a=e.getAttribute("data-i18n");e.textContent=de.i18n.strings[a]}}addButton(e){const a=this._dom.rootEl.querySelector(".lh-audit-group--metrics");if(!a)return;let n=a.querySelector(".lh-buttons");n||(n=this._dom.createChildOf(a,"div","lh-buttons"));const t=["lh-button"];e.icon&&(t.push("lh-report-icon"),t.push(`lh-report-icon--${e.icon}`));const i=this._dom.createChildOf(n,"button",t.join(" "));return i.textContent=e.text,i.addEventListener("click",e.onClick),i}resetUIState(){this._topbar&&this._topbar.resetUIState()}getReportHtml(){if(!this._opts.getStandaloneReportHTML)throw new Error("`getStandaloneReportHTML` is not set");return this.resetUIState(),this._opts.getStandaloneReportHTML()}saveAsGist(){throw new Error("Cannot save as gist from base report")}_enableFireworks(){this._dom.find(".lh-scores-container",this._dom.rootEl).classList.add("lh-score100")}_setupMediaQueryListeners(){const e=self.matchMedia("(max-width: 500px)");e.addListener(this.onMediaQueryChange),this.onMediaQueryChange(e)}_resetUIState(){this._topbar&&this._topbar.resetUIState()}onMediaQueryChange(e){this._dom.rootEl.classList.toggle("lh-narrow",e.matches)}_setupThirdPartyFilter(){const e=["uses-rel-preconnect","third-party-facades"],a=["legacy-javascript"];Array.from(this._dom.rootEl.querySelectorAll("table.lh-table")).filter((e=>e.querySelector("td.lh-table-column--url, td.lh-table-column--source-location"))).filter((a=>{const n=a.closest(".lh-audit");if(!n)throw new Error(".lh-table not within audit");return!e.includes(n.id)})).forEach((e=>{const n=function(e){return Array.from(e.tBodies[0].rows)}(e),t=this._getThirdPartyRows(n,this.json.finalUrl),i=this._dom.createComponent("3pFilter"),o=this._dom.find("input",i);o.addEventListener("change",(e=>{const a=e.target instanceof HTMLInputElement&&!e.target.checked;let i=!0,o=n[0];for(;o;){const e=a&&t.includes(o);do{o.classList.toggle("lh-row--hidden",e),o.classList.toggle("lh-row--even",!e&&i),o.classList.toggle("lh-row--odd",!e&&!i),o=o.nextElementSibling}while(o&&o.classList.contains("lh-sub-item-row"));e||(i=!i)}})),this._dom.find(".lh-3p-filter-count",i).textContent=`${t.length}`,this._dom.find(".lh-3p-ui-string",i).textContent=de.i18n.strings.thirdPartyResourcesLabel;const r=t.length===n.length,s=!t.length;if((r||s)&&(this._dom.find("div.lh-3p-filter",i).hidden=!0),!e.parentNode)return;e.parentNode.insertBefore(i,e);const l=e.closest(".lh-audit");if(!l)throw new Error(".lh-table not within audit");a.includes(l.id)&&!r&&o.click()}))}_setupElementScreenshotOverlay(e){const a=this.json.audits["full-page-screenshot"]&&this.json.audits["full-page-screenshot"].details&&"full-page-screenshot"===this.json.audits["full-page-screenshot"].details.type&&this.json.audits["full-page-screenshot"].details;a&&en.installOverlayFeature({dom:this._dom,rootEl:e,overlayContainerEl:e,fullPageScreenshot:a})}_getThirdPartyRows(e,a){const n=[],t=de.getRootDomain(a);for(const a of e){if(a.classList.contains("lh-sub-item-row"))continue;const e=a.querySelector("div.lh-text__url");if(!e)continue;const i=e.dataset.url;if(!i)continue;de.getRootDomain(i)!==t&&n.push(a)}return n}_saveFile(e){const a=e.type.match("json")?".json":".html",n=bn.getLhrFilenamePrefix(this.json)+a;this._opts.onSaveFileOverride?this._opts.onSaveFileOverride(e,n):this._dom.saveFile(e,n)}}
224
224
  /**
225
225
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
226
226
  * 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
@@ -171,7 +171,7 @@ class s{constructor(e,t){this._document=e,this._lighthouseChannel="unknown",this
171
171
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
172
172
  * See the License for the specific language governing permissions and
173
173
  * limitations under the License.
174
- */function P(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function U(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.requestedUrl}-${n}`}async function $(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await R.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function O(e){const t="viewer-"+U(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},P()+"/viewer/",t)}
174
+ */function P(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function U(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function $(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await R.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function O(e){const t="viewer-"+U(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},P()+"/viewer/",t)}
175
175
  /**
176
176
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
177
177
  * 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
@@ -203,7 +203,7 @@ class B{constructor(e){this._dom=e,this._toggleEl,this._menuEl,this.onDocumentKe
203
203
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
204
204
  * See the License for the specific language governing permissions and
205
205
  * limitations under the License.
206
- */class j{constructor(e,t={}){this.json,this._dom=e,this._opts=t,this._topbar=t.omitTopbar?null:new I(this,e),this.onMediaQueryChange=this.onMediaQueryChange.bind(this)}initFeatures(e){this.json=e,this._topbar&&(this._topbar.enable(e),this._topbar.resetUIState()),this._setupMediaQueryListeners(),this._setupThirdPartyFilter(),this._setupElementScreenshotOverlay(this._dom.rootEl);const t=this._dom.isDevTools()||this._opts.disableDarkMode||this._opts.disableAutoDarkModeAndFireworks;!t&&window.matchMedia("(prefers-color-scheme: dark)").matches&&N(this._dom,!0);const n=["performance","accessibility","best-practices","seo"].every((t=>{const n=e.categories[t];return n&&1===n.score})),r=this._opts.disableFireworks||this._opts.disableAutoDarkModeAndFireworks;n&&!r&&(this._enableFireworks(),t||N(this._dom,!0));if(e.categories.performance&&e.categories.performance.auditRefs.some((t=>Boolean("metrics"===t.group&&e.audits[t.id].errorMessage)))){this._dom.find("input.lh-metrics-toggle__input",this._dom.rootEl).checked=!0}this.json.audits["script-treemap-data"]&&this.json.audits["script-treemap-data"].details&&this.addButton({text:l.i18n.strings.viewTreemapLabel,icon:"treemap",onClick:()=>function(e){if(!e.audits["script-treemap-data"].details)throw new Error("no script treemap data found");$({lhr:{requestedUrl:e.requestedUrl,finalUrl:e.finalUrl,audits:{"script-treemap-data":e.audits["script-treemap-data"]},configSettings:{locale:e.configSettings.locale}}},P()+"/treemap/","treemap-"+U(e))}(this.json)}),this._opts.onViewTrace&&this.addButton({text:"simulate"===e.configSettings.throttlingMethod?l.i18n.strings.viewOriginalTraceLabel:l.i18n.strings.viewTraceLabel,onClick:()=>this._opts.onViewTrace?.()}),this._opts.getStandaloneReportHTML&&this._dom.find('a[data-action="save-html"]',this._dom.rootEl).classList.remove("lh-hidden");for(const e of this._dom.findAll("[data-i18n]",this._dom.rootEl)){const t=e.getAttribute("data-i18n");e.textContent=l.i18n.strings[t]}}addButton(e){const t=this._dom.rootEl.querySelector(".lh-audit-group--metrics");if(!t)return;let n=t.querySelector(".lh-buttons");n||(n=this._dom.createChildOf(t,"div","lh-buttons"));const r=["lh-button"];e.icon&&(r.push("lh-report-icon"),r.push(`lh-report-icon--${e.icon}`));const o=this._dom.createChildOf(n,"button",r.join(" "));return o.textContent=e.text,o.addEventListener("click",e.onClick),o}resetUIState(){this._topbar&&this._topbar.resetUIState()}getReportHtml(){if(!this._opts.getStandaloneReportHTML)throw new Error("`getStandaloneReportHTML` is not set");return this.resetUIState(),this._opts.getStandaloneReportHTML()}saveAsGist(){throw new Error("Cannot save as gist from base report")}_enableFireworks(){this._dom.find(".lh-scores-container",this._dom.rootEl).classList.add("lh-score100")}_setupMediaQueryListeners(){const e=self.matchMedia("(max-width: 500px)");e.addListener(this.onMediaQueryChange),this.onMediaQueryChange(e)}_resetUIState(){this._topbar&&this._topbar.resetUIState()}onMediaQueryChange(e){this._dom.rootEl.classList.toggle("lh-narrow",e.matches)}_setupThirdPartyFilter(){const e=["uses-rel-preconnect","third-party-facades"],t=["legacy-javascript"];Array.from(this._dom.rootEl.querySelectorAll("table.lh-table")).filter((e=>e.querySelector("td.lh-table-column--url, td.lh-table-column--source-location"))).filter((t=>{const n=t.closest(".lh-audit");if(!n)throw new Error(".lh-table not within audit");return!e.includes(n.id)})).forEach((e=>{const n=function(e){return Array.from(e.tBodies[0].rows)}(e),r=this._getThirdPartyRows(n,this.json.finalUrl),o=this._dom.createComponent("3pFilter"),i=this._dom.find("input",o);i.addEventListener("change",(e=>{const t=e.target instanceof HTMLInputElement&&!e.target.checked;let o=!0,i=n[0];for(;i;){const e=t&&r.includes(i);do{i.classList.toggle("lh-row--hidden",e),i.classList.toggle("lh-row--even",!e&&o),i.classList.toggle("lh-row--odd",!e&&!o),i=i.nextElementSibling}while(i&&i.classList.contains("lh-sub-item-row"));e||(o=!o)}})),this._dom.find(".lh-3p-filter-count",o).textContent=`${r.length}`,this._dom.find(".lh-3p-ui-string",o).textContent=l.i18n.strings.thirdPartyResourcesLabel;const a=r.length===n.length,s=!r.length;if((a||s)&&(this._dom.find("div.lh-3p-filter",o).hidden=!0),!e.parentNode)return;e.parentNode.insertBefore(o,e);const c=e.closest(".lh-audit");if(!c)throw new Error(".lh-table not within audit");t.includes(c.id)&&!a&&i.click()}))}_setupElementScreenshotOverlay(e){const t=this.json.audits["full-page-screenshot"]&&this.json.audits["full-page-screenshot"].details&&"full-page-screenshot"===this.json.audits["full-page-screenshot"].details.type&&this.json.audits["full-page-screenshot"].details;t&&A.installOverlayFeature({dom:this._dom,rootEl:e,overlayContainerEl:e,fullPageScreenshot:t})}_getThirdPartyRows(e,t){const n=[],r=l.getRootDomain(t);for(const t of e){if(t.classList.contains("lh-sub-item-row"))continue;const e=t.querySelector("div.lh-text__url");if(!e)continue;const o=e.dataset.url;if(!o)continue;l.getRootDomain(o)!==r&&n.push(t)}return n}_saveFile(e){const t=e.type.match("json")?".json":".html",n=G.getLhrFilenamePrefix(this.json)+t;this._opts.onSaveFileOverride?this._opts.onSaveFileOverride(e,n):this._dom.saveFile(e,n)}}
206
+ */class j{constructor(e,t={}){this.json,this._dom=e,this._opts=t,this._topbar=t.omitTopbar?null:new I(this,e),this.onMediaQueryChange=this.onMediaQueryChange.bind(this)}initFeatures(e){this.json=e,this._topbar&&(this._topbar.enable(e),this._topbar.resetUIState()),this._setupMediaQueryListeners(),this._setupThirdPartyFilter(),this._setupElementScreenshotOverlay(this._dom.rootEl);const t=this._dom.isDevTools()||this._opts.disableDarkMode||this._opts.disableAutoDarkModeAndFireworks;!t&&window.matchMedia("(prefers-color-scheme: dark)").matches&&N(this._dom,!0);const n=["performance","accessibility","best-practices","seo"].every((t=>{const n=e.categories[t];return n&&1===n.score})),r=this._opts.disableFireworks||this._opts.disableAutoDarkModeAndFireworks;n&&!r&&(this._enableFireworks(),t||N(this._dom,!0));if(e.categories.performance&&e.categories.performance.auditRefs.some((t=>Boolean("metrics"===t.group&&e.audits[t.id].errorMessage)))){this._dom.find("input.lh-metrics-toggle__input",this._dom.rootEl).checked=!0}this.json.audits["script-treemap-data"]&&this.json.audits["script-treemap-data"].details&&this.addButton({text:l.i18n.strings.viewTreemapLabel,icon:"treemap",onClick:()=>function(e){if(!e.audits["script-treemap-data"].details)throw new Error("no script treemap data found");$({lhr:{finalUrl:e.finalUrl,audits:{"script-treemap-data":e.audits["script-treemap-data"]},configSettings:{locale:e.configSettings.locale}}},P()+"/treemap/","treemap-"+U(e))}(this.json)}),this._opts.onViewTrace&&this.addButton({text:"simulate"===e.configSettings.throttlingMethod?l.i18n.strings.viewOriginalTraceLabel:l.i18n.strings.viewTraceLabel,onClick:()=>this._opts.onViewTrace?.()}),this._opts.getStandaloneReportHTML&&this._dom.find('a[data-action="save-html"]',this._dom.rootEl).classList.remove("lh-hidden");for(const e of this._dom.findAll("[data-i18n]",this._dom.rootEl)){const t=e.getAttribute("data-i18n");e.textContent=l.i18n.strings[t]}}addButton(e){const t=this._dom.rootEl.querySelector(".lh-audit-group--metrics");if(!t)return;let n=t.querySelector(".lh-buttons");n||(n=this._dom.createChildOf(t,"div","lh-buttons"));const r=["lh-button"];e.icon&&(r.push("lh-report-icon"),r.push(`lh-report-icon--${e.icon}`));const o=this._dom.createChildOf(n,"button",r.join(" "));return o.textContent=e.text,o.addEventListener("click",e.onClick),o}resetUIState(){this._topbar&&this._topbar.resetUIState()}getReportHtml(){if(!this._opts.getStandaloneReportHTML)throw new Error("`getStandaloneReportHTML` is not set");return this.resetUIState(),this._opts.getStandaloneReportHTML()}saveAsGist(){throw new Error("Cannot save as gist from base report")}_enableFireworks(){this._dom.find(".lh-scores-container",this._dom.rootEl).classList.add("lh-score100")}_setupMediaQueryListeners(){const e=self.matchMedia("(max-width: 500px)");e.addListener(this.onMediaQueryChange),this.onMediaQueryChange(e)}_resetUIState(){this._topbar&&this._topbar.resetUIState()}onMediaQueryChange(e){this._dom.rootEl.classList.toggle("lh-narrow",e.matches)}_setupThirdPartyFilter(){const e=["uses-rel-preconnect","third-party-facades"],t=["legacy-javascript"];Array.from(this._dom.rootEl.querySelectorAll("table.lh-table")).filter((e=>e.querySelector("td.lh-table-column--url, td.lh-table-column--source-location"))).filter((t=>{const n=t.closest(".lh-audit");if(!n)throw new Error(".lh-table not within audit");return!e.includes(n.id)})).forEach((e=>{const n=function(e){return Array.from(e.tBodies[0].rows)}(e),r=this._getThirdPartyRows(n,this.json.finalUrl),o=this._dom.createComponent("3pFilter"),i=this._dom.find("input",o);i.addEventListener("change",(e=>{const t=e.target instanceof HTMLInputElement&&!e.target.checked;let o=!0,i=n[0];for(;i;){const e=t&&r.includes(i);do{i.classList.toggle("lh-row--hidden",e),i.classList.toggle("lh-row--even",!e&&o),i.classList.toggle("lh-row--odd",!e&&!o),i=i.nextElementSibling}while(i&&i.classList.contains("lh-sub-item-row"));e||(o=!o)}})),this._dom.find(".lh-3p-filter-count",o).textContent=`${r.length}`,this._dom.find(".lh-3p-ui-string",o).textContent=l.i18n.strings.thirdPartyResourcesLabel;const a=r.length===n.length,s=!r.length;if((a||s)&&(this._dom.find("div.lh-3p-filter",o).hidden=!0),!e.parentNode)return;e.parentNode.insertBefore(o,e);const c=e.closest(".lh-audit");if(!c)throw new Error(".lh-table not within audit");t.includes(c.id)&&!a&&i.click()}))}_setupElementScreenshotOverlay(e){const t=this.json.audits["full-page-screenshot"]&&this.json.audits["full-page-screenshot"].details&&"full-page-screenshot"===this.json.audits["full-page-screenshot"].details.type&&this.json.audits["full-page-screenshot"].details;t&&A.installOverlayFeature({dom:this._dom,rootEl:e,overlayContainerEl:e,fullPageScreenshot:t})}_getThirdPartyRows(e,t){const n=[],r=l.getRootDomain(t);for(const t of e){if(t.classList.contains("lh-sub-item-row"))continue;const e=t.querySelector("div.lh-text__url");if(!e)continue;const o=e.dataset.url;if(!o)continue;l.getRootDomain(o)!==r&&n.push(t)}return n}_saveFile(e){const t=e.type.match("json")?".json":".html",n=G.getLhrFilenamePrefix(this.json)+t;this._opts.onSaveFileOverride?this._opts.onSaveFileOverride(e,n):this._dom.saveFile(e,n)}}
207
207
  /**
208
208
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
209
209
  * 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
@@ -262,7 +262,6 @@ class RenderBlockingResources extends Audit {
262
262
  try {
263
263
  const unusedCssItems = await UnusedCSS.request({
264
264
  CSSUsage: artifacts.CSSUsage,
265
- URL: artifacts.URL,
266
265
  devtoolsLog: artifacts.devtoolsLogs[Audit.DEFAULT_PASS],
267
266
  }, context);
268
267
  for (const item of unusedCssItems) {
@@ -53,15 +53,14 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
53
53
  /**
54
54
  * @param {LH.Artifacts.CSSStyleSheetInfo} stylesheet
55
55
  * @param {LH.Artifacts.NetworkRequest|undefined} networkRecord
56
- * @param {string} pageUrl
57
56
  * @return {{url: string, totalBytes: number, wastedBytes: number, wastedPercent: number}}
58
57
  */
59
- static computeWaste(stylesheet, networkRecord, pageUrl) {
58
+ static computeWaste(stylesheet, networkRecord) {
60
59
  const content = stylesheet.content;
61
60
  const totalTokenLength = UnminifiedCSS.computeTokenLength(content);
62
61
 
63
62
  let url = stylesheet.header.sourceURL;
64
- if (!url || url === pageUrl) {
63
+ if (!url || stylesheet.header.isInline) {
65
64
  const contentPreview = UnusedCSS.determineContentPreview(stylesheet.content);
66
65
  url = contentPreview;
67
66
  }
@@ -85,14 +84,13 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
85
84
  * @return {ByteEfficiencyAudit.ByteEfficiencyProduct}
86
85
  */
87
86
  static audit_(artifacts, networkRecords) {
88
- const pageUrl = artifacts.URL.finalUrl;
89
87
  const items = [];
90
88
  for (const stylesheet of artifacts.CSSUsage.stylesheets) {
91
89
  const networkRecord = networkRecords
92
90
  .find(record => record.url === stylesheet.header.sourceURL);
93
91
  if (!stylesheet.content) continue;
94
92
 
95
- const result = UnminifiedCSS.computeWaste(stylesheet, networkRecord, pageUrl);
93
+ const result = UnminifiedCSS.computeWaste(stylesheet, networkRecord);
96
94
 
97
95
  // If the ratio is minimal, the file is likely already minified, so ignore it.
98
96
  // If the total number of bytes to be saved is quite small, it's also safe to ignore.
@@ -8,7 +8,7 @@
8
8
  const ByteEfficiencyAudit = require('./byte-efficiency-audit.js');
9
9
  const i18n = require('../../lib/i18n/i18n.js');
10
10
  const computeTokenLength = require('../../lib/minification-estimator.js').computeJSTokenLength;
11
- const {getRequestForScript} = require('../../lib/script-helpers.js');
11
+ const {getRequestForScript, isInline} = require('../../lib/script-helpers.js');
12
12
 
13
13
  const UIStrings = {
14
14
  /** 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. */
@@ -83,7 +83,8 @@ class UnminifiedJavaScript extends ByteEfficiencyAudit {
83
83
  if (!script.content) continue;
84
84
 
85
85
  const networkRecord = getRequestForScript(networkRecords, script);
86
- const displayUrl = script.name === artifacts.URL.finalUrl ?
86
+
87
+ const displayUrl = isInline(script) ?
87
88
  `inline: ${script.content.substring(0, 40)}...` :
88
89
  script.url;
89
90
  try {
@@ -47,7 +47,6 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
47
47
  static async audit_(artifacts, _, context) {
48
48
  const unusedCssItems = await UnusedCSS.request({
49
49
  CSSUsage: artifacts.CSSUsage,
50
- URL: artifacts.URL,
51
50
  devtoolsLog: artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS],
52
51
  }, context);
53
52
  const items = unusedCssItems
@@ -19,6 +19,7 @@ const Audit = require('./audit.js');
19
19
  const JsBundles = require('../computed/js-bundles.js');
20
20
  const UnusedJavaScriptSummary = require('../computed/unused-javascript-summary.js');
21
21
  const ModuleDuplication = require('../computed/module-duplication.js');
22
+ const {isInline} = require('../lib/script-helpers.js');
22
23
 
23
24
  class ScriptTreemapDataAudit extends Audit {
24
25
  /**
@@ -236,8 +237,7 @@ class ScriptTreemapDataAudit extends Audit {
236
237
 
237
238
  // If this is an inline script, place the node inside a top-level (aka depth-one) node.
238
239
  // Also separate each iframe / the main page's inline scripts into their own top-level nodes.
239
- const isInlineHtmlScript = script.startColumn || script.startLine;
240
- if (isInlineHtmlScript) {
240
+ if (isInline(script)) {
241
241
  let htmlNode = htmlNodesByFrameId.get(script.executionContextAuxData.frameId);
242
242
  if (!htmlNode) {
243
243
  htmlNode = {
@@ -119,6 +119,8 @@ class LinkText extends Audit {
119
119
  if (
120
120
  href.startsWith('javascript:') ||
121
121
  href.startsWith('mailto:') ||
122
+ // This line prevents the audit from flagging anchor links.
123
+ // In this case it is better to use `finalUrl` than `mainDocumentUrl`.
122
124
  URL.equalWithExcludedFragments(link.href, artifacts.URL.finalUrl)
123
125
  ) {
124
126
  return false;
@@ -51,6 +51,7 @@ class ServiceWorker extends Audit {
51
51
  title: str_(UIStrings.title),
52
52
  failureTitle: str_(UIStrings.failureTitle),
53
53
  description: str_(UIStrings.description),
54
+ supportedModes: ['navigation'],
54
55
  requiredArtifacts: ['URL', 'ServiceWorker', 'WebAppManifest'],
55
56
  };
56
57
  }
@@ -128,8 +129,12 @@ class ServiceWorker extends Audit {
128
129
  * @return {LH.Audit.Product}
129
130
  */
130
131
  static audit(artifacts) {
131
- // Match against artifacts.URL.finalUrl so audit accounts for any redirects.
132
- const pageUrl = new URL(artifacts.URL.finalUrl);
132
+ // Match against `artifacts.URL.mainDocumentUrl` so audit accounts for any redirects.
133
+ // Service workers won't control network requests if the page uses `history.pushState` to "enter" the SW scope.
134
+ // For this reason it is better to evaluate the SW in relation to the main document url rather than the final frame url.
135
+ const {mainDocumentUrl} = artifacts.URL;
136
+ if (!mainDocumentUrl) throw new Error('mainDocumentUrl must exist in navigation mode');
137
+ const pageUrl = new URL(mainDocumentUrl);
133
138
  const {versions, registrations} = artifacts.ServiceWorker;
134
139
 
135
140
  const versionsForOrigin = ServiceWorker.getVersionsForOrigin(versions, pageUrl);
@@ -20,9 +20,10 @@ class MainResource {
20
20
  * @return {Promise<LH.Artifacts.NetworkRequest>}
21
21
  */
22
22
  static async compute_(data, context) {
23
- const finalUrl = data.URL.finalUrl;
23
+ const {mainDocumentUrl} = data.URL;
24
+ if (!mainDocumentUrl) throw new Error('mainDocumentUrl must exist to get the main resource');
24
25
  const requests = await NetworkRecords.request(data.devtoolsLog, context);
25
- const mainResource = NetworkAnalyzer.findResourceForUrl(requests, finalUrl);
26
+ const mainResource = NetworkAnalyzer.findResourceForUrl(requests, mainDocumentUrl);
26
27
  if (!mainResource) {
27
28
  throw new Error('Unable to identify the main resource');
28
29
  }
@@ -396,6 +396,7 @@ class PageDependencyGraph {
396
396
  const networkNodeOutput = PageDependencyGraph.getNetworkNodeOutput(networkRecords);
397
397
  const cpuNodes = PageDependencyGraph.getCPUNodes(processedTrace);
398
398
  const {requestedUrl, mainDocumentUrl} = URL;
399
+ if (!requestedUrl) throw new Error('requestedUrl is required to get the root request');
399
400
  if (!mainDocumentUrl) throw new Error('mainDocumentUrl is required to get the main resource');
400
401
 
401
402
  const rootRequest = NetworkAnalyzer.findResourceForUrl(networkRecords, requestedUrl);
@@ -35,11 +35,11 @@ class ResourceSummary {
35
35
 
36
36
  /**
37
37
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
38
- * @param {string} mainResourceURL
38
+ * @param {LH.Artifacts.URL} URLArtifact
39
39
  * @param {ImmutableObject<LH.Budget[]|null>} budgets
40
40
  * @return {Record<LH.Budget.ResourceType, ResourceEntry>}
41
41
  */
42
- static summarize(networkRecords, mainResourceURL, budgets) {
42
+ static summarize(networkRecords, URLArtifact, budgets) {
43
43
  /** @type {Record<LH.Budget.ResourceType, ResourceEntry>} */
44
44
  const resourceSummary = {
45
45
  'stylesheet': {count: 0, resourceSize: 0, transferSize: 0},
@@ -52,13 +52,13 @@ class ResourceSummary {
52
52
  'total': {count: 0, resourceSize: 0, transferSize: 0},
53
53
  'third-party': {count: 0, resourceSize: 0, transferSize: 0},
54
54
  };
55
- const budget = Budget.getMatchingBudget(budgets, mainResourceURL);
55
+ const budget = Budget.getMatchingBudget(budgets, URLArtifact.mainDocumentUrl);
56
56
  /** @type {ReadonlyArray<string>} */
57
57
  let firstPartyHosts = [];
58
58
  if (budget?.options?.firstPartyHostnames) {
59
59
  firstPartyHosts = budget.options.firstPartyHostnames;
60
60
  } else {
61
- const rootDomain = Util.getRootDomain(mainResourceURL);
61
+ const rootDomain = Util.getRootDomain(URLArtifact.finalUrl);
62
62
  firstPartyHosts = [`*.${rootDomain}`];
63
63
  }
64
64
 
@@ -107,7 +107,7 @@ class ResourceSummary {
107
107
  */
108
108
  static async compute_(data, context) {
109
109
  const networkRecords = await NetworkRecords.request(data.devtoolsLog, context);
110
- return ResourceSummary.summarize(networkRecords, data.URL.finalUrl, data.budgets);
110
+ return ResourceSummary.summarize(networkRecords, data.URL, data.budgets);
111
111
  }
112
112
  }
113
113
 
@@ -120,12 +120,11 @@ class UnusedCSS {
120
120
 
121
121
  /**
122
122
  * @param {StyleSheetInfo} stylesheetInfo The stylesheetInfo object.
123
- * @param {string} pageUrl The URL of the page, used to identify inline styles.
124
123
  * @return {LH.Audit.ByteEfficiencyItem}
125
124
  */
126
- static mapSheetToResult(stylesheetInfo, pageUrl) {
125
+ static mapSheetToResult(stylesheetInfo) {
127
126
  let url = stylesheetInfo.header.sourceURL;
128
- if (!url || url === pageUrl) {
127
+ if (!url || stylesheetInfo.header.isInline) {
129
128
  const contentPreview = UnusedCSS.determineContentPreview(stylesheetInfo.content);
130
129
  url = contentPreview;
131
130
  }
@@ -135,20 +134,20 @@ class UnusedCSS {
135
134
  }
136
135
 
137
136
  /**
138
- * @param {{CSSUsage: LH.Artifacts['CSSUsage'], URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog}} data
137
+ * @param {{CSSUsage: LH.Artifacts['CSSUsage'], devtoolsLog: LH.DevtoolsLog}} data
139
138
  * @param {LH.Artifacts.ComputedContext} context
140
139
  * @return {Promise<LH.Audit.ByteEfficiencyItem[]>}
141
140
  */
142
141
  static async compute_(data, context) {
143
- const {CSSUsage, URL, devtoolsLog} = data;
142
+ const {CSSUsage, devtoolsLog} = data;
144
143
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
145
144
  const indexedSheets = UnusedCSS.indexStylesheetsById(CSSUsage.stylesheets, networkRecords);
146
145
  UnusedCSS.indexUsedRules(CSSUsage.rules, indexedSheets);
147
146
 
148
147
  const items = Object.keys(indexedSheets)
149
- .map(sheetId => UnusedCSS.mapSheetToResult(indexedSheets[sheetId], URL.finalUrl));
148
+ .map(sheetId => UnusedCSS.mapSheetToResult(indexedSheets[sheetId]));
150
149
  return items;
151
150
  }
152
151
  }
153
152
 
154
- module.exports = makeComputedArtifact(UnusedCSS, ['CSSUsage', 'URL', 'devtoolsLog']);
153
+ module.exports = makeComputedArtifact(UnusedCSS, ['CSSUsage', 'devtoolsLog']);
@@ -137,11 +137,11 @@ class Budget {
137
137
  * If multiple budgets match based on thier 'path' property,
138
138
  * then the last-listed of those budgets is returned.
139
139
  * @param {Immutable<Array<LH.Budget>>|null} budgets
140
- * @param {string} url
140
+ * @param {string|undefined} url
141
141
  * @return {Immutable<LH.Budget> | undefined} budget
142
142
  */
143
143
  static getMatchingBudget(budgets, url) {
144
- if (budgets === null) return;
144
+ if (budgets === null || url === undefined) return;
145
145
 
146
146
  // Applies the LAST matching budget.
147
147
  for (let i = budgets.length - 1; i >= 0; i--) {
@@ -35,10 +35,8 @@ async function getBaseArtifacts(config, driver, context) {
35
35
  HostFormFactor: userAgent.includes('Android') || userAgent.includes('Mobile') ?
36
36
  'mobile' : 'desktop',
37
37
  // Contextual artifacts whose collection changes based on gather mode.
38
- // TODO: Make `requestedUrl` optional in timespan and snapshot modes.
39
38
  URL: {
40
39
  initialUrl: '',
41
- requestedUrl: '',
42
40
  finalUrl: '',
43
41
  },
44
42
  PageLoadError: null,
@@ -88,13 +86,11 @@ function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
88
86
  artifacts.LighthouseRunWarnings = deduplicateWarnings(warnings);
89
87
 
90
88
  if (artifacts.PageLoadError && !artifacts.URL.finalUrl) {
91
- artifacts.URL.finalUrl = artifacts.URL.requestedUrl;
89
+ artifacts.URL.finalUrl = artifacts.URL.requestedUrl || artifacts.URL.initialUrl;
92
90
  }
93
91
 
94
92
  // Check that the runner remembered to mutate the special-case URL artifact.
95
- // TODO: Make `requestedUrl` optional.
96
93
  if (!artifacts.URL.initialUrl) throw new Error('Runner did not set initialUrl');
97
- if (!artifacts.URL.requestedUrl) throw new Error('Runner did not set requestedUrl');
98
94
  if (!artifacts.URL.finalUrl) throw new Error('Runner did not set finalUrl');
99
95
 
100
96
  return artifacts;
@@ -229,9 +229,8 @@ async function _navigation(navigationContext) {
229
229
  const navigateResult = await _navigate(navigationContext);
230
230
 
231
231
  // Every required url is initialized to an empty string in `getBaseArtifacts`.
232
- // If we haven't set the required urls yet, set them here.
233
- const {URL} = phaseState.baseArtifacts;
234
- if (!URL.finalUrl || !URL.initialUrl) {
232
+ // If we haven't set all the required urls yet, set them here.
233
+ if (!Object.values(phaseState.baseArtifacts).every(Boolean)) {
235
234
  phaseState.baseArtifacts.URL = {
236
235
  initialUrl,
237
236
  requestedUrl: navigateResult.requestedUrl,
@@ -38,8 +38,6 @@ async function snapshotGather(options) {
38
38
  const baseArtifacts = await getBaseArtifacts(config, driver, {gatherMode: 'snapshot'});
39
39
  baseArtifacts.URL = {
40
40
  initialUrl: url,
41
- // TODO: Remove `requestedUrl` from snapshot mode.
42
- requestedUrl: url,
43
41
  finalUrl: url,
44
42
  };
45
43
 
@@ -59,8 +59,6 @@ async function startTimespanGather(options) {
59
59
  async () => {
60
60
  baseArtifacts.URL = {
61
61
  initialUrl,
62
- // TODO: Remove requestedUrl from timespan mode
63
- requestedUrl: initialUrl,
64
62
  finalUrl,
65
63
  };
66
64
 
@@ -5,6 +5,14 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
+ /**
9
+ * @param {LH.Artifacts.Script} script
10
+ * @return {boolean}
11
+ */
12
+ function isInline(script) {
13
+ return Boolean(script.startLine || script.startColumn);
14
+ }
15
+
8
16
  /**
9
17
  * @param {LH.Artifacts.NetworkRequest[]} networkRecords
10
18
  * @param {LH.Artifacts.Script} script
@@ -18,4 +26,4 @@ function getRequestForScript(networkRecords, script) {
18
26
  return networkRequest;
19
27
  }
20
28
 
21
- module.exports = {getRequestForScript};
29
+ module.exports = {getRequestForScript, isInline};
@@ -158,11 +158,6 @@ class Runner {
158
158
  // No browser required, just load the artifacts from disk.
159
159
  const path = this._getDataSavePath(settings);
160
160
  artifacts = assetSaver.loadArtifacts(path);
161
- const requestedUrl = artifacts.URL.requestedUrl;
162
-
163
- if (!requestedUrl) {
164
- throw new Error('Cannot run audit mode on empty URL');
165
- }
166
161
  } else {
167
162
  const runnerStatus = {msg: 'Gather phase', id: 'lh:runner:gather'};
168
163
  log.time(runnerStatus, 'verbose');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse",
3
- "version": "9.5.0-dev.20220404",
3
+ "version": "9.5.0-dev.20220407",
4
4
  "description": "Automated auditing, performance metrics, and best practices for the web.",
5
5
  "main": "./lighthouse-core/index.js",
6
6
  "bin": {
@@ -105,7 +105,7 @@ class ReportGenerator {
105
105
 
106
106
  // First we have metadata about the LHR.
107
107
  rows.push(rowFormatter(topLevelKeys));
108
- rows.push(rowFormatter(topLevelKeys.map(key => lhr[key])));
108
+ rows.push(rowFormatter(topLevelKeys.map(key => lhr[key] ?? null)));
109
109
 
110
110
  // Some spacing.
111
111
  rows.push([]);
@@ -38,7 +38,7 @@ function computeWindowNameSuffix(json) {
38
38
  // @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
39
39
  const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
40
40
  const fetchTime = json.fetchTime || fallbackFetchTime;
41
- return `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
41
+ return `${json.lighthouseVersion}-${json.finalUrl}-${fetchTime}`;
42
42
  }
43
43
 
44
44
  /**
@@ -120,7 +120,6 @@ function openTreemap(json) {
120
120
  /** @type {LH.Treemap.Options} */
121
121
  const treemapOptions = {
122
122
  lhr: {
123
- requestedUrl: json.requestedUrl,
124
123
  finalUrl: json.finalUrl,
125
124
  audits: {
126
125
  'script-treemap-data': json.audits['script-treemap-data'],
@@ -191,11 +191,10 @@ declare module Artifacts {
191
191
  /** URL of the main frame before Lighthouse starts. */
192
192
  initialUrl: string;
193
193
  /**
194
- * URL of the first document request during a Lighthouse navigation.
195
- * Will be the same as `initialUrl` in timespan/snapshot.
196
- * TODO: Make this property `undefined` in timespan/snapshot.
194
+ * URL of the initially requested URL during a Lighthouse navigation.
195
+ * Will be `undefined` in timespan/snapshot.
197
196
  */
198
- requestedUrl: string;
197
+ requestedUrl?: string;
199
198
  /**
200
199
  * URL of the last document request during a Lighthouse navigation.
201
200
  * Will be `undefined` in timespan/snapshot.
@@ -13,8 +13,8 @@ import {ConfigSettings} from './settings';
13
13
  interface Result {
14
14
  /** Gather mode used to collect artifacts for this result. */
15
15
  gatherMode: Result.GatherMode;
16
- /** The URL that was supplied to Lighthouse and initially navigated to. */
17
- requestedUrl: string;
16
+ /** The URL that Lighthouse initially navigated to. Will be `undefined` in timespan/snapshot. */
17
+ requestedUrl?: string;
18
18
  /** The post-redirects URL that Lighthouse loaded. */
19
19
  finalUrl: string;
20
20
  /** The ISO-8601 timestamp of when the results were generated. */
@@ -10,7 +10,6 @@ import {Locale} from './settings';
10
10
  declare module Treemap {
11
11
  interface Options {
12
12
  lhr: {
13
- requestedUrl: string;
14
13
  finalUrl: string;
15
14
  audits: {
16
15
  'script-treemap-data': AuditResult;