1/** 2 * Provides array filter 3 */ 4[].filter || (Array.prototype.filter = // Use the native array filter method, if available. 5 function(a, //a function to test each value of the array against. Truthy values will be put into the new array and falsy values will be excluded from the new array 6 b, // placeholder 7 c, // placeholder 8 d, // placeholder 9 e // placeholder 10 ) { 11 c = this; // cache the array 12 d = []; // array to hold the new values which match the expression 13 for (e in c) // for each value in the array, 14 ~~e + '' == e && e >= 0 && // coerce the array position and if valid, 15 a.call(b, c[e], +e, c) && // pass the current value into the expression and if truthy, 16 d.push(c[e]); // add it to the new array 17 18 return d // give back the new array 19 }); 20 21/** 22 * Provides last indexOf for arrays 23 */ 24if (!Array.prototype.lastIndexOf) { 25 Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) { 26 "use strict"; 27 28 if (this == null) { 29 throw new TypeError(); 30 } 31 32 var t = Object(this); 33 var len = t.length >>> 0; 34 if (len === 0) { 35 return -1; 36 } 37 38 var n = len; 39 if (arguments.length > 1) { 40 n = Number(arguments[1]); 41 if (n != n) { 42 n = 0; 43 } 44 else { 45 if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { 46 n = (n > 0 || -1) * Math.floor(Math.abs(n)); 47 } 48 } 49 } 50 51 var k = n >= 0 52 ? Math.min(n, len - 1) 53 : len - Math.abs(n); 54 55 for (; k >= 0; k--) { 56 if (k in t && t[k] === searchElement) { 57 return k; 58 } 59 } 60 return -1; 61 }; 62} 63 64(function ($) { 65 /** 66 * Tracking helpers 67 */ 68 Drupal.rc_ua = { 69 trackAddtoCartFunc : function (product, $element, callback) { 70 var obj, 71 firing_context, 72 event = 'rc.ecom.addToCart'; 73 if ($element.parents('[data-rc-ua-ecommerce-detail]').length > 0) { 74 firing_context = 'Details'; 75 } 76 else { 77 if ($element.parents().find('.ui-dialog').length > 0) { 78 event = 'rc.ecom.addToCartQuote' 79 firing_context = 'Detailed Quote'; 80 } 81 else { 82 var list = $element.parents('[data-rc-ua-ecommerce-impression]').data('data-rc-ua-ecommerce-list'); 83 firing_context = 'List: ' + list; 84 } 85 } 86 if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'tm') { 87 obj = { 88 'event': event, 89 'eventCategory': 'eCommerce', 90 'eventAction': 'Add to Cart from ' + firing_context, 91 'eventLabel': product.id, 92 'ecommerce': { 93 'add': { 94 'products': [product] 95 } 96 }, 97 'eventCallback': callback, 98 'callback': callback 99 }; 100 window[Drupal.settings.rc_ua.rc_ua_tm_datalayer].push(obj); 101 } 102 else { 103 ga('ec:addProduct', product); 104 ga('ec:setAction', 'add'); 105 ga('send', { 106 'hitType': 'event', 107 'eventCategory': 'eCommerce', 108 'eventAction': 'Add to Cart from ' + firing_context, 109 'eventLabel': product.id, 110 'eventValue': Math.round(product.price), 111 'hitCallback': callback 112 }); 113 } 114 115 ga4.event({ 116 event: 'add_to_cart', 117 value: Math.round(product.price), 118 eventAction: 'Add to Cart from ' + firing_context, 119 eventCategory: 'eCommerce', 120 eventLabel: product.id, 121 items: [ 122 product 123 ] 124 }); 125 }, 126 127 trackCheckoutStepFunc: function (step, obj, callback) { 128 if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'tm') { 129 dlo = Object.assign({}, obj, { 130 'callback': callback, 131 'eventCallback': callback, 132 'eventCategory': 'eCommerce', 133 'eventAction': 'Checkout Step', 134 'eventLabel': step.step 135 }); 136 window[Drupal.settings.rc_ua.rc_ua_tm_datalayer].push(dlo); 137 } 138 else { 139 ga('ec:addProduct', step.product); 140 ga('ec:setAction', 'checkout', { 141 'step': step.step 142 }); 143 ga('send', { 144 'hitType': 'event', 145 'eventCategory': 'eCommerce', 146 'eventAction': 'Checkout Step', 147 'eventLabel': step.step, 148 'eventValue': Math.round(step.product.price), 149 'hitCallback': callback 150 }); 151 } 152 153 ga4.event({ 154 value: Math.round(step.product.price), 155 items: [ 156 step.product 157 ], 158 step: step.step, 159 event: 'begin_checkout', 160 eventCategory: 'eCommerce', 161 eventAction: 'Checkout Step', 162 eventLabel: step.step, 163 }); 164 } 165 }; 166 167 /** 168 * Drupal behaviors 169 */ 170 Drupal.behaviors.rc_ua = { 171 initProductClicks: function (context, settings) { 172 $('[data-rc-ua-ecommerce-click-path]:not([data-rc-ua-ecommerce-click-path=""])', context).once('rc_ua_initProductClicks', function () { 173 var path = $(this).attr('data-rc-ua-ecommerce-click-path'); 174 var product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-impression')); 175 var element = this; 176 $('a', this).each(function () { 177 var href = $(this).attr('href') 178 if (href !== undefined && href.indexOf(path) == 0) { 179 $(this).click(function (e) { 180 e.preventDefault(); 181 var href = $(this).attr('href'); 182 var link = $(this); 183 if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'tm') { 184 obj = { 185 'event': 'rc.ecom.productClick', 186 'eventCategory': 'eCommerce', 187 'eventAction': 'Product Click', 188 'eventLabel': product.id, 189 'ecommerce': { 190 'click': { 191 'actionField': {list: product.list, position: product.position}, 192 'products': [product] 193 } 194 }, 195 'eventCallback': function () { 196 if (link.attr('target') === "_blank") { 197 // Reasoning on this approach, here https://stackoverflow.com/a/68097403 198 let anchor = document.createElement('a'); 199 anchor.href = href; 200 anchor.target = "_blank"; 201 anchor.click(); 202 } else { 203 window.location = href; 204 } 205 } 206 }; 207 window[Drupal.settings.rc_ua.rc_ua_tm_datalayer].push(obj); 208 } 209 else { 210 ga('ec:addProduct', product); 211 ga('ec:setAction', 'click', { list: product.list }); 212 ga('send', { 213 'hitType': 'event', 214 'eventCategory': 'eCommerce', 215 'eventAction': 'Product Click', 216 'eventLabel': product.id, 217 'eventValue': null, 218 'hitCallback': function () { 219 if (link.attr('target') === "_blank") { 220 // Reasoning on this approach, here https://stackoverflow.com/a/68097403 221 let anchor = document.createElement('a'); 222 anchor.href = href; 223 anchor.target = "_blank"; 224 anchor.click(); 225 } else { 226 window.location = href; 227 } 228 } 229 }); 230 231 ga4.event({ 232 event: 'select_item', 233 eventCategory: 'eCommerce', 234 eventAction: 'Product Click', 235 eventLabel: product.id, 236 items: [ 237 product 238 ], 239 }); 240 241 setTimeout(function () { 242 if (link.attr('target') === "_blank") { 243 // Reasoning on this approach, here https://stackoverflow.com/a/68097403 244 let anchor = document.createElement('a'); 245 anchor.href = href; 246 anchor.target = "_blank"; 247 anchor.click(); 248 } else { 249 window.location = href; 250 } 251 }, 2000); 252 } 253 }); 254 } 255 }); 256 }); 257 }, 258 initProductLists: function (context, settings) { 259 if (Drupal.settings.rc_ua.rc_ua_tracking_method != 'ua') { 260 return; 261 } 262 $('[data-rc-ua-ecommerce-list]:not([data-rc-ua-ecommerce-list=""])', context).once('rc_ua_trackProductLists', function () { 263 var eclist = $(this).attr('data-rc-ua-ecommerce-list'); 264 var liststart = parseInt($(this).attr('data-rc-ua-ecommerce-list-start')); 265 266 $("[data-rc-ua-ecommerce-impression]", this).each(function (ind, elem) { 267 $(this).data('data-rc-ua-ecommerce-list', eclist); 268 $(this).data('data-rc-ua-ecommerce-list-pos', liststart + ind + 1); 269 }); 270 }); 271 }, 272 trackProductImpressions: function (context, settings) { 273 var hasImpressions = false;
274 var max_items = 10; 275 var queued_items = 0; 276 var total_items = $('[data-rc-ua-ecommerce-impression]:not([data-rc-ua-ecommerce-impression=""])', context).length; 277 var processed_items = 0; 278 var event_lists = []; 279 var event_label = []; 280 var event_label_filter = function (arr) { 281 return arr.filter(function (e, i, a) { 282 return a.lastIndexOf(e) === i; 283 }); 284 }; 285 286 $('[data-rc-ua-ecommerce-impression]:not([data-rc-ua-ecommerce-impression=""])', context).once('rc_ua_trackProductImpressions', function () { 287 var product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-impression')), 288 pos = $(this).data('data-rc-ua-ecommerce-list-pos'), 289 list = $(this).data('data-rc-ua-ecommerce-list'); 290 291 if (typeof(list) != 'undefined' && list) { 292 product.list = list; 293 } 294 295 if (typeof(pos) != 'undefined' && pos) { 296 product.pos = pos; 297 } 298 299 if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'tm') { 300 window[Drupal.settings.rc_ua.rc_ua_tm_datalayer].push({ 301 eventLabel: product.list, 302 eventCategory: "eCommerce", 303 eventAction: "Product Impressions", 304 'event': 'rc.ecom.impressions', 305 'ecommerce': { 306 'impressions': [ product ] 307 } 308 }); 309 } 310 else { 311 ga('ec:addImpression', product); 312 queued_items++; 313 event_lists.push(product.list); 314 if ((queued_items % max_items) == 0) { 315 event_label = event_label_filter(event_lists); 316 ga('send', { 317 'hitType': 'event', 318 'eventCategory': 'eCommerce', 319 'eventAction': 'Product Impressions', 320 'eventLabel': 'Lists: ' + event_label.join(), 321 'eventValue': null, 322 'nonInteraction': 1 323 }); 324 processed_items = processed_items + queued_items; 325 queued_items = 0; 326 event_lists = []; 327 } 328 hasImpressions = true; 329 } 330 331 event_label = event_label_filter(event_lists); 332 ga4.event({ 333 event: 'view_item', 334 eventCategory: 'eCommerce', 335 eventAction: 'Product Impressions', 336 eventLabel: 'Lists: ' + event_label.join(), 337 items: [ 338 product 339 ] 340 }); 341 }); 342 343 if (Drupal.settings.rc_ua.rc_ua_tracking_method != 'tm' && hasImpressions && processed_items < total_items) { 344 event_label = event_label_filter(event_lists); 345 ga('send', { 346 'hitType': 'event', 347 'eventCategory': 'eCommerce', 348 'eventAction': 'Product Impressions', 349 'eventLabel': 'Lists:' + event_label.join(), 350 'eventValue': null, 351 'nonInteraction': 1 352 }); 353 } 354 }, 355 trackProductDetails: function (context, settings) { 356 $('[data-rc-ua-ecommerce-detail]:not([data-rc-ua-ecommerce-detail=""])', context).once('rc_ua_trackProductDetails', function () { 357 // The product being viewed. 358 var product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-detail')); 359 if (Drupal.settings.rc_ua.rc_ua_tracking_method === 'ua') { 360 ga('ec:addProduct', product); 361 ga('ec:setAction', 'detail'); // Detail action. 362 ga('send', { 363 'hitType': 'event', 364 'eventCategory': 'eCommerce', 365 'eventAction': 'Product Detail View', 366 'eventLabel': product.id, 367 'eventValue': Math.round(product.price), 368 'nonInteraction': 1 369 }); 370 } 371 else if (Drupal.settings.rc_ua.rc_ua_tracking_method === 'tm') { 372 window[Drupal.settings.rc_ua.rc_ua_tm_datalayer].push({ 373 'event': 'rc.ecom.productDetails', 374 'eventCategory': 'eCommerce', 375 'eventAction': 'Product Detail View', 376 'eventLabel': product.id, 377 'eventValue': Math.round(product.price), 378 'ecommerce': { 379 'detail': { 380 'products': [product] 381 } 382 } 383 }); 384 } 385 386 ga4.event({ 387 event: 'view_item', 388 value: Math.round(product.price), 389 items: [ 390 product 391 ], 392 eventCategory: 'eCommerce', 393 eventAction: 'Product Impressions', 394 eventLabel: product.id 395 }); 396 }); 397 }, 398 399 trackAddToCart: function (context, settings) { 400 var product; 401 $('[data-rc-ua-ecommerce-submit-addtocart]:not([data-rc-ua-ecommerce-submit-addtocart=""])', context).once('rc_ua_trackSubmitAddToCart', function () { 402 product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-submit-addtocart')); 403 $(this).on('submit', function() { 404 var _this = this; 405 if(!$(this).hasClass('rc-ua-tracked-item')) { 406 var callback = function() { 407 $(_this).addClass('rc-ua-tracked-item'); 408 $('.form-submit', _this).click(); 409 }; 410 Drupal.rc_ua.trackAddtoCartFunc(product, $(this), callback); 411 // return false;
412 } 413 // return true; 414 }); 415 }); 416 417 $('[data-rc-ua-ecommerce-click-addtocart]:not([data-rc-ua-ecommerce-click-addtocart=""])', context).once('rc_ua_trackClickAddToCart', function () { 418 product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-click-addtocart')); 419 $(this).on('click', function() { 420 var _this = this; 421 if(!$(this).hasClass('rc-ua-tracked-item')) { 422 var callback = function() { 423 $(_this).addClass('rc-ua-tracked-item'); 424 $(_this).click(); 425 }; 426 Drupal.rc_ua.trackAddtoCartFunc(product, $(this), callback); 427 // return false; 428 } 429 // return true; 430 }); 431 }); 432 433 $('[data-rc-ua-ecommerce-addtocart]:not([data-rc-ua-ecommerce-addtocart=""])', context).once('rc_ua_trackAddToCart', function () { 434 product = $.parseJSON($(this).attr('data-rc-ua-ecommerce-addtocart')); 435 Drupal.rc_ua.trackAddtoCartFunc(product, $(this)); 436 }); 437 }, 438 439 trackCheckoutSteps: function (context, settings) { 440 var step, obj, callback; 441 $('[data-rc-ua-ecommerce-submit-checkoutsteps]:not([data-rc-ua-ecommerce-submit-checkoutsteps=""])', context).once('rc_ua_trackSubmitCheckoutSteps', function () { 442 $(this).submit(function (e) { 443 var _this = this; 444 if(!$(this).hasClass('rc-ua-tracked-item')) { 445 callback = function() { 446 $(_this).addClass('rc-ua-tracked-item'); 447 $('.form-submit', _this).last().trigger('click'); 448 }; 449 step = $.parseJSON($(this).attr('data-rc-ua-ecommerce-submit-checkoutsteps')); 450 obj = { 451 'event': 'rc.ecom.checkout', 452 'ecommerce': { 453 'checkout': { 454 'actionField': {'step': step.step}, 455 'products': [step.product] 456 } 457 } 458 }; 459 Drupal.rc_ua.trackCheckoutStepFunc(step, obj, callback); 460 // return false; 461 } 462 // return true; 463 }); 464 }); 465 $('[data-rc-ua-ecommerce-click-checkoutsteps]:not([data-rc-ua-ecommerce-click-checkoutsteps=""])', context).once('rc_ua_trackClickCheckoutSteps', function () { 466 step = $.parseJSON($(this).attr('data-rc-ua-ecommerce-click-checkoutsteps')); 467 obj = { 468 'event': 'rc.ecom.checkout', 469 'ecommerce': { 470 'checkout': { 471 'actionField': {'step': step.step}, 472 'products': [step.product] 473 } 474 } 475 }; 476 $(this).on('click', function() { 477 Drupal.rc_ua.trackCheckoutStepFunc(step, obj); 478 }); 479 }); 480 481 $('[data-rc-ua-ecommerce-checkoutsteps]:not([data-rc-ua-ecommerce-checkoutsteps=""])', context).once('rc_ua_trackCheckoutSteps', function () { 482 step = $.parseJSON($(this).attr('data-rc-ua-ecommerce-checkoutsteps')); 483 obj = { 484 'event': 'rc.ecom.checkout', 485 'ecommerce': { 486 'checkout': { 487 'actionField': {'step': step.step}, 488 'products': [step.product] 489 } 490 } 491 }; 492 Drupal.rc_ua.trackCheckoutStepFunc(step, obj); 493 }); 494 495 }, 496 attach: function (context, settings) { 497 if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'ua' && typeof ga != 'undefined') { 498 ga('require', 'ec'); 499 } else if (Drupal.settings.rc_ua.rc_ua_tracking_method == 'tm') { 500 if (typeof(window[Drupal.settings.rc_ua.rc_ua_tm_datalayer]) == 'undefined') { 501 // Using gtm tracking method, but no dataLayer object present, which means tag manager is not present or 502 // disabled within current context, and tracking calls would generate errors. 503 return; 504 } 505 } else if (Drupal.settings.rc_ua.rc_ua_tracking_method != 'tm') { 506 // No ga object, no tag manager, so no tracking. 507 return; 508 } 509 510 this.initProductClicks(context, settings); 511 this.initProductLists(context, settings); 512 this.trackProductImpressions(context, settings); 513 this.trackProductDetails(context, settings); 514 this.trackAddToCart(context, settings); 515 this.trackCheckoutSteps(context, settings); 516 } 517 }; 518})(jQuery);
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.