-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathga-spy-datalayer.preview.html
139 lines (118 loc) · 7.08 KB
/
ga-spy-datalayer.preview.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<script title="gtm:ga-spy-to-datalayer">
/**
* Expose all non-GTM-based ga commands to GTM via the data layer.
*
* https://github.com/smhmic/gaSpy/
* @version 0.8
*/
var dataLayer = window.dataLayer,
dataLayerNamespace = 'spy.ga';
(function(e){var n,t,o=function(n){if(e=null,!n.callback||"function"!=typeof n.callback)throw Error("["+n.debugLogPrefix+"] Aborting; No listener callback provided.");return n.gaObjName=n.gaObjName||window.GoogleAnalyticsObject||"ga",n.debug=!!n.debug,n.debugLogPrefix=n.debugLogPrefix||"gaSpy",n}("function"==typeof e?{callback:e}:e),a=o.gaObjName,i=window[a],l=window.console&&o.debug?function(){var e=[].slice.call(arguments);e.unshift("["+o.debugLogPrefix+"]"),console.log.apply(console,e)}:function(){},r=function(e){var n,t={};return o.debug&&function(n,t){for(n="Intercepted: ga(",t=0;t<e.length;t++)n+="string"==typeof e[t]?'"'+e[t]+'"':e[t],t+1<e.length&&(n+=", ");n+=")",l(n)}(),"function"==typeof e[0]?t.callback=e[0]:e[0]&&e[0].split&&(n=e[0].split("."),t.trackerName=n.length>1?n[0]:"t0",t.command=n.length>1?n[1]:n[0],n=n[n.length-1].split(":"),t.pluginName=n.length>1?n[0]:void 0,t.pluginMethodName=n.length>1?n[1]:void 0,"require"===t.command||"provide"===t.command?(t.pluginName=e[1],"provide"===t.command&&(t.pluginConstructor=e[2])):("send"===t.command&&(t.hitType=e[e.length-1].hitType||e[1]),"object"==typeof e[e.length-1]&&(t.trackerName=e[e.length-1].name||t.trackerName))),l("Run listener callback",t),!1===o.callback(e,t)?l("Block hit")||!1:!0},c=function(){var e=[].slice.call(arguments);if(o.debug){if(!r(e))return}else try{if(!r(e))return}catch(n){}return c.gaOrig.apply(c.gaOrig,e)},g=function(){var e,n=c.gaOrig=window[a];l("Hijack",n.gaOrig?"(already hijacked)":""),window[a]=c;for(e in n)n.hasOwnProperty(e)&&(window[a][e]=n[e])};if(l("Config:",o),i||(l("Instantiate GA command queue"),i=window[a]=function(){(window[a].q=window[a].q||[]).push(arguments)},i.l=1*new Date),i.getAll)l("GA already loaded; cannot see previous commands"),g();else{if(!i.l)throw Error("["+o.debugLogPrefix+"] Aborting; `"+a+"` not the GA object.");if(l("Command queue instantiated, but library not yet loaded"),i.q&&i.q.length){for(l("Applying listener to",i.q.length," queued commands"),n=[],t=0;t<i.q.length;t++)r([].slice.call(i.q[t]))&&n.push(i.q[t]);i.q=n}else i.q=[];i(g),g()}}
)( function( a, the ){
var scope = '', frame = {};
// If last argument is object, use as fields object.
var fields = typeof a[a.length-1] == 'object' ? a.pop() : {};
// Ignore callbacks.
if( the.callback ) return;
// Ignore commands from GTM.
//TODO: Does this work when gtm loads ga plugins (i.e. autolinker)?
if( the.trackerName && the.trackerName.substr( 0, 3 ) == 'gtm' ) return;
if( the.pluginName ){
scope = 'plugin.'+the.pluginName;
if( the.command === 'provide' )
fields = a[2]; // plugin constructor
else {
//TODO: provide generic data layer structure for custom arguments
// if( command === 'require' ){ }
}
}
else switch( the.command ){
case 'create':
fields.trackingId = fields.trackingId || a[1];
fields.cookieDomain = fields.cookieDomain || a[2];
fields.name = fields.name || a[3];
break;
case 'set':
if( a[1] ) fields[ a[1] ] = a[2];
break;
case 'send':
scope = 'hit';
switch( fields.hitType = fields.hitType || a[1] ){
case 'pageview':
fields.page = fields.page || a[2];
break;
case 'event':
fields.eventCategory = fields.eventCategory || a[2];
fields.eventAction = fields.eventAction || a[3];
fields.eventLabel = fields.eventLabel || a[4];
fields.eventValue = fields.eventValue || a[5];
break;
case 'social':
fields.socialNetwork = fields.socialNetwork || a[2];
fields.socialAction = fields.socialAction || a[3];
fields.socialTarget = fields.socialTarget || a[4];
break;
case 'social':
fields.timingCategory = fields.timingCategory || a[2];
fields.timingVar = fields.timingVar || a[3];
fields.timingValue = fields.timingValue || a[4];
fields.timingLabel = fields.timingLabel || a[5];
break;
}
break;
case 'remove':
break;
default:
scope = 'unknown';
}
// Push command data to data layer.
dataLayerNamespace = dataLayerNamespace+(dataLayerNamespace&&scope?'.':'')+scope;
frame[dataLayerNamespace] = fields;
frame.event = dataLayerNamespace;
dataLayer.push( frame );
// The values specified in a send command apply only to the hit; clear them
// immediately after so data layer more closely reflects data in tracker
// object, and so subsequent hits will not be polluted by prior values.
// Instead of this (which adds generic message for every command), it's cleaner
// to accomplish this using a low priority -firing tag (or cleanup tag) that runs:
// `google_tag_manager[{{Container ID}}].dataLayer.set(dataLayerNamespace,undefined);`:
if( 'send' === the.command ){
frame = {};
frame[dataLayerNamespace] = undefined;
dataLayer.push( frame );
}
// return false; <-- Uncomment to block non-GTM commands.
} );
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-00000-1', 'auto');
ga('send', 'pageview');
</script>
<style type="text/css">
.btn::after, button::after { content: attr(onclick) }
hr, .btn, button { float:left; clear:both; margin: 0.1em; padding: 0.3em; font: 0.8em Consolas, Menlo, monospace; }
</style>
<a class="btn" href="#href" onclick="ga('send','pageview',this.href,'virtual pageview with special hardcoded page title'); return false" ></a>
<a class="btn" href="#href" onclick="ga('send','page',this.href,'supposed to be a virtual pageview'); return false" ></a>
<hr>
<button onclick="ga('send','event','test','click','button')" ></button>
<button onclick="ga('send','timing','test','click',performance.timing.domInteractive-new Date())" ></button>
<button onclick="ga('send','social','hardcoded network','action','target')" ></button>
<hr>
<button onclick="ga('create','UA-00000-2',{name:'altTracker'})" ></button>
<button onclick="ga('altTracker.send','event','test','altTracker')" ></button>
<hr>
<button onclick="ga('gtmFakedCommand.send','event','test','gtmFakedCommand')" ></button>
<iframe title="Set GTM debug mode cookie" src="https://www.googletagmanager.com/set_cookie?uiv2&id=GTM-PKDMTX>m_auth=cDtUVCAnGX-iIp5jGQAmsA>m_preview=env-2>m_debug=x" width=1 height=1 border=0></iframe>
<!-- TODO: can do ^^this^^ with an GTM environment? -->
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-PKDMTX');</script>
<!-- End Google Tag Manager -->