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_domain: valuesArray.el_hostname, 469 link_classes: valuesArray.el_classes, 470 link_id: valuesArray.el_id, 471 }; 472 } else if (type == 'tel') { 473 fieldsArray = { 474 event_category: 'tel', 475 event_label: label || valuesArray.title.replace('tel:', ''), 476 tel_number: link.replace('tel:', ''), 477 link_text: label || valuesArray.title, 478 link_url: link, 479 link_classes: valuesArray.el_classes, 480 link_id: valuesArray.el_id, 481 }; 482 } else if (type == 'mailto') { 483 fieldsArray = { 484 event_category: 'mailto', 485 event_label: label || valuesArray.title.replace('mailto:', ''), 486 email_address: link.replace('mailto:', ''), 487 link_text: label || valuesArray.title.replace('mailto:', ''), 488 link_url: link, 489 link_classes: valuesArray.el_classes, 490 link_id: valuesArray.el_id, 491 }; 492 } else if (type == 'internal-as-outbound') { 493 fieldsArray = { 494 event_category: internalAsOutboundCategory, 495 event_label: label || valuesArray.title, 496 event_name: 'click', 497 is_affiliate_link: true, 498 affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''), 499 link_text: label || valuesArray.title, 500 link_url: link, 501 link_domain: valuesArray.el_hostname, 502 link_classes: valuesArray.el_classes, 503 link_id: valuesArray.el_id, 504 outbound: true, 505 }; 506 } else if (type == 'external') { 507 fieldsArray = { 508 event_category: 'outbound-link', 509 event_label: label || valuesArray.title, 510 is_affiliate_link: false, 511 link_text: label || valuesArray.title, 512 link_url: link, 513 link_domain: valuesArray.el_hostname, 514 link_classes: valuesArray.el_classes, 515 link_id: valuesArray.el_id, 516 outbound: true, 517 }; 518 } else if (type == 'cross-hostname') { 519 fieldsArray = { 520 event_category: 'cross-hostname', 521 event_label: label || valuesArray.title, 522 link_text: label || valuesArray.title, 523 link_url: link, 524 link_domain: valuesArray.el_hostname, 525 link_classes: valuesArray.el_classes, 526 link_id: valuesArray.el_id, 527 }; 528 } 529 530 if (fieldsArray) { 531 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 532 } else { 533 if (type && type != 'internal') { 534 fieldsArray = { 535 event_category: type, 536 event_label: label || valuesArray.title, 537 link_text: label || valuesArray.title, 538 link_url: link, 539 link_domain: valuesArray.el_hostname, 540 link_classes: valuesArray.el_classes, 541 link_id: valuesArray.el_id, 542 }; 543 544 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 545 } else { 546 valuesArray.exit = 'type'; 547 __gtagTrackerNotSend(valuesArray); 548 } 549 } 550 } else { 551 /* Prevent standard click, track then open */ 552 if (type != 'cross-hostname' && type != 'external' && type != 'internal-as-outboun
552d') { 553 if (!event.defaultPrevented) { 554 if (event.preventDefault) { 555 event.preventDefault(); 556 } else { 557 event.returnValue = false; 558 } 559 } 560 } 561 562 if (type == 'download') { 563 fieldsArray = { 564 event_category: 'download', 565 event_label: label || valuesArray.title, 566 event_callback: __gtagTrackerHitBack, 567 file_extension: valuesArray.extension, 568 file_name: valuesArray.link.replace(/^.*\//g, ''), 569 link_text: label || valuesArray.title, 570 link_url: link, 571 link_domain: valuesArray.el_hostname, 572 link_classes: valuesArray.el_classes, 573 link_id: valuesArray.el_id, 574 }; 575 576 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 577 } else if (type == 'internal-as-outbound') { 578 beforeUnloadChanged = true; 579 window.onbeforeunload = function (e) { 580 if (!event.defaultPrevented) { 581 if (event.preventDefault) { 582 event.preventDefault(); 583 } else { 584 event.returnValue = false; 585 } 586 } 587 588 fieldsArray = { 589 event_category: internalAsOutboundCategory, 590 event_label: label || valuesArray.title, 591 event_callback: __gtagTrackerHitBack, 592 is_affiliate_link: true, 593 affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''), 594 link_text: label || valuesArray.title, 595 link_url: link, 596 link_domain: valuesArray.el_hostname, 597 link_classes: valuesArray.el_classes, 598 link_id: valuesArray.el_id, 599 outbound: true, 600 }; 601 602 if (navigator.sendBeacon) { 603 fieldsArray.transport = 'beacon'; 604 } 605 606 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 607 608 setTimeout(__gtagTrackerHitBack, 1000); 609 }; 610 } else if (type == 'external') { 611 beforeUnloadChanged = true; 612 window.onbeforeunload = function (e) { 613 614 fieldsArray = { 615 event_category: 'outbound-link', 616 event_label: label || valuesArray.title, 617 event_callback: __gtagTrackerHitBack, 618 is_affiliate_link: false, 619 link_text: label || valuesArray.title, 620 link_url: link, 621 link_domain: valuesArray.el_hostname, 622 link_classes: valuesArray.el_classes, 623 link_id: valuesArray.el_id, 624 outbound: true, 625 }; 626 627 if (navigator.sendBeacon) { 628 fieldsArray.transport = 'beacon'; 629 } 630 631 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 632 }; 633 } else if (type == 'cross-hostname') { 634 beforeUnloadChanged = true; 635 window.onbeforeunload = function (e) { 636 if (!event.defaultPrevented) { 637 if (event.preventDefault) { 638 event.preventDefault(); 639 } else { 640 event.returnValue = false; 641 } 642 } 643 644 fieldsArray = { 645 event_category: 'cross-hostname', 646 event_label: label || valuesArray.title, 647 event_callback: __gtagTrackerHitBack, 648 link_text: label || valuesArray.title, 649 link_url: link, 650 link_domain: valuesArray.el_hostname, 651 link_classes: valuesArray.el_classes, 652 link_id: valuesArray.el_id, 653 }; 654 655 if (navigator.sendBeacon) { 656 fieldsArray.transport = 'beacon'; 657 } 658 659 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 660 setTimeout(__gtagTrackerHitBack, 1000); 661 }; 662 } else {
663 if (type && type !== 'internal') { 664 fieldsArray = { 665 event_category: type, 666 event_label: label || valuesArray.title, 667 event_callback: __gtagTrackerHitBack, 668 link_text: label || valuesArray.title, 669 link_url: link, 670 link_domain: valuesArray.el_hostname, 671 link_classes: valuesArray.el_classes, 672 link_id: valuesArray.el_id, 673 }; 674 675 __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray); 676 } else { 677 valuesArray.exit = 'type'; 678 __gtagTrackerNotSend(valuesArray); 679 } 680 } 681 682 if (type != 'external' && type != 'cross-hostname' && type != 'internal-as-outbound') { 683 /* Run event_callback again if GA takes longer than 1 second */ 684 setTimeout(__gtagTrackerHitBack, 1000); 685 } else { 686 if (type == 'external') { 687 setTimeout(__gtagTrackerNoRedirectExternal, 1100); 688 } else if (type == 'cross-hostname') { 689 setTimeout(__gtagTrackerNoRedirectCrossHostname, 1100); 690 } else { 691 setTimeout(__gtagTrackerNoRedirectInboundAsExternal, 1100); 692 } 693 } 694 695 // Clear out the beforeunload event if it was set to avoid sending false events. 696 setTimeout(maybePreventBeforeUnload, 100); 697 } 698 } else { 699 maybePreventBeforeUnload(); 700 valuesArray.exit = 'internal'; 701 __gtagTrackerNotSend(valuesArray); 702 } 703 } else { 704 valuesArray.exit = 'notlink'; 705 __gtagTrackerNotSend(valuesArray); 706 } 707 } 708 709 var prevHash = window.location.hash; 710 711 function __gtagTrackerHashChangeEvent() { 712 /* Todo: Ready this section for JS unit testing */ 713 if (monsterinsights_frontend.hash_tracking === "true" && prevHash != window.location.hash && monsterinsights_frontend.v4_id) { 714 prevHash = window.location.hash; 715 716 __gtagTracker('config', monsterinsights_frontend.v4_id, { 717 page_path: location.pathname + location.search + location.hash, 718 }); 719 720 __gtagTrackerLog("Hash change to: " + location.pathname + location.search + location.hash); 721 } else { 722 __gtagTrackerLog("Hash change to (untracked): " + location.pathname + location.search + location.hash); 723 } 724 } 725 726 function maybePreventBeforeUnload() { 727 if (beforeUnloadChanged) { 728 window.onbeforeunload = null; 729 } 730 } 731 732 /* Attach the event to all clicks in the document after page has loaded */ 733 var __gtagTrackerWindow = window; 734 if (__gtagTrackerWindow.addEventListener) { 735 __gtagTrackerWindow.addEventListener( 736 "load", 737 function () { 738 document.body.addEventListener( 739 "click", 740 __gtagTrackerClickEvent, 741 false 742 ); 743 }, 744 false 745 ); 746 window.addEventListener("hashchange", __gtagTrackerHashChangeEvent, false); 747 } else { 748 if (__gtagTrackerWindow.attachEvent) { 749 __gtagTrackerWindow.attachEvent( 750 "onload", 751 function () { 752 document.body.attachEvent("onclick", __gtagTrackerClickEvent); 753 } 754 ); 755 window.attachEvent("onhashchange", __gtagTrackerHashChangeEvent); 756 } 757 } 758 759 if (typeof String.prototype.endsWith !== 'function') { 760 String.prototype.endsWith = function (suffix) { 761 return this.indexOf(suffix, this.length - suffix.length) !== -1; 762 }; 763 } 764 if (typeof String.prototype.startsWith !== 'function') { 765 String.prototype.startsWith = function (prefix) { 766 return this.indexOf(prefix) === 0; 767 }; 768 } 769 770 if (typeof Array.prototype.lastIndexOf !== 'function') { 771 Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) { 772 'use strict'; 773 774 if (this === void 0 || this === null) { 775 throw new TypeError(); 776 } 777 778 var n, k, 779 t = Object(this), 780 len = t.length >>> 0; /* jshint ignore:line */ 781 if (len === 0) { 782 return -1; 783 } 784 785 n = len - 1; 786 if (arguments.length > 1) { 787 n = Number(arguments[1]); 788 if (n != n) { 789 n = 0; 790 } else if (n != 0 && n != ( 791 1 / 0 792 ) && n != -( 793 1 / 0 794 )) { /* jshint ignore:line */ 795 n = ( 796 n > 0 || -1 797 ) * Math.floor(Math.abs(n)); 798 } 799 } 800 801 for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) { 802 if (k in t && t[k] === searchElement) { 803 return k; 804 } 805 } 806 return -1; 807 }; 808 } 809}; 810var 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.