PageSourceSearch

https://stiklestad.no/wp-content/plugins/wp-analytify-pro/inc/modu…/js/analytify-events-tracking.js?ver=9.0.1

js stiklestad.no collected 2026-10-02 12:26:20 UTC 9,537 bytes, 327 lines download raw bytes

1'use strict';
2
3/**
4 * Handles tracking for all events.
5 * 
6 */
7
8// Wrapping the code in an anonymous function to avoid conflicts.
9( function () {
10
11	// Holds previous hash.
12	const prevHash = window.location.hash;
13
14	const eventsTrackingMode = analytify_events_tracking.tracking_mode;
15	const GAMode = analytify_events_tracking.ga_mode;
16
17	function trim_link_string(x) {
18		return x.replace(/^\s+|\s+$/gm, '');
19	}
20
21	/**
22	 * Returns the type of link tracking.
23	 *
24	 * @param {object} el The element to track.
25	 * @returns 
26	 */
27	function get_tracking_type( el ) {
28
29		// Default tracking type.
30		let type = 'unknown';
31
32		const link = el.href;
33		const {hostname} = el;
34		const {protocol} = el;
35		const {pathname} = el;
36
37		const {download_extension} = analytify_events_tracking;
38		const current_domain = analytify_events_tracking.root_domain;
39
40		const affiliate_links = 'undefined' !== typeof analytify_events_tracking.affiliate_link ? analytify_events_tracking.affiliate_link : {};
41
42		if ( link.match(/^javascript\:/i) ) {
43
44			// if its a JS link, it's internal
45			type = 'internal';
46		} else if ( 'tel' == trim_link_string(protocol) || 'tel:' == trim_link_string(protocol) ) {
47
48			// Track telephone event.
49			type = 'tel';
50		} else if ( 'mailto' == trim_link_string(protocol) || 'mailto:' == trim_link_string(protocol) ) {
51
52			// Track mail event.
53			type = 'mailto';
54		} else if ( 0 < hostname.length && 0 < current_domain.length && ! hostname.endsWith( current_domain ) ) {
55
56			// Track external links.
57			type = 'external';
58		} else if ( 0 < Object.keys(affiliate_links).length && 0 < pathname.length ) {
59			for ( const affiliate_link_index in affiliate_links ) {
60				const affiliate_link = affiliate_links[affiliate_link_index];
61				if ( affiliate_link.path && pathname.endsWith( affiliate_link.path ) ) {
62					type = 'outbound';
63					break;
64				}
65			}
66		}
67
68		// Track download files.
69		if ( 'unknown' === type && 0 < download_extension.length ) {
70			let regExp = '';
71		try {
72			regExp = new RegExp(`.*\\.(${  download_extension  })(\\?.*)?$`);
73		} catch (e) {
74
75			// Silent fail - Invalid RegExp for download tracking
76		}
77
78			if ( 'undefined' != typeof regExp && el.href.match( regExp ) ) {
79				type = 'download';
80			}
81		}
82
83		if ( 'unknown' === type ) {
84			type = 'internal';
85		}
86
87		return type;
88	}
89
90	/**
91	 * Sends the event call.
92	 * 
93	 * @param {string} category Event category.
94	 * @param {string} action   Event action.
95	 * @param {string} label    Event label.
96	 */
97	function send_event_call(category, action, label) {
98		if ('gtag' === eventsTrackingMode) {
99			if ('function' !== typeof gtag) {
100				return;
101			}
102
103			if ( 'ga4' === GAMode ) {
104				const eventData = {
105					'wpa_link_action': action,
106					'wpa_category': category,
107					'wpa_link_label': label,
108					'wpa_device_category': get_device_category(),
109					'wpa_click_hour': new Date().getHours().toString(),
110					'wpa_click_day': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][new Date().getDay()],
111					'wpa_traffic_source': get_traffic_source(),
112					'wpa_country_code': extract_country_code(action),
113				};
114
115				gtag('event', 'analytify_event_tracking', eventData);
116			} else {
117				gtag('event', action, {
118					'event_category': category,
119					'event_label': label,
120				});
121			}
122		} else {
123			if ('function' === typeof ga) {
124				ga('send', 'event', category, action, label);
125			}
126		}
127	}
128
129	/**
130	 * Determine device category based on screen size
131	 */
132	function get_device_category() {
133		const width = window.innerWidth;
134		if (768 >= width) {return 'mobile';}
135		if (1024 >= width) {return 'tablet';}
136		return 'desktop';
137	}
138
139	/**
140	 * True when document.referrer's hostname is host or a subdomain of host (e.g. www.google.com vs google.com).
141	 *
142	 * @param {string} referrer Full referrer URL
143	 * @param {string} host     Bare host, e.g. google.com
144	 * @returns {boolean}
145	 */
146	function referrer_hostname_is_or_subdomain_of(referrer, host) {
147		try {
148			const h = new URL(referrer).hostname.toLowerCase();
149			const b = String(host).toLowerCase();
150			return h === b || h.endsWith(`.${  b}`);
151		} catch (e) {
152			return false;
153		}
154	}
155
156	/**
157	 * Determine traffic source
158	 */
159	function get_traffic_source() {
160		const {referrer} = document;
161		const utmSource = get_url_parameter('utm_source');
162		
163		if (utmSource) {return utmSource;}
164		if (!referrer) {return 'direct';}
165		if (referrer_hostname_is_or_subdomain_of(referrer, 'google.com')) {return 'google';}
166		if (referrer_hostname_is_or_subdomain_of(referrer, 'facebook.com')) {return 'facebook';}
167		if (referrer_hostname_is_or_subdomain_of(referrer, 'twitter.com') || referrer_hostname_is_or_subdomain_of(referrer, 'x.com')) {return 'twitter';}
168		if (referrer_hostname_is_or_subdomain_of(referrer, 'linkedin.com')) {return 'linkedin';}
169		if (referrer_hostname_is_or_subdomain_of(referrer, 'instagram.com')) {return 'instagram';}
170		if (referrer_hostname_is_or_subdomain_of(referrer, 'youtube.com')) {return 'youtube';}
171		return 'referral';
172	}
173
174	/**
175	 * Get URL parameter value
176	 */
177	function get_url_parameter(name) {
178		const urlParams = new URLSearchParams(window.location.search);
179		return urlParams.get(name) || '';
180	}
181
182	/**
183	 * Extract country code from tel number
184	 */
185	function extract_country_code(telHref) {
186		if (!telHref || 'string' !== typeof telHref) {
187			return 'unknown';
188		}
189
190		// Remove 'tel:' and any non-digit characters except '+'
191		const cleanNumber = telHref.replace('tel:', '').replace(/[^\d+]/g, '');
192		
193		if (cleanNumber.startsWith('+')) {
194
195			// Pakistani numbers (+92)
196			if (cleanNumber.startsWith('+92')) {
197				return '+92';
198			}
199			
200			// North American numbers (+1)
201			if (cleanNumber.startsWith('+1')) {
202				return '+1';
203			}
204
205			// For others, extract up to 3 digits, but check common 2-digit codes first
206			// This is a heuristic approach since country codes vary in length
207			const threeDigitMatch = cleanNumber.match(/^\+(\d{1,3})/);
208			if (threeDigitMatch) {
209				const [ , code] = threeDigitMatch;
210
211				// Common 2-digit codes start with these prefixes
212				if (3 === code.length && ['20', '27', '30', '31', '32', '33', '34', '36', '39', '40', '41', '43', '44', '45', '46', '47', '48', '49', '51', '52', '53', '54', '55', '56', '57', '58', '60', '61', '62', '63', '64', '65', '66', '81', '82', '84', '86', '90', '91', '92', '93', '94', '95', '98'].some(prefix => code.startsWith(prefix))) {
213					return `+${code.substring(0, 2)}`;
214				}
215				return `+${code}`;
216			}
217		}
218		
219		return 'unknown';
220	}
221
222	/**
223	 * Enhanced tel link tracking with comprehensive data collection
224	 * 
225	 * @param {object} target The tel link element
226	 */
227	function track_enhanced_tel_event(target) {
228
229		// console.log('Enhanced tel tracking triggered for:', target.href);
230		
231		const action = target.getAttribute('data-vars-ga-action') || target.href;
232		const label = target.getAttribute('data-vars-ga-label') || target.title || target.innerText || target.href;
233		
234		send_event_call('tel', action, label);
235	}
236
237	/**
238	 * Tracks events.
239	 * 
240	 * @param {object} event Event object.
241	 * @returns 
242	 */
243	function track_event( event ) {
244
245		if ( '1' != analytify_events_tracking.is_track_user ) {
246			return;
247		}
248
249		event = event || window.event;
250
251		let target = event.target || event.srcElement;
252
253		// If link is not define. Get the parent link.
254		while (target && ('undefined' == typeof target.tagName || 'a' != target.tagName.toLowerCase() || !target.href)) {
255			target = target.parentNode;
256		}
257
258		// if its links
259		if ( target && target.href ) {
260
261			let action = '';
262			let label = '';
263
264			const tracking_type = get_tracking_type( target );
265
266			switch ( tracking_type ) {
267				case 'outbound':
268					action = target.getAttribute('data-vars-ga-action') || target.href;
269					label = target.getAttribute('data-vars-ga-label') || target.title || target.innerText || target.href;
270					send_event_call( 'outbound-link', action, label );
271					break;
272
273				case 'download':
274					action = target.getAttribute('data-vars-ga-action') || target.href;
275					label = target.getAttribute('data-vars-ga-label') || target.title || target.innerText || target.href;
276					send_event_call( 'download', action, label );
277					break;
278
279				case 'tel':
280					track_enhanced_tel_event(target);
281					break;
282
283				case 'external':
284					action = target.getAttribute('data-vars-ga-action') || target.href;
285					label = target.getAttribute('data-vars-ga-label') || target.title || target.innerText || target.href;
286					send_event_call( 'external', action, label );
287					break;
288
289				case 'mailto':
290					action = target.getAttribute('data-vars-ga-action') || target.href;
291					label = target.getAttribute('data-vars-ga-label') || target.title || target.innerText || target.href;
292					send_event_call( 'mail', action, label );
293					break;
294
295				default:
296					break;
297			}
298		}
299	}
300
301	/**
302	 * Tracks hash change.
303	 */
304	function track_hash() {
305
306		// If hash tracking is enabled.
307		if ( 'on' == analytify_events_tracking.anchor_tracking && prevHash != window.location.hash ) {
308			if ('gtag' === eventsTrackingMode) {
309				if ('function' === typeof gtag) {
310					gtag('config', trackingCode, { 'page_path': location.pathname + location.search + location.hash });
311				}
312			} else if ('function' === typeof ga) {
313				ga('set', 'page', location.pathname + location.search + location.hash);
314				ga('send', 'pageview');
315			}
316		}
317	}
318	
319	// When hash changes.
320	window.addEventListener( 'hashchange', track_hash, false );
321
322	// On Click.
323	window.addEventListener( "load", () => {
324		document.body.addEventListener( "click", track_event, false );
325	}, false);
326
327}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.