Source: dist/extras/matomo/init.js

/**
 * Extra - Matomo
 *
 * Provides advanced tracking with Matomo.
 *
 * @module Extras/Matomo
 * @license The MIT License (MIT)
 * @copyright (c) 2025 eVAL Agency
 * @author Charlie Powell
 * @see https://markdownmaster.com/docs/extras/matomo.html
 * @since 4.0.0
 */

/**
 * Called after any page load operation
 *
 * Track Matomo/Piwik events on pageload
 *
 * @param {CMS} event.detail.cms CMS object for reference if needed
 * @param {FileCollection[]|null} event.detail.collection Collection of files to view for listing pages
 * @param {File|null} event.detail.file Single file to view when available
 * @param {string} event.detail.mode Type of view, usually either "list", "single", or error.
 * @param {string} event.detail.search Any search query
 * @param {string} event.detail.tag Any tag selected to view
 * @param {string} event.detail.type Content type selected
 */
document.addEventListener('cms:route', event => {
	let _paq = window._paq || [];

	if (event.detail.tag !== null) {
		// Track tag listings as search events
		// trackSiteSearch(keyword, [category], [resultsCount])
		_paq.push(['trackSiteSearch', 'tag:' + event.detail.tag, event.detail.type, event.detail.collection.totalResults]);
	}
	else if(event.detail.search !== null) {
		// Track search events
		// trackSiteSearch(keyword, [category], [resultsCount])
		_paq.push(['trackSiteSearch', event.detail.search, event.detail.type, event.detail.collection.totalResults]);
	}
	else {
		// Track page views
		_paq.push(['setCustomUrl', window.location.pathname + window.location.search]);
		_paq.push(['setDocumentTitle', document.title]);
		_paq.push(['trackPageView']);
	}
});


/**
 * Sent a ping periodically to notify Matomo that the user is still on the page.
 */
setInterval(() => {
	let _paq = window._paq || [];
	_paq.push(['ping']);
}, 30000);


/**
 * Create a custom element to handle opting in and out of Matomo tracking.
 */
class MatomoOptInOutLink extends HTMLAnchorElement {

	constructor() {
		// Always call super first in constructor
		super();

		this.update();

		this.addEventListener('click', event => {
			let _paq = window._paq || [];

			if( this.dataset['mode'] === 'optin' ) {
				_paq.push(['forgetUserOptOut']);
			}
			else if( this.dataset['mode'] === 'optout' ) {
				_paq.push(['optUserOut']);
			}
			else {
				alert('Unable to connect to our Analytics software, you are probably running Ad-Block so there is nothing to do.');
			}

			event.preventDefault();
			this.update();
		});
	}

	update() {
		let element = this;

		if(Object.hasOwn(window, '_paq')) {
			_paq.push([function() {
				if( this.isUserOptedOut() ) {
					element.innerText = 'You are currently opted out. Click here to opt in.';
					element.dataset['mode'] = 'optin';
				}
				else {
					element.innerText = 'You are currently opted in. Click here to opt out.';
					element.dataset['mode'] = 'optout';
				}
			}]);
		}
		else {
			element.innerText = 'You are either running adblock or the Analytics system cannot be reached.';
			element.dataset['mode'] = 'unavail';
		}
	}
}

customElements.define('matomo-opt-inout', MatomoOptInOutLink, {extends: 'a'});