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