From 8d40270b1a35796ebc748f6fa698e507a5f36a1e Mon Sep 17 00:00:00 2001 From: justinsa Date: Sat, 12 Sep 2015 17:57:29 -0700 Subject: [PATCH] Release 1.1.0 * Dist files updated with release versions. * Removed obsolete index.html file. * Updated package.json and bower.json files to take advantage of features in their respective specs. --- Gruntfile.js | 1 + bower.json | 27 +- dist/angular-google-analytics.js | 564 ++++++++++++++++----------- dist/angular-google-analytics.min.js | 7 +- index.html | 46 --- package.json | 10 +- 6 files changed, 380 insertions(+), 275 deletions(-) delete mode 100644 index.html diff --git a/Gruntfile.js b/Gruntfile.js index bdee37b..1d92407 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -11,6 +11,7 @@ module.exports = function(grunt) { ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + ' * @link <%= pkg.homepage %>\n' + ' * @author <%= pkg.author %>\n' + + ' * @contributors <%= pkg.contributors %>\n' + ' * @license MIT License, http://www.opensource.org/licenses/MIT\n' + ' */\n' }, diff --git a/bower.json b/bower.json index 5a730cf..55db8b5 100644 --- a/bower.json +++ b/bower.json @@ -1,14 +1,35 @@ { - "author": "revolunet", + "authors": [ + "Julien Bouquillon (https://github.com/revolunet)", + "Justin Saunders (https://github.com/justinsa)", + "Chris Esplin (https://github.com/deltaepsilon)", + "Adam Misiorny (https://github.com/adam187)" + ], "name": "angular-google-analytics", "description": "Easy Analytics for your AngularJS application", - "version": "1.0.0", + "keywords": [ + "analytics", + "angular", + "angularjs", + "angular-js", + "google-analytics", + "tracking", + "visitor-tracking", + "universal-analytics" + ], + "version": "1.1.0", "homepage": "https://github.com/revolunet/angular-google-analytics", + "license": [ + { + "type": "MIT", + "url": "http://revolunet.mit-license.org" + } + ], "repository": { "type": "git", "url": "git://github.com/revolunet/angular-google-analytics.git" }, - "main": "./dist/angular-google-analytics.min.js", + "main": "./dist/angular-google-analytics.js", "dependencies": { "angular": ">=1" }, diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index 28db1c1..a07bb36 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,37 +1,40 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v1.0.0 - 2015-08-26 + * @version v1.1.0 - 2015-09-12 * @link http://github.com/revolunet/angular-google-analytics - * @author Julien Bouquillon + * @author Julien Bouquillon (https://github.com/revolunet) + * @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) * @license MIT License, http://www.opensource.org/licenses/MIT */ (function (window, document, angular, undefined) { 'use strict'; angular.module('angular-google-analytics', []) .provider('Analytics', function () { - var created = false, - trackRoutes = true, - accounts, + var accounts, + analyticsJS = true, + cookieConfig = 'auto', + created = false, + crossDomainLinker = false, + crossLinkDomains, + currency = 'USD', + delayScriptTag = false, displayFeatures, - trackPrefix = '', domainName, - analyticsJS = false, - pageEvent = '$routeChangeSuccess', - cookieConfig = 'auto', ecommerce = false, enhancedEcommerce = false, enhancedLinkAttribution = false, - currency = 'USD', - removeRegExp, experimentId, ignoreFirstPageLoad = false, - crossDomainLinker = false, - crossLinkDomains, - trackUrlParams = false, - delayScriptTag = false, - logAllCalls = false; + logAllCalls = false, + offlineMode = false, + pageEvent = '$routeChangeSuccess', + removeRegExp, + trackPrefix = '', + trackRoutes = true, + trackUrlParams = false; - this._logs = []; + this.log = []; + this._offlineQueue = []; /** * Configuration Methods @@ -49,101 +52,108 @@ // the trackEvent property must be set to true when there is only a single tracker. accounts = [{ tracker: tracker, trackEvent: true }]; } - return true; + return this; }; this.trackPages = function (doTrack) { trackRoutes = doTrack; - return true; + return this; }; this.trackPrefix = function (prefix) { trackPrefix = prefix; - return true; + return this; }; this.setDomainName = function (domain) { domainName = domain; - return true; + return this; }; this.useDisplayFeatures = function (val) { displayFeatures = !!val; - return true; + return this; }; this.useAnalytics = function (val) { analyticsJS = !!val; - return true; + return this; }; this.useEnhancedLinkAttribution = function (val) { enhancedLinkAttribution = !!val; - return true; + return this; }; this.useCrossDomainLinker = function (val) { crossDomainLinker = !!val; - return true; + return this; }; this.setCrossLinkDomains = function (domains) { crossLinkDomains = domains; - return true; + return this; }; this.setPageEvent = function (name) { pageEvent = name; - return true; + return this; }; this.setCookieConfig = function (config) { cookieConfig = config; - return true; + return this; }; this.useECommerce = function (val, enhanced) { ecommerce = !!val; enhancedEcommerce = !!enhanced; - return true; + return this; }; this.setCurrency = function (currencyCode) { currency = currencyCode; - return true; + return this; }; this.setRemoveRegExp = function (regex) { if (regex instanceof RegExp) { removeRegExp = regex; - return true; } - return false; + return this; }; this.setExperimentId = function (id) { experimentId = id; - return true; + return this; }; this.ignoreFirstPageLoad = function (val) { ignoreFirstPageLoad = !!val; - return true; + return this; }; this.trackUrlParams = function (val) { trackUrlParams = !!val; - return true; + return this; + }; + + this.startOffline = function (val) { + offlineMode = !!val; + if (offlineMode === true) { + this.delayScriptTag(true); + } + return this; }; this.delayScriptTag = function (val) { delayScriptTag = !!val; - return true; + return this; }; this.logAllCalls = function (val) { logAllCalls = !!val; - return true; + return this; }; /** @@ -157,6 +167,9 @@ **/ var generateCommandName = function (commandName, config) { + if (angular.isString(config)) { + return config + '.' + commandName; + } return isPropertyDefined('name', config) ? (config.name + '.' + commandName) : commandName; }; @@ -164,6 +177,10 @@ return angular.isObject(config) && angular.isDefined(config[key]); }; + var isPropertySetTo = function (key, config, value) { + return isPropertyDefined(key, config) && config[key] === value; + }; + var getUrl = function () { var url = trackUrlParams ? $location.url() : $location.path(); return removeRegExp ? url.replace(removeRegExp, '') : url; @@ -190,6 +207,34 @@ return object; }; + /** + * get ActionFieldObject + * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data + * @param id + * @param affliation + * @param revenue + * @param tax + * @param shipping + * @param coupon + * @param list + * @param step + * @param option + */ + var getActionFieldObject = function (id, affiliation, revenue, tax, shipping, coupon, list, step, option) { + var obj = {}; + if (id) { obj.id = id; } + if (affiliation) { obj.affiliation = affiliation; } + if (revenue) { obj.revenue = revenue; } + if (tax) { obj.tax = tax; } + if (shipping) { obj.shipping = shipping; } + if (coupon) { obj.coupon = coupon; } + if (list) { obj.list = list; } + if (step) { obj.step = step; } + if (option) { obj.option = option; } + return obj; + }; + + /** * Private Methods */ @@ -201,6 +246,10 @@ }; var _gaq = function () { + if (offlineMode === true) { + that._offlineQueue.push([_gaq, arguments]); + return; + } if (!$window._gaq) { $window._gaq = []; } @@ -217,6 +266,10 @@ }; var _ga = function () { + if (offlineMode === true) { + that._offlineQueue.push([_ga, arguments]); + return; + } if (typeof $window.ga !== 'function') { that._log('warn', 'ga function not set on window'); return; @@ -228,24 +281,32 @@ }; var _gaMultipleTrackers = function (includeFn) { - if (typeof $window.ga !== 'function') { - that._log('warn', 'ga function not set on window'); - return; - } - // Drop the includeFn from the arguments and preserve the original command name var args = Array.prototype.slice.call(arguments, 1), - commandName = args[0]; + commandName = args[0], + trackers = []; + if (typeof includeFn === 'function') { + accounts.forEach(function (account) { + if (includeFn(account)) { + trackers.push(account); + } + }); + } else { + // No include function indicates that all accounts are to be used + trackers = accounts; + } - accounts.forEach(function (trackerObj) { - if (typeof includeFn === 'function' && !includeFn(trackerObj)) { - return; - } - args[0] = generateCommandName(commandName, trackerObj); - if (logAllCalls === true) { - that._log.apply(that, args); - } - $window.ga.apply(null, args); + // To preserve backwards compatibility fallback to _ga method if no account + // matches the specified includeFn. This preserves existing behaviors by + // performing the single tracker operation. + if (trackers.length === 0) { + _ga.apply(that, args); + return; + } + + trackers.forEach(function (tracker) { + args[0] = generateCommandName(commandName, tracker); + _ga.apply(that, args); }); }; @@ -261,7 +322,7 @@ break; } } - this._logs.push(Array.prototype.slice.call(arguments)); + this.log.push(Array.prototype.slice.call(arguments)); } }; @@ -331,9 +392,12 @@ accounts.forEach(function (trackerObj) { var options = {}; - trackerObj.crossDomainLinker = isPropertyDefined('crossDomainLinker', trackerObj) ? trackerObj.crossDomainLinker : crossDomainLinker; trackerObj.cookieConfig = isPropertyDefined('cookieConfig', trackerObj) ? trackerObj.cookieConfig : cookieConfig; + trackerObj.crossDomainLinker = isPropertyDefined('crossDomainLinker', trackerObj) ? trackerObj.crossDomainLinker : crossDomainLinker; trackerObj.crossLinkDomains = isPropertyDefined('crossLinkDomains', trackerObj) ? trackerObj.crossLinkDomains : crossLinkDomains; + trackerObj.displayFeatures = isPropertyDefined('displayFeatures', trackerObj) ? trackerObj.displayFeatures : displayFeatures; + trackerObj.enhancedLinkAttribution = isPropertyDefined('enhancedLinkAttribution', trackerObj) ? trackerObj.enhancedLinkAttribution : enhancedLinkAttribution; + trackerObj.trackEcommerce = isPropertyDefined('trackEcommerce', trackerObj) ? trackerObj.trackEcommerce : ecommerce; trackerObj.trackEvent = isPropertyDefined('trackEvent', trackerObj) ? trackerObj.trackEvent : false; options.allowLinker = trackerObj.crossDomainLinker; @@ -349,28 +413,28 @@ _ga(generateCommandName('linker:autoLink', trackerObj), trackerObj.crossLinkDomains); } } - }); - if (displayFeatures) { - _ga('require', 'displayfeatures'); - } + if (trackerObj.displayFeatures) { + _ga(generateCommandName('require', trackerObj), 'displayfeatures'); + } - if (trackRoutes && !ignoreFirstPageLoad) { - _ga('send', 'pageview', getUrl()); - } + if (trackerObj.trackEcommerce) { + if (!enhancedEcommerce) { + _ga(generateCommandName('require', trackerObj), 'ecommerce'); + } else { + _ga(generateCommandName('require', trackerObj), 'ec'); + _ga(generateCommandName('set', trackerObj), '&cu', currency); + } + } - if (ecommerce) { - if (!enhancedEcommerce) { - _ga('require', 'ecommerce', 'ecommerce.js'); - } else { - _ga('require', 'ec', 'ec.js'); - _ga('set', '&cu', currency); + if (trackerObj.enhancedLinkAttribution) { + _ga(generateCommandName('require', trackerObj), 'linkid'); } - } - if (enhancedLinkAttribution) { - _ga('require', 'linkid', 'linkid.js'); - } + if (trackRoutes && !ignoreFirstPageLoad) { + _ga(generateCommandName('send', trackerObj), 'pageview', getUrl()); + } + }); if (experimentId) { var expScript = document.createElement('script'), @@ -383,12 +447,24 @@ return true; }; - this._ecommerceEnabled = function () { - return ecommerce && !enhancedEcommerce; + this._ecommerceEnabled = function (warn, command) { + var result = ecommerce && !enhancedEcommerce; + if (warn === true && result === false) { + if (ecommerce && enhancedEcommerce) { + that._log('warn', command + ' is not available when Enhanced Ecommerce is enabled with analytics.js'); + } else { + that._log('warn', 'Ecommerce must be enabled to use ' + command + ' with analytics.js'); + } + } + return result; }; - this._enhancedEcommerceEnabled = function () { - return ecommerce && enhancedEcommerce; + this._enhancedEcommerceEnabled = function (warn, command) { + var result = ecommerce && enhancedEcommerce; + if (warn === true && result === false) { + that._log('warn', 'Enhanced Ecommerce must be enabled to use ' + command + ' with analytics.js'); + } + return result; }; /** @@ -440,7 +516,7 @@ _analyticsJs(function () { var opt_fieldObject = {}; var includeFn = function (trackerObj) { - return isPropertyDefined('trackEvent', trackerObj) && trackerObj.trackEvent === true; + return isPropertySetTo('trackEvent', trackerObj, true); }; if (angular.isDefined(noninteraction)) { @@ -472,17 +548,22 @@ _gaq(['_addTrans', transactionId, affiliation, total, tax, shipping, city, state, country]); }); _analyticsJs(function () { - if (that._ecommerceEnabled()) { - _ga('ecommerce:addTransaction', { - id: transactionId, - affiliation: affiliation, - revenue: total, - tax: tax, - shipping: shipping, - currency: currency || 'USD' - }); - } else { - that._log('warn', 'Ecommerce must be enabled to use addTrans with analytics.js'); + if (that._ecommerceEnabled(true, 'addTrans')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers( + includeFn, + 'ecommerce:addTransaction', + { + id: transactionId, + affiliation: affiliation, + revenue: total, + tax: tax, + shipping: shipping, + currency: currency || 'USD' + }); } }); }; @@ -504,17 +585,22 @@ _gaq(['_addItem', transactionId, sku, name, category, price, quantity]); }); _analyticsJs(function () { - if (that._ecommerceEnabled()) { - _ga('ecommerce:addItem', { - id: transactionId, - name: name, - sku: sku, - category: category, - price: price, - quantity: quantity - }); - } else { - that._log('warn', 'Ecommerce must be enabled to use addItem with analytics.js'); + if (that._ecommerceEnabled(true, 'addItem')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers( + includeFn, + 'ecommerce:addItem', + { + id: transactionId, + name: name, + sku: sku, + category: category, + price: price, + quantity: quantity + }); } }); }; @@ -530,10 +616,12 @@ _gaq(['_trackTrans']); }); _analyticsJs(function () { - if (that._ecommerceEnabled()) { - _ga('ecommerce:send'); - } else { - that._log('warn', 'Ecommerce must be enabled to use trackTrans with analytics.js'); + if (that._ecommerceEnabled(true, 'trackTrans')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers(includeFn, 'ecommerce:send'); } }); }; @@ -545,10 +633,12 @@ */ this._clearTrans = function () { _analyticsJs(function () { - if (that._ecommerceEnabled()) { - _ga('ecommerce:clear'); - } else { - that._log('warn', 'Ecommerce must be enabled to use clearTrans with analytics.js'); + if (that._ecommerceEnabled(true, 'clearTrans')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers(includeFn, 'ecommerce:clear'); } }); }; @@ -569,26 +659,32 @@ * @param quantity * @param coupon * @param position + * @private */ this._addProduct = function (productId, name, category, brand, variant, price, quantity, coupon, position) { _gaJs(function () { _gaq(['_addProduct', productId, name, category, brand, variant, price, quantity, coupon, position]); }); _analyticsJs(function () { - if (that._enhancedEcommerceEnabled()) { - _ga('ec:addProduct', { - id: productId, - name: name, - category: category, - brand: brand, - variant: variant, - price: price, - quantity: quantity, - coupon: coupon, - position: position - }); - } else { - that._log('warn', 'Enhanced ecommerce must be enabled to use addProduct with analytics.js'); + if (that._enhancedEcommerceEnabled(true, 'addProduct')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers( + includeFn, + 'ec:addProduct', + { + id: productId, + name: name, + category: category, + brand: brand, + variant: variant, + price: price, + quantity: quantity, + coupon: coupon, + position: position + }); } }); }; @@ -604,25 +700,31 @@ * @param variant * @param position * @param price + * @private */ this._addImpression = function (id, name, list, brand, category, variant, position, price){ _gaJs(function () { _gaq(['_addImpression', id, name, list, brand, category, variant, position, price]); }); _analyticsJs(function () { - if (that._enhancedEcommerceEnabled()) { - _ga('ec:addImpression', { - id: id, - name: name, - category: category, - brand: brand, - variant: variant, - list: list, - position: position, - price: price - }); - } else { - that._log('warn', 'Enhanced ecommerce must be enabled to use addImpression with analytics.js'); + if (that._enhancedEcommerceEnabled(true, 'addImpression')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers( + includeFn, + 'ec:addImpression', + { + id: id, + name: name, + category: category, + brand: brand, + variant: variant, + list: list, + position: position, + price: price + }); } }); }; @@ -634,69 +736,50 @@ * @param name * @param creative * @param position + * @private */ this._addPromo = function (productId, name, creative, position) { _gaJs(function () { _gaq(['_addPromo', productId, name, creative, position]); }); _analyticsJs(function () { - if (that._enhancedEcommerceEnabled()) { - _ga('ec:addPromo', { - id: productId, - name: name, - creative: creative, - position: position - }); - } else { - that._log('warn', 'Enhanced ecommerce must be enabled to use addPromo with analytics.js'); + if (that._enhancedEcommerceEnabled(true, 'addPromo')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers( + includeFn, + 'ec:addPromo', + { + id: productId, + name: name, + creative: creative, + position: position + }); } }); }; - /** - * get ActionFieldObject - * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data - * @param id - * @param affliation - * @param revenue - * @param tax - * @param shipping - * @param coupon - * @param list - * @param step - * @param option - */ - this._getActionFieldObject = function (id, affiliation, revenue, tax, shipping, coupon, list, step, option) { - var obj = {}; - if (id) { obj.id = id; } - if (affiliation) { obj.affiliation = affiliation; } - if (revenue) { obj.revenue = revenue; } - if (tax) { obj.tax = tax; } - if (shipping) { obj.shipping = shipping; } - if (coupon) { obj.coupon = coupon; } - if (list) { obj.list = list; } - if (step) { obj.step = step; } - if (option) { obj.option = option; } - return obj; - }; - /** * Set Action being performed * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-actions * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-types * @param action - * @param name * @param obj + * @private */ this._setAction = function (action, obj){ _gaJs(function () { _gaq(['_setAction', action, obj]); }); _analyticsJs(function () { - if (that._enhancedEcommerceEnabled()) { - _ga('ec:setAction', action, obj); - } else { - that._log('warn', 'Enhanced ecommerce must be enabled to use setAction with analytics.js'); + if (that._enhancedEcommerceEnabled(true, 'setAction')) { + var includeFn = function (trackerObj) { + return isPropertySetTo('trackEcommerce', trackerObj, true); + }; + + _gaMultipleTrackers(includeFn, 'ec:setAction', action, obj); } }); }; @@ -713,19 +796,20 @@ * @param list * @param step * @param option + * @private */ this._trackTransaction = function (transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option) { - this._setAction('purchase', this._getActionFieldObject(transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option)); + this._setAction('purchase', getActionFieldObject(transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option)); }; /** * Track Refund * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-refunds * @param transactionId - * + * @private */ this._trackRefund = function (transactionId) { - this._setAction('refund', this._getActionFieldObject(transactionId)); + this._setAction('refund', getActionFieldObject(transactionId)); }; /** @@ -733,22 +817,31 @@ * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-checkout * @param step * @param option - * + * @private */ this._trackCheckOut = function (step, option) { - this._setAction('checkout', this._getActionFieldObject(null, null, null, null, null, null, null, step, option)); + this._setAction('checkout', getActionFieldObject(null, null, null, null, null, null, null, step, option)); + }; + + /** + * Track detail + * @private + */ + this._trackDetail = function () { + this._setAction('detail'); + this._pageView(); }; /** * Track add/remove to cart * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#add-remove-cart * @param action - * + * @private */ this._trackCart = function (action) { if (['add', 'remove'].indexOf(action) !== -1) { this._setAction(action); - this._send('event', 'UX', 'click', action + ' to cart'); + this._trackEvent('UX', 'click', action + (action === 'add' ? ' to cart' : ' from cart')); } }; @@ -756,30 +849,39 @@ * Track promo click * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks * @param promotionName - * + * @private */ this._promoClick = function (promotionName) { this._setAction('promo_click'); - this._send('event', 'Internal Promotions', 'click', promotionName); + this._trackEvent('Internal Promotions', 'click', promotionName); }; /** * Track product click * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-promo-clicks * @param promotionName - * + * @private */ this._productClick = function (listName) { - this._setAction('click', this._getActionFieldObject(null, null, null, null, null, null, listName, null, null)); - this._send('event', 'UX', 'click', listName); + this._setAction('click', getActionFieldObject(null, null, null, null, null, null, listName, null, null)); + this._trackEvent('UX', 'click', listName); + }; + + /** + * Send page view + * @param trackerName + * @private + */ + this._pageView = function (trackerName) { + _analyticsJs(function () { + _ga(generateCommandName('send', trackerName), 'pageview'); + }); }; /** * Send custom events * https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings#implementation * https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions#implementation - * - * @param obj * @private */ this._send = function () { @@ -790,30 +892,28 @@ }); }; - this._pageView = function () { - this._send('pageview'); - }; - /** * Set custom dimensions, metrics or experiment * https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets * https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs - * @param name - * @param value + * @param name (Required) + * @param value (Required) + * @param trackerName (Not Required) * @private */ - this._set = function (name, value) { + this._set = function (name, value, trackerName) { _analyticsJs(function () { - _ga('set', name, value); + _ga(generateCommandName('set', trackerName), name, value); }); }; /** - * Track User Timings - * @timingCategory (Required): A string for categorizing all user timing variables into logical groups(e.g jQuery). - * @timingVar (Required): A string to identify the variable being recorded(e.g. JavaScript Load). - * @timingValue (Required): The number of milliseconds in elapsed time to report to Google Analytics(e.g. 20). - * @timingLabel (Not Required): A string that can be used to add flexibility in visualizing user timings in the reports(e.g. Google CDN). + * Track user timings + * @param timingCategory (Required): A string for categorizing all user timing variables into logical groups(e.g jQuery). + * @param timingVar (Required): A string to identify the variable being recorded(e.g. JavaScript Load). + * @param timingValue (Required): The number of milliseconds in elapsed time to report to Google Analytics(e.g. 20). + * @param timingLabel (Not Required): A string that can be used to add flexibility in visualizing user timings in the reports(e.g. Google CDN). + * @private */ this._trackTimings = function (timingCategory, timingVar, timingValue, timingLabel) { this._send('timing', timingCategory, timingVar, timingValue, timingLabel); @@ -836,15 +936,29 @@ } return { - _logs: that._logs, - displayFeatures: displayFeatures, - ecommerce: ecommerce, - enhancedEcommerce: enhancedEcommerce, - enhancedLinkAttribution: enhancedLinkAttribution, + log: that.log, + configuration: { + accounts: accounts, + universalAnalytics: analyticsJS, + crossDomainLinker: crossDomainLinker, + crossLinkDomains: crossLinkDomains, + currency: currency, + delayScriptTag: delayScriptTag, + displayFeatures: displayFeatures, + domainName: domainName, + ecommerce: that._ecommerceEnabled(), + enhancedEcommerce: that._enhancedEcommerceEnabled(), + enhancedLinkAttribution: enhancedLinkAttribution, + experimentId: experimentId, + ignoreFirstPageLoad: ignoreFirstPageLoad, + logAllCalls: logAllCalls, + pageEvent: pageEvent, + removeRegExp: removeRegExp, + trackPrefix: trackPrefix, + trackRoutes: trackRoutes, + trackUrlParams: trackUrlParams + }, getUrl: getUrl, - experimentId: experimentId, - ignoreFirstPageLoad: ignoreFirstPageLoad, - delayScriptTag: delayScriptTag, setCookieConfig: that._setCookieConfig, getCookieConfig: function () { return cookieConfig; @@ -863,11 +977,20 @@ return that._createScriptTag(); }, - ecommerceEnabled: function () { - return that._ecommerceEnabled(); - }, - enhancedEcommerceEnabled: function () { - return that._enhancedEcommerceEnabled(); + offline: function (mode) { + if (mode === true && offlineMode === false) { + // Go to offline mode + offlineMode = true; + } + if (mode === false && offlineMode === true) { + // Go to online mode and process the offline queue + offlineMode = false; + while (that._offlineQueue.length > 0) { + var obj = that._offlineQueue.shift(); + obj[0].apply(that, obj[1]); + } + } + return offlineMode; }, trackPage: function (url, title, custom) { that._trackPage(url, title, custom); @@ -903,8 +1026,7 @@ that._promoClick(promotionName); }, trackDetail: function () { - that._setAction('detail'); - that._pageView(); + that._trackDetail(); }, trackCart: function (action) { that._trackCart(action); @@ -921,14 +1043,14 @@ setAction: function (action, obj) { that._setAction(action, obj); }, - send: function (obj) { - that._send(obj); - }, pageView: function () { that._pageView(); }, - set: function (name, value) { - that._set(name, value); + send: function (obj) { + that._send(obj); + }, + set: function (name, value, trackerName) { + that._set(name, value, trackerName); } }; }]; diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index f3fff6a..1519e73 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,9 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v1.0.0 - 2015-08-26 + * @version v1.1.0 - 2015-09-12 * @link http://github.com/revolunet/angular-google-analytics - * @author Julien Bouquillon + * @author Julien Bouquillon (https://github.com/revolunet) + * @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) * @license MIT License, http://www.opensource.org/licenses/MIT */ -(function(n,t,e,i){"use strict";e.module("angular-google-analytics",[]).provider("Analytics",function(){var c,a,r,o,s,u,l=!1,d=!0,m="",f=!1,g="$routeChangeSuccess",p="auto",_=!1,h=!1,k=!1,y="USD",w=!1,E=!1,v=!1,b=!1,T=!1;this._logs=[],this.setAccount=function(n){return c=e.isUndefined(n)||n===!1?i:e.isArray(n)?n:e.isObject(n)?[n]:[{tracker:n,trackEvent:!0}],!0},this.trackPages=function(n){return d=n,!0},this.trackPrefix=function(n){return m=n,!0},this.setDomainName=function(n){return r=n,!0},this.useDisplayFeatures=function(n){return a=!!n,!0},this.useAnalytics=function(n){return f=!!n,!0},this.useEnhancedLinkAttribution=function(n){return k=!!n,!0},this.useCrossDomainLinker=function(n){return E=!!n,!0},this.setCrossLinkDomains=function(n){return u=n,!0},this.setPageEvent=function(n){return g=n,!0},this.setCookieConfig=function(n){return p=n,!0},this.useECommerce=function(n,t){return _=!!n,h=!!t,!0},this.setCurrency=function(n){return y=n,!0},this.setRemoveRegExp=function(n){return n instanceof RegExp?(o=n,!0):!1},this.setExperimentId=function(n){return s=n,!0},this.ignoreFirstPageLoad=function(n){return w=!!n,!0},this.trackUrlParams=function(n){return v=!!n,!0},this.delayScriptTag=function(n){return b=!!n,!0},this.logAllCalls=function(n){return T=!!n,!0},this.$get=["$document","$location","$log","$rootScope","$window",function(A,j,C,P,D){var I=this,L=function(n,t){return q("name",t)?t.name+"."+n:n},q=function(n,t){return e.isObject(t)&&e.isDefined(t[n])},S=function(){var n=v?j.url():j.path();return o?n.replace(o,""):n},x=function(){var n={utm_source:"campaignSource",utm_medium:"campaignMedium",utm_term:"campaignTerm",utm_content:"campaignContent",utm_campaign:"campaignName"},t={};return e.forEach(j.search(),function(i,c){var a=n[c];e.isDefined(a)&&(t[a]=i)}),t},O=function(n){!f&&D._gaq&&"function"==typeof n&&n()},N=function(){D._gaq||(D._gaq=[]),T===!0&&I._log.apply(I,arguments),D._gaq.push.apply(D._gaq,arguments)},$=function(n){f&&D.ga&&"function"==typeof n&&n()},F=function(){return"function"!=typeof D.ga?(I._log("warn","ga function not set on window"),i):(T===!0&&I._log.apply(I,arguments),D.ga.apply(null,arguments),i)},U=function(n){if("function"!=typeof D.ga)return I._log("warn","ga function not set on window"),i;var t=Array.prototype.slice.call(arguments,1),e=t[0];c.forEach(function(i){("function"!=typeof n||n(i))&&(t[0]=L(e,i),T===!0&&I._log.apply(I,t),D.ga.apply(null,t))})};return this._log=function(){if(arguments.length>0){if(arguments.length>1)switch(arguments[0]){case"warn":C.warn(Array.prototype.slice.call(arguments,1));break;case"error":C.error(Array.prototype.slice.call(arguments,1))}this._logs.push(Array.prototype.slice.call(arguments))}},this._createScriptTag=function(){if(!c||1>c.length)return this._log("warn","No account id set to create script tag"),i;if(c.length>1&&(this._log("warn","Multiple trackers are not supported with ga.js. Using first tracker only"),c=c.slice(0,1)),l===!0)return this._log("warn","ga.js or analytics.js script tag already created"),i;N(["_setAccount",c[0].tracker]),r&&N(["_setDomainName",r]),k&&N(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),d&&!w&&(o?N(["_trackPageview",S()]):N(["_trackPageview"]));var n;return n=a?("https:"===t.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===t.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",function(){var t=A[0],e=t.createElement("script");e.type="text/javascript",e.async=!0,e.src=n;var i=t.getElementsByTagName("script")[0];i.parentNode.insertBefore(e,i)}(n),l=!0,!0},this._createAnalyticsScriptTag=function(){if(!c)return this._log("warn","No account id set to create analytics script tag"),i;if(l===!0)return this._log("warn","ga.js or analytics.js script tag already created"),i;if(function(n,t,e,i,c,a,r){n.GoogleAnalyticsObject=c,n[c]=n[c]||function(){(n[c].q=n[c].q||[]).push(arguments)},n[c].l=1*new Date,a=t.createElement(e),r=t.getElementsByTagName(e)[0],a.async=1,a.src=i,r.parentNode.insertBefore(a,r)}(n,t,"script","//www.google-analytics.com/analytics.js","ga"),c.forEach(function(n){var t={};n.crossDomainLinker=q("crossDomainLinker",n)?n.crossDomainLinker:E,n.cookieConfig=q("cookieConfig",n)?n.cookieConfig:p,n.crossLinkDomains=q("crossLinkDomains",n)?n.crossLinkDomains:u,n.trackEvent=q("trackEvent",n)?n.trackEvent:!1,t.allowLinker=n.crossDomainLinker,q("name",n)&&(t.name=n.name),F("create",n.tracker,n.cookieConfig,t),n.crossDomainLinker===!0&&(F(L("require",n),"linker"),e.isDefined(n.crossLinkDomains)&&F(L("linker:autoLink",n),n.crossLinkDomains))}),a&&F("require","displayfeatures"),d&&!w&&F("send","pageview",S()),_&&(h?(F("require","ec","ec.js"),F("set","&cu",y)):F("require","ecommerce","ecommerce.js")),k&&F("require","linkid","linkid.js"),s){var r=t.createElement("script"),o=t.getElementsByTagName("script")[0];r.src="//www.google-analytics.com/cx/api.js?experiment="+s,o.parentNode.insertBefore(r,o)}return l=!0,!0},this._ecommerceEnabled=function(){return _&&!h},this._enhancedEcommerceEnabled=function(){return _&&h},this._trackPage=function(n,t,c){n=n?n:S(),t=t?t:A[0].title,O(function(){N(["_set","title",t]),N(["_trackPageview",m+n])}),$(function(){var a={page:m+n,title:t};e.extend(a,x()),e.isObject(c)&&e.extend(a,c),U(i,"send","pageview",a)})},this._trackEvent=function(n,t,i,c,a,r){O(function(){N(["_trackEvent",n,t,i,c,!!a])}),$(function(){var o={},s=function(n){return q("trackEvent",n)&&n.trackEvent===!0};e.isDefined(a)&&(o.nonInteraction=!!a),e.isObject(r)&&e.extend(o,r),U(s,"send","event",n,t,i,c,o)})},this._addTrans=function(n,t,e,i,c,a,r,o,s){O(function(){N(["_addTrans",n,t,e,i,c,a,r,o])}),$(function(){I._ecommerceEnabled()?F("ecommerce:addTransaction",{id:n,affiliation:t,revenue:e,tax:i,shipping:c,currency:s||"USD"}):I._log("warn","Ecommerce must be enabled to use addTrans with analytics.js")})},this._addItem=function(n,t,e,i,c,a){O(function(){N(["_addItem",n,t,e,i,c,a])}),$(function(){I._ecommerceEnabled()?F("ecommerce:addItem",{id:n,name:e,sku:t,category:i,price:c,quantity:a}):I._log("warn","Ecommerce must be enabled to use addItem with analytics.js")})},this._trackTrans=function(){O(function(){N(["_trackTrans"])}),$(function(){I._ecommerceEnabled()?F("ecommerce:send"):I._log("warn","Ecommerce must be enabled to use trackTrans with analytics.js")})},this._clearTrans=function(){$(function(){I._ecommerceEnabled()?F("ecommerce:clear"):I._log("warn","Ecommerce must be enabled to use clearTrans with analytics.js")})},this._addProduct=function(n,t,e,i,c,a,r,o,s){O(function(){N(["_addProduct",n,t,e,i,c,a,r,o,s])}),$(function(){I._enhancedEcommerceEnabled()?F("ec:addProduct",{id:n,name:t,category:e,brand:i,variant:c,price:a,quantity:r,coupon:o,position:s}):I._log("warn","Enhanced ecommerce must be enabled to use addProduct with analytics.js")})},this._addImpression=function(n,t,e,i,c,a,r,o){O(function(){N(["_addImpression",n,t,e,i,c,a,r,o])}),$(function(){I._enhancedEcommerceEnabled()?F("ec:addImpression",{id:n,name:t,category:c,brand:i,variant:a,list:e,position:r,price:o}):I._log("warn","Enhanced ecommerce must be enabled to use addImpression with analytics.js")})},this._addPromo=function(n,t,e,i){O(function(){N(["_addPromo",n,t,e,i])}),$(function(){I._enhancedEcommerceEnabled()?F("ec:addPromo",{id:n,name:t,creative:e,position:i}):I._log("warn","Enhanced ecommerce must be enabled to use addPromo with analytics.js")})},this._getActionFieldObject=function(n,t,e,i,c,a,r,o,s){var u={};return n&&(u.id=n),t&&(u.affiliation=t),e&&(u.revenue=e),i&&(u.tax=i),c&&(u.shipping=c),a&&(u.coupon=a),r&&(u.list=r),o&&(u.step=o),s&&(u.option=s),u},this._setAction=function(n,t){O(function(){N(["_setAction",n,t])}),$(function(){I._enhancedEcommerceEnabled()?F("ec:setAction",n,t):I._log("warn","Enhanced ecommerce must be enabled to use setAction with analytics.js")})},this._trackTransaction=function(n,t,e,i,c,a,r,o,s){this._setAction("purchase",this._getActionFieldObject(n,t,e,i,c,a,r,o,s))},this._trackRefund=function(n){this._setAction("refund",this._getActionFieldObject(n))},this._trackCheckOut=function(n,t){this._setAction("checkout",this._getActionFieldObject(null,null,null,null,null,null,null,n,t))},this._trackCart=function(n){-1!==["add","remove"].indexOf(n)&&(this._setAction(n),this._send("event","UX","click",n+" to cart"))},this._promoClick=function(n){this._setAction("promo_click"),this._send("event","Internal Promotions","click",n)},this._productClick=function(n){this._setAction("click",this._getActionFieldObject(null,null,null,null,null,null,n,null,null)),this._send("event","UX","click",n)},this._send=function(){var n=Array.prototype.slice.call(arguments);n.unshift("send"),$(function(){F.apply(I,n)})},this._pageView=function(){this._send("pageview")},this._set=function(n,t){$(function(){F("set",n,t)})},this._trackTimings=function(n,t,e,i){this._send("timing",n,t,e,i)},b||(f?this._createAnalyticsScriptTag():this._createScriptTag()),d&&P.$on(g,function(){I._trackPage()}),{_logs:I._logs,displayFeatures:a,ecommerce:_,enhancedEcommerce:h,enhancedLinkAttribution:k,getUrl:S,experimentId:s,ignoreFirstPageLoad:w,delayScriptTag:b,setCookieConfig:I._setCookieConfig,getCookieConfig:function(){return p},createAnalyticsScriptTag:function(n){return n&&(p=n),I._createAnalyticsScriptTag()},createScriptTag:function(n){return n&&(p=n),I._createScriptTag()},ecommerceEnabled:function(){return I._ecommerceEnabled()},enhancedEcommerceEnabled:function(){return I._enhancedEcommerceEnabled()},trackPage:function(n,t,e){I._trackPage(n,t,e)},trackEvent:function(n,t,e,i,c,a){I._trackEvent(n,t,e,i,c,a)},addTrans:function(n,t,e,i,c,a,r,o,s){I._addTrans(n,t,e,i,c,a,r,o,s)},addItem:function(n,t,e,i,c,a){I._addItem(n,t,e,i,c,a)},trackTrans:function(){I._trackTrans()},clearTrans:function(){I._clearTrans()},addProduct:function(n,t,e,i,c,a,r,o,s){I._addProduct(n,t,e,i,c,a,r,o,s)},addPromo:function(n,t,e,i){I._addPromo(n,t,e,i)},addImpression:function(n,t,e,i,c,a,r,o){I._addImpression(n,t,e,i,c,a,r,o)},productClick:function(n){I._productClick(n)},promoClick:function(n){I._promoClick(n)},trackDetail:function(){I._setAction("detail"),I._pageView()},trackCart:function(n){I._trackCart(n)},trackCheckout:function(n,t){I._trackCheckOut(n,t)},trackTimings:function(n,t,e,i){I._trackTimings(n,t,e,i)},trackTransaction:function(n,t,e,i,c,a,r,o,s){I._trackTransaction(n,t,e,i,c,a,r,o,s)},setAction:function(n,t){I._setAction(n,t)},send:function(n){I._send(n)},pageView:function(){I._pageView()},set:function(n,t){I._set(n,t)}}}]}).directive("gaTrackEvent",["Analytics","$parse",function(n,t){return{restrict:"A",link:function(e,i,c){var a=t(c.gaTrackEvent);i.bind("click",function(){(!c.gaTrackEventIf||e.$eval(c.gaTrackEventIf))&&a.length>1&&n.trackEvent.apply(n,a(e))})}}}])})(window,document,window.angular); \ No newline at end of file +!function(a,b,c,d){"use strict";c.module("angular-google-analytics",[]).provider("Analytics",function(){var e,f,g,h,i,j,k=!0,l="auto",m=!1,n=!1,o="USD",p=!1,q=!1,r=!1,s=!1,t=!1,u=!1,v=!1,w="$routeChangeSuccess",x="",y=!0,z=!1;this.log=[],this._offlineQueue=[],this.setAccount=function(a){return e=c.isUndefined(a)||a===!1?d:c.isArray(a)?a:c.isObject(a)?[a]:[{tracker:a,trackEvent:!0}],this},this.trackPages=function(a){return y=a,this},this.trackPrefix=function(a){return x=a,this},this.setDomainName=function(a){return h=a,this},this.useDisplayFeatures=function(a){return g=!!a,this},this.useAnalytics=function(a){return k=!!a,this},this.useEnhancedLinkAttribution=function(a){return s=!!a,this},this.useCrossDomainLinker=function(a){return n=!!a,this},this.setCrossLinkDomains=function(a){return f=a,this},this.setPageEvent=function(a){return w=a,this},this.setCookieConfig=function(a){return l=a,this},this.useECommerce=function(a,b){return q=!!a,r=!!b,this},this.setCurrency=function(a){return o=a,this},this.setRemoveRegExp=function(a){return a instanceof RegExp&&(j=a),this},this.setExperimentId=function(a){return i=a,this},this.ignoreFirstPageLoad=function(a){return t=!!a,this},this.trackUrlParams=function(a){return z=!!a,this},this.startOffline=function(a){return v=!!a,v===!0&&this.delayScriptTag(!0),this},this.delayScriptTag=function(a){return p=!!a,this},this.logAllCalls=function(a){return u=!!a,this},this.$get=["$document","$location","$log","$rootScope","$window",function(A,B,C,D,E){var F=this,G=function(a,b){return c.isString(b)?b+"."+a:H("name",b)?b.name+"."+a:a},H=function(a,b){return c.isObject(b)&&c.isDefined(b[a])},I=function(a,b,c){return H(a,b)&&b[a]===c},J=function(){var a=z?B.url():B.path();return j?a.replace(j,""):a},K=function(){var a={utm_source:"campaignSource",utm_medium:"campaignMedium",utm_term:"campaignTerm",utm_content:"campaignContent",utm_campaign:"campaignName"},b={};return c.forEach(B.search(),function(d,e){var f=a[e];c.isDefined(f)&&(b[f]=d)}),b},L=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},M=function(a){!k&&E._gaq&&"function"==typeof a&&a()},N=function(){return v===!0?void F._offlineQueue.push([N,arguments]):(E._gaq||(E._gaq=[]),u===!0&&F._log.apply(F,arguments),void E._gaq.push.apply(E._gaq,arguments))},O=function(a){k&&E.ga&&"function"==typeof a&&a()},P=function(){return v===!0?void F._offlineQueue.push([P,arguments]):"function"!=typeof E.ga?void F._log("warn","ga function not set on window"):(u===!0&&F._log.apply(F,arguments),void E.ga.apply(null,arguments))},Q=function(a){var b=Array.prototype.slice.call(arguments,1),c=b[0],d=[];return"function"==typeof a?e.forEach(function(b){a(b)&&d.push(b)}):d=e,0===d.length?void P.apply(F,b):void d.forEach(function(a){b[0]=G(c,a),P.apply(F,b)})};return this._log=function(){if(arguments.length>0){if(arguments.length>1)switch(arguments[0]){case"warn":C.warn(Array.prototype.slice.call(arguments,1));break;case"error":C.error(Array.prototype.slice.call(arguments,1))}this.log.push(Array.prototype.slice.call(arguments))}},this._createScriptTag=function(){if(!e||e.length<1)return void this._log("warn","No account id set to create script tag");if(e.length>1&&(this._log("warn","Multiple trackers are not supported with ga.js. Using first tracker only"),e=e.slice(0,1)),m===!0)return void this._log("warn","ga.js or analytics.js script tag already created");N(["_setAccount",e[0].tracker]),h&&N(["_setDomainName",h]),s&&N(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),y&&!t&&N(j?["_trackPageview",J()]:["_trackPageview"]);var a;return a=g?("https:"===b.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===b.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",function(){var b=A[0],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)}(a),m=!0,!0},this._createAnalyticsScriptTag=function(){if(!e)return void this._log("warn","No account id set to create analytics script tag");if(m===!0)return void this._log("warn","ga.js or analytics.js script tag already created");if(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)}(a,b,"script","//www.google-analytics.com/analytics.js","ga"),e.forEach(function(a){var b={};a.cookieConfig=H("cookieConfig",a)?a.cookieConfig:l,a.crossDomainLinker=H("crossDomainLinker",a)?a.crossDomainLinker:n,a.crossLinkDomains=H("crossLinkDomains",a)?a.crossLinkDomains:f,a.displayFeatures=H("displayFeatures",a)?a.displayFeatures:g,a.enhancedLinkAttribution=H("enhancedLinkAttribution",a)?a.enhancedLinkAttribution:s,a.trackEcommerce=H("trackEcommerce",a)?a.trackEcommerce:q,a.trackEvent=H("trackEvent",a)?a.trackEvent:!1,b.allowLinker=a.crossDomainLinker,H("name",a)&&(b.name=a.name),P("create",a.tracker,a.cookieConfig,b),a.crossDomainLinker===!0&&(P(G("require",a),"linker"),c.isDefined(a.crossLinkDomains)&&P(G("linker:autoLink",a),a.crossLinkDomains)),a.displayFeatures&&P(G("require",a),"displayfeatures"),a.trackEcommerce&&(r?(P(G("require",a),"ec"),P(G("set",a),"&cu",o)):P(G("require",a),"ecommerce")),a.enhancedLinkAttribution&&P(G("require",a),"linkid"),y&&!t&&P(G("send",a),"pageview",J())}),i){var d=b.createElement("script"),h=b.getElementsByTagName("script")[0];d.src="//www.google-analytics.com/cx/api.js?experiment="+i,h.parentNode.insertBefore(d,h)}return m=!0,!0},this._ecommerceEnabled=function(a,b){var c=q&&!r;return a===!0&&c===!1&&(q&&r?F._log("warn",b+" is not available when Enhanced Ecommerce is enabled with analytics.js"):F._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&&F._log("warn","Enhanced Ecommerce must be enabled to use "+b+" with analytics.js"),c},this._trackPage=function(a,b,e){a=a?a:J(),b=b?b:A[0].title,M(function(){N(["_set","title",b]),N(["_trackPageview",x+a])}),O(function(){var f={page:x+a,title:b};c.extend(f,K()),c.isObject(e)&&c.extend(f,e),Q(d,"send","pageview",f)})},this._trackEvent=function(a,b,d,e,f,g){M(function(){N(["_trackEvent",a,b,d,e,!!f])}),O(function(){var h={},i=function(a){return I("trackEvent",a,!0)};c.isDefined(f)&&(h.nonInteraction=!!f),c.isObject(g)&&c.extend(h,g),Q(i,"send","event",a,b,d,e,h)})},this._addTrans=function(a,b,c,d,e,f,g,h,i){M(function(){N(["_addTrans",a,b,c,d,e,f,g,h])}),O(function(){if(F._ecommerceEnabled(!0,"addTrans")){var f=function(a){return I("trackEcommerce",a,!0)};Q(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){M(function(){N(["_addItem",a,b,c,d,e,f])}),O(function(){if(F._ecommerceEnabled(!0,"addItem")){var g=function(a){return I("trackEcommerce",a,!0)};Q(g,"ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f})}})},this._trackTrans=function(){M(function(){N(["_trackTrans"])}),O(function(){if(F._ecommerceEnabled(!0,"trackTrans")){var a=function(a){return I("trackEcommerce",a,!0)};Q(a,"ecommerce:send")}})},this._clearTrans=function(){O(function(){if(F._ecommerceEnabled(!0,"clearTrans")){var a=function(a){return I("trackEcommerce",a,!0)};Q(a,"ecommerce:clear")}})},this._addProduct=function(a,b,c,d,e,f,g,h,i){M(function(){N(["_addProduct",a,b,c,d,e,f,g,h,i])}),O(function(){if(F._enhancedEcommerceEnabled(!0,"addProduct")){var j=function(a){return I("trackEcommerce",a,!0)};Q(j,"ec:addProduct",{id:a,name:b,category:c,brand:d,variant:e,price:f,quantity:g,coupon:h,position:i})}})},this._addImpression=function(a,b,c,d,e,f,g,h){M(function(){N(["_addImpression",a,b,c,d,e,f,g,h])}),O(function(){if(F._enhancedEcommerceEnabled(!0,"addImpression")){var i=function(a){return I("trackEcommerce",a,!0)};Q(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){M(function(){N(["_addPromo",a,b,c,d])}),O(function(){if(F._enhancedEcommerceEnabled(!0,"addPromo")){var e=function(a){return I("trackEcommerce",a,!0)};Q(e,"ec:addPromo",{id:a,name:b,creative:c,position:d})}})},this._setAction=function(a,b){M(function(){N(["_setAction",a,b])}),O(function(){if(F._enhancedEcommerceEnabled(!0,"setAction")){var c=function(a){return I("trackEcommerce",a,!0)};Q(c,"ec:setAction",a,b)}})},this._trackTransaction=function(a,b,c,d,e,f,g,h,i){this._setAction("purchase",L(a,b,c,d,e,f,g,h,i))},this._trackRefund=function(a){this._setAction("refund",L(a))},this._trackCheckOut=function(a,b){this._setAction("checkout",L(null,null,null,null,null,null,null,a,b))},this._trackDetail=function(){this._setAction("detail"),this._pageView()},this._trackCart=function(a){-1!==["add","remove"].indexOf(a)&&(this._setAction(a),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",L(null,null,null,null,null,null,a,null,null)),this._trackEvent("UX","click",a)},this._pageView=function(a){O(function(){P(G("send",a),"pageview")})},this._send=function(){var a=Array.prototype.slice.call(arguments);a.unshift("send"),O(function(){P.apply(F,a)})},this._set=function(a,b,c){O(function(){P(G("set",c),a,b)})},this._trackTimings=function(a,b,c,d){this._send("timing",a,b,c,d)},p||(k?this._createAnalyticsScriptTag():this._createScriptTag()),y&&D.$on(w,function(){F._trackPage()}),{log:F.log,configuration:{accounts:e,universalAnalytics:k,crossDomainLinker:n,crossLinkDomains:f,currency:o,delayScriptTag:p,displayFeatures:g,domainName:h,ecommerce:F._ecommerceEnabled(),enhancedEcommerce:F._enhancedEcommerceEnabled(),enhancedLinkAttribution:s,experimentId:i,ignoreFirstPageLoad:t,logAllCalls:u,pageEvent:w,removeRegExp:j,trackPrefix:x,trackRoutes:y,trackUrlParams:z},getUrl:J,setCookieConfig:F._setCookieConfig,getCookieConfig:function(){return l},createAnalyticsScriptTag:function(a){return a&&(l=a),F._createAnalyticsScriptTag()},createScriptTag:function(a){return a&&(l=a),F._createScriptTag()},offline:function(a){if(a===!0&&v===!1&&(v=!0),a===!1&&v===!0)for(v=!1;F._offlineQueue.length>0;){var b=F._offlineQueue.shift();b[0].apply(F,b[1])}return v},trackPage:function(a,b,c){F._trackPage(a,b,c)},trackEvent:function(a,b,c,d,e,f){F._trackEvent(a,b,c,d,e,f)},addTrans:function(a,b,c,d,e,f,g,h,i){F._addTrans(a,b,c,d,e,f,g,h,i)},addItem:function(a,b,c,d,e,f){F._addItem(a,b,c,d,e,f)},trackTrans:function(){F._trackTrans()},clearTrans:function(){F._clearTrans()},addProduct:function(a,b,c,d,e,f,g,h,i){F._addProduct(a,b,c,d,e,f,g,h,i)},addPromo:function(a,b,c,d){F._addPromo(a,b,c,d)},addImpression:function(a,b,c,d,e,f,g,h){F._addImpression(a,b,c,d,e,f,g,h)},productClick:function(a){F._productClick(a)},promoClick:function(a){F._promoClick(a)},trackDetail:function(){F._trackDetail()},trackCart:function(a){F._trackCart(a)},trackCheckout:function(a,b){F._trackCheckOut(a,b)},trackTimings:function(a,b,c,d){F._trackTimings(a,b,c,d)},trackTransaction:function(a,b,c,d,e,f,g,h,i){F._trackTransaction(a,b,c,d,e,f,g,h,i)},setAction:function(a,b){F._setAction(a,b)},pageView:function(){F._pageView()},send:function(a){F._send(a)},set:function(a,b,c){F._set(a,b,c)}}}]}).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))})}}}])}(window,document,window.angular); \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 0b0f5d9..0000000 --- a/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - Fork me on GitHub -

AngularJS google analytics

-
A simple service to use google analytics tracker in your AngularJS apps.
- -

- Here's an example usage : -

- - - - - diff --git a/package.json b/package.json index 07da2b0..ecdbe47 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,15 @@ { "name": "angular-google-analytics", "description": "Angular Google Analytics - Easy tracking for your AngularJS application", - "version": "1.0.0", + "version": "1.1.0", "homepage": "http://github.com/revolunet/angular-google-analytics", - "author": "Julien Bouquillon ", + "author": "Julien Bouquillon (https://github.com/revolunet)", + "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)" + ], "main": "index.js", "repository": { "type": "git",