Analytics/Tracking
* drag the tracking object a decade into the future
This commit is contained in:
parent
a90d1d242a
commit
92f949b3c6
14 changed files with 293 additions and 166 deletions
1
setup/sql/updates/1765569409_01.sql
Normal file
1
setup/sql/updates/1765569409_01.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
UPDATE `aowow_dbversion` SET `build` = CONCAT(IFNULL(`build`, ''), ' globaljs');
|
||||
|
|
@ -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 });
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -792,7 +792,7 @@ var Menu = new function()
|
|||
});
|
||||
|
||||
explodeInto(menu, implodedMenu);
|
||||
};
|
||||
}
|
||||
|
||||
function explodeInto(menu, implodedMenu) // Reverse of implode
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue