Skip to content
106 changes: 92 additions & 14 deletions assets/src/js/admin/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,6 @@ document.addEventListener('DOMContentLoaded', () => {
this.showMessages();
},

toggleSection: function (target) {
let section = document.getElementById(target + '_content');
let chevron = document.getElementById(target + '_chevron');

if (section.className.indexOf('hidden') !== -1) {
section.className = 'block';
chevron.classList.add('rotate-180');
} else {
section.className = 'hidden';
chevron.classList.remove('rotate-180');
}
},

/**
* Toggle Option and store in DB.
*
Expand Down Expand Up @@ -132,6 +119,10 @@ document.addEventListener('DOMContentLoaded', () => {
toggleStatus = 'on';
}

if (button.dataset.addtlOpts === '1') {
plausible.toggleSection(button.value.replace('-', '_'));
}

const form = new FormData();
form.append('action', 'plausible_analytics_toggle_option');
form.append('option_name', button.name);
Expand All @@ -150,6 +141,91 @@ document.addEventListener('DOMContentLoaded', () => {
plausible.maybeDisableOptions(data.capabilities);
},

/**
* Adds an input node.
*
* @param target
*/
addField: function (target) {
let clone = document.getElementsByClassName(target.replace('_', '-') + '-field')[0].cloneNode(true);
let rows = document.getElementsByClassName(target.replace('_', '-') + '-field');
let current_row = rows.length;
let input = clone.querySelector('input');
let trash = clone.querySelector('a');

input.value = '';
input.setAttribute('id', target + '[' + current_row + ']');
input.setAttribute('name', target + '[' + current_row + ']');
trash.setAttribute('onclick', 'plausibleRemoveField("' + target + '[' + current_row + ']")');
trash.classList.remove('hidden');

document.getElementById(target + '_list').appendChild(clone);
},

/**
* Removes an input node.
*
* @param target
*/
removeField: function (target) {
let rowClass = target.replace(/\[[0-9]+]/, '').replace('_', '-');
let rows = document.getElementsByClassName(rowClass + '-field');
let input = document.getElementById(target);
let listItem = input.closest('.' + rowClass + '-field');

listItem.remove();

plausible.resetListItems(rows, target.replace(/\[[0-9]+]/, ''));
},

/**
* Make sure all items in a list have properly incremented id, name and onclick attributes.
*
* @param listItems
* @param list
*/
resetListItems: function (listItems, list) {
if (listItems === null || listItems === undefined || listItems.length === 0) {
return;
}

for (let i = 0; i < listItems.length; i++) {
let item = listItems[i];
let input = item.querySelector('input');
let trash = item.querySelector('a');

input.setAttribute('id', list + '[' + i + ']');
input.setAttribute('name', list + '[' + i + ']');
trash.setAttribute('onclick', 'plausibleRemoveField("' + list + '[' + i + ']")');
}
},

/**
* Toggles a collapsable section and rotates a chevron if it exists.
*
* @param target
*/
toggleSection: function (target) {
let section = document.getElementById(target + '_content');
let chevron = document.getElementById(target + '_chevron');

if (section.className.indexOf('hidden') !== -1) {
section.classList.add('block');
section.classList.remove('hidden');

if (chevron !== null) {
chevron.classList.add('rotate-180');
}
} else {
section.classList.add('hidden');
section.classList.remove('block');

if (chevron !== null) {
chevron.classList.remove('rotate-180');
}
}
},

/**
* Save value of input or text area to DB.
*
Expand All @@ -160,7 +236,7 @@ document.addEventListener('DOMContentLoaded', () => {
const section = button.closest('.plausible-analytics-section');
const inputs = section.querySelectorAll('input, textarea');
const form = new FormData();
const options = [];
let options = [];

inputs.forEach(function (input) {
input = plausible.validateInput(input);
Expand Down Expand Up @@ -577,6 +653,8 @@ document.addEventListener('DOMContentLoaded', () => {
}

plausibleToggleSection = plausible.toggleSection;
plausibleAddField = plausible.addField;
plausibleRemoveField = plausible.removeField;

plausible.init();
});
2 changes: 1 addition & 1 deletion assets/src/js/admin/main.min.js

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions assets/src/js/affiliate-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* Cloaked (Affiliate) Links tracking JS
*
* @since 2.4.0
*/

const plausibleLinksTracking = {
middleMouseButton: 1,

/**
* Intialize.
*/
init: () => {
plausibleLinksTracking.bindEvents();
},

/**
* Bind Events.
*/
bindEvents: () => {
document.addEventListener('click', plausibleLinksTracking.handleLinkClick);
document.addEventListener('auxclick', plausibleLinksTracking.handleLinkClick);
},

/**
* Handle Link Clicks.
*
* @param e
*/
handleLinkClick: (e) => {
if (e.type === 'auxclick' && e.button !== plausibleLinksTracking.middleMouseButton) {
return;
}

var link = plausibleLinksTracking.getLinkEl(e.target);

if (link && plausibleLinksTracking.shouldTrackLink(link)) {
var eventName = 'Cloaked Link: Click';
var eventProps = {url: link.href};

return plausibleLinksTracking.sendLinkClickEvent(e, link, eventName, eventProps);
}
},

/**
* Retrieves a link element from an event target.
*
* @param link
*
* @returns {{href}|*}
*/
getLinkEl: (link) => {
while (link && (typeof link.tagName === 'undefined' || link.tagName.toLowerCase() !== 'a' || !link.href)) {
link = link.parentNode;
}

return link;
},

/**
* Should we track this link?
*
* @param link
* @returns {boolean}
*/
shouldTrackLink: (link) => {
let affiliateLinks = plausibleAffiliateLinks;

let foundMatch = affiliateLinks.filter((affiliateLink) => {
return link.href.match(affiliateLink);
});

return foundMatch.length > 0;
},

/**
* Sends the click event to the Plausible API.
*
* @param event
* @param link
* @param eventName
* @param eventProps
*/
sendLinkClickEvent: (event, link, eventName, eventProps) => {
var followedLink = false;

function followLink() {
if (!followedLink) {
followedLink = true;
window.location = link.href;
}
}

if (plausibleLinksTracking.shouldFollowLink(event, link)) {
plausible(eventName, {props: eventProps, callback: followLink});
setTimeout(followLink, 5000);
event.preventDefault();
} else {
plausible(eventName, {props: eventProps});
}
},

/**
*
* @param event
* @param link
* @returns {*|boolean}
*/
shouldFollowLink: (event, link) => {
// If default has been prevented by an external script, Plausible should not intercept navigation.
if (event.defaultPrevented) {
return false;
}

var targetsCurrentWindow = !link.target || link.target.match(/^_(self|parent|top)$/i);
var isRegularClick = !(event.ctrlKey || event.metaKey || event.shiftKey) && event.type === 'click';

return targetsCurrentWindow && isRegularClick;
}
}

plausibleLinksTracking.init();
Loading