1/** 2 * Developer's Notice: 3 * 4 * Note: JS in this file (and this file itself) is not guaranteed backwards compatibility. JS can be added, changed or removed at any time without notice. 5 * For more information see the `Backwards Compatibility Guidelines for Developers` section of the README.md file. 6 */ 7/** 8 * Handles: 9 * - JS Events handling 10 * 11 * @since 7.15.0 12 */ 13var MonsterInsights = function () { 14 /* MonsterInsights JS events tracking works on all major browsers, including IE starting at IE 7, via polyfills for any major JS function used that 15 is not supported by at least 95% of the global and/or US browser marketshare. Currently, IE 7 & 8 which as of 2/14/17 have under 0.25% global marketshare, require 16 us to polyfill Array.prototype.lastIndexOf, and if they continue to drop, we might remove this polyfill at some point. In that case note that events tracking 17 for IE 7/8 will continue to work, with the exception of events tracking of downloads. */ 18 var lastClicked = []; 19 var internalAsOutboundCategory = ''; 20 var beforeUnloadChanged = false; 21 22 this.setLastClicked = function (valuesArray, fieldsArray, tracked) { 23 valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : []; 24 fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : []; 25 tracked = typeof tracked !== 'undefined' ? tracked : false; 26 27 lastClicked.valuesArray = valuesArray; 28 lastClicked.fieldsArray = fieldsArray; 29 }; 30 31 this.getLastClicked = function () { 32 return lastClicked; 33 }; 34 35 this.setInternalAsOutboundCategory = function (category) { 36 internalAsOutboundCategory = category; 37 }; 38 39 this.getInternalAsOutboundCategory = function () { 40 return internalAsOutboundCategory; 41 }; 42 43 this.sendEvent = function (type, action, fieldsArray) { 44 __gtagTrackerSend(type, action, fieldsArray, []); 45 }; 46 47 function __gtagTrackerIsDebug() { 48 if (window.monsterinsights_debug_mode) { 49 return true; 50 } else { 51 return false; 52 } 53 } 54 55 function cloneFields(fields, allowedKeys, disallowedKeys) { 56 var clone = {}; 57 58 for (var key in fields) { 59 if (!fields.hasOwnProperty(key)) { 60 continue 61 } 62 63 if (allowedKeys && allowedKeys.indexOf(key) === -1) { 64 continue 65 } 66 67 if (disallowedKeys && disallowedKeys.indexOf(key) > -1) { 68 continue 69 } 70 71 clone[key] = fields[key]; 72 } 73 74 return clone; 75 } 76 77 function __gtagMaybeTrackerV4(type, action, fieldsArray) { 78 if (!monsterinsights_frontend.v4_id || type !== 'event') { 79 return; 80 } 81 82 var eventCategory = fieldsArray.event_category || ''; 83 84 var fieldsToRemove = [ 85 'event_name', 86 'event_category', 87 'event_label', 88 'value', 89 ]; 90 91 var fields = cloneFields(fieldsArray, null, fieldsToRemove); 92 fields.action = action; 93 fields.send_to = monsterinsights_frontend.v4_id; 94 95 let hitType = eventCategory.replace('-', '_'); 96 if (eventCategory.indexOf('outbound-link') !== -1) { 97 hitType = 'click' 98 } else if (eventCategory === 'download') { 99 hitType = 'file_download' 100 } 101 102 __gtagTracker(type, hitType, fields); 103 } 104 105 function __gtagTrackerSendDual(type, action, fieldsArray, valuesArray) { 106 type = typeof type !== 'undefined' ? type : 'event'; 107 action = typeof action !== 'undefined' ? action : ''; 108 valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : []; 109 fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {}; 110 111 __gtagMaybeTrackerV4(type, action, fieldsArray); 112 113 lastClicked.valuesArray = valuesArray; 114 lastClicked.fieldsArray = fieldsArray; 115 lastClicked.fieldsArray.event_action = action; 116 lastClicked.tracked = true; 117 __gtagTrackerLog('Tracked: ' + valuesArray.type); 118 __gtagTrackerLog(lastClicked); 119 } 120 121 /** 122 * This attempts to be compatible with the gtag function. 123 * 124 * @see https://developers.google.com/analytics/devguides/collection/gtagjs 125 * @param type string Type of request, event, timing, config. 126 * @param action string Event action or UA for config. 127 * @param fieldsArray object The configuration object. 128 * @param valuesArray object The values for the log. 129 * @private 130 */ 131 function __gtagTrackerSend(type, action, fieldsArray, valuesArray) { 132 type = typeof type !== 'undefined' ? type : 'event'; 133 action = typeof action !== 'undefined' ? action : ''; 134 valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : []; 135 fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {}; 136 137 __gtagTracker(type, action, fieldsArray); 138 139 lastClicked.valuesArray = valuesArray; 140 lastClicked.fieldsArray = fieldsArray; 141 lastClicked.fieldsArray.event_action = action; 142 lastClicked.tracked = true; 143 __gtagTrackerLog('Tracked: ' + valuesArray.type); 144 __gtagTrackerLog(lastClicked); 145 } 146 147 function __gtagTrackerNotSend(valuesArray) { 148 valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : []; 149 150 lastClicked.valuesArray = valuesArray; 151 lastClicked.fieldsArray = []; 152 lastClicked.tracked = false;
153 __gtagTrackerLog('Not Tracked: ' + valuesArray.exit); 154 __gtagTrackerLog(lastClicked); 155 } 156 157 function __gtagTrackerLog(message) { 158 if (__gtagTrackerIsDebug()) { 159 console.dir(message); 160 } 161 } 162 163 function __gtagTrackerStringTrim(x) { 164 return x.replace(/^\s+|\s+$/gm, ''); 165 } 166 167 function __gtagTrackerGetDomain() { 168 var i = 0, currentdomain = document.domain, p = currentdomain.split('.'), s = '_gd' + ( 169 new Date() 170 ).getTime(); 171 while (i < (p.length - 1) && document.cookie.indexOf(s + '=' + s) == -1) { 172 currentdomain = p.slice(-1 - ( 173 ++i 174 )).join('.'); 175 document.cookie = s + "=" + s + ";domain=" + currentdomain + ";"; 176 } 177 document.cookie = s + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain=" + currentdomain + ";"; 178 return currentdomain; 179 } 180 181 function __gtagTrackerGetExtension(extension) { 182 extension = extension.toString(); 183 extension = extension.substring(0, ( 184 extension.indexOf("#") == -1 185 ) ? extension.length : extension.indexOf("#")); /* Remove the anchor at the end, if there is one */ 186 extension = extension.substring(0, ( 187 extension.indexOf("?") == -1 188 ) ? extension.length : extension.indexOf("?")); /* Remove the query after the file name, if there is one */ 189 extension = extension.substring(extension.lastIndexOf("/") + 1, extension.length); /* Remove everything before the last slash in the path */ 190 if (extension.length > 0 && extension.indexOf('.') !== -1) { /* If there's a period left in the URL, then there's a extension. Else it is not a extension. */ 191 extension = extension.substring(extension.lastIndexOf(".") + 1); /* Remove everything but what's after the first period */ 192 return extension; 193 } else { 194 return ""; 195 } 196 } 197 198 function __gtagTrackerTrackedClick(event) { 199 return event.which == 1 || event.which == 2 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey; 200 } 201 202 function __gtagTrackerGetDownloadExtensions() { 203 var download_extensions = []; 204 if (typeof monsterinsights_frontend.download_extensions == 'string') { 205 download_extensions = monsterinsights_frontend.download_extensions.split(","); 206 } 207 return download_extensions; 208 } 209 210 function __gtagTrackerGetInboundPaths() { 211 var inbound_paths = []; 212 if (typeof monsterinsights_frontend.inbound_paths == 'string') { 213 inbound_paths = JSON.parse(monsterinsights_frontend.inbound_paths); 214 } 215 216 return inbound_paths; 217 } 218 219 function __gtagTrackerTrackedClickType(event) { 220 if (event.which == 1) { 221 return 'event.which=1'; 222 } else if (event.which == 2) { 223 return 'event.which=2'; 224 } else if (event.metaKey) { 225 return 'metaKey'; 226 } else if (event.ctrlKey) { 227 return 'ctrlKey'; 228 } else if (event.shiftKey) { 229 return 'shiftKey'; 230 } else if (event.altKey) { 231 return 'altKey'; 232 } else { 233 return ''; 234 } 235 } 236 237 function __gtagTrackerLinkType(el) { 238 var download_extensions = __gtagTrackerGetDownloadExtensions(); 239 var inbound_paths = __gtagTrackerGetInboundPaths(); 240 var type = 'unknown'; 241 var link = el.href; 242 var extension = __gtagTrackerGetExtension(el.href); 243 var currentdomain = __gtagTrackerGetDomain(); 244 var hostname = el.hostname; 245 var protocol = el.protocol; 246 var pathname = el.pathname; 247 link = link.toString(); 248 var index, len; 249 var category = el.getAttribute("data-vars-ga-category"); 250 251 if (category) { 252 return category; 253 } 254 255 if (link.match(/^javascript\:/i)) { 256 type = 'internal'; /* if it's a JS link, it's internal */ 257 } else if (protocol && protocol.length > 0 && ( 258 __gtagTrackerStringTrim(protocol) == 'tel' || __gtagTrackerStringTrim(protocol) == 'tel:' 259 )) { /* If it's a telephone link */ 260 type = "tel"; 261 } else if (protocol && protocol.length > 0 && ( 262 __gtagTrackerStringTrim(protocol) == 'mailto' || __gtagTrackerStringTrim(protocol) == 'mailto:' 263 )) { /* If it's a email */ 264 type = "mailto"; 265 } else if (hostname && currentdomain && hostname.length > 0 && currentdomain.length > 0 && !hostname.endsWith('.' + currentdomain) && hostname !== currentdomain) { /* If it's a outbound */ 266 type = "external"; 267 } else if (pathname && JSON.stringify(inbound_paths) != "{}" && pathname.length > 0) { /* If it's an internal as outbound */ 268 var inbound_paths_length = inbound_paths.length; 269 for (var inbound_paths_index = 0; inbound_paths_index < inbound_paths_length; inbound_paths_index++) { 270 if (inbound_paths[inbound_paths_index].path && inbound_paths[inbound_paths_index].label && inbound_paths[inbound_paths_index].path.length > 0 && inbound_paths[inbound_paths_index].label.length > 0 && pathname.startsWith(inbound_paths[inbound_paths_index].path)) {
271 type = "internal-as-outbound"; 272 internalAsOutboundCategory = "outbound-link-" + inbound_paths[inbound_paths_index].label; 273 break; 274 } 275 } 276 /* Enable window.monsterinsights_experimental_mode at your own risk. We might eventually remove it. Also you may/can/will burn through GA quota for your property quickly. */ 277 } else if (hostname && window.monsterinsights_experimental_mode && hostname.length > 0 && document.domain.length > 0 && hostname !== document.domain) { /* If it's a cross-hostname link */ 278 type = "cross-hostname"; 279 } 280 281 if (extension && ( 282 type === 'unknown' || 'external' === type 283 ) && download_extensions.length > 0 && extension.length > 0) { /* If it's a download */ 284 for (index = 0, len = download_extensions.length; index < len; ++index) { 285 if (download_extensions[index].length > 0 && ( 286 link.endsWith(download_extensions[index]) || download_extensions[index] == extension 287 )) { 288 type = "download"; 289 break; 290 } 291 } 292 } 293 294 if (type === 'unknown') { 295 type = 'internal'; 296 } 297 return type; 298 } 299 300 function __gtagTrackerLinkTarget(el, event) { 301 302 /* Is actual target set and not _(self|parent|top)? */ 303 var target = ( 304 el.target && !el.target.match(/^_(self|parent|top)$/i) 305 ) ? el.target : false;
306 307 /* Assume a target if Ctrl|shift|meta-click */ 308 if (event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2) { 309 target = "_blank"; 310 } 311 return target; 312 } 313 314 function __gtagTrackerGetTitle(el) { 315 if (el.getAttribute("data-vars-ga-label") && el.getAttribute("data-vars-ga-label").replace(/\n/ig, '')) { 316 return el.getAttribute("data-vars-ga-label").replace(/\n/ig, ''); 317 } else if (el.title && el.title.replace(/\n/ig, '')) { 318 return el.title.replace(/\n/ig, ''); 319 } else if (el.innerText && el.innerText.replace(/\n/ig, '')) { 320 return el.innerText.replace(/\n/ig, ''); 321 } else if (el.getAttribute('aria-label') && el.getAttribute('aria-label').replace(/\n/ig, '')) { 322 return el.getAttribute('aria-label').replace(/\n/ig, ''); 323 } else if (el.alt && el.alt.replace(/\n/ig, '')) { 324 return el.alt.replace(/\n/ig, ''); 325 } else if (el.textContent && el.textContent.replace(/\n/ig, '')) { 326 return el.textContent.replace(/\n/ig, ''); 327 } else if (el.firstChild && el.firstChild.tagName == "IMG") { 328 return el.firstChild.src; 329 } else { 330 return undefined; 331 } 332 } 333 334 function __gtagTrackerGetInnerTitle(el) { 335 var children = el.children; 336 var count = 0; 337 var child; 338 var value; 339 for (var i = 0; i < children.length; i++) { 340 child = children[i];
341 value = __gtagTrackerGetTitle(child); 342 if (value) { 343 return value; 344 } 345 /* max search 100 elements to ensure performance */ 346 if (count == 99) { 347 return undefined; 348 } 349 count++; 350 } 351 return undefined; 352 } 353 354 function __gtagTrackerClickEvent(event) { 355 var el = event.srcElement || event.target; 356 var valuesArray = []; 357 var fieldsArray; 358 359 /* Start Values Array */ 360 valuesArray.el = el; 361 valuesArray.click_type = __gtagTrackerTrackedClickType(event); 362 363 /* If GA is blocked or not loaded, or not main|middle|touch click then don't track */ 364 if ('undefined' === typeof __gtagTracker || !__gtagTrackerTrackedClick(event)) { 365 valuesArray.exit = 'loaded'; 366 __gtagTrackerNotSend(valuesArray); 367 return; 368 } 369 370 /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */ 371 while (el && ( 372 typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || !el.href 373 )) { 374 el = el.parentNode; 375 } 376 377 /* if a link with valid href has been clicked */ 378 if (el && el.href && !el.hasAttribute('xlink:href')) { 379 var link = el.href; /* What link are we tracking */ 380 var extension = __gtagTrackerGetExtension(el.href); /* What extension is this link */ 381 var download_extensions = __gtagTrackerGetDownloadExtensions(); /* Let's get the extensions to track */ 382 var inbound_paths = __gtagTrackerGetInboundPaths(); /* Let's get the internal paths to track */ 383 var home_url = monsterinsights_frontend.home_url; /* Let's get the url to compare for external/internal use */ 384 var currentdomain = __gtagTrackerGetDomain(); /* What domain are we on? */ 385 var type = __gtagTrackerLinkType(el); /* What type of link is this? */ 386 var target = __gtagTrackerLinkTarget(el, event); /* Is a new tab/window being opened? */ 387 var action = el.getAttribute("data-vars-ga-action"); 388 var label = el.getAttribute("data-vars-ga-label"); 389 390 /* Element */ 391 valuesArray.el = el; /* el is an a element so we can parse it */ 392 valuesArray.el_href = el.href; /* "http://example.com:3000/pathname/?search=test#hash" */ 393 valuesArray.el_protocol = el.protocol; /* "http:" */ 394 valuesArray.el_hostname = el.hostname; /* "example.com" */ 395 valuesArray.el_port = el.port; /* "3000" */ 396 valuesArray.el_pathname = el.pathname; /* "/pathname/" */ 397 valuesArray.el_search = el.search; /* "?search=test" */ 398 valuesArray.el_hash = el.hash; /* "#hash" */ 399 valuesArray.el_host = el.host; /* "example.com:3000" */ 400 valuesArray.el_classes = el.getAttribute('class') 401 valuesArray.el_id = el.id 402 403 /* Settings */ 404 valuesArray.debug_mode = __gtagTrackerIsDebug(); /* "example.com:3000" */ 405 valuesArray.download_extensions = download_extensions; /* Let's get the extensions to track */ 406 valuesArray.inbound_paths = inbound_paths; /* Let's get the internal paths to track */ 407 valuesArray.home_url = home_url; /* Let's get the url to compare for external/internal use */ 408 409 /* Parsed/Logic */ 410 valuesArray.link = link; /* What link are we tracking */ 411 valuesArray.extension = extension; /* What extension is this link */ 412 valuesArray.type = type; /* What type of link is this */ 413 valuesArray.target = target; /* Is a new tab/window being opened? */ 414 valuesArray.title = __gtagTrackerGetTitle(el); /* Try link title, then text content */ 415 416 /* only find innerTitle if we need one */ 417 if (!valuesArray.label && !valuesArray.title) { 418 valuesArray.title = __gtagTrackerGetInnerTitle(el); 419 } 420 421 /* Let's track everything but internals (that aren't internal-as-externals) and javascript */ 422 if (type !== 'internal' && type !== 'javascript') { 423 424 var __gtagTrackerHitBackRun = false; /* Tracker has not yet run */ 425 426 /* HitCallback to open link in same window after tracker */ 427 var __gtagTrackerHitBack = function () { 428 /* Run the hitback only once */ 429 if (__gtagTrackerHitBackRun) { 430 return; 431 } 432 maybePreventBeforeUnload(); 433 __gtagTrackerHitBackRun = true; 434 435 if ( el.attributes.download ) { 436 var linkTag = document.createElement('a'); 437 linkTag.href = el.href; 438 linkTag.download = el.download; 439 linkTag.click(); 440 } else { 441 window.location.href = link; 442 } 443 }; 444 445 var __gtagTrackerNoRedirectExternal = function () { 446 valuesArray.exit = 'external'; 447 __gtagTrackerNotSend(valuesArray); 448 }; 449 450 var __gtagTrackerNoRedirectInboundAsExternal = function () {
451 valuesArray.exit = 'internal-as-outbound'; 452 __gtagTrackerNotSend(valuesArray); 453 }; 454 var __gtagTrackerNoRedirectCrossHostname = function () { 455 valuesArray.exit = 'cross-hostname'; 456 __gtagTrackerNotSend(valuesArray); 457 }; 458 459 if (target || type == 'mailto' || type == 'tel') { /* If target opens a new window then just track */ 460 if (type == 'download') { 461 fieldsArray = { 462 event_category: 'download', 463 event_label: label || valuesArray.title, 464 file_extension: valuesArray.extension, 465 file_name: valuesArray.link.replace(/^.*\//g, ''), 466 link_text: label || valuesArray.title, 467 link_url: link, 468 link_type: 'download', 469 link_domain: valuesArray.el_hostname, 470 link_classes: valuesArray.el_classes, 471 link_id: valuesArray.el_id, 472 }; 473 } else if (type == 'tel') { 474 fieldsArray = { 475 event_category: 'tel', 476 event_label: label || valuesArray.title.replace('tel:', ''), 477 tel_number: link.replace('tel:', ''), 478 link_text: label || valuesArray.title, 479 link_url: link, 480 link_type: 'tel', 481 link_classes: valuesArray.el_classes, 482 link_id: valuesArray.el_id, 483 }; 484 } else if (type == 'mailto') { 485 fieldsArray = { 486 event_category: 'mailto', 487 event_label: label || valuesArray.title.replace('mailto:', ''), 488 email_address: link.replace('mailto:', ''), 489 link_text: label || valuesArray.title.replace('mailto:', ''), 490 link_url: link, 491 link_type: 'mailto', 492 link_classes: valuesArray.el_classes, 493 link_id: valuesArray.el_id, 494 }; 495 } else if (type == 'internal-as-outbound') { 496 fieldsArray = { 497 event_category: internalAsOutboundCategory, 498 event_label: label || valuesArray.title, 499 event_name: 'click', 500 is_affiliate_link: true, 501 affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''), 502 link_text: label || valuesArray.title, 503 link_url: link, 504 link_type: 'affiliate', 505 link_domain: valuesArray.el_hostname, 506 link_classes: valuesArray.el_classes, 507 link_id: valuesArray.el_id, 508 outbound: true, 509 }; 510 } else if (type == 'external') { 511 fieldsArray = { 512 event_category: 'outbound-link', 513 event_label: label || valuesArray.title, 514 is_affiliate_link: false, 515 link_text: label || valuesArray.title, 516 link_url: link, 517 link_type: 'outbound', 518 link_domain: valuesArray.el_hostname, 519 link_classes: valuesArray.el_classes, 520 link_id: valuesArray.el_id, 521 outbound: true, 522 }; 523 } else if (type == 'cross-hostname') { 524 fieldsArray = { 525 event_category: 'cross-hostname', 526 event_label: label || valuesArray.title, 527 link_text: label || valuesArray.title, 528 link_url: link, 529 link_domain: valuesArray.el_hostname, 530 link_classes: valuesArray.el_classes, 531 link_id: valuesArray.el_id, 532 }; 533 } 534 535 if (fieldsArray) { 536 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 537 } else { 538 if (type && type != 'internal') { 539 fieldsArray = { 540 event_category: type, 541 event_label: label || valuesArray.title, 542 link_text: label || valuesArray.title, 543 link_url: link, 544 link_type: 'internal', 545 link_domain: valuesArray.el_hostname, 546 link_classes: valuesArray.el_classes, 547 link_id: valuesArray.el_id, 548 }; 549 550 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 551 } else { 552 valuesArray.exit = 'type'; 553 __gtagTrackerNotSend(valuesArray); 554 } 555 } 556 } else { 557 /* Prevent standard click, track then open */ 558 if (type != 'cross-hostname' && type != 'external' && type != 'internal-as-outboun
558d') { 559 if (!event.defaultPrevented) { 560 if (event.preventDefault) { 561 event.preventDefault(); 562 } else { 563 event.returnValue = false; 564 } 565 } 566 } 567 568 if (type == 'download') { 569 fieldsArray = { 570 event_category: 'download', 571 event_label: label || valuesArray.title, 572 event_callback: __gtagTrackerHitBack, 573 file_extension: valuesArray.extension, 574 file_name: valuesArray.link.replace(/^.*\//g, ''), 575 link_text: label || valuesArray.title, 576 link_url: link, 577 link_type: 'download', 578 link_domain: valuesArray.el_hostname, 579 link_classes: valuesArray.el_classes, 580 link_id: valuesArray.el_id, 581 }; 582 583 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 584 } else if (type == 'internal-as-outbound') { 585 beforeUnloadChanged = true; 586 window.onbeforeunload = function (e) { 587 if (!event.defaultPrevented) { 588 if (event.preventDefault) { 589 event.preventDefault(); 590 } else { 591 event.returnValue = false; 592 } 593 } 594 595 fieldsArray = { 596 event_category: internalAsOutboundCategory, 597 event_label: label || valuesArray.title, 598 event_callback: __gtagTrackerHitBack, 599 is_affiliate_link: true, 600 affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''), 601 link_text: label || valuesArray.title, 602 link_url: link, 603 link_type: 'affiliate', 604 link_domain: valuesArray.el_hostname, 605 link_classes: valuesArray.el_classes, 606 link_id: valuesArray.el_id, 607 outbound: true, 608 }; 609 610 if (navigator.sendBeacon) { 611 fieldsArray.transport = 'beacon'; 612 } 613 614 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 615 616 setTimeout(__gtagTrackerHitBack, 1000); 617 }; 618 } else if (type == 'external') { 619 beforeUnloadChanged = true; 620 window.onbeforeunload = function (e) { 621 622 fieldsArray = { 623 event_category: 'outbound-link', 624 event_label: label || valuesArray.title, 625 event_callback: __gtagTrackerHitBack, 626 is_affiliate_link: false, 627 link_text: label || valuesArray.title, 628 link_url: link, 629 link_type: 'outbound', 630 link_domain: valuesArray.el_hostname, 631 link_classes: valuesArray.el_classes, 632 link_id: valuesArray.el_id, 633 outbound: true, 634 }; 635 636 if (navigator.sendBeacon) { 637 fieldsArray.transport = 'beacon'; 638 } 639 640 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 641 }; 642 } else if (type == 'cross-hostname') { 643 beforeUnloadChanged = true; 644 window.onbeforeunload = function (e) { 645 if (!event.defaultPrevented) { 646 if (event.preventDefault) { 647 event.preventDefault(); 648 } else { 649 event.returnValue = false; 650 } 651 } 652 653 fieldsArray = { 654 event_category: 'cross-hostname', 655 event_label: label || valuesArray.title, 656 event_callback: __gtagTrackerHitBack, 657 link_text: label || valuesArray.title, 658 link_url: link, 659 link_domain: valuesArray.el_hostname, 660 link_classes: valuesArray.el_classes, 661 link_id: valuesArray.el_id, 662 }; 663 664 if (navigator.sendBeacon) { 665 fieldsArray.transport = 'beacon'; 666 } 667 668 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 669 setTimeout(__gtagTrackerHitBack, 1000); 670 }; 671 } else {
672 if (type && type !== 'internal') { 673 fieldsArray = { 674 event_category: type, 675 event_label: label || valuesArray.title, 676 event_callback: __gtagTrackerHitBack, 677 link_text: label || valuesArray.title, 678 link_url: link, 679 link_type: 'internal', 680 link_domain: valuesArray.el_hostname, 681 link_classes: valuesArray.el_classes, 682 link_id: valuesArray.el_id, 683 }; 684 685 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 686 } else { 687 valuesArray.exit = 'type'; 688 __gtagTrackerNotSend(valuesArray); 689 } 690 } 691 692 if (type != 'external' && type != 'cross-hostname' && type != 'internal-as-outbound') { 693 /* Run event_callback again if GA takes longer than 1 second */ 694 setTimeout(__gtagTrackerHitBack, 1000); 695 } else { 696 if (type == 'external') { 697 setTimeout(__gtagTrackerNoRedirectExternal, 1100); 698 } else if (type == 'cross-hostname') { 699 setTimeout(__gtagTrackerNoRedirectCrossHostname, 1100); 700 } else { 701 setTimeout(__gtagTrackerNoRedirectInboundAsExternal, 1100); 702 } 703 } 704 705 // Clear out the beforeunload event if it was set to avoid sending false events. 706 setTimeout(maybePreventBeforeUnload, 100); 707 } 708 } else { 709 maybePreventBeforeUnload(); 710 valuesArray.exit = 'internal'; 711 __gtagTrackerNotSend(valuesArray); 712 } 713 } else { 714 valuesArray.exit = 'notlink'; 715 __gtagTrackerNotSend(valuesArray); 716 } 717 } 718 719 var prevHash = window.location.hash; 720 721 function __gtagTrackerHashChangeEvent() { 722 /* Todo: Ready this section for JS unit testing */ 723 if (monsterinsights_frontend.hash_tracking === "true" && prevHash != window.location.hash && monsterinsights_frontend.v4_id) { 724 prevHash = window.location.hash; 725 726 __gtagTracker('config', monsterinsights_frontend.v4_id, { 727 page_path: location.pathname + location.search + location.hash, 728 }); 729 730 __gtagTrackerLog("Hash change to: " + location.pathname + location.search + location.hash); 731 } else { 732 __gtagTrackerLog("Hash change to (untracked): " + location.pathname + location.search + location.hash); 733 } 734 } 735 736 function maybePreventBeforeUnload() { 737 if (beforeUnloadChanged) { 738 window.onbeforeunload = null; 739 } 740 } 741 742 /* Attach the event to all clicks in the document after page has loaded */ 743 var __gtagTrackerWindow = window; 744 if (__gtagTrackerWindow.addEventListener) { 745 __gtagTrackerWindow.addEventListener( 746 "load", 747 function () { 748 document.body.addEventListener( 749 "click", 750 __gtagTrackerClickEvent, 751 false 752 ); 753 }, 754 false 755 ); 756 window.addEventListener("hashchange", __gtagTrackerHashChangeEvent, false); 757 } else { 758 if (__gtagTrackerWindow.attachEvent) { 759 __gtagTrackerWindow.attachEvent( 760 "onload", 761 function () { 762 document.body.attachEvent("onclick", __gtagTrackerClickEvent); 763 } 764 ); 765 window.attachEvent("onhashchange", __gtagTrackerHashChangeEvent); 766 } 767 } 768 769 if (typeof String.prototype.endsWith !== 'function') { 770 String.prototype.endsWith = function (suffix) { 771 return this.indexOf(suffix, this.length - suffix.length) !== -1; 772 }; 773 } 774 if (typeof String.prototype.startsWith !== 'function') { 775 String.prototype.startsWith = function (prefix) { 776 return this.indexOf(prefix) === 0; 777 }; 778 } 779 780 if (typeof Array.prototype.lastIndexOf !== 'function') { 781 Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) { 782 'use strict'; 783 784 if (this === void 0 || this === null) { 785 throw new TypeError(); 786 } 787 788 var n, k, 789 t = Object(this), 790 len = t.length >>> 0; /* jshint ignore:line */ 791 if (len === 0) { 792 return -1; 793 } 794 795 n = len - 1; 796 if (arguments.length > 1) { 797 n = Number(arguments[1]); 798 if (n != n) { 799 n = 0; 800 } else if (n != 0 && n != ( 801 1 / 0 802 ) && n != -( 803 1 / 0 804 )) { /* jshint ignore:line */ 805 n = ( 806 n > 0 || -1 807 ) * Math.floor(Math.abs(n)); 808 } 809 } 810 811 for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) { 812 if (k in t && t[k] === searchElement) { 813 return k; 814 } 815 } 816 return -1; 817 }; 818 } 819}; 820var MonsterInsightsObject = new MonsterInsights();
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.