ngx-matomo-client
Version:
Matomo (fka. Piwik) client for Angular applications
304 lines (290 loc) • 16.6 kB
JavaScript
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