1(function ($) { 2 3Drupal.googleanalytics = {}; 4 5$(document).ready(function() { 6 7 // Attach mousedown, keyup, touchstart events to document only and catch 8 // clicks on all elements. 9 $(document.body).bind("mousedown keyup touchstart", function(event) { 10 11 // Catch the closest surrounding link of a clicked element. 12 $(event.target).closest("a,area").each(function() { 13 14 // Is the clicked URL internal? 15 if (Drupal.googleanalytics.isInternal(this.href)) { 16 // Skip 'click' tracking, if custom tracking events are bound. 17 if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) { 18 // Do nothing here. The custom event will handle all tracking. 19 //console.info("Click on .colorbox item has been detected."); 20 } 21 // Is download tracking activated and the file extension configured for download tracking? 22 else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) { 23 // Download link clicked. 24 gtag('event', Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), { 25 event_category: 'Downloads', 26 event_label: Drupal.googleanalytics.getPageUrl(this.href), 27 transport_type: 'beacon' 28 }); 29 } 30 else if (Drupal.googleanalytics.isInternalSpecial(this.href)) { 31 // Keep the internal URL for Google Analytics website overlay intact. 32 // @todo: May require tracking ID 33 var target = this; 34 $.each(Drupal.settings.googleanalytics.account, function () { 35 gtag('config', this, { 36 page_path: Drupal.googleanalytics.getPageUrl(target.href), 37 transport_type: 'beacon' 38 }); 39 }); 40 } 41 } 42 else { 43 if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) { 44 // Mailto link clicked. 45 gtag('event', 'Click', { 46 event_category: 'Mails', 47 event_label: this.href.substring(7), 48 transport_type: 'beacon' 49 }); 50 } 51 else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) { 52 if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) { 53 // External link clicked / No top-level cross domain clicked. 54 gtag('event', 'Click', { 55 event_category: 'Outbound links', 56 event_label: this.href, 57 transport_type: 'beacon' 58 }); 59 } 60 } 61 } 62 }); 63 }); 64 65 // Track hash changes as unique pageviews, if this option has been enabled. 66 if (Drupal.settings.googleanalytics.trackUrlFragments) { 67 window.onhashchange = function() { 68 $.each(Drupal.settings.googleanalytics.account, function () { 69 gtag('config', this, { 70 page_path: location.pathname + location.search + location.hash 71 }); 72 }); 73 }; 74 } 75 76 // Colorbox: This event triggers when the transition has completed and the 77 // newly loaded content has been revealed. 78 if (Drupal.settings.googleanalytics.trackColorbox) { 79 $(document).bind("cbox_complete", function () { 80 var href = $.colorbox.element().attr("href"); 81 if (href) { 82 $.each(Drupal.settings.googleanalytics.account, function () { 83 gtag('config', this, { 84 page_path: Drupal.googleanalytics.getPageUrl(href) 85 }); 86 }); 87 } 88 }); 89 } 90 91}); 92 93/** 94 * Check whether the hostname is part of the cross domains or not. 95 * 96 * @param string hostname 97 * The hostname of the clicked URL. 98 * @param array crossDomains 99 * All cross domain hostnames as JS array. 100 * 101 * @return boolean 102 */ 103Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) { 104 /** 105 * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is 106 * `null` or `undefined`, https://bugs.jquery.com/ticket/10076, 107 * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174 108 * 109 * @todo: Remove/Refactor in D8 110 */ 111 if (!crossDomains) { 112 return false;
113 } 114 else { 115 return $.inArray(hostname, crossDomains) > -1 ? true : false; 116 } 117}; 118 119/** 120 * Check whether this is a download URL or not. 121 * 122 * @param string url 123 * The web url to check. 124 * 125 * @return boolean 126 */ 127Drupal.googleanalytics.isDownload = function (url) { 128 var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); 129 return isDownload.test(url); 130}; 131 132/** 133 * Check whether this is an absolute internal URL or not. 134 * 135 * @param string url 136 * The web url to check. 137 * 138 * @return boolean 139 */ 140Drupal.googleanalytics.isInternal = function (url) { 141 var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i"); 142 return isInternal.test(url); 143}; 144 145/** 146 * Check whether this is a special URL or not. 147 * 148 * URL types: 149 * - gotwo.module /go/* links. 150 * 151 * @param string url 152 * The web url to check. 153 * 154 * @return boolean 155 */ 156Drupal.googleanalytics.isInternalSpecial = function (url) { 157 var isInternalSpecial = new RegExp("(\/go\/.*)$", "i"); 158 return isInternalSpecial.test(url); 159}; 160 161/** 162 * Extract the relative internal URL from an absolute internal URL. 163 * 164 * Examples: 165 * - https://mydomain.com/node/1 -> /node/1 166 * - https://example.com/foo/bar -> https://example.com/foo/bar 167 * 168 * @param string url 169 * The web url to check. 170 * 171 * @return string 172 * Internal website URL 173 */ 174Drupal.googleanalytics.getPageUrl = function (url) { 175 var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i"); 176 return url.replace(extractInternalUrl, ''); 177}; 178 179/** 180 * Extract the download file extension from the URL. 181 * 182 * @param string url 183 * The web url to check. 184 * 185 * @return string 186 * The file extension of the passed url. e.g. "zip", "txt" 187 */ 188Drupal.googleanalytics.getDownloadExtension = function (url) { 189 var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); 190 var extension = extractDownloadextension.exec(url); 191 return (extension === null) ? '' : extension[1]; 192}; 193 194})(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.