1/* global pys_fb_pixel_regular_events, pys_fb_pixel_dynamic_triggers, pys_fb_pixel_dynamic_events, pys_fb_pixel_custom_code_events */ 2jQuery(document).ready(function ($) { 3 4 var utm_terms = ['utm_source', 'utm_media', 'utm_campaign', 'utm_term', 'utm_content']; 5 var scroll_pos_thresholds = {}; 6 7 // load FB pixel 8 !function (f, b, e, v, n, t, s) { 9 if (f.fbq)return; 10 n = f.fbq = function () { 11 n.callMethod ? 12 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 13 }; 14 if (!f._fbq)f._fbq = n; 15 n.push = n; 16 n.loaded = !0; 17 n.version = '2.0'; 18 n.agent = 'dvpixelyoursite'; 19 n.queue = []; 20 t = b.createElement(e); 21 t.async = !0; 22 t.src = v; 23 s = b.getElementsByTagName(e)[0]; 24 s.parentNode.insertBefore(t, s) 25 }(window, 26 document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); 27 28 manageCookies(); 29 regularEvents(); 30 regularCustomCodeEvents(); 31 dynamicEvents(); 32 33 // WooCommerce Affiliate and ajax-ed AddToCart Events 34 $(".ajax_add_to_cart, .product_type_external").click(function () { 35 36 var event_id = $(this).attr('data-pys-ajax-event-id'); 37 38 if (typeof event_id == 'undefined' || typeof pys_fb_pixel_ajax_events == 'undefined') { 39 return; 40 } 41 42 if (pys_fb_pixel_ajax_events.hasOwnProperty(event_id)) { 43 evaluateDynamicEventByID(pys_fb_pixel_ajax_events[event_id]); 44 } 45 46 }); 47 48 // WooCommerce PayPal Event 49 $(document).on('submit click', '#place_order', function () { 50 51 var method = $('input[name="payment_method"]:checked').val(); 52 53 if (method == false || method != 'paypal') { 54 return; 55 } 56 57 try { 58 59 if (typeof pys_fb_pixel_woo_paypal_event_id == 'undefined' || typeof pys_fb_pixel_ajax_events == 'undefined') { 60 return; 61 } 62 63 if (pys_fb_pixel_ajax_events.hasOwnProperty(pys_fb_pixel_woo_paypal_event_id)) { 64 evaluateDynamicEventByID(pys_fb_pixel_ajax_events[pys_fb_pixel_woo_paypal_event_id]); 65 } 66 67 } catch (e) { 68 console.log(e); 69 } 70 71 }); 72 73 // EDD AddToCart 74 $('.edd-add-to-cart').click(function () { 75 76 try { 77 78 // extract pixel event ids from classes like 'pys-event-id-{UNIQUE ID}' 79 var classes = $.grep(this.className.split(" "), function (element, index) { 80 return element.indexOf('pys-event-id-') === 0; 81 }); 82 83 // verify that we have at least one matching class 84 if (typeof classes == 'undefined' || classes.length == 0) { 85 return; 86 } 87 88 // extract event id from class name 89 var regexp = /pys-event-id-(.*)/; 90 var event_id = regexp.exec(classes[0]); 91 92 if (event_id == null) { 93 return; 94 } 95 96 event_id = event_id[1]; 97 98 if (pys_fb_pixel_ajax_events.hasOwnProperty(event_id)) { 99 evaluateDynamicEventByID(pys_fb_pixel_ajax_events[event_id]); 100 } 101 102 } catch (e) { 103 console.log(e); 104 } 105 106 }); 107 108 /** 109 * Process Init, PageView, General, Search, WooCommerce (except ajax-ed AddToCart), 110 * and Custom On Page events. In case if delay param is present - event will be fired after desired timeout. 111 */ 112 function regularEvents() { 113 114 try { 115 116 if (typeof pys_fb_pixel_regular_events == 'undefined') { 117 return; 118 } 119 120 for (var i = 0; i < pys_fb_pixel_regular_events.length; i++) { 121 122 var event = pys_fb_pixel_regular_events[i]; 123 124 // optionally, add traffic source params 125 event = addTrafficSourceParams(event); 126 127 if (event.hasOwnProperty('delay') == false || event.delay == 0) { 128 fbq(event.type, event.name, event.params); 129 } else { 130 131 setTimeout(function (type, name, params) { 132 fbq(type, name, params); 133 }, event.delay * 1000, event.type, event.name, event.params); 134 135 } 136 137 } 138 139 } catch (e){ 140 console.error(e); 141 } 142 143 } 144 145 /** 146 * Process only custom code regular events. 147 */ 148 function regularCustomCodeEvents() { 149 150 if ( pys_fb_pixel_custom_code_events != 'undefined' ) { 151 return; 152 } 153 154 $.each(pys_fb_pixel_custom_code_events, function (index, code) { 155 eval(code); 156 }); 157 158 } 159 160 function dynamicEvents() { 161 162 if (typeof pys_fb_pixel_dynamic_triggers == 'undefined' || typeof pys_fb_pixel_dynamic_events == 'undefined') { 163 return; 164 } 165 166 // setup listeners for css click, css mouse over triggers 167 // setup scroll pos thresholds 168 $.each(pys_fb_pixel_dynamic_triggers, function (index, trigger) { 169 170 switch (trigger.trigger_type ) { 171 case 'css_click': 172 attachCssClickHandler(trigger); 173 break; 174 175 case 'css_mouseover': 176 attachMouseOverHandler(trigger); 177 break; 178 179 case 'scroll_pos': 180 setupScrollPosThresholds(trigger); 181 break; 182 183 default: 184 break; 185 } 186 187 }); 188 189 // setup url click handlers 190 $('[data-pys-event-id]').onFirst('click', function () { 191 192 // Non-default binding used to avoid situations when some code in external js 193 // stopping events propagation, eg. returns false, and our handler will never called. 194 195 var event_id = parseInt( $(this).attr('data-pys-event-id') ); 196 197 if (isNaN(event_id)) { 198 return; 199 } 200 201 if (pys_fb_pixel_dynamic_events.hasOwnProperty(event_id)) { 202 evaluateDynamicEventByID(pys_fb_pixel_dynamic_events[event_id]); 203 } 204 205 }); 206 207 // manage on scroll triggers 208 $(document).scroll(function () { 209 210 var scroll_pos = $(window).scrollTop(); 211 212 $.each(scroll_pos_thresholds, function (scroll_threshold, events_ids) { 213 214 scroll_threshold = parseInt(scroll_threshold.substring(1)); // integer threshold value 215 216 // position is not reached 217 if (scroll_pos <= scroll_threshold) { 218 return true; 219 } 220 221 // fire events for current threshold 222 $.map(events_ids, function (event_id, index) { 223 224 // fire event only once for current scroll pos 225 scroll_pos_thresholds['_' + scroll_threshold][index] = null; 226 227 if (pys_fb_pixel_dynamic_events.hasOwnProperty(event_id)) { 228 evaluateDynamicEventByID(pys_fb_pixel_dynamic_events[event_id]); 229 } 230 231 }); 232 233 }); 234 235 }); 236 237 } 238 239 function setupScrollPosThresholds(trigger) { 240 241 var height = $(document).height() - $(window).height(); 242 243 // convert % to pixels 244 var scroll_pos = parseInt(trigger.trigger_value); 245 scroll_pos = height * scroll_pos / 100; 246 scroll_pos = Math.round(scroll_pos); 247 248 scroll_pos = '_' + scroll_pos; 249 250 // add new position 251 if (typeof scroll_pos_thresholds[scroll_pos] === 'undefined') { 252 scroll_pos_thresholds[scroll_pos] = []; 253 } 254 255 // array is used because many events can be attached to same scroll position 256 // so each position has an array with events ids 257 scroll_pos_thresholds[scroll_pos].push(trigger.event_id); 258 259 } 260 261 function attachCssClickHandler(trigger) { 262 263 // Non-default binding used to avoid situations when some code in external js 264 // stopping events propagation, eg. returns false, and our handler will never called 265 $(document).onFirst('click', trigger.trigger_value, function () { 266 267 if (pys_fb_pixel_dynamic_events.hasOwnProperty(trigger.event_id)) { 268 evaluateDynamicEventByID(pys_fb_pixel_dynamic_events[trigger.event_id]); 269 } 270 271 }); 272 273 } 274 275 function attachMouseOverHandler(trigger) { 276 277 // Non-default binding used to avoid situations when some code in external js 278 // stopping events propagation, eg. returns false, and our handler will never called 279 $(trigger.trigger_value).onFirst('mouseover', function () { 280 281 // event should be fired only once 282 if( $(this).hasClass('pys-mouse-over-' + trigger.event_id) ) { 283 return; 284 } 285 286 $(this).addClass('pys-mouse-over-' + trigger.event_id); 287 288 if (pys_fb_pixel_dynamic_events.hasOwnProperty(trigger.event_id)) { 289 evaluateDynamicEventByID(pys_fb_pixel_dynamic_events[trigger.event_id]); 290 } 291 292 }); 293 294 } 295 296 function evaluateDynamicEventByID(event) { 297 298 if (event.hasOwnProperty('custom_code')) { 299 eval(event.custom_code); 300 } else { 301 302 event = addTrafficSourceParams(event); 303 fbq(event.type, event.name, event.params); 304 305 } 306 307 } 308 309 function getTrafficSource() { 310 311 try { 312 313 var referrer = document.referrer.toString(); 314 315 var direct = referrer.length == 0; 316 //noinspection JSUnresolvedVariable 317 var internal = direct ? false : referrer.indexOf(pys_fb_pixel_options.site_url) === 0; 318 var external = !(direct || internal); 319 var cookie = typeof Cookies.get('pys_fb_pixel_traffic_source') == 'undefined' ? false : Cookies.get('pys_fb_pixel_traffic_source'); 320 321 if (external == false) { 322 return cookie ? cookie : 'direct'; 323 } else { 324 return cookie && cookie == referrer ? cookie : referrer; 325 } 326 327 } catch (e) { 328 329 console.log(e); 330 return ''; 331 332 } 333 334 } 335 336 /** 337 * Return UTM terms from request query variables or from cookies. 338 */ 339 function getUTMs() { 340 341 try { 342 343 var terms = {}; 344 var queryVars = getQueryVars(); 345 346 $.each(utm_terms, function (index, name) { 347 348 if (Cookies.get('pys_fb_pixel_' + name)) { 349 terms[name] = Cookies.get('pys_fb_pixel_' + name); 350 } else if (queryVars.hasOwnProperty(name)) { 351 terms[name] = queryVars[name]; 352 } 353 354 }); 355 356 return terms; 357 358 } catch (e) { 359 console.log(e); 360 return {}; 361 } 362 363 } 364 365 function manageCookies() { 366 367 try { 368 369 var source = getTrafficSource(); 370 371 if (source != 'direct') { 372 Cookies.set('pys_fb_pixel_traffic_source', source); 373 } else { 374 Cookies.remove('pys_fb_pixel_traffic_source'); 375 } 376 377 var queryVars = getQueryVars(); 378 379 $.each(utm_terms, function (index, name) { 380 381 if (Cookies.get('pys_fb_pixel_' + name) == undefined && queryVars.hasOwnProperty(name)) { 382 Cookies.set('pys_fb_pixel_' + name, queryVars[name]); 383 } 384 385 }); 386 387 } catch (e) { 388 console.log(e); 389 } 390 391 } 392 393 /** 394 * Add `traffic_source` and `utm` params to event params for any event except `init`. 395 */ 396 function addTrafficSourceParams(event) { 397 398 try { 399 400 //noinspection JSUnresolvedVariable 401 if (pys_fb_pixel_options.track_traffic_source == false || event.type == 'init') { 402 return event; 403 } 404 405 event.params.traffic_source = getTrafficSource(); 406 407 $.each(getUTMs(), function (name, value) { 408 409 if ($.inArray(name, utm_terms) >= 0) { 410 event.params[name] = value; 411 } 412 413 }); 414 415 return event; 416 417 } catch (e) { 418 419 console.log(e); 420 return event; 421 422 } 423 424 } 425 426 /** 427 * Return query variables object with where property name is query variable and property value is query variable value. 428 */ 429 function getQueryVars() { 430 431 try { 432 433 var result = {}, tmp = []; 434 435 window.location.search 436 .substr(1) 437 .split("&") 438 .forEach(function (item) { 439 440 tmp = item.split('='); 441 442 if (tmp.length > 1) { 443 result[tmp[0]] = tmp[1]; 444 } 445 446 }); 447 448 return result; 449 450 } catch (e) { 451 console.log(e); 452 return {}; 453 } 454 455 } 456 457});
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.