UNPKG

ngx-matomo-client

Version:

Matomo (fka. Piwik) client for Angular applications

354 lines (340 loc) 16.1 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, ElementRef, Injectable, booleanAttribute, Directive, Input, HostListener, PLATFORM_ID, NgModule, Optional, SkipSelf, ENVIRONMENT_INITIALIZER, ErrorHandler } from '@angular/core'; import { ɵINTERNAL_MATOMO_CONFIGURATION as _INTERNAL_MATOMO_CONFIGURATION, ɵInternalMatomoTracker as _InternalMatomoTracker, ɵASYNC_INTERNAL_MATOMO_CONFIGURATION as _ASYNC_INTERNAL_MATOMO_CONFIGURATION, ɵScriptInjector as _ScriptInjector, MatomoTracker, ɵrunOnce as _runOnce, ɵisAutoConfigurationMode as _isAutoConfigurationMode, ɵisExplicitTrackerConfiguration as _isExplicitTrackerConfiguration, ɵgetTrackersConfiguration as _getTrackersConfiguration, ɵappendTrailingSlash as _appendTrailingSlash, ɵcreateMatomoFeature as _createMatomoFeature } from 'ngx-matomo-client/core'; import { isPlatformBrowser } from '@angular/common'; import { debounceTime, identity } from 'rxjs'; const MATOMO_FORM_ANALYTICS_CONFIGURATION = new InjectionToken('MATOMO_FORM_ANALYTICS_CONFIGURATION'); const DEFAULT_FORM_ANALYTICS_CONFIGURATION = { disabled: false, loadScript: false, autoScan: true, autoScanDelay: 0, }; const INTERNAL_MATOMO_FORM_ANALYTICS_CONFIGURATION = new InjectionToken('INTERNAL_MATOMO_FORM_ANALYTICS_CONFIGURATION', { factory() { const matomoConfig = inject(_INTERNAL_MATOMO_CONFIGURATION); const userConfig = inject(MATOMO_FORM_ANALYTICS_CONFIGURATION, { optional: true }) || {}; const merged = { ...DEFAULT_FORM_ANALYTICS_CONFIGURATION, ...userConfig, }; return { ...merged, disabled: merged.disabled || matomoConfig.disabled, }; }, }); function throwFormNotFoundError(selector) { throw new Error(`Directive ${selector} can only be used inside [matomoTrackForm]`); } function coerceElement(elementOrRef) { return elementOrRef instanceof ElementRef ? elementOrRef.nativeElement : elementOrRef; } class MatomoFormAnalytics { constructor() { this.delegate = inject(_InternalMatomoTracker); } disableFormAnalytics() { this.delegate.push(['FormAnalytics::disableFormAnalytics']); } enableFormAnalytics() { this.delegate.push(['FormAnalytics::enableFormAnalytics']); } enableDebugMode() { this.delegate.push(['FormAnalytics::enableDebugMode']); } setTrackingTimer(delayInMilliSeconds) { this.delegate.push(['FormAnalytics::setTrackingTimer', delayInMilliSeconds]); } scanForForms(root) { this.delegate.push(['FormAnalytics::scanForForms', coerceElement(root)]); } trackForm(formElement) { this.delegate.push(['FormAnalytics::trackForm', coerceElement(formElement)]); } trackFormSubmit(formElement) { this.delegate.push(['FormAnalytics::trackFormSubmit', coerceElement(formElement)]); } trackFormConversion(formElementOrName, formId) { this.delegate.push([ 'FormAnalytics::trackFormConversion', typeof formElementOrName === 'string' ? formElementOrName : coerceElement(formElementOrName), formId, ]); } isFormAnalyticsEnabled() { return this.delegate.get('FormAnalytics::isFormAnalyticsEnabled'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalytics, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalytics }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalytics, decorators: [{ type: Injectable }] }); class TrackFormDirective { set matomoIgnore(ignore) { if (ignore) { this.elementRef.nativeElement.setAttribute('data-matomo-ignore', ''); } else { this.elementRef.nativeElement.removeAttribute('data-matomo-ignore'); } } set matomoTrackForm(name) { if (name) { this.elementRef.nativeElement.setAttribute('data-matomo-name', name); } else { this.elementRef.nativeElement.removeAttribute('data-matomo-name'); } if (this.initialized) { this.track(); } } constructor() { this.elementRef = inject(ElementRef); this.tracker = inject(MatomoFormAnalytics); this.initialized = false; /** If true, will track a conversion after form submit */ this.trackConversionOnSubmit = false; this.elementRef.nativeElement.setAttribute('data-matomo-form', ''); } ngAfterViewInit() { this.track(); this.initialized = true; } track() { this.tracker.trackForm(this.elementRef); } trackSubmit() { this.tracker.trackFormSubmit(this.elementRef); } trackConversion() { this.tracker.trackFormConversion(this.elementRef); } trackFormConversionOnSubmit() { if (this.trackConversionOnSubmit) { this.trackConversion(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.0.5", type: TrackFormDirective, isStandalone: true, selector: "[matomoTrackForm]", inputs: { trackConversionOnSubmit: ["trackConversionOnSubmit", "trackConversionOnSubmit", booleanAttribute], matomoIgnore: ["matomoIgnore", "matomoIgnore", booleanAttribute], matomoTrackForm: "matomoTrackForm" }, host: { listeners: { "submit": "trackFormConversionOnSubmit()" } }, exportAs: ["matomoTrackForm"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackForm]', standalone: true, exportAs: 'matomoTrackForm', }] }], ctorParameters: () => [], propDecorators: { trackConversionOnSubmit: [{ type: Input, args: [{ transform: booleanAttribute }] }], matomoIgnore: [{ type: Input, args: [{ transform: booleanAttribute }] }], matomoTrackForm: [{ type: Input }], trackFormConversionOnSubmit: [{ type: HostListener, args: ['submit'] }] } }); class TrackFormFieldDirective { constructor() { this.elementRef = inject(ElementRef); this.form = inject(TrackFormDirective, { optional: true }) ?? throwFormNotFoundError('[matomoTrackFormField]'); this.initialized = false; } set matomoIgnore(ignore) { if (ignore) { this.elementRef.nativeElement.setAttribute('data-matomo-ignore', ''); } else { this.elementRef.nativeElement.removeAttribute('data-matomo-ignore'); } } set matomoTrackFormField(name) { if (name) { this.elementRef.nativeElement.setAttribute('data-matomo-name', name); } else { this.elementRef.nativeElement.removeAttribute('data-matomo-name'); } if (this.initialized) { this.track(); } } ngAfterViewInit() { this.track(); this.initialized = true; } track() { this.form.track(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.0.5", type: TrackFormFieldDirective, isStandalone: true, selector: "[matomoTrackFormField]", inputs: { matomoIgnore: ["matomoIgnore", "matomoIgnore", booleanAttribute], matomoTrackFormField: "matomoTrackFormField" }, exportAs: ["matomoTrackFormField"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormFieldDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackFormField]', standalone: true, exportAs: 'matomoTrackFormField', }] }], propDecorators: { matomoIgnore: [{ type: Input, args: [{ transform: booleanAttribute }] }], matomoTrackFormField: [{ type: Input }] } }); class TrackFormsDirective { constructor() { this.elementRef = inject(ElementRef); this.tracker = inject(MatomoFormAnalytics); } ngAfterViewInit() { this.scan(); } scan() { this.tracker.scanForForms(this.elementRef); } trackSubmit(element) { this.tracker.trackFormSubmit(element); } trackConversion(element) { this.tracker.trackFormConversion(element); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: TrackFormsDirective, isStandalone: true, selector: "[matomoTrackForms]", exportAs: ["matomoTrackForms"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TrackFormsDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackForms]', standalone: true, exportAs: 'matomoTrackForms', }] }] }); const DEFAULT_SCRIPT_SUFFIX = 'plugins/FormAnalytics/tracker.min.js'; class MatomoFormAnalyticsInitializer { constructor() { this.config = inject(INTERNAL_MATOMO_FORM_ANALYTICS_CONFIGURATION); this.coreConfig = inject(_ASYNC_INTERNAL_MATOMO_CONFIGURATION); this.scriptInjector = inject(_ScriptInjector); this.tracker = inject(MatomoTracker); this.formAnalytics = inject(MatomoFormAnalytics); this.platformId = inject(PLATFORM_ID); this.initialize = _runOnce(async () => { // Do not set-up router if running on server if (!isPlatformBrowser(this.platformId)) { return; } if (this.config.disabled) { this.formAnalytics.disableFormAnalytics(); return; } if (this.config.loadScript) { const scriptUrl = typeof this.config.loadScript === 'boolean' ? await this.buildDefaultScriptUrl() : this.config.loadScript; this.scriptInjector.injectDOMScript(scriptUrl); } if (this.config.autoScan) { const delayOp = this.config.autoScanDelay ? debounceTime(this.config.autoScanDelay) : identity; this.pageTrackedSubscription = this.tracker.pageViewTracked .pipe(delayOp) .subscribe(() => this.formAnalytics.scanForForms()); } }); } ngOnDestroy() { this.pageTrackedSubscription?.unsubscribe(); } async buildDefaultScriptUrl() { const config = await this.coreConfig; if (_isAutoConfigurationMode(config) && _isExplicitTrackerConfiguration(config)) { const [mainTracker] = _getTrackersConfiguration(config); if (mainTracker) { return _appendTrailingSlash(mainTracker.trackerUrl) + DEFAULT_SCRIPT_SUFFIX; } } throw new Error('Cannot resolve default matomo FormAnalytics plugin script url. ' + 'Please explicitly provide `loadScript` configuration property instead of `true`'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsInitializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsInitializer }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsInitializer, decorators: [{ type: Injectable }] }); const MATOMO_FORM_ANALYTICS_DIRECTIVES = [ TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective, ]; class MatomoFormAnalyticsModule { constructor(formAnalytics, parent) { this.formAnalytics = formAnalytics; if (!parent) { // Do not initialize if it is already (by a parent module) this.formAnalytics.initialize(); } } static forRoot(config = {}) { return { ngModule: MatomoFormAnalyticsModule, providers: [{ provide: MATOMO_FORM_ANALYTICS_CONFIGURATION, useValue: config }], }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsModule, deps: [{ token: MatomoFormAnalyticsInitializer }, { token: MatomoFormAnalyticsModule, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsModule, imports: [TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective], exports: [TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: MatomoFormAnalyticsModule, decorators: [{ type: NgModule, args: [{ imports: [...MATOMO_FORM_ANALYTICS_DIRECTIVES], exports: [...MATOMO_FORM_ANALYTICS_DIRECTIVES], }] }], ctorParameters: () => [{ type: MatomoFormAnalyticsInitializer }, { type: MatomoFormAnalyticsModule, decorators: [{ type: Optional }, { type: SkipSelf }] }] }); /** Enable automatic page views tracking */ function withFormAnalytics(config) { const providers = [ MatomoFormAnalytics, MatomoFormAnalyticsInitializer, { provide: MATOMO_FORM_ANALYTICS_CONFIGURATION, useValue: config, }, { provide: ENVIRONMENT_INITIALIZER, multi: true, useValue() { const errorHandler = inject(ErrorHandler); // Do NOT wait here for initialization, because app startup should NOT be blocked until deferred config is resolved // However, correctly propagate errors to error handler Promise.resolve(inject(MatomoFormAnalyticsInitializer).initialize()).catch(error => errorHandler.handleError(error)); }, }, ]; return _createMatomoFeature("FormAnalytics" /* FormAnalyticsMatomoFeatureKind.FormAnalytics */, providers); } /* * Public API Surface of plugin form-analytics */ /** * Generated bundle index. Do not edit. */ export { MATOMO_FORM_ANALYTICS_CONFIGURATION, MATOMO_FORM_ANALYTICS_DIRECTIVES, MatomoFormAnalytics, MatomoFormAnalyticsModule, TrackFormDirective, TrackFormFieldDirective, TrackFormsDirective, withFormAnalytics }; //# sourceMappingURL=ngx-matomo-client-form-analytics.mjs.map