diff --git a/BUILD.gn b/BUILD.gn index 7894e33cc4..8458826633 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -28,20 +28,10 @@ if (external_devtools_frontend) { "front_end/audits_worker/AuditsService.js", "front_end/audits_worker/lighthouse/lighthouse-dt-bundle.js", "front_end/audits_worker/module.json", - "front_end/audits/AuditsPanel.js", - "front_end/audits/AuditsController.js", - "front_end/audits/AuditsReportSelector.js", - "front_end/audits/AuditsReportRenderer.js", - "front_end/audits/AuditsStartView.js", - "front_end/audits/AuditsProtocolService.js", - "front_end/audits/AuditsStatusView.js", "front_end/audits/auditsDialog.css", "front_end/audits/auditsStartView.css", "front_end/audits/auditsPanel.css", - "front_end/audits/RadioSetting.js", "front_end/audits/lighthouse/report.css", - "front_end/audits/lighthouse/report.js", - "front_end/audits/lighthouse/report-generator.js", "front_end/audits/lighthouse/template.html", "front_end/audits/lighthouse/templates.html", "front_end/audits/module.json", @@ -719,6 +709,17 @@ if (external_devtools_frontend) { "front_end/css_overview/CSSOverviewModel.js", "front_end/css_overview/CSSOverviewController.js", "front_end/css_overview/CSSOverviewCompletedView.js", + "front_end/audits/audits.js", + "front_end/audits/lighthouse/report-generator.js", + "front_end/audits/lighthouse/report.js", + "front_end/audits/RadioSetting.js", + "front_end/audits/AuditsStatusView.js", + "front_end/audits/AuditsStartView.js", + "front_end/audits/AuditsReportSelector.js", + "front_end/audits/AuditsReportRenderer.js", + "front_end/audits/AuditsProtocolService.js", + "front_end/audits/AuditsPanel.js", + "front_end/audits/AuditsController.js", "front_end/console/console.js", "front_end/console/ConsoleContextSelector.js", "front_end/console/ConsoleFilter.js", @@ -1265,6 +1266,17 @@ if (external_devtools_frontend) { "$resources_out_dir/css_overview/CSSOverviewModel.js", "$resources_out_dir/css_overview/CSSOverviewController.js", "$resources_out_dir/css_overview/CSSOverviewCompletedView.js", + "$resources_out_dir/audits/lighthouse/report.js", + "$resources_out_dir/audits/lighthouse/report-generator.js", + "$resources_out_dir/audits/audits.js", + "$resources_out_dir/audits/RadioSetting.js", + "$resources_out_dir/audits/AuditsStatusView.js", + "$resources_out_dir/audits/AuditsStartView.js", + "$resources_out_dir/audits/AuditsReportSelector.js", + "$resources_out_dir/audits/AuditsReportRenderer.js", + "$resources_out_dir/audits/AuditsProtocolService.js", + "$resources_out_dir/audits/AuditsPanel.js", + "$resources_out_dir/audits/AuditsController.js", "$resources_out_dir/console/console.js", "$resources_out_dir/console/ConsoleContextSelector.js", "$resources_out_dir/console/ConsoleFilter.js", diff --git a/front_end/audits/AuditsController.js b/front_end/audits/AuditsController.js index 2f0be02d34..0ff5c19f64 100644 --- a/front_end/audits/AuditsController.js +++ b/front_end/audits/AuditsController.js @@ -6,7 +6,7 @@ * @implements {SDK.SDKModelObserver} * @unrestricted */ -Audits.AuditController = class extends Common.Object { +class AuditController extends Common.Object { constructor(protocolService) { super(); @@ -202,14 +202,10 @@ Audits.AuditController = class extends Common.Object { this.dispatchEventToListeners(Audits.Events.PageAuditabilityChanged, {helpText}); } -}; - - -/** @typedef {{setting: !Common.Setting, configID: string, title: string, description: string}} */ -Audits.Preset; +} /** @type {!Array.} */ -Audits.Presets = [ +export const Presets = [ // configID maps to Lighthouse's Object.keys(config.categories)[0] value { setting: Common.settings.createSetting('audits.cat_perf', true), @@ -250,11 +246,8 @@ Audits.Presets = [ }, ]; -/** @typedef {{setting: !Common.Setting, description: string, setFlags: function(!Object, string), options: (!Array|undefined), title: (string|undefined)}} */ -Audits.RuntimeSetting; - /** @type {!Array.} */ -Audits.RuntimeSettings = [ +export const RuntimeSettings = [ { setting: Common.settings.createSetting('audits.device_type', 'mobile'), description: ls`Apply mobile emulation during auditing`, @@ -288,9 +281,34 @@ Audits.RuntimeSettings = [ }, ]; -Audits.Events = { +export const Events = { PageAuditabilityChanged: Symbol('PageAuditabilityChanged'), AuditProgressChanged: Symbol('AuditProgressChanged'), RequestAuditStart: Symbol('RequestAuditStart'), RequestAuditCancel: Symbol('RequestAuditCancel'), }; + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.AuditController = AuditController; + +/** @typedef {{setting: !Common.Setting, configID: string, title: string, description: string}} */ +Audits.Preset; + +Audits.Events = Events; + +/** @typedef {{setting: !Common.Setting, description: string, setFlags: function(!Object, string), options: (!Array|undefined), title: (string|undefined)}} */ +Audits.RuntimeSetting; + +/** @type {!Array.} */ +Audits.RuntimeSettings = RuntimeSettings; + +/** @type {!Array.} */ +Audits.Presets = Presets; diff --git a/front_end/audits/AuditsPanel.js b/front_end/audits/AuditsPanel.js index afecc040cb..7820c10ebf 100644 --- a/front_end/audits/AuditsPanel.js +++ b/front_end/audits/AuditsPanel.js @@ -5,7 +5,7 @@ /** * @unrestricted */ -Audits.AuditsPanel = class extends UI.Panel { +export default class AuditsPanel extends UI.Panel { constructor() { super('audits'); this.registerRequiredCSS('audits/lighthouse/report.css'); @@ -364,4 +364,15 @@ Audits.AuditsPanel = class extends UI.Panel { const inspectedURL = await this._controller.getInspectedURL(); await resourceTreeModel.navigate(inspectedURL); } -}; +} + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.AuditsPanel = AuditsPanel; diff --git a/front_end/audits/AuditsProtocolService.js b/front_end/audits/AuditsProtocolService.js index 6f31a5f0ae..23544bc359 100644 --- a/front_end/audits/AuditsProtocolService.js +++ b/front_end/audits/AuditsProtocolService.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Audits.ProtocolService = class extends Common.Object { +export class ProtocolService extends Common.Object { constructor() { super(); /** @type {?Protocol.Connection} */ @@ -90,4 +90,15 @@ Audits.ProtocolService = class extends Common.Object { return this._backendPromise.then(_ => this._backend.send(method, params)); } -}; +} + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.ProtocolService = ProtocolService; diff --git a/front_end/audits/AuditsReportRenderer.js b/front_end/audits/AuditsReportRenderer.js index 1f89642714..8ac9ad942d 100644 --- a/front_end/audits/AuditsReportRenderer.js +++ b/front_end/audits/AuditsReportRenderer.js @@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +const MaxLengthForLinks = 40; + /** * @override */ -Audits.ReportRenderer = class extends ReportRenderer { +export class AuditsReportRenderer extends ReportRenderer { /** * @param {!Element} el Parent element to render the report into. * @param {!ReportRenderer.RunnerResultArtifacts=} artifacts @@ -77,8 +79,8 @@ Audits.ReportRenderer = class extends ReportRenderer { const url = detailsItem.sourceUrl; const line = Number(detailsItem.sourceLine); const column = Number(detailsItem.sourceColumn); - const element = await Components.Linkifier.linkifyURL( - url, {lineNumber: line, column, maxLength: Audits.ReportRenderer.MaxLengthForLinks}); + const element = + await Components.Linkifier.linkifyURL(url, {lineNumber: line, column, maxLength: MaxLengthForLinks}); origElement.title = ''; origElement.textContent = ''; origElement.appendChild(element); @@ -93,12 +95,12 @@ Audits.ReportRenderer = class extends ReportRenderer { el.classList.add('dark'); } } -}; +} /** * @override */ -Audits.ReportUIFeatures = class extends ReportUIFeatures { +export class AuditsReportUIFeatures extends ReportUIFeatures { /** * @param {!DOM} dom */ @@ -182,10 +184,27 @@ Audits.ReportUIFeatures = class extends ReportUIFeatures { resetUIState() { this._resetUIState(); } -}; +} + + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.ReportRenderer = AuditsReportRenderer; /** * @const * @type {number} */ -Audits.ReportRenderer.MaxLengthForLinks = 40; +Audits.ReportRenderer.MaxLengthForLinks = MaxLengthForLinks; + +/** + * @constructor + */ +Audits.ReportUIFeatures = AuditsReportUIFeatures; diff --git a/front_end/audits/AuditsReportSelector.js b/front_end/audits/AuditsReportSelector.js index 4ac9fd45fe..6d1e6d48d5 100644 --- a/front_end/audits/AuditsReportSelector.js +++ b/front_end/audits/AuditsReportSelector.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Audits.ReportSelector = class { +export default class ReportSelector { constructor(renderNewAuditView) { this._renderNewAuditView = renderNewAuditView; this._newAuditItem = createElement('option'); @@ -94,9 +94,9 @@ Audits.ReportSelector = class { selectNewAudit() { this._comboBox.select(this._newAuditItem); } -}; +} -Audits.ReportSelector.Item = class { +export class Item { /** * @param {!ReportRenderer.ReportJSON} lighthouseResult * @param {function()} renderReport @@ -130,4 +130,20 @@ Audits.ReportSelector.Item = class { } this._showLandingCallback(); } -}; +} + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.ReportSelector = ReportSelector; + +/** + * @constructor + */ +Audits.ReportSelector.Item = Item; diff --git a/front_end/audits/AuditsStartView.js b/front_end/audits/AuditsStartView.js index 034387b5e7..a6c2399bf8 100644 --- a/front_end/audits/AuditsStartView.js +++ b/front_end/audits/AuditsStartView.js @@ -5,7 +5,7 @@ /** * @unrestricted */ -Audits.StartView = class extends UI.Widget { +export default class StartView extends UI.Widget { /** * @param {!Audits.AuditController} controller */ @@ -176,4 +176,15 @@ Audits.StartView = class extends UI.Widget { this._helpText.textContent = text; } } -}; +} + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +/** + * @constructor + */ +Audits.StartView = StartView; diff --git a/front_end/audits/AuditsStatusView.js b/front_end/audits/AuditsStatusView.js index c8a67a5afe..3717a42851 100644 --- a/front_end/audits/AuditsStatusView.js +++ b/front_end/audits/AuditsStatusView.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Audits.StatusView = class { +export default class StatusView { /** * @param {!Audits.AuditController} controller */ @@ -18,7 +18,7 @@ Audits.StatusView = class { this._inspectedURL = ''; this._textChangedAt = 0; - this._fastFactsQueued = Audits.StatusView.FastFacts.slice(); + this._fastFactsQueued = FastFacts.slice(); this._currentPhase = null; this._scheduledTextChangeTimeout = null; this._scheduledFastFactTimeout = null; @@ -68,7 +68,7 @@ Audits.StatusView = class { clearTimeout(this._scheduledFastFactTimeout); this._textChangedAt = 0; - this._fastFactsQueued = Audits.StatusView.FastFacts.slice(); + this._fastFactsQueued = FastFacts.slice(); this._currentPhase = null; this._scheduledTextChangeTimeout = null; this._scheduledFastFactTimeout = null; @@ -150,7 +150,7 @@ Audits.StatusView = class { const deviceType = Audits.RuntimeSettings.find(item => item.setting.name === 'audits.device_type').setting.get(); const throttling = Audits.RuntimeSettings.find(item => item.setting.name === 'audits.throttling').setting.get(); - const match = Audits.StatusView.LoadingMessages.find(item => { + const match = LoadingMessages.find(item => { return item.deviceType === deviceType && item.throttling === throttling; }); @@ -162,7 +162,7 @@ Audits.StatusView = class { * @return {?Audits.StatusView.StatusPhases} */ _getPhaseForMessage(message) { - return Audits.StatusView.StatusPhases.find(phase => message.startsWith(phase.statusMessagePrefix)); + return StatusPhases.find(phase => message.startsWith(phase.statusMessagePrefix)); } _resetProgressBarClasses() { @@ -188,7 +188,7 @@ Audits.StatusView = class { _updateFastFactIfNecessary() { const now = performance.now(); - if (now - this._textChangedAt < Audits.StatusView.fastFactRotationInterval) { + if (now - this._textChangedAt < fastFactRotationInterval) { return; } if (!this._fastFactsQueued.length) { @@ -220,7 +220,7 @@ Audits.StatusView = class { } const msSinceLastChange = performance.now() - this._textChangedAt; - const msToTextChange = Audits.StatusView.minimumTextVisibilityDuration - msSinceLastChange; + const msToTextChange = minimumTextVisibilityDuration - msSinceLastChange; this._scheduledTextChangeTimeout = setTimeout(() => { this._commitTextChange(text); @@ -239,7 +239,7 @@ Audits.StatusView = class { this._commitTextChange(''); this._statusText.createChild('p').createTextChild(Common.UIString('Ah, sorry! We ran into an error.')); - if (Audits.StatusView.KnownBugPatterns.some(pattern => pattern.test(err.message))) { + if (KnownBugPatterns.some(pattern => pattern.test(err.message))) { const message = Common.UIString( 'Try to navigate to the URL in a fresh Chrome profile without any other tabs or extensions open and try again.'); this._statusText.createChild('p').createTextChild(message); @@ -282,11 +282,16 @@ Stack Trace: ${err.stack} ls`If this issue is reproducible, please report it at the Lighthouse GitHub repo.`); this._statusText.createChild('code', 'monospace').createTextChild(issueBody.trim()); } -}; +} +/** @const */ +export const fastFactRotationInterval = 6000; + +/** @const */ +export const minimumTextVisibilityDuration = 3000; /** @type {!Array.} */ -Audits.StatusView.KnownBugPatterns = [ +export const KnownBugPatterns = [ /PARSING_PROBLEM/, /DOCUMENT_REQUEST/, /READ_FAILED/, @@ -296,7 +301,7 @@ Audits.StatusView.KnownBugPatterns = [ ]; /** @typedef {{message: string, progressBarClass: string, order: number}} */ -Audits.StatusView.StatusPhases = [ +export const StatusPhases = [ { id: 'loading', progressBarClass: 'loading', @@ -320,7 +325,7 @@ Audits.StatusView.StatusPhases = [ ]; /** @typedef {{message: string, deviceType: string, throttling: string}} */ -Audits.StatusView.LoadingMessages = [ +export const LoadingMessages = [ { deviceType: 'mobile', throttling: 'on', @@ -343,26 +348,49 @@ Audits.StatusView.LoadingMessages = [ }, ]; -Audits.StatusView.FastFacts = [ - ls`1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: WebPageTest and DevTools 3G definition].`, - ls`Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: WPO Stats]`, - ls`BBC has seen a loss of 10% of their users for every extra second of page load [Source: WPO Stats]`, - ls`By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: WPO Stats]`, - ls`Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: WPO Stats]`, - ls`If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: Google Developers Blog]`, - ls`75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile]`, - ls`The average user device costs less than 200 USD. [Source: International Data Corporation]`, - ls`53% of all site visits are abandoned if page load takes more than 3 seconds [Source: Google DoubleClick blog]`, - ls`19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: Google DoubleClick blog]`, - ls`14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: Google DoubleClick blog]`, - ls`70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: Think with Google]`, - ls`As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: Think with Google]`, - ls`As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: Think with Google]`, - ls`70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: Think with Google]`, - ls`Lighthouse only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: Lighthouse team]`, +export const FastFacts = [ + ls +`1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: WebPageTest and DevTools 3G definition].`, + ls`Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: WPO Stats]`, + ls`BBC has seen a loss of 10% of their users for every extra second of page load [Source: WPO Stats]`, ls +`By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: WPO Stats]`, + ls`Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: WPO Stats]`, ls +`If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: Google Developers Blog]`, + ls`75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile]`, + ls`The average user device costs less than 200 USD. [Source: International Data Corporation]`, + ls`53% of all site visits are abandoned if page load takes more than 3 seconds [Source: Google DoubleClick blog]`, + ls +`19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: Google DoubleClick blog]`, + ls +`14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: Google DoubleClick blog]`, + ls +`70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: Think with Google]`, + ls +`As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: Think with Google]`, + ls +`As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: Think with Google]`, + ls`70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: Think with Google]`, ls + `Lighthouse only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: Lighthouse team]`, ]; -/** @const */ -Audits.StatusView.fastFactRotationInterval = 6000; -/** @const */ -Audits.StatusView.minimumTextVisibilityDuration = 3000; + /* Legacy exported object */ + self.Audits = self.Audits || {}; + + /* Legacy exported object */ + Audits = Audits || {}; + + /** + * @constructor + */ + Audits.StatusView = StatusView; + + Audits.StatusView.FastFacts = FastFacts; + + /** @type {!Array.} */ + Audits.StatusView.KnownBugPatterns = KnownBugPatterns; + + /** @typedef {{message: string, progressBarClass: string, order: number}} */ + Audits.StatusView.StatusPhases = StatusPhases; + + /** @typedef {{message: string, deviceType: string, throttling: string}} */ + Audits.StatusView.LoadingMessages = LoadingMessages; diff --git a/front_end/audits/RadioSetting.js b/front_end/audits/RadioSetting.js index bbe09e5e45..07f9567b8e 100644 --- a/front_end/audits/RadioSetting.js +++ b/front_end/audits/RadioSetting.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Audits.RadioSetting = class { +export default class RadioSetting { /** * @param {!Array} options * @param {!Common.Setting} setting @@ -65,4 +65,13 @@ Audits.RadioSetting = class { const selectedRadio = this._radioElements.find(radio => radio.checked); this._setting.set(selectedRadio.value); } -}; +} + +/* Legacy exported object */ +self.Audits = self.Audits || {}; + +/* Legacy exported object */ +Audits = Audits || {}; + +// TODO(http://crbug.com/1006759): Add type information if necessary +Audits.RadioSetting = RadioSetting; diff --git a/front_end/audits/audits.js b/front_end/audits/audits.js new file mode 100644 index 0000000000..2ad97b3ea3 --- /dev/null +++ b/front_end/audits/audits.js @@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './lighthouse/report.js'; +import './lighthouse/report-generator.js'; +import './RadioSetting.js'; +import './AuditsPanel.js'; +import './AuditsController.js'; +import './AuditsReportSelector.js'; +import './AuditsReportRenderer.js'; +import './AuditsStartView.js'; +import './AuditsStatusView.js'; +import './AuditsProtocolService.js'; + +import * as AuditsController from './AuditsController.js'; +import * as AuditsPanel from './AuditsPanel.js'; +import * as AuditsProtocolService from './AuditsProtocolService.js'; +import * as AuditsReportRenderer from './AuditsReportRenderer.js'; +import * as AuditsReportSelector from './AuditsReportSelector.js'; +import * as AuditsStartView from './AuditsStartView.js'; +import * as AuditsStatusView from './AuditsStatusView.js'; +import * as RadioSetting from './RadioSetting.js'; + +export { + AuditsController, + AuditsPanel, + AuditsProtocolService, + AuditsReportRenderer, + AuditsReportSelector, + AuditsStartView, + AuditsStatusView, + RadioSetting, +}; diff --git a/front_end/audits/module.json b/front_end/audits/module.json index f58b5e83ac..4b9d123875 100644 --- a/front_end/audits/module.json +++ b/front_end/audits/module.json @@ -19,7 +19,9 @@ "services", "ui" ], - "scripts": [ + "scripts": [], + "modules": [ + "audits.js", "lighthouse/report.js", "lighthouse/report-generator.js", "RadioSetting.js", @@ -37,9 +39,7 @@ "auditsStartView.css", "lighthouse/template.html", "lighthouse/templates.html", - "lighthouse/report.css", - "lighthouse/report-generator.js", - "lighthouse/report.js" + "lighthouse/report.css" ], "skip_compilation": [ "lighthouse/report.js", diff --git a/scripts/test/run_type_check.py b/scripts/test/run_type_check.py index c272235225..10214c83c5 100755 --- a/scripts/test/run_type_check.py +++ b/scripts/test/run_type_check.py @@ -282,6 +282,8 @@ GENERATED_SKIP_COMPILATION_FILES = [ 'cm/foldcode.js', 'cm/foldgutter.js', 'cm/brace-fold.js', + 'audits/lighthouse/report.js', + 'audits/lighthouse/report-generator.js' ]