Analytics/Tracking

* drag the tracking object a decade into the future
This commit is contained in:
Sarjuuk 2025-12-12 18:30:37 +01:00
parent a90d1d242a
commit 92f949b3c6
14 changed files with 293 additions and 166 deletions

View file

@ -0,0 +1 @@
UPDATE `aowow_dbversion` SET `build` = CONCAT(IFNULL(`build`, ''), ' globaljs');

View file

@ -110,7 +110,12 @@ Announcement.prototype = {
// aowow - animation fix - jQuery.animate hard snaps into place after half the time passed
this.parentDiv.style.opacity = '100';
this.parentDiv.style.height = (this.parentDiv.offsetHeight + 10) + 'px';
g_trackEvent('Announcements', 'Show', '' + this.name);
$WH.Track.nonInteractiveEvent({
category: 'Announcements',
action: 'Show',
label: '' + this.name
});
},
hide: function()
@ -132,7 +137,11 @@ Announcement.prototype = {
markRead: function()
{
g_trackEvent('Announcements', 'Close', '' + this.name);
$WH.Track.interactiveEvent({
category: 'Announcements',
action: 'Close',
label: '' + this.name
});
g_setWowheadCookie('announcement-' + this.id, 'closed');
this.hide();
},
@ -147,11 +156,22 @@ Announcement.prototype = {
{
this.text = text;
Markup.printHtml(this.text, this.parent + '-markup');
g_addAnalyticsToNode($WH.ge(this.parent + '-markup'), {
'category': 'Announcements',
'actions': {
'Follow link': function(node) { return true; }
}
}, this.id);
let parent = $WH.ge(this.parent + '-markup');
$WH.qsa('a', parent).forEach(link => {
$WH.aE(link, 'click', () => {
let label = 'unknown';
let txt = g_getFirstTextContent(link);
if (txt)
label = g_urlize(txt).substr(0, 80);
else if (link.title)
label = g_urlize(link.title).substr(0, 80);
else if (link.id)
label = g_urlize(link.id).substr(0, 80);
label = `${ this.id || 0 }-${ label }`;
$WH.Track.linkClick(link, { category: 'Announcements', label: label });
});
});
}
};

View file

@ -3296,7 +3296,7 @@ Listview.templates = {
return Listview.funcBox.assocArrCmp(a.skill, b.skill, g_spell_skills);
}
},
/* AoWoW: custom start */
/* AoWoW: custom start */
{
id: 'stackRules',
name: LANG.asr_behaviour,
@ -3578,7 +3578,7 @@ Listview.templates = {
return 0;
}
},
/* AoWoW: custom end */
/* AoWoW: custom end */
{
id: 'completed', // Listview.COLUMN_ID_COMPLETION
name: LANG.completion, // WH.TERMS.completion
@ -7350,7 +7350,7 @@ Listview.templates = {
$(td).mouseover(function (event, menu) { $WH.Tooltip.showAtCursor(menu, event, 0, 0); }.bind(td, tt));
$(td).mousemove(function (event) { $WH.Tooltip.cursorUpdate(event); })
.mouseout(function () { $WH.Tooltip.hide(); });
/* aowow - we dont do patches
/* aowow - we dont do patches
var g = typeof g_hearthhead != "undefined" && g_hearthhead ? "hearthstone" : "wow";
if (!g_getPatchVersionObject.hasOwnProperty("parsed") || !g_getPatchVersionObject.parsed[g]) {
g_getPatchVersionObject();
@ -7369,7 +7369,7 @@ Listview.templates = {
j = j.replace(f, f + " (" + new Date(c.timestamp).toDateString() + ")");
}
}
*/
*/
let j = changelog.version; // aowow - tmp
$(td).html(j);
},

View file

@ -276,6 +276,12 @@ var MapViewer = new function()
this.show = function(opt)
{
$WH.Track.interactiveEvent({
category: "Zone Maps",
action: "Show",
label: opt.link ? opt.link : "General"
});
if (opt.link)
{
tempParent = $WH.ce('div');

View file

@ -792,7 +792,7 @@ var Menu = new function()
});
explodeInto(menu, implodedMenu);
};
}
function explodeInto(menu, implodedMenu) // Reverse of implode
{

View file

@ -604,7 +604,11 @@ var ModelViewer = new function()
}
}
g_trackEvent('Model Viewer', 'Show', g_urlize(trackCode));
$WH.Track.interactiveEvent({
category: 'Model Viewer',
action: 'Show',
label: g_urlize(trackCode) // WH.Strings.slug(trackCode)
});
oldHash = location.hash;
}

View file

@ -182,7 +182,11 @@ var ScreenshotViewer = new function()
if (!resizing)
{
g_trackEvent('Screenshots', 'Show', screenshot.id + ( (screenshot.caption && screenshot.caption.length) ? ' (' + screenshot.caption + ')' : ''));
$WH.Track.interactiveEvent({
category: 'Screenshots',
action: 'Show',
label: screenshot.id + (screenshot.caption && screenshot.caption.length ? ` (${ screenshot.caption })` : '')
});
// ORIGINAL

View file

@ -359,6 +359,11 @@ Tabs.trackClick = function(tab)
if (!this.trackable || tab.tracked)
return;
g_trackEvent('Tabs', 'Show', this.trackable + ': ' + tab.id);
$WH.Track.interactiveEvent({
category: 'Tab Click',
action: 'Page: ' + this.trackable,
label: 'Tab: ' + tab.id
});
tab.tracked = 1;
}

View file

@ -1,130 +1,207 @@
/*
TODO: Create "Tracking" class
*/
function g_trackPageview(tag)
// https://developers.google.com/tag-platform/security/guides/consent
$WH.Track = new function ()
{
function track()
{
if (typeof ga == 'function')
ga('send', 'pageview', tag);
const trackAction = 'Click';
const siteVariables = {
// adsBlocked: 3,
// adsUnblocked: 4,
loggedInUserIsPremium: 2,
userIsLoggedIn: 1,
// userShouldSeeAds: 5
};
const maxRetryTime = 10000;
const retryTimeout = 10;
const scrollDepthPoints = [25, 50, 75, 90, 100];
const _self = {
gaReady: false,
scriptAdded: undefined
};
$(document).ready(track);
}
function g_trackEvent(category, action, label, value)
{
function track()
this.gaInit = function (nTries)
{
if (typeof ga == 'function')
ga('send', 'event', category, action, label, value);
};
$(document).ready(track);
}
function g_attachTracking(node, category, action, label, value)
{
var $node = $(node);
$node.click(function()
{
g_trackEvent(category, action, label, value);
});
}
function g_addAnalytics()
{
var objs = {
'home-logo': {
'category': 'Homepage Logo',
'actions': {
'Click image': function(node) { return true; }
}
},
'home-featuredbox': {
'category': 'Featured Box',
'actions': {
'Follow link': function(node) { return (node.parentNode.className != 'home-featuredbox-links'); },
'Click image': function(node) { return (node.parentNode.className == 'home-featuredbox-links'); }
}
},
'home-oneliner': {
'category': 'Oneliner',
'actions': {
'Follow link': function(node) { return true; }
}
},
'sidebar-container': {
'category': 'Page sidebar',
'actions': {
'Click image': function(node) { return true; }
}
},
'toptabs-promo': {
'category': 'Page header',
'actions': {
'Click image': function(node) { return true; }
}
}
};
for (var i in objs)
{
var e = $WH.ge(i);
if (e)
g_addAnalyticsToNode(e, objs[i]);
}
}
function g_getNodeTextId(node)
{
var id = null,
text = g_getFirstTextContent(node);
if (text)
id = g_urlize(text);
else if (node.title)
id = g_urlize(node.title);
else if (node.id)
id = g_urlize(node.id);
return id;
}
function g_addAnalyticsToNode(node, opts, labelPrefix)
{
if (!opts || !opts.actions || !opts.category)
{
if ($WH.isset('g_dev') && g_dev)
if (!_self.scriptAdded)
{
console.log('Tried to add analytics event without appropriate parameters.');
console.log(node);
console.log(opts);
}
return;
}
var category = opts.category;
var tags = $WH.gE(node, 'a');
for (var i = 0; i < tags.length; ++i)
{
var node = tags[i];
var action = 'Follow link';
for (var a in opts.actions)
{
if (opts.actions[a] && opts.actions[a](node))
(function (_window, _document, node, src, varName, gaJSNode, firstJSNode)
{
action = a;
break;
}
_window['GoogleAnalyticsObject'] = varName;
_window[varName] = _window[varName] || function () { (_window[varName].q = _window[varName].q || []).push(arguments) },
_window[varName].l = 1 * new Date;
gaJSNode = _document.createElement(node),
firstJSNode = _document.getElementsByTagName(node)[0];
gaJSNode.async = 1;
gaJSNode.src = src;
firstJSNode.parentNode.insertBefore(gaJSNode, firstJSNode);
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
let attachGTAG = () => {
let script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=CFG_GTAG_MEASUREMENT_ID';
document.body.appendChild(script);
};
if (document.body)
attachGTAG();
else
$WH.aE(document, 'DOMContentLoaded', attachGTAG);
window.dataLayer = window.dataLayer || [];
window.gtag = function () { dataLayer.push(arguments) };
gtag('js', new Date);
gtag('config', 'CFG_GTAG_MEASUREMENT_ID');
_self.scriptAdded = true;
}
var label = (labelPrefix ? labelPrefix + '-' : '') + g_getNodeTextId(node);
g_attachTracking(node, category, action, label);
if (!window.ga || !ga.create)
{
if (!nTries)
nTries = 1;
if (nTries > 100)
return;
setTimeout($WH.Track.gaInit.bind($WH.Track, nTries + 1), nTries * 9);
return;
}
ga('create', 'UA_MEASUREMENT_KEY', 'CFG_UA_MEASUREMENT_KEY');
// trackSiteVar(siteVariables.userShouldSeeAds, $WH.WAS.showAds());
trackSiteVar(siteVariables.userIsLoggedIn, /* $WH.User.isLoggedIn() */g_user.id > 0);
// if ($WH.User.isLoggedIn())
if (g_user.id > 0)
trackSiteVar(siteVariables.loggedInUserIsPremium, /* $WH.User.isPremium() */g_user.premium);
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
_self.gaReady = true;
scrollDepthPoints.forEach(registerTrackScroll);
};
this.interactiveEvent = evt => trackEvent(evt );
this.nonInteractiveEvent = evt => trackEvent(evt, { nonInteraction: true });
this.interactiveEventOutgoing = evt => trackEvent(evt, { isOutgoing: true });
this.linkClick = (anchor, evt) => trackEvent({ ...evt, action: trackAction, value: anchor.href }, { isOutgoing: true });
function trackSiteVar(idx, val)
{
ga('set', 'dimension' + idx, val)
}
}
$(document).ready(g_addAnalytics);
function registerTrackScroll(depth)
{
let trackDone = false;
const trackScroll = () => {
if (trackDone)
return;
trackDone = true;
requestAnimationFrame(() => {
const y = window.scrollY;
const h = document.documentElement.scrollHeight - document.documentElement.clientHeight;
if (y / h * 100 >= depth)
{
trackEvent({
action: 'scroll_event',
event_category: 'Scroll Depth',
event_label: `${ depth }%`,
scroll_depth: depth
});
window.removeEventListener('scroll', trackScroll, { passive: true })
}
trackDone = false;
});
};
window.addEventListener('scroll', trackScroll, { passive: true })
}
function trackEvent(evt, opts)
{
const { action: act, ...o } = evt;
const { category: cat, label: lab, value: val } = o;
const { nonInteraction: ni, isOutgoing: io } = opts || {};
let { retryCount: rc } = opts || {};
if (!_self.gaReady)
{
if ($WH.isset('g_dev') && g_dev)
return;
if (!rc)
rc = 0;
rc++;
if (rc * retryTimeout > maxRetryTime)
return;
setTimeout(trackEvent.bind(null, evt, {
nonInteraction: ni,
isOutgoing: io,
retryCount: rc
}), retryTimeout);
return;
}
let attr;
if (typeof ni === 'boolean')
{
attr ??= {};
attr.nonInteraction = ni ? 1 : 0;
}
if (io)
{
attr ??= {};
attr.transport = 'beacon';
}
if (cat)
ga('send', 'event', cat, act, lab, val, attr);
gtag('event', act, o);
}
};
// aowow - repurpose old tracking
$(document).ready(function () {
var trackObjs = {
'header-logo': { 'label': 'Database Logo', 'actions': { 'Click image': (node) => true } },
'home-logo': { 'label': 'Homepage Logo', 'actions': { 'Click image': (node) => true } },
'home-oneliner': { 'label': 'Oneliner', 'actions': { 'Follow link': (node) => true } },
'home-featuredbox': { 'label': 'Featured Box', 'actions': { 'Follow link': (node) => node.parentNode.className != 'home-featuredbox-links',
'Click image': (node) => node.parentNode.className == 'home-featuredbox-links' }
}
};
Object.entries(trackObjs).forEach(([nodeId, trackInfo]) => {
let parent = $WH.ge(nodeId);
if (!parent)
return;
$WH.qsa('a', parent).forEach(link => {
Object.entries(trackInfo.actions).forEach(([action, testFn]) => {
$WH.aE(link, 'click', evt => {
if (!testFn(link))
return;
let txt = 'unknown';
if (_ = g_getFirstTextContent(link))
txt = g_urlize(_).substr(0, 80);
else if (link.title)
txt = g_urlize(link.title).substr(0, 80);
else if (link.id)
txt = g_urlize(link.id).substr(0, 80);
label = `${trackInfo.label}-${action}-${txt}`;
$WH.Track.linkClick(link, { category: PageTemplate.get('pageName') || 'unknown', label: label });
});
});
});
});
});

View file

@ -176,7 +176,13 @@ var VideoViewer = new function()
if (!resizing)
{
g_trackEvent('Videos', 'Show', video.id + (video.caption.length ? ' (' + video.caption + ')' : ''));
var hasCaption = (video.caption != null && video.caption.length);
$WH.Track.interactiveEvent({
category: 'Videos',
action: 'Show',
label: video.id + (hasCaption ? ` (${ video.caption })` : '')
});
if (video.videoType == 1)
imgDiv.innerHTML = Markup.toHtml('[youtube=' + video.videoId + ' width=' + imgWidth + ' height=' + imgHeight + ' autoplay=true]', {mode:Markup.MODE_ARTICLE});
@ -249,7 +255,6 @@ var VideoViewer = new function()
// CAPTION
var hasCaption = (video.caption != null && video.caption.length);
var hasSubject = (video.subject != null && video.subject.length && video.type && video.typeId);
if (hasCaption || hasSubject)