UNPKG

@o3r/application

Version:

This module provides development help to monitor your Otter Application

262 lines (252 loc) 12.4 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, DOCUMENT, Injectable, DestroyRef, NgModule } from '@angular/core'; import { isProductionEnvironment, sendOtterMessage, filterMessageContent } from '@o3r/core'; import { ENVIRONMENT_CONFIG_TOKEN } from '@o3r/routing'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { LoggerService } from '@o3r/logger'; import { fromEvent } from 'rxjs'; /** * Method that returns the setting of the user regarding animations. * This setting is generally set in the Operating System settings, and it is used by browsers. * Refer to: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion */ function prefersReducedMotion() { const mediaQueryList = window.matchMedia('(prefers-reduced-motion)'); return mediaQueryList.matches; } /** * Determine if the given message is a Application message * @param message message to check */ const isApplicationMessage = (message) => { return message && (message.dataType === 'toggleVisualTesting' || message.dataType === 'stateSelection' || message.dataType === 'applicationInformation' || message.dataType === 'unselectState' || message.dataType === 'requestMessages' || message.dataType === 'connect'); }; const OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS = { isActivatedOnBootstrap: false }; const OTTER_APPLICATION_DEVTOOLS_OPTIONS = new InjectionToken('Otter Application Devtools options'); class OtterApplicationDevtools { constructor() { this.options = inject(OTTER_APPLICATION_DEVTOOLS_OPTIONS, { optional: true }); this.document = inject(DOCUMENT, { optional: true }); this.env = inject(ENVIRONMENT_CONFIG_TOKEN, { optional: true }); } getApplicationInformation() { return { appName: this.options?.appName || 'unknown', appVersion: this.env?.APP_VERSION || 'unknown', isProduction: isProductionEnvironment(this.document?.body.dataset) }; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OtterApplicationDevtools, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OtterApplicationDevtools, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OtterApplicationDevtools, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); /* eslint-disable no-console -- purpose of the service is to log in the console */ class ApplicationDevtoolsConsoleService { /** Name of the Window property to access to the devtools */ static { this.windowModuleName = 'application'; } constructor() { this.applicationDevtools = inject(OtterApplicationDevtools); const options = inject(OTTER_APPLICATION_DEVTOOLS_OPTIONS, { optional: true }); this.options = { ...OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS, ...options }; if (this.options.isActivatedOnBootstrap) { this.activate(); } } /** @inheritDoc */ activate() { const windowWithDevtools = window; windowWithDevtools._OTTER_DEVTOOLS_ ||= {}; windowWithDevtools._OTTER_DEVTOOLS_[ApplicationDevtoolsConsoleService.windowModuleName] = this; console.info(`Otter Application Devtools is now accessible via the _OTTER_DEVTOOLS_.${ApplicationDevtoolsConsoleService.windowModuleName} variable`); } /** Display the information relative to the running application */ displayApplicationInfo() { console.info('Application info', this.applicationDevtools.getApplicationInformation()); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsConsoleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsConsoleService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsConsoleService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); const OTTER_STATE_RIBBON_ID = 'otter-devtools-state-ribbon'; class ApplicationDevtoolsMessageService { constructor() { this.document = inject(DOCUMENT); this.sendMessage = (sendOtterMessage); this.destroyRef = inject(DestroyRef); this.logger = inject(LoggerService); this.applicationDevtools = inject(OtterApplicationDevtools); this.options = { ...OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS, ...inject(OTTER_APPLICATION_DEVTOOLS_OPTIONS, { optional: true }) }; if (this.options.isActivatedOnBootstrap) { this.activate(); } } sendApplicationInformation() { this.sendMessage('applicationInformation', this.applicationDevtools.getApplicationInformation()); } /** * Function to connect the plugin to the Otter DevTools extension */ connectPlugin() { this.logger.debug('Otter DevTools is plugged to application service of the application'); void this.sendApplicationInformation(); } /** * Function to trigger a re-send a requested messages to the Otter Chrome DevTools extension * @param only restricted list of messages to re-send */ handleReEmitRequest(only) { if (!only || only.includes('applicationInformation')) { this.sendApplicationInformation(); } } /** * Function to handle the incoming messages from Otter Chrome DevTools extension * @param message */ async handleEvents(message) { this.logger.debug('Message handling by the application service', message); switch (message.dataType) { case 'connect': { this.connectPlugin(); break; } case 'requestMessages': { this.handleReEmitRequest(message.only); break; } case 'toggleVisualTesting': { await this.toggleVisualTestingRender(message.toggle); break; } case 'stateSelection': { this.onStateSelection(message); break; } case 'unselectState': { this.unselectState(); break; } default: { this.logger.warn('Message ignored by the application service', message); } } } unselectState() { const ribbonElement = this.document.body.querySelector(`#${OTTER_STATE_RIBBON_ID}`); if (ribbonElement) { ribbonElement.remove(); } } onStateSelection(message) { let ribbonElement = this.document.body.querySelector(`#${OTTER_STATE_RIBBON_ID}`); if (!ribbonElement) { ribbonElement = this.document.createElement('div'); ribbonElement.id = OTTER_STATE_RIBBON_ID; this.document.body.append(ribbonElement); } if (message.stateName) { ribbonElement.innerHTML = message.stateName; ribbonElement.style.background = message.stateColor; ribbonElement.style.color = message.stateColorContrast; ribbonElement.style.position = 'fixed'; ribbonElement.style.bottom = '0'; ribbonElement.style.right = '0'; ribbonElement.style.transform = 'translate(calc(100% * (1 - cos(45deg)))) rotate(-45deg)'; ribbonElement.style.transformOrigin = 'bottom left'; ribbonElement.style.clipPath = 'inset(0 -100%)'; ribbonElement.style.boxShadow = `0px 0px 0px 999px ${message.stateColor}`; } else { ribbonElement.style.display = 'none'; } } /** * Toggle visual testing rendering * @param enabled activate or deactivate the visual testing mode */ async toggleVisualTestingRender(enabled) { try { const visualTestUtils = await import('@o3r/testing/visual-test/utils'); const isEnabled = enabled ?? visualTestUtils.isVisualTestingEnabled(); visualTestUtils.toggleVisualTestingRender(isEnabled); } catch (err) { this.logger.warn('Visual testing utilities are not available:', err); } } /** @inheritDoc */ activate() { fromEvent(window, 'message').pipe(takeUntilDestroyed(this.destroyRef), filterMessageContent(isApplicationMessage)).subscribe((e) => this.handleEvents(e)); import('@o3r/testing/visual-test/utils') .then((visualTestUtils) => visualTestUtils.prepareVisualTesting(this.options.e2eIgnoreClass)) .catch((err) => this.logger.warn('Visual testing utilities are not available:', err)); this.sendApplicationInformation(); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsMessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsMessageService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsMessageService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); class ApplicationDevtoolsModule { /** * Initialize Otter Devtools * @param options */ static instrument(options) { return { ngModule: ApplicationDevtoolsModule, providers: [ { provide: OTTER_APPLICATION_DEVTOOLS_OPTIONS, useValue: { ...OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS, ...options }, multi: false }, ApplicationDevtoolsMessageService, ApplicationDevtoolsConsoleService, OtterApplicationDevtools ] }; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsModule }); } /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsModule, providers: [ { provide: OTTER_APPLICATION_DEVTOOLS_OPTIONS, useValue: OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS }, ApplicationDevtoolsMessageService, ApplicationDevtoolsConsoleService, OtterApplicationDevtools ] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ApplicationDevtoolsModule, decorators: [{ type: NgModule, args: [{ providers: [ { provide: OTTER_APPLICATION_DEVTOOLS_OPTIONS, useValue: OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS }, ApplicationDevtoolsMessageService, ApplicationDevtoolsConsoleService, OtterApplicationDevtools ] }] }] }); /** * Generated bundle index. Do not edit. */ export { ApplicationDevtoolsConsoleService, ApplicationDevtoolsMessageService, ApplicationDevtoolsModule, OTTER_APPLICATION_DEVTOOLS_DEFAULT_OPTIONS, OTTER_APPLICATION_DEVTOOLS_OPTIONS, OtterApplicationDevtools, isApplicationMessage, prefersReducedMotion }; //# sourceMappingURL=o3r-application.mjs.map