Commit d45f7746ac174146dbfc0fc04628dea3369a859a

Authored by Palak Handa
1 parent f263889f05
Exists in master and in 1 other branch paytm

file add

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
... ...