PageSourceSearch

https://act4sa.org/wp-content/themes/act4sa/vendor/duable/du-analytics/assets/analytics.js?ver=1.0.0

js act4sa.org collected 2026-10-08 14:36:39 UTC 10,691 bytes, 384 lines download raw bytes

1/**
2 * Call new instance
3
4  var analytics = new DU_Analytics( 
5    { 
6      debug:            true,   // Only log events to browser
7      ga:               true,  // Send to Google Analytics
8      du_receiver:      false,  // Send to analytics.duable.com
9      hover_interval:   1500,   // Interval to send hover data
10      read_interval:    2000,   // Interval to send reading data
11      hover_elements:   '[data-du-hover]',   // Track hovers
12      click_elements:   '[data-du-click]',   // Track clicks
13      reading_elements: '[data-du-reading]', // Track reading time
14
15      // Following only necessary if du_receiver true
16      client_key:       1234,     // Client key for attribution
17      audience_var:     'aud_id', // URL Variable to track audience
18      variation_var:    'var_id'  // URL Variable to track variation
19    } 
20  );
21
22*/
23
24
25/**
26 * Jquery Inview 2
27 * Version: 0.1
28 * Author: Matthew Frey (mmmeff)
29 *    - forked from http://github.com/protonet/jquery.inview/
30 */
31(function(e){function t(){var t=e();if(e.each(n,function(e,i){var n=i.data.selector,a=i.$element;t=t.add(n?a.find(n):a)}),t.length)for(var i=0;t.length>i;i++)if(t[i])if(e.contains(r,t[i])){var a=e(t[i]),c=a.data("inview"),l=a[0].getBoundingClientRect(),o=a.height(),h=a.width();l.top>=0-o&&l.left>=0-h&&l.bottom<=(d.innerHeight||r.clientHeight)+o&&l.right<=(d.innerWidth||r.clientWidth)+h?c||a.data("inview",!0).trigger("inview",[!0]):c&&a.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,d=window,r=a.documentElement,c=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[c]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,333))},remove:function(t){try{delete n[t.guid+"-"+this[c]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery);
32
33
34
35// Date.now shim
36if (!Date.now) {
37    Date.now = function() { return new Date().getTime(); }
38}
39
40var DU_Analytics = function( options ) {
41  /**
42   * Path to log analytics receiver
43   */
44  
45  //this.path           = du_analytics_ajax.script;
46  this.prefix         = "du_";
47
48  var defaults = {
49    user_id:          this.get_current_user(),
50    client_key:       0,      // Client ID to attribute events
51    debug:            true,   // no data sent to server
52    ga:               true,   // Log events in GA
53    du_receiver:      false,  // Log evens in Du Analytics
54    hover_elements:   '[data-du-hover]',    // Track hovering
55    click_elements:   '[data-du-click]',    // Track clicks
56    reading_elements: '[data-du-reading]',  // Track reading
57    submit_elements:  '[data-du-submit]',   // Track form submissions
58    read_interval:    3000,  // interval to send read event in ms
59    hover_interval:   2000,  // interval to send hover event in ms
60    audience_var:     this.get_url_variable( 'aud_id' ), // Aud url var
61    variation_var:    this.get_url_variable( 'var_id' ), // Variation url var
62  }
63
64
65  // Grab options from instance
66  var self = this;
67
68  Object.keys( defaults ).forEach( function (key ) {
69    self[ key ] = defaults[ key ];
70  });
71
72  Object.keys( options ).forEach( function( key ) {
73    self[ key ] = options[ key ];
74  });
75  
76  // start capturing events
77  this.capture_events();
78
79};
80
81
82// get variable from URL
83DU_Analytics.prototype.get_url_variable = function( variable ) {
84  var query = window.location.search.substring(1);
85  var vars = query.split("&");
86  for (var i=0;i<vars.length;i++) {
87    var pair = vars[i].split("=");
88    if(pair[0] == variable){return pair[1];}
89  }
90  return( false );
91}
92
93
94// send data to server
95DU_Analytics.prototype.send_data = function( data ) {
96  data.action     = 'analytics_data';
97  data.url        = window.location.href;
98
99  // Log current audience / variations
100  data.audience_var = this.get_url_variable( this.audience_var ); 
101  data.variation_var = this.get_url_variable( this.variation_var ); 
102  
103  // Send client key for verification
104  data.client_key = this.client_key;
105
106  // Intervals
107  data.hover_interval = this.hover_interval;
108  data.read_interval = this.read_interval;
109
110
111  // Debug is on so just log results in browser
112  if ( this.debug != false ) {
113    var send_data = {
114      eventCategory: data.el,               // Element 
115      eventAction: data.el_ev,              // Event
116      eventLabel: data.user_id,             // User ID
117    }
118    data.duration ? send_data[ 'eventValue' ] = data.duration : "";
119    console.log( 'GA:' );
120    console.log( send_data );
121    console.log( 'DU-A:' );
122    console.log( data );
123    return;
124  // Google Analytics logging GTAG
125  } else if ( this.ga != false && typeof gtag == 'function' ) {
126    var send_data = {
127      event_category: data.el,               // Element 
128      event_label: data.user_id,             // User ID
129    }
130    data.duration ? send_data[ 'value' ] = data.duration : "";
131    // Send to GA
132    gtag( 'event', data.el_ev, send_data );
133    return;
134  // Google Analytics logging GA
135  } else if ( this.ga != false && typeof ga == 'function' ) {
136    var send_data = {
137      eventCategory: data.el,               // Element 
138      eventAction: data.el_ev,              // Event
139      eventLabel: data.user_id,             // User ID
140    }
141    data.duration ? send_data[ 'eventValue' ] = data.duration : "";
142
143    // Send to GA
144    ga( 'send', 'event', send_data );
145    return;
146
147  // Duable Analytics logging
148  } else if ( this.du_receiver != false ) {
149
150    // POST to du analytics receiver
151    jQuery.ajax({
152      url:  this.path,
153      type: 'post',
154      data: data
155    })
156    .done( function( response ){
157
158    });
159    return;
160  }
161
162}
163
164/**
165 * If cookie exists for current user return stored id
166 * Or else save id as cookie and return saved value
167 */
168DU_Analytics.prototype.get_current_user = function() {
169  if ( this.cookie_exists( this.prefix + 'analytics_user' ) ) {
170    return this.get_cookie( this.prefix + 'analytics_user' );   // get user id
171  } else {
172    this.set_cookie( this.prefix + 'analytics_user', Date.now(), 30 );  // set user id
173    if ( !this.cookie_exists( this.prefix + 'analytics_user' ) ) {
174      return Date.now();  // if cookies aren't working, return the timestamp
175    }
176    return this.get_cookie( this.prefix + 'analytics_user' );    // get user id
177  }
178}
179
180// set cookie
181DU_Analytics.prototype.set_cookie = function ( cname, cvalue, exdays ) {
182  var d = new Date();
183  d.setTime( d.getTime() + ( exdays*24*60*60*1000 ) );
184  var expires = "expires="+ d.toUTCString();
185  document.cookie = cname + "=" + cvalue + "; " + expires;
186}
187
188// get cookie value
189DU_Analytics.prototype.get_cookie = function ( cname ) {
190  var name = cname + "=";
191  var ca = document.cookie.split( ';' );
192  for ( var i = 0; i <ca.length; i++ ) {
193    var c = ca[ i ];
194    while ( c.charAt( 0 )==' ' ) {
195      c = c.substring( 1 );
196    }
197    if ( c.indexOf( name ) == 0 ) {
198      return c.substring( name.length,c.length );
199    }
200  }
201  return "";
202}
203
204// check if cookie exists
205DU_Analytics.prototype.cookie_exists = function( cname ) {
206  var cur_cookie = this.get_cookie( cname );
207  if ( cur_cookie != "" ) {
208    return true;
209  } else {
210    return false;
211  }
212}
213
214/**
215 * Timer function to log reading events based
216 * on read_interval variable
217 */
218
219
220// House reading times for elements
221var du_reading_start = new Array(0);
222
223DU_Analytics.prototype.start_reading = function( el ) {
224
225  // Store start time for this element's hover
226  du_reading_start[ el ] = Date.now();
227
228}
229
230
231// no longer viewing element
232DU_Analytics.prototype.stop_reading = function( el ) {
233  var end_reading   = new Date();
234  var start_reading = du_reading_start[ el ];
235  var el_name = el;
236  
237  var duration = end_reading - start_reading;
238  
239  // Remove element from array
240  du_reading_start.splice( el_name, 0 );
241
242  // Don't log short views
243  if ( duration < 1000 ) return;
244
245  var self = this;
246  
247  var data = {
248    el_ev:    'reading',
249    duration: duration, 
250    user_id:  self.user_id,
251    time:     Date.now(),
252    el:       el,
253  };
254
255  self.send_data( data );
256
257}
258
259
260/**
261 * Timer function to log hover events based
262 * on hover_interval variable
263 */
264
265// House hover times for elements
266var du_hover_start = new Array(0);
267
268DU_Analytics.prototype.start_hover = function( el ) {
269
270  // Store start time for this element's hover
271  du_hover_start[ el ] = Date.now();
272
273}
274
275
276// no longer viewing element
277DU_Analytics.prototype.stop_hover = function( el ) {  
278  var end_hover   = new Date();
279  var start_hover = du_hover_start[ el ];
280
281  var duration = end_hover - start_hover;
282
283  // Remove element from array
284  du_hover_start.splice( el, 1 );
285
286  // Don't log short hovers
287  if ( duration < 1000 ) return;
288
289  var self = this;
290  
291  var data = {
292    el_ev:    'hover',
293    duration: duration, 
294    user_id:  self.user_id,
295    //el:       el,
296    time:     Date.now(),
297    el:       el,
298  };
299
300  self.send_data( data );
301
302}
303
304
305/**
306 * User Events To Capture
307 * to do: add scrolling if <body data-du-scrolling>
308 * to do: add option for which elements to watch (classname, etc.)
309 */
310DU_Analytics.prototype.capture_events = function() {
311
312  var self = this;
313
314
315  // Collect CLICKS
316  jQuery( 'body' ).on( 'click', self.click_elements, function() {
317    var data = {
318      el_ev:    'click',
319      user_id:  self.user_id,
320      el:       jQuery( this ).attr( 'id' ),
321      time:     Date.now()
322    };
323
324    // send data to server
325    self.send_data( data );
326
327  });
328
329
330  // Collect HOVERS
331  jQuery( 'body' ).on( 'mouseover', self.hover_elements, function() {
332    self.start_hover( jQuery( this ).attr( 'id' ) );
333  });  
334
335  jQuery( 'body' ).on( 'mouseout', self.hover_elements, function() {
336    self.stop_hover( jQuery( this ).attr( 'id' ) );
337  });  
338
339/*
340  var $elem = $( self.reading_elements );
341  if ( $elem.is( ':in-viewport' ) ) {
342    self.start_reading( jQuery( this ).attr( 'id' ) );
343  } else {
344    self.stop_reading( jQuery( this ).attr( 'id' ) );
345  }
346 */
347  // Collect READING TIME
348  jQuery( self.reading_elements ).bind( 'inview', function( event, isInView ) {
349    if ( isInView ) {
350      self.start_reading( jQuery( this ).attr( 'id' ) );
351    } else {
352      self.stop_reading( jQuery( this ).attr( 'id' ) );
353    }
354  });
355
356  // Collect form Submissions
357  jQuery( document ).on( 'submit', self.submit_elements, function() {
358    var data = {
359      el_ev:    'submit',
360      user_id:  self.user_id,
361      el:       jQuery( this ).attr( 'id' ),
362      time:     Date.now()
363    };
364
365    // send data to server
366    self.send_data( data );
367  });
368
369}
370
371function du_send_analytics( cat, action, label ) {
372  var send_data = {
373    eventCategory: cat,               // Element 
374    eventAction: action,              // Event
375    eventLabel: label,              // User ID
376  }
377  // Send to GA
378  ga( 'send', 'event', send_data );
379  return;
380}
381
382
383
384

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.