1 | import { InjectionToken, ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, Directive, ElementRef, Renderer2, Input, NgModule } from '@angular/core';
|
2 | import { BehaviorSubject, ReplaySubject } from 'rxjs';
|
3 | import { filter, map, delay } from 'rxjs/operators';
|
4 | import { Location } from '@angular/common';
|
5 | import { NavigationEnd, Router } from '@angular/router';
|
6 |
|
7 | class DefaultConfig {
|
8 | constructor() {
|
9 | this.pageTracking = {
|
10 | autoTrackVirtualPages: true,
|
11 | basePath: '',
|
12 | excludedRoutes: [],
|
13 | clearIds: false,
|
14 | clearHash: false,
|
15 | clearQueryParams: false,
|
16 | idsRegExp: /^\d+$|^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
|
17 | };
|
18 | this.developerMode = false;
|
19 | this.ga = {};
|
20 | this.appInsights = {};
|
21 | this.gtm = {};
|
22 | this.gst = {};
|
23 | }
|
24 | }
|
25 |
|
26 | const ANGULARTICS2_TOKEN = new InjectionToken('ANGULARTICS2');
|
27 |
|
28 | class RouterlessTracking {
|
29 | trackLocation(settings) {
|
30 | return new BehaviorSubject({ url: '/' });
|
31 | }
|
32 | prepareExternalUrl(url) {
|
33 | return url;
|
34 | }
|
35 | }
|
36 |
|
37 | class Angulartics2 {
|
38 | constructor(tracker, setup) {
|
39 | this.tracker = tracker;
|
40 | this.pageTrack = new ReplaySubject(10);
|
41 | this.eventTrack = new ReplaySubject(10);
|
42 | this.exceptionTrack = new ReplaySubject(10);
|
43 | this.setAlias = new ReplaySubject(10);
|
44 | this.setUsername = new ReplaySubject(10);
|
45 | this.setUserProperties = new ReplaySubject(10);
|
46 | this.setUserPropertiesOnce = new ReplaySubject(10);
|
47 | this.setSuperProperties = new ReplaySubject(10);
|
48 | this.setSuperPropertiesOnce = new ReplaySubject(10);
|
49 | this.userTimings = new ReplaySubject(10);
|
50 | const defaultConfig = new DefaultConfig();
|
51 | this.settings = Object.assign(Object.assign({}, defaultConfig), setup.settings);
|
52 | this.settings.pageTracking = Object.assign(Object.assign({}, defaultConfig.pageTracking), setup.settings.pageTracking);
|
53 | this.tracker
|
54 | .trackLocation(this.settings)
|
55 | .subscribe((event) => this.trackUrlChange(event.url));
|
56 | }
|
57 |
|
58 | filterDeveloperMode() {
|
59 | return filter((value, index) => !this.settings.developerMode);
|
60 | }
|
61 | trackUrlChange(url) {
|
62 | if (this.settings.pageTracking.autoTrackVirtualPages && !this.matchesExcludedRoute(url)) {
|
63 | const clearedUrl = this.clearUrl(url);
|
64 | let path;
|
65 | if (this.settings.pageTracking.basePath.length) {
|
66 | path = this.settings.pageTracking.basePath + clearedUrl;
|
67 | }
|
68 | else {
|
69 | path = this.tracker.prepareExternalUrl(clearedUrl);
|
70 | }
|
71 | this.pageTrack.next({ path });
|
72 | }
|
73 | }
|
74 | |
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | matchesExcludedRoute(url) {
|
81 | for (const excludedRoute of this.settings.pageTracking.excludedRoutes) {
|
82 | const matchesRegex = excludedRoute instanceof RegExp && excludedRoute.test(url);
|
83 | if (matchesRegex || url.indexOf(excludedRoute) !== -1) {
|
84 | return true;
|
85 | }
|
86 | }
|
87 | return false;
|
88 | }
|
89 | |
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | clearUrl(url) {
|
96 | if (this.settings.pageTracking.clearIds || this.settings.pageTracking.clearQueryParams ||
|
97 | this.settings.pageTracking.clearHash) {
|
98 | return url
|
99 | .split('/')
|
100 | .map(part => this.settings.pageTracking.clearQueryParams ? part.split('?')[0] : part)
|
101 | .map(part => this.settings.pageTracking.clearHash ? part.split('#')[0] : part)
|
102 | .filter(part => !this.settings.pageTracking.clearIds || !part.match(this.settings.pageTracking.idsRegExp))
|
103 | .join('/');
|
104 | }
|
105 | return url;
|
106 | }
|
107 | }
|
108 | Angulartics2.ɵprov = ɵɵdefineInjectable({ factory: function Angulartics2_Factory() { return new Angulartics2(ɵɵinject(RouterlessTracking), ɵɵinject(ANGULARTICS2_TOKEN)); }, token: Angulartics2, providedIn: "root" });
|
109 | Angulartics2.decorators = [
|
110 | { type: Injectable, args: [{ providedIn: 'root' },] }
|
111 | ];
|
112 | Angulartics2.ctorParameters = () => [
|
113 | { type: RouterlessTracking },
|
114 | { type: undefined, decorators: [{ type: Inject, args: [ANGULARTICS2_TOKEN,] }] }
|
115 | ];
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | class AngularRouterTracking {
|
124 | constructor(router, location) {
|
125 | this.router = router;
|
126 | this.location = location;
|
127 | }
|
128 | trackLocation(settings) {
|
129 | return this.router.events.pipe(filter(e => e instanceof NavigationEnd), filter(() => !settings.developerMode), map((e) => {
|
130 | return { url: e.urlAfterRedirects };
|
131 | }), delay(0));
|
132 | }
|
133 | prepareExternalUrl(url) {
|
134 | return this.location.prepareExternalUrl(url);
|
135 | }
|
136 | }
|
137 | AngularRouterTracking.ɵprov = ɵɵdefineInjectable({ factory: function AngularRouterTracking_Factory() { return new AngularRouterTracking(ɵɵinject(Router), ɵɵinject(Location)); }, token: AngularRouterTracking, providedIn: "root" });
|
138 | AngularRouterTracking.decorators = [
|
139 | { type: Injectable, args: [{ providedIn: 'root' },] }
|
140 | ];
|
141 | AngularRouterTracking.ctorParameters = () => [
|
142 | { type: Router },
|
143 | { type: Location }
|
144 | ];
|
145 |
|
146 | class Angulartics2On {
|
147 | constructor(elRef, angulartics2, renderer) {
|
148 | this.elRef = elRef;
|
149 | this.angulartics2 = angulartics2;
|
150 | this.renderer = renderer;
|
151 | this.angularticsProperties = {};
|
152 | }
|
153 | ngAfterContentInit() {
|
154 | this.renderer.listen(this.elRef.nativeElement, this.angulartics2On || 'click', (event) => this.eventTrack(event));
|
155 | }
|
156 | eventTrack(event) {
|
157 | const action = this.angularticsAction;
|
158 | const properties = Object.assign(Object.assign({}, this.angularticsProperties), { eventType: event.type });
|
159 | if (this.angularticsCategory) {
|
160 | properties.category = this.angularticsCategory;
|
161 | }
|
162 | if (this.angularticsLabel) {
|
163 | properties.label = this.angularticsLabel;
|
164 | }
|
165 | if (this.angularticsValue) {
|
166 | properties.value = this.angularticsValue;
|
167 | }
|
168 | this.angulartics2.eventTrack.next({
|
169 | action,
|
170 | properties,
|
171 | });
|
172 | }
|
173 | }
|
174 | Angulartics2On.decorators = [
|
175 | { type: Directive, args: [{ selector: '[angulartics2On]' },] }
|
176 | ];
|
177 | Angulartics2On.ctorParameters = () => [
|
178 | { type: ElementRef },
|
179 | { type: Angulartics2 },
|
180 | { type: Renderer2 }
|
181 | ];
|
182 | Angulartics2On.propDecorators = {
|
183 | angulartics2On: [{ type: Input, args: ['angulartics2On',] }],
|
184 | angularticsAction: [{ type: Input }],
|
185 | angularticsCategory: [{ type: Input }],
|
186 | angularticsLabel: [{ type: Input }],
|
187 | angularticsValue: [{ type: Input }],
|
188 | angularticsProperties: [{ type: Input }]
|
189 | };
|
190 | class Angulartics2OnModule {
|
191 | }
|
192 | Angulartics2OnModule.decorators = [
|
193 | { type: NgModule, args: [{
|
194 | declarations: [Angulartics2On],
|
195 | exports: [Angulartics2On],
|
196 | },] }
|
197 | ];
|
198 |
|
199 | class Angulartics2Module {
|
200 | static forRoot(settings = {}) {
|
201 | return {
|
202 | ngModule: Angulartics2Module,
|
203 | providers: [
|
204 | { provide: ANGULARTICS2_TOKEN, useValue: { settings } },
|
205 | { provide: RouterlessTracking, useClass: AngularRouterTracking },
|
206 | Angulartics2,
|
207 | ],
|
208 | };
|
209 | }
|
210 | }
|
211 | Angulartics2Module.decorators = [
|
212 | { type: NgModule, args: [{
|
213 | imports: [Angulartics2OnModule],
|
214 | exports: [Angulartics2On],
|
215 | },] }
|
216 | ];
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 | export { ANGULARTICS2_TOKEN, AngularRouterTracking, Angulartics2, Angulartics2Module, Angulartics2On, Angulartics2OnModule, DefaultConfig, RouterlessTracking };
|
223 |
|