Commit d45f7746ac174146dbfc0fc04628dea3369a859a
1 parent
f263889f05
Exists in
master
and in
1 other branch
file add
Showing
2 changed files
with
1308 additions
and
0 deletions
Show diff stats
dist/angular-google-analytics.js
... | ... | @@ -0,0 +1,1299 @@ |
1 | +/** | |
2 | + * Angular Google Analytics - Easy tracking for your AngularJS application | |
3 | + * @version v1.1.8 - 2016-12-30 | |
4 | + * @link http://github.com/revolunet/angular-google-analytics | |
5 | + * @author Julien Bouquillon <julien@revolunet.com> (https://github.com/revolunet) | |
6 | + * @contributors Julien Bouquillon (https://github.com/revolunet),Justin Saunders (https://github.com/justinsa),Chris Esplin (https://github.com/deltaepsilon),Adam Misiorny (https://github.com/adam187) | |
7 | + * @license MIT License, http://www.opensource.org/licenses/MIT | |
8 | + */ | |
9 | +/* globals define */ | |
10 | +(function (root, factory) { | |
11 | + 'use strict'; | |
12 | + if (typeof module !== 'undefined' && module.exports) { | |
13 | + if (typeof angular === 'undefined') { | |
14 | + factory(require('angular')); | |
15 | + } else { | |
16 | + factory(angular); | |
17 | + } | |
18 | + module.exports = 'angular-google-analytics'; | |
19 | + } else if (typeof define === 'function' && define.amd) { | |
20 | + define(['angular'], factory); | |
21 | + } else { | |
22 | + factory(root.angular); | |
23 | + } | |
24 | +}(this, function (angular, undefined) { | |
25 | + 'use strict'; | |
26 | + angular.module('angular-google-analytics', []) | |
27 | + .provider('Analytics', function () { | |
28 | + var accounts, | |
29 | + analyticsJS = true, | |
30 | + cookieConfig = 'auto', // DEPRECATED | |
31 | + created = false, | |
32 | + crossDomainLinker = false, | |
33 | + crossLinkDomains, | |
34 | + currency = 'USD', | |
35 | + debugMode = false, | |
36 | + delayScriptTag = false, | |
37 | + displayFeatures = false, | |
38 | + disableAnalytics = false, | |
39 | + domainName, | |
40 | + ecommerce = false, | |
41 | + enhancedEcommerce = false, | |
42 | + enhancedLinkAttribution = false, | |
43 | + experimentId, | |
44 | + ignoreFirstPageLoad = false, | |
45 | + logAllCalls = false, | |
46 | + hybridMobileSupport = false, | |
47 | + offlineMode = false, | |
48 | + pageEvent = '$routeChangeSuccess', | |
49 | + readFromRoute = false, | |
50 | + removeRegExp, | |
51 | + testMode = false, | |
52 | + traceDebuggingMode = false, | |
53 | + trackPrefix = '', | |
54 | + trackRoutes = true, | |
55 | + trackUrlParams = false; | |
56 | + | |
57 | + this.log = []; | |
58 | + this.offlineQueue = []; | |
59 | + | |
60 | + /** | |
61 | + * Configuration Methods | |
62 | + **/ | |
63 | + | |
64 | + this.setAccount = function (tracker) { | |
65 | + if (angular.isUndefined(tracker) || tracker === false) { | |
66 | + accounts = undefined; | |
67 | + } else if (angular.isArray(tracker)) { | |
68 | + accounts = tracker; | |
69 | + } else if (angular.isObject(tracker)) { | |
70 | + accounts = [tracker]; | |
71 | + } else { | |
72 | + // In order to preserve an existing behavior with how the _trackEvent function works, | |
73 | + // the trackEvent property must be set to true when there is only a single tracker. | |
74 | + accounts = [{ tracker: tracker, trackEvent: true }]; | |
75 | + } | |
76 | + return this; | |
77 | + }; | |
78 | + | |
79 | + this.trackPages = function (val) { | |
80 | + trackRoutes = !!val; | |
81 | + return this; | |
82 | + }; | |
83 | + | |
84 | + this.trackPrefix = function (prefix) { | |
85 | + trackPrefix = prefix; | |
86 | + return this; | |
87 | + }; | |
88 | + | |
89 | + this.setDomainName = function (domain) { | |
90 | + domainName = domain; | |
91 | + return this; | |
92 | + }; | |
93 | + | |
94 | + this.useDisplayFeatures = function (val) { | |
95 | + displayFeatures = !!val; | |
96 | + return this; | |
97 | + }; | |
98 | + | |
99 | + this.useAnalytics = function (val) { | |
100 | + analyticsJS = !!val; | |
101 | + return this; | |
102 | + }; | |
103 | + | |
104 | + this.useEnhancedLinkAttribution = function (val) { | |
105 | + enhancedLinkAttribution = !!val; | |
106 | + return this; | |
107 | + }; | |
108 | + | |
109 | + this.useCrossDomainLinker = function (val) { | |
110 | + crossDomainLinker = !!val; | |
111 | + return this; | |
112 | + }; | |
113 | + | |
114 | + this.setCrossLinkDomains = function (domains) { | |
115 | + crossLinkDomains = domains; | |
116 | + return this; | |
117 | + }; | |
118 | + | |
119 | + this.setPageEvent = function (name) { | |
120 | + pageEvent = name; | |
121 | + return this; | |
122 | + }; | |
123 | + | |
124 | + /* DEPRECATED */ | |
125 | + this.setCookieConfig = function (config) { | |
126 | + cookieConfig = config; | |
127 | + return this; | |
128 | + }; | |
129 | + | |
130 | + this.useECommerce = function (val, enhanced) { | |
131 | + ecommerce = !!val; | |
132 | + enhancedEcommerce = !!enhanced; | |
133 | + return this; | |
134 | + }; | |
135 | + | |
136 | + this.setCurrency = function (currencyCode) { | |
137 | + currency = currencyCode; | |
138 | + return this; | |
139 | + }; | |
140 | + | |
141 | + this.setRemoveRegExp = function (regex) { | |
142 | + if (regex instanceof RegExp) { | |
143 | + removeRegExp = regex; | |
144 | + } | |
145 | + return this; | |
146 | + }; | |
147 | + | |
148 | + this.setExperimentId = function (id) { | |
149 | + experimentId = id; | |
150 | + return this; | |
151 | + }; | |
152 | + | |
153 | + this.ignoreFirstPageLoad = function (val) { | |
154 | + ignoreFirstPageLoad = !!val; | |
155 | + return this; | |
156 | + }; | |
157 | + | |
158 | + this.trackUrlParams = function (val) { | |
159 | + trackUrlParams = !!val; | |
160 | + return this; | |
161 | + }; | |
162 | + | |
163 | + this.disableAnalytics = function (val) { | |
164 | + disableAnalytics = !!val; | |
165 | + return this; | |
166 | + }; | |
167 | + | |
168 | + this.setHybridMobileSupport = function (val) { | |
169 | + hybridMobileSupport = !!val; | |
170 | + return this; | |
171 | + }; | |
172 | + | |
173 | + this.startOffline = function (val) { | |
174 | + offlineMode = !!val; | |
175 | + if (offlineMode === true) { | |
176 | + this.delayScriptTag(true); | |
177 | + } | |
178 | + return this; | |
179 | + }; | |
180 | + | |
181 | + this.delayScriptTag = function (val) { | |
182 | + delayScriptTag = !!val; | |
183 | + return this; | |
184 | + }; | |
185 | + | |
186 | + this.logAllCalls = function (val) { | |
187 | + logAllCalls = !!val; | |
188 | + return this; | |
189 | + }; | |
190 | + | |
191 | + this.enterTestMode = function () { | |
192 | + testMode = true; | |
193 | + return this; | |
194 | + }; | |
195 | + | |
196 | + this.enterDebugMode = function (enableTraceDebugging) { | |
197 | + debugMode = true; | |
198 | + traceDebuggingMode = !!enableTraceDebugging; | |
199 | + return this; | |
200 | + }; | |
201 | + | |
202 | + // Enable reading page url from route object | |
203 | + this.readFromRoute = function(val) { | |
204 | + readFromRoute = !!val; | |
205 | + return this; | |
206 | + }; | |
207 | + | |
208 | + /** | |
209 | + * Public Service | |
210 | + */ | |
211 | + this.$get = ['$document', // To read page title | |
212 | + '$location', // | |
213 | + '$log', // | |
214 | + '$rootScope',// | |
215 | + '$window', // | |
216 | + '$injector', // To access ngRoute module without declaring a fixed dependency | |
217 | + function ($document, $location, $log, $rootScope, $window, $injector) { | |
218 | + var that = this; | |
219 | + | |
220 | + /** | |
221 | + * Side-effect Free Helper Methods | |
222 | + **/ | |
223 | + | |
224 | + var isPropertyDefined = function (key, config) { | |
225 | + return angular.isObject(config) && angular.isDefined(config[key]); | |
226 | + }; | |
227 | + | |
228 | + var isPropertySetTo = function (key, config, value) { | |
229 | + return isPropertyDefined(key, config) && config[key] === value; | |
230 | + }; | |
231 | + | |
232 | + var generateCommandName = function (commandName, config) { | |
233 | + if (angular.isString(config)) { | |
234 | + return config + '.' + commandName; | |
235 | + } | |
236 | + return isPropertyDefined('name', config) ? (config.name + '.' + commandName) : commandName; | |
237 | + }; | |
238 | + | |
239 | + // Try to read route configuration and log warning if not possible | |
240 | + var $route = {}; | |
241 | + if (readFromRoute) { | |
242 | + if (!$injector.has('$route')) { | |
243 | + $log.warn('$route service is not available. Make sure you have included ng-route in your application dependencies.'); | |
244 | + } else { | |
245 | + $route = $injector.get('$route'); | |
246 | + } | |
247 | + } | |
248 | + | |
249 | + // Get url for current page | |
250 | + var getUrl = function () { | |
251 | + // Using ngRoute provided tracking urls | |
252 | + if (readFromRoute && $route.current && ('pageTrack' in $route.current)) { | |
253 | + return $route.current.pageTrack; | |
254 | + } | |
255 | + | |
256 | + // Otherwise go the old way | |
257 | + var url = trackUrlParams ? $location.url() : $location.path(); | |
258 | + return removeRegExp ? url.replace(removeRegExp, '') : url; | |
259 | + }; | |
260 | + | |
261 | + var getUtmParams = function () { | |
262 | + var utmToCampaignVar = { | |
263 | + utm_source: 'campaignSource', | |
264 | + utm_medium: 'campaignMedium', | |
265 | + utm_term: 'campaignTerm', | |
266 | + utm_content: 'campaignContent', | |
267 | + utm_campaign: 'campaignName' | |
268 | + }; | |
269 | + var object = {}; | |
270 | + | |
271 | + angular.forEach($location.search(), function (value, key) { | |
272 | + var campaignVar = utmToCampaignVar[key]; | |
273 | + | |
274 | + if (angular.isDefined(campaignVar)) { | |
275 | + object[campaignVar] = value; | |
276 | + } | |
277 | + }); | |
278 | + | |
279 | + return object; | |
280 | + }; | |
281 | + | |
282 | + /** | |
283 | + * get ActionFieldObject | |
284 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data | |
285 | + * @param id | |
286 | + * @param affliation | |
287 | + * @param revenue | |
288 | + * @param tax | |
289 | + * @param shipping | |
290 | + * @param coupon | |
291 | + * @param list | |
292 | + * @param step | |
293 | + * @param option | |
294 | + */ | |
295 | + var getActionFieldObject = function (id, affiliation, revenue, tax, shipping, coupon, list, step, option) { | |
296 | + var obj = {}; | |
297 | + if (id) { obj.id = id; } | |
298 | + if (affiliation) { obj.affiliation = affiliation; } | |
299 | + if (revenue) { obj.revenue = revenue; } | |
300 | + if (tax) { obj.tax = tax; } | |
301 | + if (shipping) { obj.shipping = shipping; } | |
302 | + if (coupon) { obj.coupon = coupon; } | |
303 | + if (list) { obj.list = list; } | |
304 | + if (step) { obj.step = step; } | |
305 | + if (option) { obj.option = option; } | |
306 | + return obj; | |
307 | + }; | |
308 | + | |
309 | + /** | |
310 | + * Private Methods | |
311 | + */ | |
312 | + | |
313 | + var _getProtocol = function (httpPostfix, httpsPostfix) { | |
314 | + var protocol = '', | |
315 | + isSslEnabled = document.location.protocol === 'https:', | |
316 | + isChromeExtension = document.location.protocol === 'chrome-extension:', | |
317 | + isHybridApplication = analyticsJS === true && hybridMobileSupport === true; | |
318 | + httpPostfix = angular.isString(httpPostfix) ? httpPostfix : ''; | |
319 | + httpsPostfix = angular.isString(httpsPostfix) ? httpsPostfix : ''; | |
320 | + if (httpPostfix !== '') { | |
321 | + protocol = 'http:' + httpPostfix; | |
322 | + } | |
323 | + if (isChromeExtension || isHybridApplication || (isSslEnabled && httpsPostfix !== '')) { | |
324 | + protocol = 'https:' + httpsPostfix; | |
325 | + } | |
326 | + return protocol; | |
327 | + }; | |
328 | + | |
329 | + var _gaJs = function (fn) { | |
330 | + if (!analyticsJS && $window._gaq && typeof fn === 'function') { | |
331 | + fn(); | |
332 | + } | |
333 | + }; | |
334 | + | |
335 | + var _gaq = function () { | |
336 | + var args = Array.prototype.slice.call(arguments); | |
337 | + if (offlineMode === true) { | |
338 | + that.offlineQueue.push([_gaq, args]); | |
339 | + return; | |
340 | + } | |
341 | + if (!$window._gaq) { | |
342 | + $window._gaq = []; | |
343 | + } | |
344 | + if (logAllCalls === true) { | |
345 | + that._log.apply(that, args); | |
346 | + } | |
347 | + $window._gaq.push(args); | |
348 | + }; | |
349 | + | |
350 | + var _analyticsJs = function (fn) { | |
351 | + if (analyticsJS && $window.ga && typeof fn === 'function') { | |
352 | + fn(); | |
353 | + } | |
354 | + }; | |
355 | + | |
356 | + var _ga = function () { | |
357 | + var args = Array.prototype.slice.call(arguments); | |
358 | + if (offlineMode === true) { | |
359 | + that.offlineQueue.push([_ga, args]); | |
360 | + return; | |
361 | + } | |
362 | + if (typeof $window.ga !== 'function') { | |
363 | + that._log('warn', 'ga function not set on window'); | |
364 | + return; | |
365 | + } | |
366 | + if (logAllCalls === true) { | |
367 | + that._log.apply(that, args); | |
368 | + } | |
369 | + $window.ga.apply(null, args); | |
370 | + }; | |
371 | + | |
372 | + var _gaMultipleTrackers = function (includeFn) { | |
373 | + // Drop the includeFn from the arguments and preserve the original command name | |
374 | + var args = Array.prototype.slice.call(arguments, 1), | |
375 | + commandName = args[0], | |
376 | + trackers = []; | |
377 | + if (typeof includeFn === 'function') { | |
378 | + accounts.forEach(function (account) { | |
379 | + if (includeFn(account)) { | |
380 | + trackers.push(account); | |
381 | + } | |
382 | + }); | |
383 | + } else { | |
384 | + // No include function indicates that all accounts are to be used | |
385 | + trackers = accounts; | |
386 | + } | |
387 | + | |
388 | + // To preserve backwards compatibility fallback to _ga method if no account | |
389 | + // matches the specified includeFn. This preserves existing behaviors by | |
390 | + // performing the single tracker operation. | |
391 | + if (trackers.length === 0) { | |
392 | + _ga.apply(that, args); | |
393 | + return; | |
394 | + } | |
395 | + | |
396 | + trackers.forEach(function (tracker) { | |
397 | + // Check tracker 'select' function, if it exists, for whether the tracker should be used with the current command. | |
398 | + // If the 'select' function returns false then the tracker will not be used with the current command. | |
399 | + if (isPropertyDefined('select', tracker) && typeof tracker.select === 'function' && !tracker.select(args)) { | |
400 | + return; | |
401 | + } | |
402 | + args[0] = generateCommandName(commandName, tracker); | |
403 | + _ga.apply(that, args); | |
404 | + }); | |
405 | + }; | |
406 | + | |
407 | + this._log = function () { | |
408 | + var args = Array.prototype.slice.call(arguments); | |
409 | + if (args.length > 0) { | |
410 | + if (args.length > 1) { | |
411 | + switch (args[0]) { | |
412 | + case 'debug': | |
413 | + case 'error': | |
414 | + case 'info': | |
415 | + case 'log': | |
416 | + case 'warn': | |
417 | + $log[args[0]](args.slice(1)); | |
418 | + break; | |
419 | + } | |
420 | + } | |
421 | + that.log.push(args); | |
422 | + } | |
423 | + }; | |
424 | + | |
425 | + /* DEPRECATED */ | |
426 | + this._createScriptTag = function () { | |
427 | + that._registerScriptTags(); | |
428 | + that._registerTrackers(); | |
429 | + }; | |
430 | + | |
431 | + /* DEPRECATED */ | |
432 | + this._createAnalyticsScriptTag = function () { | |
433 | + that._registerScriptTags(); | |
434 | + that._registerTrackers(); | |
435 | + }; | |
436 | + | |
437 | + this._registerScriptTags = function () { | |
438 | + var document = $document[0], | |
439 | + protocol = _getProtocol(), | |
440 | + scriptSource; | |
441 | + | |
442 | + if (created === true) { | |
443 | + that._log('warn', 'Script tags already created'); | |
444 | + return; | |
445 | + } | |
446 | + | |
447 | + if (disableAnalytics === true) { | |
448 | + accounts.forEach(function (trackerObj) { | |
449 | + that._log('info', 'Analytics disabled: ' + trackerObj.tracker); | |
450 | + $window['ga-disable-' + trackerObj.tracker] = true; | |
451 | + }); | |
452 | + } | |
453 | + | |
454 | + // | |
455 | + // Universal Analytics | |
456 | + // | |
457 | + if (analyticsJS === true) { | |
458 | + scriptSource = protocol + '//www.google-analytics.com/' + (debugMode ? 'analytics_debug.js' : 'analytics.js'); | |
459 | + if (testMode !== true) { | |
460 | + // If not in test mode inject the Google Analytics tag | |
461 | + (function (i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function (){ | |
462 | + (i[r].q=i[r].q||[]).push(arguments);},i[r].l=1*new Date();a=s.createElement(o), | |
463 | + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m); | |
464 | + })(window,document,'script',scriptSource,'ga'); | |
465 | + } else { | |
466 | + if (typeof $window.ga !== 'function') { | |
467 | + // In test mode create a ga function if none exists that is a noop sink. | |
468 | + $window.ga = function () {}; | |
469 | + } | |
470 | + // Log script injection. | |
471 | + that._log('inject', scriptSource); | |
472 | + } | |
473 | + | |
474 | + if (traceDebuggingMode) { | |
475 | + $window.ga_debug = { trace: true }; | |
476 | + } | |
477 | + | |
478 | + if (experimentId) { | |
479 | + var expScript = document.createElement('script'), | |
480 | + s = document.getElementsByTagName('script')[0]; | |
481 | + expScript.src = protocol + '//www.google-analytics.com/cx/api.js?experiment=' + experimentId; | |
482 | + s.parentNode.insertBefore(expScript, s); | |
483 | + } | |
484 | + // | |
485 | + // Classic Analytics | |
486 | + // | |
487 | + } else { | |
488 | + scriptSource = _getProtocol('//www', '//ssl') + '.google-analytics.com/ga.js'; | |
489 | + if (displayFeatures === true) { | |
490 | + scriptSource = protocol + '//stats.g.doubleclick.net/dc.js'; | |
491 | + } | |
492 | + | |
493 | + if (testMode !== true) { | |
494 | + // If not in test mode inject the Google Analytics tag | |
495 | + (function () { | |
496 | + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |
497 | + ga.src = scriptSource; | |
498 | + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |
499 | + })(); | |
500 | + } else { | |
501 | + // Log the source location for validation | |
502 | + that._log('inject', scriptSource); | |
503 | + } | |
504 | + } | |
505 | + | |
506 | + created = true; | |
507 | + return true; | |
508 | + }; | |
509 | + | |
510 | + this._registerTrackers = function () { | |
511 | + if (!accounts || accounts.length < 1) { | |
512 | + that._log('warn', 'No accounts to register'); | |
513 | + return; | |
514 | + } | |
515 | + | |
516 | + // | |
517 | + // Universal Analytics | |
518 | + // | |
519 | + if (analyticsJS === true) { | |
520 | + accounts.forEach(function (trackerObj) { | |
521 | + trackerObj.crossDomainLinker = isPropertyDefined('crossDomainLinker', trackerObj) ? trackerObj.crossDomainLinker : crossDomainLinker; | |
522 | + trackerObj.crossLinkDomains = isPropertyDefined('crossLinkDomains', trackerObj) ? trackerObj.crossLinkDomains : crossLinkDomains; | |
523 | + trackerObj.displayFeatures = isPropertyDefined('displayFeatures', trackerObj) ? trackerObj.displayFeatures : displayFeatures; | |
524 | + trackerObj.enhancedLinkAttribution = isPropertyDefined('enhancedLinkAttribution', trackerObj) ? trackerObj.enhancedLinkAttribution : enhancedLinkAttribution; | |
525 | + trackerObj.set = isPropertyDefined('set', trackerObj) ? trackerObj.set : {}; | |
526 | + trackerObj.trackEcommerce = isPropertyDefined('trackEcommerce', trackerObj) ? trackerObj.trackEcommerce : ecommerce; | |
527 | + trackerObj.trackEvent = isPropertyDefined('trackEvent', trackerObj) ? trackerObj.trackEvent : false; | |
528 | + | |
529 | + // Logic to choose the account fields to be used. | |
530 | + // cookieConfig is being deprecated for a tracker specific property: fields. | |
531 | + var fields = {}; | |
532 | + if (isPropertyDefined('fields', trackerObj)) { | |
533 | + fields = trackerObj.fields; | |
534 | + } else if (isPropertyDefined('cookieConfig', trackerObj)) { | |
535 | + if (angular.isString(trackerObj.cookieConfig)) { | |
536 | + fields.cookieDomain = trackerObj.cookieConfig; | |
537 | + } else { | |
538 | + fields = trackerObj.cookieConfig; | |
539 | + } | |
540 | + } else if (angular.isString(cookieConfig)) { | |
541 | + fields.cookieDomain = cookieConfig; | |
542 | + } else if (cookieConfig) { | |
543 | + fields = cookieConfig; | |
544 | + } | |
545 | + if (trackerObj.crossDomainLinker === true) { | |
546 | + fields.allowLinker = true; | |
547 | + } | |
548 | + if (isPropertyDefined('name', trackerObj)) { | |
549 | + fields.name = trackerObj.name; | |
550 | + } | |
551 | + trackerObj.fields = fields; | |
552 | + | |
553 | + _ga('create', trackerObj.tracker, trackerObj.fields); | |
554 | + | |
555 | + // Hybrid mobile application support | |
556 | + // https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks | |
557 | + if (hybridMobileSupport === true) { | |
558 | + _ga(generateCommandName('set', trackerObj), 'checkProtocolTask', null); | |
559 | + } | |
560 | + | |
561 | + // Send all custom set commands from the trackerObj.set property | |
562 | + for (var key in trackerObj.set) { | |
563 | + if (trackerObj.set.hasOwnProperty(key)) { | |
564 | + _ga(generateCommandName('set', trackerObj), key, trackerObj.set[key]); | |
565 | + } | |
566 | + } | |
567 | + | |
568 | + if (trackerObj.crossDomainLinker === true) { | |
569 | + _ga(generateCommandName('require', trackerObj), 'linker'); | |
570 | + if (angular.isDefined(trackerObj.crossLinkDomains)) { | |
571 | + _ga(generateCommandName('linker:autoLink', trackerObj), trackerObj.crossLinkDomains); | |
572 | + } | |
573 | + } | |
574 | + | |
575 | + if (trackerObj.displayFeatures) { | |
576 | + _ga(generateCommandName('require', trackerObj), 'displayfeatures'); | |
577 | + } | |
578 | + | |
579 | + if (trackerObj.trackEcommerce) { | |
580 | + if (!enhancedEcommerce) { | |
581 | + _ga(generateCommandName('require', trackerObj), 'ecommerce'); | |
582 | + } else { | |
583 | + _ga(generateCommandName('require', trackerObj), 'ec'); | |
584 | + _ga(generateCommandName('set', trackerObj), '&cu', currency); | |
585 | + } | |
586 | + } | |
587 | + | |
588 | + if (trackerObj.enhancedLinkAttribution) { | |
589 | + _ga(generateCommandName('require', trackerObj), 'linkid'); | |
590 | + } | |
591 | + | |
592 | + if (trackRoutes && !ignoreFirstPageLoad) { | |
593 | + _ga(generateCommandName('send', trackerObj), 'pageview', trackPrefix + getUrl()); | |
594 | + } | |
595 | + }); | |
596 | + // | |
597 | + // Classic Analytics | |
598 | + // | |
599 | + } else { | |
600 | + if (accounts.length > 1) { | |
601 | + that._log('warn', 'Multiple trackers are not supported with ga.js. Using first tracker only'); | |
602 | + accounts = accounts.slice(0, 1); | |
603 | + } | |
604 | + | |
605 | + _gaq('_setAccount', accounts[0].tracker); | |
606 | + if(domainName) { | |
607 | + _gaq('_setDomainName', domainName); | |
608 | + } | |
609 | + if (enhancedLinkAttribution) { | |
610 | + _gaq('_require', 'inpage_linkid', '//www.google-analytics.com/plugins/ga/inpage_linkid.js'); | |
611 | + } | |
612 | + if (trackRoutes && !ignoreFirstPageLoad) { | |
613 | + if (removeRegExp) { | |
614 | + _gaq('_trackPageview', getUrl()); | |
615 | + } else { | |
616 | + _gaq('_trackPageview'); | |
617 | + } | |
618 | + } | |
619 | + } | |
620 | + | |
621 | + return true; | |
622 | + }; | |
623 | + | |
624 | + this._ecommerceEnabled = function (warn, command) { | |
625 | + var result = ecommerce && !enhancedEcommerce; | |
626 | + if (warn === true && result === false) { | |
627 | + if (ecommerce && enhancedEcommerce) { | |
628 | + that._log('warn', command + ' is not available when Enhanced Ecommerce is enabled with analytics.js'); | |
629 | + } else { | |
630 | + that._log('warn', 'Ecommerce must be enabled to use ' + command + ' with analytics.js'); | |
631 | + } | |
632 | + } | |
633 | + return result; | |
634 | + }; | |
635 | + | |
636 | + this._enhancedEcommerceEnabled = function (warn, command) { | |
637 | + var result = ecommerce && enhancedEcommerce; | |
638 | + if (warn === true && result === false) { | |
639 | + that._log('warn', 'Enhanced Ecommerce must be enabled to use ' + command + ' with analytics.js'); | |
640 | + } | |
641 | + return result; | |
642 | + }; | |
643 | + | |
644 | + /** | |
645 | + * Track page | |
646 | + https://developers.google.com/analytics/devguides/collection/gajs/ | |
647 | + https://developers.google.com/analytics/devguides/collection/analyticsjs/pages | |
648 | + * @param url | |
649 | + * @param title | |
650 | + * @param custom | |
651 | + * @private | |
652 | + */ | |
653 | + this._trackPage = function (url, title, custom) { | |
654 | + url = url ? url : getUrl(); | |
655 | + title = title ? title : $document[0].title; | |
656 | + _gaJs(function () { | |
657 | + // http://stackoverflow.com/questions/7322288/how-can-i-set-a-page-title-with-google-analytics | |
658 | + _gaq('_set', 'title', title); | |
659 | + _gaq('_trackPageview', (trackPrefix + url)); | |
660 | + }); | |
661 | + _analyticsJs(function () { | |
662 | + var opt_fieldObject = { | |
663 | + 'page': trackPrefix + url, | |
664 | + 'title': title | |
665 | + }; | |
666 | + angular.extend(opt_fieldObject, getUtmParams()); | |
667 | + if (angular.isObject(custom)) { | |
668 | + angular.extend(opt_fieldObject, custom); | |
669 | + } | |
670 | + _gaMultipleTrackers(undefined, 'send', 'pageview', opt_fieldObject); | |
671 | + }); | |
672 | + }; | |
673 | + | |
674 | + /** | |
675 | + * Track event | |
676 | + https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide | |
677 | + https://developers.google.com/analytics/devguides/collection/analyticsjs/events | |
678 | + * @param category | |
679 | + * @param action | |
680 | + * @param label | |
681 | + * @param value | |
682 | + * @param noninteraction | |
683 | + * @param custom | |
684 | + * @private | |
685 | + */ | |
686 | + this._trackEvent = function (category, action, label, value, noninteraction, custom) { | |
687 | + _gaJs(function () { | |
688 | + _gaq('_trackEvent', category, action, label, value, !!noninteraction); | |
689 | + }); | |
690 | + _analyticsJs(function () { | |
691 | + var opt_fieldObject = {}; | |
692 | + var includeFn = function (trackerObj) { | |
693 | + return isPropertySetTo('trackEvent', trackerObj, true); | |
694 | + }; | |
695 | + | |
696 | + if (angular.isDefined(noninteraction)) { | |
697 | + opt_fieldObject.nonInteraction = !!noninteraction; | |
698 | + } | |
699 | + if (angular.isObject(custom)) { | |
700 | + angular.extend(opt_fieldObject, custom); | |
701 | + } | |
702 | + if (!angular.isDefined(opt_fieldObject.page)) { | |
703 | + opt_fieldObject.page = getUrl(); | |
704 | + } | |
705 | + _gaMultipleTrackers(includeFn, 'send', 'event', category, action, label, value, opt_fieldObject); | |
706 | + }); | |
707 | + }; | |
708 | + | |
709 | + /** | |
710 | + * Add transaction | |
711 | + * https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiEcommerce#_gat.GA_Tracker_._addTrans | |
712 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#addTrans | |
713 | + * @param transactionId | |
714 | + * @param affiliation | |
715 | + * @param total | |
716 | + * @param tax | |
717 | + * @param shipping | |
718 | + * @param city | |
719 | + * @param state | |
720 | + * @param country | |
721 | + * @private | |
722 | + */ | |
723 | + this._addTrans = function (transactionId, affiliation, total, tax, shipping, city, state, country, currency) { | |
724 | + _gaJs(function () { | |
725 | + _gaq('_addTrans', transactionId, affiliation, total, tax, shipping, city, state, country); | |
726 | + }); | |
727 | + _analyticsJs(function () { | |
728 | + if (that._ecommerceEnabled(true, 'addTrans')) { | |
729 | + var includeFn = function (trackerObj) { | |
730 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
731 | + }; | |
732 | + | |
733 | + _gaMultipleTrackers( | |
734 | + includeFn, | |
735 | + 'ecommerce:addTransaction', | |
736 | + { | |
737 | + id: transactionId, | |
738 | + affiliation: affiliation, | |
739 | + revenue: total, | |
740 | + tax: tax, | |
741 | + shipping: shipping, | |
742 | + currency: currency || 'USD' | |
743 | + }); | |
744 | + } | |
745 | + }); | |
746 | + }; | |
747 | + | |
748 | + /** | |
749 | + * Add item to transaction | |
750 | + * https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiEcommerce#_gat.GA_Tracker_._addItem | |
751 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#addItem | |
752 | + * @param transactionId | |
753 | + * @param sku | |
754 | + * @param name | |
755 | + * @param category | |
756 | + * @param price | |
757 | + * @param quantity | |
758 | + * @private | |
759 | + */ | |
760 | + this._addItem = function (transactionId, sku, name, category, price, quantity) { | |
761 | + _gaJs(function () { | |
762 | + _gaq('_addItem', transactionId, sku, name, category, price, quantity); | |
763 | + }); | |
764 | + _analyticsJs(function () { | |
765 | + if (that._ecommerceEnabled(true, 'addItem')) { | |
766 | + var includeFn = function (trackerObj) { | |
767 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
768 | + }; | |
769 | + | |
770 | + _gaMultipleTrackers( | |
771 | + includeFn, | |
772 | + 'ecommerce:addItem', | |
773 | + { | |
774 | + id: transactionId, | |
775 | + name: name, | |
776 | + sku: sku, | |
777 | + category: category, | |
778 | + price: price, | |
779 | + quantity: quantity | |
780 | + }); | |
781 | + } | |
782 | + }); | |
783 | + }; | |
784 | + | |
785 | + /** | |
786 | + * Track transaction | |
787 | + * https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiEcommerce#_gat.GA_Tracker_._trackTrans | |
788 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#sendingData | |
789 | + * @private | |
790 | + */ | |
791 | + this._trackTrans = function () { | |
792 | + _gaJs(function () { | |
793 | + _gaq('_trackTrans'); | |
794 | + }); | |
795 | + _analyticsJs(function () { | |
796 | + if (that._ecommerceEnabled(true, 'trackTrans')) { | |
797 | + var includeFn = function (trackerObj) { | |
798 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
799 | + }; | |
800 | + | |
801 | + _gaMultipleTrackers(includeFn, 'ecommerce:send'); | |
802 | + } | |
803 | + }); | |
804 | + }; | |
805 | + | |
806 | + /** | |
807 | + * Clear transaction | |
808 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce#clearingData | |
809 | + * @private | |
810 | + */ | |
811 | + this._clearTrans = function () { | |
812 | + _analyticsJs(function () { | |
813 | + if (that._ecommerceEnabled(true, 'clearTrans')) { | |
814 | + var includeFn = function (trackerObj) { | |
815 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
816 | + }; | |
817 | + | |
818 | + _gaMultipleTrackers(includeFn, 'ecommerce:clear'); | |
819 | + } | |
820 | + }); | |
821 | + }; | |
822 | + | |
823 | + /** | |
824 | + * Enhanced Ecommerce | |
825 | + */ | |
826 | + | |
827 | + /** | |
828 | + * Add Product | |
829 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-data | |
830 | + * @param productId | |
831 | + * @param name | |
832 | + * @param category | |
833 | + * @param brand | |
834 | + * @param variant | |
835 | + * @param price | |
836 | + * @param quantity | |
837 | + * @param coupon | |
838 | + * @param position | |
839 | + * @param custom | |
840 | + * @private | |
841 | + */ | |
842 | + this._addProduct = function (productId, name, category, brand, variant, price, quantity, coupon, position, custom) { | |
843 | + _gaJs(function () { | |
844 | + _gaq('_addProduct', productId, name, category, brand, variant, price, quantity, coupon, position); | |
845 | + }); | |
846 | + _analyticsJs(function () { | |
847 | + if (that._enhancedEcommerceEnabled(true, 'addProduct')) { | |
848 | + var includeFn = function (trackerObj) { | |
849 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
850 | + }; | |
851 | + var details = { | |
852 | + id: productId, | |
853 | + name: name, | |
854 | + category: category, | |
855 | + brand: brand, | |
856 | + variant: variant, | |
857 | + price: price, | |
858 | + quantity: quantity, | |
859 | + coupon: coupon, | |
860 | + position: position | |
861 | + }; | |
862 | + if (angular.isObject(custom)) { | |
863 | + angular.extend(details, custom); | |
864 | + } | |
865 | + _gaMultipleTrackers(includeFn, 'ec:addProduct', details); | |
866 | + } | |
867 | + }); | |
868 | + }; | |
869 | + | |
870 | + /** | |
871 | + * Add Impression | |
872 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#impression-data | |
873 | + * @param id | |
874 | + * @param name | |
875 | + * @param list | |
876 | + * @param brand | |
877 | + * @param category | |
878 | + * @param variant | |
879 | + * @param position | |
880 | + * @param price | |
881 | + * @private | |
882 | + */ | |
883 | + this._addImpression = function (id, name, list, brand, category, variant, position, price){ | |
884 | + _gaJs(function () { | |
885 | + _gaq('_addImpression', id, name, list, brand, category, variant, position, price); | |
886 | + }); | |
887 | + _analyticsJs(function () { | |
888 | + if (that._enhancedEcommerceEnabled(true, 'addImpression')) { | |
889 | + var includeFn = function (trackerObj) { | |
890 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
891 | + }; | |
892 | + | |
893 | + _gaMultipleTrackers( | |
894 | + includeFn, | |
895 | + 'ec:addImpression', | |
896 | + { | |
897 | + id: id, | |
898 | + name: name, | |
899 | + category: category, | |
900 | + brand: brand, | |
901 | + variant: variant, | |
902 | + list: list, | |
903 | + position: position, | |
904 | + price: price | |
905 | + }); | |
906 | + } | |
907 | + }); | |
908 | + }; | |
909 | + | |
910 | + /** | |
911 | + * Add Promo | |
912 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce | |
913 | + * @param productId | |
914 | + * @param name | |
915 | + * @param creative | |
916 | + * @param position | |
917 | + * @private | |
918 | + */ | |
919 | + this._addPromo = function (productId, name, creative, position) { | |
920 | + _gaJs(function () { | |
921 | + _gaq('_addPromo', productId, name, creative, position); | |
922 | + }); | |
923 | + _analyticsJs(function () { | |
924 | + if (that._enhancedEcommerceEnabled(true, 'addPromo')) { | |
925 | + var includeFn = function (trackerObj) { | |
926 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
927 | + }; | |
928 | + | |
929 | + _gaMultipleTrackers( | |
930 | + includeFn, | |
931 | + 'ec:addPromo', | |
932 | + { | |
933 | + id: productId, | |
934 | + name: name, | |
935 | + creative: creative, | |
936 | + position: position | |
937 | + }); | |
938 | + } | |
939 | + }); | |
940 | + }; | |
941 | + | |
942 | + /** | |
943 | + * Set Action | |
944 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-actions | |
945 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-types | |
946 | + * @param action | |
947 | + * @param obj | |
948 | + * @private | |
949 | + */ | |
950 | + this._setAction = function (action, obj){ | |
951 | + _gaJs(function () { | |
952 | + _gaq('_setAction', action, obj); | |
953 | + }); | |
954 | + _analyticsJs(function () { | |
955 | + if (that._enhancedEcommerceEnabled(true, 'setAction')) { | |
956 | + var includeFn = function (trackerObj) { | |
957 | + return isPropertySetTo('trackEcommerce', trackerObj, true); | |
958 | + }; | |
959 | + | |
960 | + _gaMultipleTrackers(includeFn, 'ec:setAction', action, obj); | |
961 | + } | |
962 | + }); | |
963 | + }; | |
964 | + | |
965 | + /** | |
966 | + * Track Transaction | |
967 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-transactions | |
968 | + * @param transactionId | |
969 | + * @param affiliation | |
970 | + * @param revenue | |
971 | + * @param tax | |
972 | + * @param shipping | |
973 | + * @param coupon | |
974 | + * @param list | |
975 | + * @param step | |
976 | + * @param option | |
977 | + * @private | |
978 | + */ | |
979 | + this._trackTransaction = function (transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option) { | |
980 | + this._setAction('purchase', getActionFieldObject(transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option)); | |
981 | + }; | |
982 | + | |
983 | + /** | |
984 | + * Track Refund | |
985 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-refunds | |
986 | + * @param transactionId | |
987 | + * @private | |
988 | + */ | |
989 | + this._trackRefund = function (transactionId) { | |
990 | + this._setAction('refund', getActionFieldObject(transactionId)); | |
991 | + }; | |
992 | + | |
993 | + /** | |
994 | + * Track Checkout | |
995 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-checkout | |
996 | + * @param step | |
997 | + * @param option | |
998 | + * @private | |
999 | + */ | |
1000 | + this._trackCheckOut = function (step, option) { | |
1001 | + this._setAction('checkout', getActionFieldObject(null, null, null, null, null, null, null, step, option)); | |
1002 | + }; | |
1003 | + | |
1004 | + /** | |
1005 | + * Track detail | |
1006 | + * @private | |
1007 | + */ | |
1008 | + this._trackDetail = function () { | |
1009 | + this._setAction('detail'); | |
1010 | + this._pageView(); | |
1011 | + }; | |
1012 | + | |
1013 | + /** | |
1014 | + * Track add/remove to cart | |
1015 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#add-remove-cart | |
1016 | + * @param action | |
1017 | + * @param list | |
1018 | + * @private | |
1019 | + */ | |
1020 | + this._trackCart = function (action, listName) { | |
1021 | + if (['add', 'remove'].indexOf(action) !== -1) { | |
1022 | + this._setAction(action, { list: listName }); | |
1023 | + this._trackEvent('UX', 'click', action + (action === 'add' ? ' to cart' : ' from cart')); | |
1024 | + } | |
1025 | + }; | |
1026 | + | |
1027 | + /** | |
1028 | + * Track promo click | |
1029 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks | |
1030 | + * @param promotionName | |
1031 | + * @private | |
1032 | + */ | |
1033 | + this._promoClick = function (promotionName) { | |
1034 | + this._setAction('promo_click'); | |
1035 | + this._trackEvent('Internal Promotions', 'click', promotionName); | |
1036 | + }; | |
1037 | + | |
1038 | + /** | |
1039 | + * Track product click | |
1040 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks | |
1041 | + * @param promotionName | |
1042 | + * @private | |
1043 | + */ | |
1044 | + this._productClick = function (listName) { | |
1045 | + this._setAction('click', getActionFieldObject(null, null, null, null, null, null, listName, null, null)); | |
1046 | + this._trackEvent('UX', 'click', listName); | |
1047 | + }; | |
1048 | + | |
1049 | + /** | |
1050 | + * Send page view | |
1051 | + * @param trackerName | |
1052 | + * @private | |
1053 | + */ | |
1054 | + this._pageView = function (trackerName) { | |
1055 | + _analyticsJs(function () { | |
1056 | + _ga(generateCommandName('send', trackerName), 'pageview'); | |
1057 | + }); | |
1058 | + }; | |
1059 | + | |
1060 | + /** | |
1061 | + * Send custom events | |
1062 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings#implementation | |
1063 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions#implementation | |
1064 | + * @private | |
1065 | + */ | |
1066 | + this._send = function () { | |
1067 | + var args = Array.prototype.slice.call(arguments); | |
1068 | + args.unshift('send'); | |
1069 | + _analyticsJs(function () { | |
1070 | + _ga.apply(that, args); | |
1071 | + }); | |
1072 | + }; | |
1073 | + | |
1074 | + /** | |
1075 | + * Set custom dimensions, metrics or experiment | |
1076 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets | |
1077 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs | |
1078 | + * @param name (Required) | |
1079 | + * @param value (Required) | |
1080 | + * @param trackerName (Optional) | |
1081 | + * @private | |
1082 | + */ | |
1083 | + this._set = function (name, value, trackerName) { | |
1084 | + _analyticsJs(function () { | |
1085 | + _ga(generateCommandName('set', trackerName), name, value); | |
1086 | + }); | |
1087 | + }; | |
1088 | + | |
1089 | + /** | |
1090 | + * Track user timings | |
1091 | + * @param timingCategory (Required): A string for categorizing all user timing variables into logical groups(e.g jQuery). | |
1092 | + * @param timingVar (Required): A string to identify the variable being recorded(e.g. JavaScript Load). | |
1093 | + * @param timingValue (Required): The number of milliseconds in elapsed time to report to Google Analytics(e.g. 20). | |
1094 | + * @param timingLabel (Optional): A string that can be used to add flexibility in visualizing user timings in the reports(e.g. Google CDN). | |
1095 | + * @private | |
1096 | + */ | |
1097 | + this._trackTimings = function (timingCategory, timingVar, timingValue, timingLabel) { | |
1098 | + _analyticsJs(function () { | |
1099 | + _gaMultipleTrackers(undefined, 'send', 'timing', timingCategory, timingVar, timingValue, timingLabel); | |
1100 | + }); | |
1101 | + }; | |
1102 | + | |
1103 | + /** | |
1104 | + * Exception tracking | |
1105 | + * https://developers.google.com/analytics/devguides/collection/analyticsjs/exceptions | |
1106 | + * @param description (Optional): A description of the exception. | |
1107 | + * @param isFatal (Optional): true if the exception was fatal, false otherwise. | |
1108 | + * @private | |
1109 | + */ | |
1110 | + this._trackException = function (description, isFatal) { | |
1111 | + _analyticsJs(function () { | |
1112 | + _gaMultipleTrackers(undefined, 'send', 'exception', { exDescription: description, exFatal: !!isFatal}); | |
1113 | + }); | |
1114 | + }; | |
1115 | + | |
1116 | + // creates the Google Analytics tracker | |
1117 | + if (!delayScriptTag) { | |
1118 | + this._registerScriptTags(); | |
1119 | + this._registerTrackers(); | |
1120 | + } | |
1121 | + | |
1122 | + // activates page tracking | |
1123 | + if (trackRoutes) { | |
1124 | + $rootScope.$on(pageEvent, function () { | |
1125 | + // Apply $route based filtering if configured | |
1126 | + if (readFromRoute) { | |
1127 | + // Avoid tracking undefined routes, routes without template (e.g. redirect routes) | |
1128 | + // and those explicitly marked as 'do not track' | |
1129 | + if (!$route.current || !$route.current.templateUrl || $route.current.doNotTrack) { | |
1130 | + return; | |
1131 | + } | |
1132 | + } | |
1133 | + | |
1134 | + that._trackPage(); | |
1135 | + }); | |
1136 | + } | |
1137 | + | |
1138 | + return { | |
1139 | + log: that.log, | |
1140 | + offlineQueue: that.offlineQueue, | |
1141 | + configuration: { | |
1142 | + accounts: accounts, | |
1143 | + universalAnalytics: analyticsJS, | |
1144 | + crossDomainLinker: crossDomainLinker, | |
1145 | + crossLinkDomains: crossLinkDomains, | |
1146 | + currency: currency, | |
1147 | + debugMode: debugMode, | |
1148 | + delayScriptTag: delayScriptTag, | |
1149 | + disableAnalytics: disableAnalytics, | |
1150 | + displayFeatures: displayFeatures, | |
1151 | + domainName: domainName, | |
1152 | + ecommerce: that._ecommerceEnabled(), | |
1153 | + enhancedEcommerce: that._enhancedEcommerceEnabled(), | |
1154 | + enhancedLinkAttribution: enhancedLinkAttribution, | |
1155 | + experimentId: experimentId, | |
1156 | + hybridMobileSupport: hybridMobileSupport, | |
1157 | + ignoreFirstPageLoad: ignoreFirstPageLoad, | |
1158 | + logAllCalls: logAllCalls, | |
1159 | + pageEvent: pageEvent, | |
1160 | + readFromRoute: readFromRoute, | |
1161 | + removeRegExp: removeRegExp, | |
1162 | + testMode: testMode, | |
1163 | + traceDebuggingMode: traceDebuggingMode, | |
1164 | + trackPrefix: trackPrefix, | |
1165 | + trackRoutes: trackRoutes, | |
1166 | + trackUrlParams: trackUrlParams | |
1167 | + }, | |
1168 | + getUrl: getUrl, | |
1169 | + /* DEPRECATED */ | |
1170 | + setCookieConfig: function (config) { | |
1171 | + that._log('warn', 'DEPRECATION WARNING: setCookieConfig method is deprecated. Please use tracker fields instead.'); | |
1172 | + return that._setCookieConfig.apply(that, arguments); | |
1173 | + }, | |
1174 | + /* DEPRECATED */ | |
1175 | + getCookieConfig: function () { | |
1176 | + that._log('warn', 'DEPRECATION WARNING: getCookieConfig method is deprecated. Please use tracker fields instead.'); | |
1177 | + return cookieConfig; | |
1178 | + }, | |
1179 | + /* DEPRECATED */ | |
1180 | + createAnalyticsScriptTag: function (config) { | |
1181 | + that._log('warn', 'DEPRECATION WARNING: createAnalyticsScriptTag method is deprecated. Please use registerScriptTags and registerTrackers methods instead.'); | |
1182 | + if (config) { | |
1183 | + cookieConfig = config; | |
1184 | + } | |
1185 | + return that._createAnalyticsScriptTag(); | |
1186 | + }, | |
1187 | + /* DEPRECATED */ | |
1188 | + createScriptTag: function () { | |
1189 | + that._log('warn', 'DEPRECATION WARNING: createScriptTag method is deprecated. Please use registerScriptTags and registerTrackers methods instead.'); | |
1190 | + return that._createScriptTag(); | |
1191 | + }, | |
1192 | + registerScriptTags: function () { | |
1193 | + return that._registerScriptTags(); | |
1194 | + }, | |
1195 | + registerTrackers: function () { | |
1196 | + return that._registerTrackers(); | |
1197 | + }, | |
1198 | + offline: function (mode) { | |
1199 | + if (mode === true && offlineMode === false) { | |
1200 | + // Go to offline mode | |
1201 | + offlineMode = true; | |
1202 | + } | |
1203 | + if (mode === false && offlineMode === true) { | |
1204 | + // Go to online mode and process the offline queue | |
1205 | + offlineMode = false; | |
1206 | + while (that.offlineQueue.length > 0) { | |
1207 | + var obj = that.offlineQueue.shift(); | |
1208 | + obj[0].apply(that, obj[1]); | |
1209 | + } | |
1210 | + } | |
1211 | + return offlineMode; | |
1212 | + }, | |
1213 | + trackPage: function (url, title, custom) { | |
1214 | + that._trackPage.apply(that, arguments); | |
1215 | + }, | |
1216 | + trackEvent: function (category, action, label, value, noninteraction, custom) { | |
1217 | + that._trackEvent.apply(that, arguments); | |
1218 | + }, | |
1219 | + addTrans: function (transactionId, affiliation, total, tax, shipping, city, state, country, currency) { | |
1220 | + that._addTrans.apply(that, arguments); | |
1221 | + }, | |
1222 | + addItem: function (transactionId, sku, name, category, price, quantity) { | |
1223 | + that._addItem.apply(that, arguments); | |
1224 | + }, | |
1225 | + trackTrans: function () { | |
1226 | + that._trackTrans.apply(that, arguments); | |
1227 | + }, | |
1228 | + clearTrans: function () { | |
1229 | + that._clearTrans.apply(that, arguments); | |
1230 | + }, | |
1231 | + addProduct: function (productId, name, category, brand, variant, price, quantity, coupon, position, custom) { | |
1232 | + that._addProduct.apply(that, arguments); | |
1233 | + }, | |
1234 | + addPromo: function (productId, name, creative, position) { | |
1235 | + that._addPromo.apply(that, arguments); | |
1236 | + }, | |
1237 | + addImpression: function (productId, name, list, brand, category, variant, position, price) { | |
1238 | + that._addImpression.apply(that, arguments); | |
1239 | + }, | |
1240 | + productClick: function (listName) { | |
1241 | + that._productClick.apply(that, arguments); | |
1242 | + }, | |
1243 | + promoClick : function (promotionName) { | |
1244 | + that._promoClick.apply(that, arguments); | |
1245 | + }, | |
1246 | + trackDetail: function () { | |
1247 | + that._trackDetail.apply(that, arguments); | |
1248 | + }, | |
1249 | + trackCart: function (action, list) { | |
1250 | + that._trackCart.apply(that, arguments); | |
1251 | + }, | |
1252 | + trackCheckout: function (step, option) { | |
1253 | + that._trackCheckOut.apply(that, arguments); | |
1254 | + }, | |
1255 | + trackTimings: function (timingCategory, timingVar, timingValue, timingLabel) { | |
1256 | + that._trackTimings.apply(that, arguments); | |
1257 | + }, | |
1258 | + trackTransaction: function (transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option) { | |
1259 | + that._trackTransaction.apply(that, arguments); | |
1260 | + }, | |
1261 | + trackException: function (description, isFatal) { | |
1262 | + that._trackException.apply(that, arguments); | |
1263 | + }, | |
1264 | + setAction: function (action, obj) { | |
1265 | + that._setAction.apply(that, arguments); | |
1266 | + }, | |
1267 | + pageView: function () { | |
1268 | + that._pageView.apply(that, arguments); | |
1269 | + }, | |
1270 | + send: function (obj) { | |
1271 | + that._send.apply(that, arguments); | |
1272 | + }, | |
1273 | + set: function (name, value, trackerName) { | |
1274 | + that._set.apply(that, arguments); | |
1275 | + } | |
1276 | + }; | |
1277 | + }]; | |
1278 | + }) | |
1279 | + | |
1280 | + .directive('gaTrackEvent', ['Analytics', '$parse', function (Analytics, $parse) { | |
1281 | + return { | |
1282 | + restrict: 'A', | |
1283 | + link: function (scope, element, attrs) { | |
1284 | + var options = $parse(attrs.gaTrackEvent); | |
1285 | + element.bind('click', function () { | |
1286 | + if(attrs.gaTrackEventIf){ | |
1287 | + if(!scope.$eval(attrs.gaTrackEventIf)){ | |
1288 | + return; // Cancel this event if we don't pass the ga-track-event-if condition | |
1289 | + } | |
1290 | + } | |
1291 | + if (options.length > 1) { | |
1292 | + Analytics.trackEvent.apply(Analytics, options(scope)); | |
1293 | + } | |
1294 | + }); | |
1295 | + } | |
1296 | + }; | |
1297 | + }]); | |
1298 | + return angular.module('angular-google-analytics'); | |
1299 | +})); | ... | ... |
dist/angular-google-analytics.min.js
... | ... | @@ -0,0 +1,9 @@ |
1 | +/** | |
2 | + * Angular Google Analytics - Easy tracking for your AngularJS application | |
3 | + * @version v1.1.8 - 2016-12-30 | |
4 | + * @link http://github.com/revolunet/angular-google-analytics | |
5 | + * @author Julien Bouquillon <julien@revolunet.com> (https://github.com/revolunet) | |
6 | + * @contributors Julien Bouquillon (https://github.com/revolunet),Justin Saunders (https://github.com/justinsa),Chris Esplin (https://github.com/deltaepsilon),Adam Misiorny (https://github.com/adam187) | |
7 | + * @license MIT License, http://www.opensource.org/licenses/MIT | |
8 | + */ | |
9 | +!function(a,b){"use strict";"undefined"!=typeof module&&module.exports?(b("undefined"==typeof angular?require("angular"):angular),module.exports="angular-google-analytics"):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(this,function(a,b){"use strict";return a.module("angular-google-analytics",[]).provider("Analytics",function(){var c,d,e,f,g,h=!0,i="auto",j=!1,k=!1,l="USD",m=!1,n=!1,o=!1,p=!1,q=!1,r=!1,s=!1,t=!1,u=!1,v=!1,w=!1,x="$routeChangeSuccess",y=!1,z=!1,A=!1,B="",C=!0,D=!1;this.log=[],this.offlineQueue=[],this.setAccount=function(d){return c=a.isUndefined(d)||d===!1?b:a.isArray(d)?d:a.isObject(d)?[d]:[{tracker:d,trackEvent:!0}],this},this.trackPages=function(a){return C=!!a,this},this.trackPrefix=function(a){return B=a,this},this.setDomainName=function(a){return e=a,this},this.useDisplayFeatures=function(a){return o=!!a,this},this.useAnalytics=function(a){return h=!!a,this},this.useEnhancedLinkAttribution=function(a){return s=!!a,this},this.useCrossDomainLinker=function(a){return k=!!a,this},this.setCrossLinkDomains=function(a){return d=a,this},this.setPageEvent=function(a){return x=a,this},this.setCookieConfig=function(a){return i=a,this},this.useECommerce=function(a,b){return q=!!a,r=!!b,this},this.setCurrency=function(a){return l=a,this},this.setRemoveRegExp=function(a){return a instanceof RegExp&&(g=a),this},this.setExperimentId=function(a){return f=a,this},this.ignoreFirstPageLoad=function(a){return t=!!a,this},this.trackUrlParams=function(a){return D=!!a,this},this.disableAnalytics=function(a){return p=!!a,this},this.setHybridMobileSupport=function(a){return v=!!a,this},this.startOffline=function(a){return w=!!a,w===!0&&this.delayScriptTag(!0),this},this.delayScriptTag=function(a){return n=!!a,this},this.logAllCalls=function(a){return u=!!a,this},this.enterTestMode=function(){return z=!0,this},this.enterDebugMode=function(a){return m=!0,A=!!a,this},this.readFromRoute=function(a){return y=!!a,this},this.$get=["$document","$location","$log","$rootScope","$window","$injector",function(E,F,G,H,I,J){var K=this,L=function(b,c){return a.isObject(c)&&a.isDefined(c[b])},M=function(a,b,c){return L(a,b)&&b[a]===c},N=function(b,c){return a.isString(c)?c+"."+b:L("name",c)?c.name+"."+b:b},O={};y&&(J.has("$route")?O=J.get("$route"):G.warn("$route service is not available. Make sure you have included ng-route in your application dependencies."));var P=function(){if(y&&O.current&&"pageTrack"in O.current)return O.current.pageTrack;var a=D?F.url():F.path();return g?a.replace(g,""):a},Q=function(){var b={utm_source:"campaignSource",utm_medium:"campaignMedium",utm_term:"campaignTerm",utm_content:"campaignContent",utm_campaign:"campaignName"},c={};return a.forEach(F.search(),function(d,e){var f=b[e];a.isDefined(f)&&(c[f]=d)}),c},R=function(a,b,c,d,e,f,g,h,i){var j={};return a&&(j.id=a),b&&(j.affiliation=b),c&&(j.revenue=c),d&&(j.tax=d),e&&(j.shipping=e),f&&(j.coupon=f),g&&(j.list=g),h&&(j.step=h),i&&(j.option=i),j},S=function(b,c){var d="",e="https:"===document.location.protocol,f="chrome-extension:"===document.location.protocol,g=h===!0&&v===!0;return b=a.isString(b)?b:"",c=a.isString(c)?c:"",""!==b&&(d="http:"+b),(f||g||e&&""!==c)&&(d="https:"+c),d},T=function(a){!h&&I._gaq&&"function"==typeof a&&a()},U=function(){var a=Array.prototype.slice.call(arguments);return w===!0?void K.offlineQueue.push([U,a]):(I._gaq||(I._gaq=[]),u===!0&&K._log.apply(K,a),void I._gaq.push(a))},V=function(a){h&&I.ga&&"function"==typeof a&&a()},W=function(){var a=Array.prototype.slice.call(arguments);return w===!0?void K.offlineQueue.push([W,a]):"function"!=typeof I.ga?void K._log("warn","ga function not set on window"):(u===!0&&K._log.apply(K,a),void I.ga.apply(null,a))},X=function(a){var b=Array.prototype.slice.call(arguments,1),d=b[0],e=[];return"function"==typeof a?c.forEach(function(b){a(b)&&e.push(b)}):e=c,0===e.length?void W.apply(K,b):void e.forEach(function(a){L("select",a)&&"function"==typeof a.select&&!a.select(b)||(b[0]=N(d,a),W.apply(K,b))})};return this._log=function(){var a=Array.prototype.slice.call(arguments);if(a.length>0){if(a.length>1)switch(a[0]){case"debug":case"error":case"info":case"log":case"warn":G[a[0]](a.slice(1))}K.log.push(a)}},this._createScriptTag=function(){K._registerScriptTags(),K._registerTrackers()},this._createAnalyticsScriptTag=function(){K._registerScriptTags(),K._registerTrackers()},this._registerScriptTags=function(){var a,b=E[0],d=S();if(j===!0)return void K._log("warn","Script tags already created");if(p===!0&&c.forEach(function(a){K._log("info","Analytics disabled: "+a.tracker),I["ga-disable-"+a.tracker]=!0}),h===!0){if(a=d+"//www.google-analytics.com/"+(m?"analytics_debug.js":"analytics.js"),z!==!0?!function(a,b,c,d,e,f,g){a.GoogleAnalyticsObject=e,a[e]=a[e]||function(){(a[e].q=a[e].q||[]).push(arguments)},a[e].l=1*new Date,f=b.createElement(c),g=b.getElementsByTagName(c)[0],f.async=1,f.src=d,g.parentNode.insertBefore(f,g)}(window,b,"script",a,"ga"):("function"!=typeof I.ga&&(I.ga=function(){}),K._log("inject",a)),A&&(I.ga_debug={trace:!0}),f){var e=b.createElement("script"),g=b.getElementsByTagName("script")[0];e.src=d+"//www.google-analytics.com/cx/api.js?experiment="+f,g.parentNode.insertBefore(e,g)}}else a=S("//www","//ssl")+".google-analytics.com/ga.js",o===!0&&(a=d+"//stats.g.doubleclick.net/dc.js"),z!==!0?!function(){var c=b.createElement("script");c.type="text/javascript",c.async=!0,c.src=a;var d=b.getElementsByTagName("script")[0];d.parentNode.insertBefore(c,d)}():K._log("inject",a);return j=!0,!0},this._registerTrackers=function(){return!c||c.length<1?void K._log("warn","No accounts to register"):(h===!0?c.forEach(function(b){b.crossDomainLinker=L("crossDomainLinker",b)?b.crossDomainLinker:k,b.crossLinkDomains=L("crossLinkDomains",b)?b.crossLinkDomains:d,b.displayFeatures=L("displayFeatures",b)?b.displayFeatures:o,b.enhancedLinkAttribution=L("enhancedLinkAttribution",b)?b.enhancedLinkAttribution:s,b.set=L("set",b)?b.set:{},b.trackEcommerce=L("trackEcommerce",b)?b.trackEcommerce:q,b.trackEvent=!!L("trackEvent",b)&&b.trackEvent;var c={};L("fields",b)?c=b.fields:L("cookieConfig",b)?a.isString(b.cookieConfig)?c.cookieDomain=b.cookieConfig:c=b.cookieConfig:a.isString(i)?c.cookieDomain=i:i&&(c=i),b.crossDomainLinker===!0&&(c.allowLinker=!0),L("name",b)&&(c.name=b.name),b.fields=c,W("create",b.tracker,b.fields),v===!0&&W(N("set",b),"checkProtocolTask",null);for(var e in b.set)b.set.hasOwnProperty(e)&&W(N("set",b),e,b.set[e]);b.crossDomainLinker===!0&&(W(N("require",b),"linker"),a.isDefined(b.crossLinkDomains)&&W(N("linker:autoLink",b),b.crossLinkDomains)),b.displayFeatures&&W(N("require",b),"displayfeatures"),b.trackEcommerce&&(r?(W(N("require",b),"ec"),W(N("set",b),"&cu",l)):W(N("require",b),"ecommerce")),b.enhancedLinkAttribution&&W(N("require",b),"linkid"),C&&!t&&W(N("send",b),"pageview",B+P())}):(c.length>1&&(K._log("warn","Multiple trackers are not supported with ga.js. Using first tracker only"),c=c.slice(0,1)),U("_setAccount",c[0].tracker),e&&U("_setDomainName",e),s&&U("_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"),C&&!t&&(g?U("_trackPageview",P()):U("_trackPageview"))),!0)},this._ecommerceEnabled=function(a,b){var c=q&&!r;return a===!0&&c===!1&&(q&&r?K._log("warn",b+" is not available when Enhanced Ecommerce is enabled with analytics.js"):K._log("warn","Ecommerce must be enabled to use "+b+" with analytics.js")),c},this._enhancedEcommerceEnabled=function(a,b){var c=q&&r;return a===!0&&c===!1&&K._log("warn","Enhanced Ecommerce must be enabled to use "+b+" with analytics.js"),c},this._trackPage=function(c,d,e){c=c?c:P(),d=d?d:E[0].title,T(function(){U("_set","title",d),U("_trackPageview",B+c)}),V(function(){var f={page:B+c,title:d};a.extend(f,Q()),a.isObject(e)&&a.extend(f,e),X(b,"send","pageview",f)})},this._trackEvent=function(b,c,d,e,f,g){T(function(){U("_trackEvent",b,c,d,e,!!f)}),V(function(){var h={},i=function(a){return M("trackEvent",a,!0)};a.isDefined(f)&&(h.nonInteraction=!!f),a.isObject(g)&&a.extend(h,g),a.isDefined(h.page)||(h.page=P()),X(i,"send","event",b,c,d,e,h)})},this._addTrans=function(a,b,c,d,e,f,g,h,i){T(function(){U("_addTrans",a,b,c,d,e,f,g,h)}),V(function(){if(K._ecommerceEnabled(!0,"addTrans")){var f=function(a){return M("trackEcommerce",a,!0)};X(f,"ecommerce:addTransaction",{id:a,affiliation:b,revenue:c,tax:d,shipping:e,currency:i||"USD"})}})},this._addItem=function(a,b,c,d,e,f){T(function(){U("_addItem",a,b,c,d,e,f)}),V(function(){if(K._ecommerceEnabled(!0,"addItem")){var g=function(a){return M("trackEcommerce",a,!0)};X(g,"ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f})}})},this._trackTrans=function(){T(function(){U("_trackTrans")}),V(function(){if(K._ecommerceEnabled(!0,"trackTrans")){var a=function(a){return M("trackEcommerce",a,!0)};X(a,"ecommerce:send")}})},this._clearTrans=function(){V(function(){if(K._ecommerceEnabled(!0,"clearTrans")){var a=function(a){return M("trackEcommerce",a,!0)};X(a,"ecommerce:clear")}})},this._addProduct=function(b,c,d,e,f,g,h,i,j,k){T(function(){U("_addProduct",b,c,d,e,f,g,h,i,j)}),V(function(){if(K._enhancedEcommerceEnabled(!0,"addProduct")){var l=function(a){return M("trackEcommerce",a,!0)},m={id:b,name:c,category:d,brand:e,variant:f,price:g,quantity:h,coupon:i,position:j};a.isObject(k)&&a.extend(m,k),X(l,"ec:addProduct",m)}})},this._addImpression=function(a,b,c,d,e,f,g,h){T(function(){U("_addImpression",a,b,c,d,e,f,g,h)}),V(function(){if(K._enhancedEcommerceEnabled(!0,"addImpression")){var i=function(a){return M("trackEcommerce",a,!0)};X(i,"ec:addImpression",{id:a,name:b,category:e,brand:d,variant:f,list:c,position:g,price:h})}})},this._addPromo=function(a,b,c,d){T(function(){U("_addPromo",a,b,c,d)}),V(function(){if(K._enhancedEcommerceEnabled(!0,"addPromo")){var e=function(a){return M("trackEcommerce",a,!0)};X(e,"ec:addPromo",{id:a,name:b,creative:c,position:d})}})},this._setAction=function(a,b){T(function(){U("_setAction",a,b)}),V(function(){if(K._enhancedEcommerceEnabled(!0,"setAction")){var c=function(a){return M("trackEcommerce",a,!0)};X(c,"ec:setAction",a,b)}})},this._trackTransaction=function(a,b,c,d,e,f,g,h,i){this._setAction("purchase",R(a,b,c,d,e,f,g,h,i))},this._trackRefund=function(a){this._setAction("refund",R(a))},this._trackCheckOut=function(a,b){this._setAction("checkout",R(null,null,null,null,null,null,null,a,b))},this._trackDetail=function(){this._setAction("detail"),this._pageView()},this._trackCart=function(a,b){["add","remove"].indexOf(a)!==-1&&(this._setAction(a,{list:b}),this._trackEvent("UX","click",a+("add"===a?" to cart":" from cart")))},this._promoClick=function(a){this._setAction("promo_click"),this._trackEvent("Internal Promotions","click",a)},this._productClick=function(a){this._setAction("click",R(null,null,null,null,null,null,a,null,null)),this._trackEvent("UX","click",a)},this._pageView=function(a){V(function(){W(N("send",a),"pageview")})},this._send=function(){var a=Array.prototype.slice.call(arguments);a.unshift("send"),V(function(){W.apply(K,a)})},this._set=function(a,b,c){V(function(){W(N("set",c),a,b)})},this._trackTimings=function(a,c,d,e){V(function(){X(b,"send","timing",a,c,d,e)})},this._trackException=function(a,c){V(function(){X(b,"send","exception",{exDescription:a,exFatal:!!c})})},n||(this._registerScriptTags(),this._registerTrackers()),C&&H.$on(x,function(){(!y||O.current&&O.current.templateUrl&&!O.current.doNotTrack)&&K._trackPage()}),{log:K.log,offlineQueue:K.offlineQueue,configuration:{accounts:c,universalAnalytics:h,crossDomainLinker:k,crossLinkDomains:d,currency:l,debugMode:m,delayScriptTag:n,disableAnalytics:p,displayFeatures:o,domainName:e,ecommerce:K._ecommerceEnabled(),enhancedEcommerce:K._enhancedEcommerceEnabled(),enhancedLinkAttribution:s,experimentId:f,hybridMobileSupport:v,ignoreFirstPageLoad:t,logAllCalls:u,pageEvent:x,readFromRoute:y,removeRegExp:g,testMode:z,traceDebuggingMode:A,trackPrefix:B,trackRoutes:C,trackUrlParams:D},getUrl:P,setCookieConfig:function(a){return K._log("warn","DEPRECATION WARNING: setCookieConfig method is deprecated. Please use tracker fields instead."),K._setCookieConfig.apply(K,arguments)},getCookieConfig:function(){return K._log("warn","DEPRECATION WARNING: getCookieConfig method is deprecated. Please use tracker fields instead."),i},createAnalyticsScriptTag:function(a){return K._log("warn","DEPRECATION WARNING: createAnalyticsScriptTag method is deprecated. Please use registerScriptTags and registerTrackers methods instead."),a&&(i=a),K._createAnalyticsScriptTag()},createScriptTag:function(){return K._log("warn","DEPRECATION WARNING: createScriptTag method is deprecated. Please use registerScriptTags and registerTrackers methods instead."),K._createScriptTag()},registerScriptTags:function(){return K._registerScriptTags()},registerTrackers:function(){return K._registerTrackers()},offline:function(a){if(a===!0&&w===!1&&(w=!0),a===!1&&w===!0)for(w=!1;K.offlineQueue.length>0;){var b=K.offlineQueue.shift();b[0].apply(K,b[1])}return w},trackPage:function(a,b,c){K._trackPage.apply(K,arguments)},trackEvent:function(a,b,c,d,e,f){K._trackEvent.apply(K,arguments)},addTrans:function(a,b,c,d,e,f,g,h,i){K._addTrans.apply(K,arguments)},addItem:function(a,b,c,d,e,f){K._addItem.apply(K,arguments)},trackTrans:function(){K._trackTrans.apply(K,arguments)},clearTrans:function(){K._clearTrans.apply(K,arguments)},addProduct:function(a,b,c,d,e,f,g,h,i,j){K._addProduct.apply(K,arguments)},addPromo:function(a,b,c,d){K._addPromo.apply(K,arguments)},addImpression:function(a,b,c,d,e,f,g,h){K._addImpression.apply(K,arguments)},productClick:function(a){K._productClick.apply(K,arguments)},promoClick:function(a){K._promoClick.apply(K,arguments)},trackDetail:function(){K._trackDetail.apply(K,arguments)},trackCart:function(a,b){K._trackCart.apply(K,arguments)},trackCheckout:function(a,b){K._trackCheckOut.apply(K,arguments)},trackTimings:function(a,b,c,d){K._trackTimings.apply(K,arguments)},trackTransaction:function(a,b,c,d,e,f,g,h,i){K._trackTransaction.apply(K,arguments)},trackException:function(a,b){K._trackException.apply(K,arguments)},setAction:function(a,b){K._setAction.apply(K,arguments)},pageView:function(){K._pageView.apply(K,arguments)},send:function(a){K._send.apply(K,arguments)},set:function(a,b,c){K._set.apply(K,arguments)}}}]}).directive("gaTrackEvent",["Analytics","$parse",function(a,b){return{restrict:"A",link:function(c,d,e){var f=b(e.gaTrackEvent);d.bind("click",function(){e.gaTrackEventIf&&!c.$eval(e.gaTrackEventIf)||f.length>1&&a.trackEvent.apply(a,f(c))})}}}]),a.module("angular-google-analytics")}); | |
0 | 10 | \ No newline at end of file | ... | ... |