UNPKG

ngx-matomo-client

Version:

Matomo (fka. Piwik) client for Angular applications

304 lines (290 loc) 16.6 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, ElementRef, Service, input, booleanAttribute, afterRenderEffect, Directive, PLATFORM_ID, NgModule, provideEnvironmentInitializer, 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: "22.0.0", ngImport: i0, type: MatomoFormAnalytics, deps: [], target: i0.ɵɵFactoryTarget.Service }); } static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalytics, autoProvided: false }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalytics, decorators: [{ type: Service, args: [{ autoProvided: false }] }] }); class TrackFormDirective { constructor() { this.elementRef = inject(ElementRef); this.tracker = inject(MatomoFormAnalytics); /** If true, will track a conversion after form submit */ this.trackConversionOnSubmit = input(false, { ...(ngDevMode ? { debugName: "trackConversionOnSubmit" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); this.matomoIgnore = input(undefined, { ...(ngDevMode ? { debugName: "matomoIgnore" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); this.matomoTrackForm = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "matomoTrackForm" }] : /* istanbul ignore next */ [])); afterRenderEffect(() => { this.matomoTrackForm(); this.track(); }); } 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: "22.0.0", ngImport: i0, type: TrackFormDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: TrackFormDirective, isStandalone: true, selector: "[matomoTrackForm]", inputs: { trackConversionOnSubmit: { classPropertyName: "trackConversionOnSubmit", publicName: "trackConversionOnSubmit", isSignal: true, isRequired: false, transformFunction: null }, matomoIgnore: { classPropertyName: "matomoIgnore", publicName: "matomoIgnore", isSignal: true, isRequired: false, transformFunction: null }, matomoTrackForm: { classPropertyName: "matomoTrackForm", publicName: "matomoTrackForm", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-matomo-form": "" }, listeners: { "submit": "trackFormConversionOnSubmit()" }, properties: { "attr.data-matomo-ignore": "matomoIgnore() ? \"\" : null", "attr.data-matomo-name": "matomoTrackForm() || null" } }, exportAs: ["matomoTrackForm"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: TrackFormDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackForm]', exportAs: 'matomoTrackForm', host: { 'data-matomo-form': '', '[attr.data-matomo-ignore]': 'matomoIgnore() ? "" : null', '[attr.data-matomo-name]': 'matomoTrackForm() || null', '(submit)': 'trackFormConversionOnSubmit()', }, }] }], ctorParameters: () => [], propDecorators: { trackConversionOnSubmit: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackConversionOnSubmit", required: false }] }], matomoIgnore: [{ type: i0.Input, args: [{ isSignal: true, alias: "matomoIgnore", required: false }] }], matomoTrackForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "matomoTrackForm", required: false }] }] } }); class TrackFormFieldDirective { constructor() { this.form = inject(TrackFormDirective, { optional: true }) ?? throwFormNotFoundError('[matomoTrackFormField]'); this.matomoIgnore = input(undefined, { ...(ngDevMode ? { debugName: "matomoIgnore" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); this.matomoTrackFormField = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "matomoTrackFormField" }] : /* istanbul ignore next */ [])); afterRenderEffect(() => { this.matomoTrackFormField(); this.track(); }); } track() { this.form.track(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: TrackFormFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: TrackFormFieldDirective, isStandalone: true, selector: "[matomoTrackFormField]", inputs: { matomoIgnore: { classPropertyName: "matomoIgnore", publicName: "matomoIgnore", isSignal: true, isRequired: false, transformFunction: null }, matomoTrackFormField: { classPropertyName: "matomoTrackFormField", publicName: "matomoTrackFormField", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-matomo-ignore": "matomoIgnore() ? \"\" : null", "attr.data-matomo-name": "matomoTrackFormField() || null" } }, exportAs: ["matomoTrackFormField"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: TrackFormFieldDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackFormField]', exportAs: 'matomoTrackFormField', host: { '[attr.data-matomo-ignore]': 'matomoIgnore() ? "" : null', '[attr.data-matomo-name]': 'matomoTrackFormField() || null', }, }] }], ctorParameters: () => [], propDecorators: { matomoIgnore: [{ type: i0.Input, args: [{ isSignal: true, alias: "matomoIgnore", required: false }] }], matomoTrackFormField: [{ type: i0.Input, args: [{ isSignal: true, alias: "matomoTrackFormField", required: false }] }] } }); 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: "22.0.0", ngImport: i0, type: TrackFormsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.0", type: TrackFormsDirective, isStandalone: true, selector: "[matomoTrackForms]", exportAs: ["matomoTrackForms"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: TrackFormsDirective, decorators: [{ type: Directive, args: [{ selector: '[matomoTrackForms]', 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: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsInitializer, deps: [], target: i0.ɵɵFactoryTarget.Service }); } static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsInitializer, autoProvided: false }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsInitializer, decorators: [{ type: Service, args: [{ autoProvided: false }] }] }); const MATOMO_FORM_ANALYTICS_DIRECTIVES = [ TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective, ]; class MatomoFormAnalyticsModule { constructor() { this.formAnalytics = inject(MatomoFormAnalyticsInitializer); const parent = inject(MatomoFormAnalyticsModule, { optional: true, skipSelf: true }); 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: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsModule, imports: [TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective], exports: [TrackFormDirective, TrackFormsDirective, TrackFormFieldDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: MatomoFormAnalyticsModule, decorators: [{ type: NgModule, args: [{ imports: [...MATOMO_FORM_ANALYTICS_DIRECTIVES], exports: [...MATOMO_FORM_ANALYTICS_DIRECTIVES], }] }], ctorParameters: () => [] }); /** Enable automatic page views tracking */ function withFormAnalytics(config) { const providers = [ MatomoFormAnalytics, MatomoFormAnalyticsInitializer, { provide: MATOMO_FORM_ANALYTICS_CONFIGURATION, useValue: config, }, provideEnvironmentInitializer(() => { 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