AuditsController.js 6.2 KB

123456789101112131415161718192021222324252627
  1. class AuditController extends Common.Object{constructor(protocolService){super();protocolService.registerStatusCallback(message=>this.dispatchEventToListeners(Audits.Events.AuditProgressChanged,{message}));for(const preset of Audits.Presets){preset.setting.addChangeListener(this.recomputePageAuditability.bind(this));}
  2. SDK.targetManager.observeModels(SDK.ServiceWorkerManager,this);SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged,this.recomputePageAuditability,this);}
  3. modelAdded(serviceWorkerManager){if(this._manager){return;}
  4. this._manager=serviceWorkerManager;this._serviceWorkerListeners=[this._manager.addEventListener(SDK.ServiceWorkerManager.Events.RegistrationUpdated,this.recomputePageAuditability,this),this._manager.addEventListener(SDK.ServiceWorkerManager.Events.RegistrationDeleted,this.recomputePageAuditability,this),];this.recomputePageAuditability();}
  5. modelRemoved(serviceWorkerManager){if(this._manager!==serviceWorkerManager){return;}
  6. Common.EventTarget.removeEventListeners(this._serviceWorkerListeners);this._manager=null;this.recomputePageAuditability();}
  7. _hasActiveServiceWorker(){if(!this._manager){return false;}
  8. const mainTarget=this._manager.target();if(!mainTarget){return false;}
  9. const inspectedURL=mainTarget.inspectedURL().asParsedURL();const inspectedOrigin=inspectedURL&&inspectedURL.securityOrigin();for(const registration of this._manager.registrations().values()){if(registration.securityOrigin!==inspectedOrigin){continue;}
  10. for(const version of registration.versions.values()){if(version.controlledClients.length>1){return true;}}}
  11. return false;}
  12. _hasAtLeastOneCategory(){return Audits.Presets.some(preset=>preset.setting.get());}
  13. _unauditablePageMessage(){if(!this._manager){return null;}
  14. const mainTarget=this._manager.target();const inspectedURL=mainTarget&&mainTarget.inspectedURL();if(inspectedURL&&!/^(http|chrome-extension)/.test(inspectedURL)){return Common.UIString('Can only audit HTTP/HTTPS pages and Chrome extensions. Navigate to a different page to start an audit.');}
  15. return null;}
  16. async _evaluateInspectedURL(){const mainTarget=this._manager.target();const runtimeModel=mainTarget.model(SDK.RuntimeModel);const executionContext=runtimeModel&&runtimeModel.defaultExecutionContext();let inspectedURL=mainTarget.inspectedURL();if(!executionContext){return inspectedURL;}
  17. try{const result=await executionContext.evaluate({expression:'window.location.href',objectGroup:'audits',includeCommandLineAPI:false,silent:false,returnByValue:true,generatePreview:false},false,false);if(!result.exceptionDetails&&result.object){inspectedURL=result.object.value;result.object.release();}}catch(err){console.error(err);}
  18. return inspectedURL;}
  19. getFlags(){const flags={internalDisableDeviceScreenEmulation:true};for(const runtimeSetting of Audits.RuntimeSettings){runtimeSetting.setFlags(flags,runtimeSetting.setting.get());}
  20. return flags;}
  21. getCategoryIDs(){const categoryIDs=[];for(const preset of Audits.Presets){if(preset.setting.get()){categoryIDs.push(preset.configID);}}
  22. return categoryIDs;}
  23. async getInspectedURL(options){if(options&&options.force||!this._inspectedURL){this._inspectedURL=await this._evaluateInspectedURL();}
  24. return this._inspectedURL;}
  25. recomputePageAuditability(){const hasActiveServiceWorker=this._hasActiveServiceWorker();const hasAtLeastOneCategory=this._hasAtLeastOneCategory();const unauditablePageMessage=this._unauditablePageMessage();let helpText='';if(hasActiveServiceWorker){helpText=Common.UIString('Multiple tabs are being controlled by the same service worker. Close your other tabs on the same origin to audit this page.');}else if(!hasAtLeastOneCategory){helpText=Common.UIString('At least one category must be selected.');}else if(unauditablePageMessage){helpText=unauditablePageMessage;}
  26. this.dispatchEventToListeners(Audits.Events.PageAuditabilityChanged,{helpText});}}
  27. export const Presets=[{setting:Common.settings.createSetting('audits.cat_perf',true),configID:'performance',title:ls`Performance`,description:ls`How long does this app take to show content and become usable`},{setting:Common.settings.createSetting('audits.cat_pwa',true),configID:'pwa',title:ls`Progressive Web App`,description:ls`Does this page meet the standard of a Progressive Web App`},{setting:Common.settings.createSetting('audits.cat_best_practices',true),configID:'best-practices',title:ls`Best practices`,description:ls`Does this page follow best practices for modern web development`},{setting:Common.settings.createSetting('audits.cat_a11y',true),configID:'accessibility',title:ls`Accessibility`,description:ls`Is this page usable by people with disabilities or impairments`},{setting:Common.settings.createSetting('audits.cat_seo',true),configID:'seo',title:ls`SEO`,description:ls`Is this page optimized for search engine results ranking`},{setting:Common.settings.createSetting('audits.cat_pubads',false),plugin:true,configID:'lighthouse-plugin-publisher-ads',title:ls`Publisher Ads`,description:ls`Is this page optimized for ad speed and quality`},];export const RuntimeSettings=[{setting:Common.settings.createSetting('audits.device_type','mobile'),description:ls`Apply mobile emulation during auditing`,setFlags:(flags,value)=>{flags.emulatedFormFactor=value;},options:[{label:ls`Mobile`,value:'mobile'},{label:ls`Desktop`,value:'desktop'},],},{setting:Common.settings.createSetting('audits.throttling',true),title:ls`Simulated throttling`,learnMore:'https://github.com/GoogleChrome/lighthouse/blob/master/docs/throttling.md#devtools-audits-panel-throttling',setFlags:(flags,value)=>{flags.throttlingMethod=value?'simulate':'devtools';},},{setting:Common.settings.createSetting('audits.clear_storage',true),title:ls`Clear storage`,description:ls`Reset storage (localStorage, IndexedDB, etc) before auditing. (Good for performance & PWA testing)`,setFlags:(flags,value)=>{flags.disableStorageReset=!value;},},];export const Events={PageAuditabilityChanged:Symbol('PageAuditabilityChanged'),AuditProgressChanged:Symbol('AuditProgressChanged'),RequestAuditStart:Symbol('RequestAuditStart'),RequestAuditCancel:Symbol('RequestAuditCancel'),};self.Audits=self.Audits||{};Audits=Audits||{};Audits.AuditController=AuditController;Audits.Preset;Audits.Events=Events;Audits.RuntimeSetting;Audits.RuntimeSettings=RuntimeSettings;Audits.Presets=Presets;