From 9926db0161dcc2e8199752e1140b20a73b73ca34 Mon Sep 17 00:00:00 2001 From: ultrayoshi Date: Wed, 27 Aug 2014 17:57:46 +0200 Subject: [PATCH 01/18] Fix lint error: missing semicolon --- test/unit/angular-google-analytics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index fb566cc..35cf5eb 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -162,7 +162,7 @@ describe('angular-google-analytics', function(){ var data = { name: "dimension1", value: "value1", - } + }; expect(Analytics._logs.length).toBe(0); Analytics.set(data.name, data.value); expect(Analytics._logs.length).toBe(1); From 14347d5d1dfd83d244599857337d5e453b7a2618 Mon Sep 17 00:00:00 2001 From: ultrayoshi Date: Wed, 27 Aug 2014 18:21:06 +0200 Subject: [PATCH 02/18] Call ga create event for each tracker object --- src/angular-google-analytics.js | 8 +++++++- test/unit/angular-google-analytics.js | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index aa3eb64..e9363d0 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -128,7 +128,13 @@ angular.module('angular-google-analytics', []) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m); })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - $window.ga('create', accountId, cookieConfig); + if (angular.isArray(accountId)) { + accountId.forEach(function (trackerObj) { + $window.ga('create', trackerObj.tracker, cookieConfig, { name: trackerObj.name }); + }); + } else { + $window.ga('create', accountId, cookieConfig); + } if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index 35cf5eb..d085e8f 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -245,5 +245,26 @@ describe('angular-google-analytics', function(){ }); + describe('supports multiple tracking objects', function() { + var trackers = [ + { tracker: 'UA-12345-12', name: "tracker1" }, + { tracker: 'UA-12345-34', name: "tracker2" } + ]; + + beforeEach(module(function(AnalyticsProvider) { + AnalyticsProvider.setAccount(trackers); + AnalyticsProvider.useAnalytics(true); + })); + + it('should call ga create event for each tracker', function () { + inject(function($window) { + spyOn($window, 'ga'); + inject(function(Analytics) { + expect($window.ga).toHaveBeenCalledWith('create', trackers[0].tracker, 'auto', { name: trackers[0].name }); + expect($window.ga).toHaveBeenCalledWith('create', trackers[1].tracker, 'auto', { name: trackers[1].name }); + }); + }); + }); + }); }); From 54eeae2e86c42d3580f364648836aeab6d722db6 Mon Sep 17 00:00:00 2001 From: ultrayoshi Date: Wed, 27 Aug 2014 18:27:15 +0200 Subject: [PATCH 03/18] Call ga send pageview event for each tracker --- src/angular-google-analytics.js | 25 +++++++++++++++++-------- test/unit/angular-google-analytics.js | 23 ++++++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index e9363d0..1fcc0ef 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -129,11 +129,11 @@ angular.module('angular-google-analytics', []) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); if (angular.isArray(accountId)) { - accountId.forEach(function (trackerObj) { - $window.ga('create', trackerObj.tracker, cookieConfig, { name: trackerObj.name }); - }); + accountId.forEach(function (trackerObj) { + $window.ga('create', trackerObj.tracker, cookieConfig, { name: trackerObj.name }); + }); } else { - $window.ga('create', accountId, cookieConfig); + $window.ga('create', accountId, cookieConfig); } if (trackRoutes && !ignoreFirstPageLoad) { @@ -170,10 +170,19 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_trackPageview', trackPrefix + url]); this._log('_trackPageview', arguments); } else if (trackRoutes && analyticsJS && $window.ga) { - $window.ga('send', 'pageview', { - 'page': trackPrefix + url, - 'title': title - }); + if (angular.isArray(accountId)) { + accountId.forEach(function (trackerObj) { + $window.ga(trackerObj.name + '.send', 'pageview', { + 'page': trackPrefix + url, + 'title': title + }); + }); + } else { + $window.ga('send', 'pageview', { + 'page': trackPrefix + url, + 'title': title + }); + } this._log('pageview', arguments); } }; diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index d085e8f..b1dc9e6 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -257,13 +257,26 @@ describe('angular-google-analytics', function(){ })); it('should call ga create event for each tracker', function () { + inject(function($window) { + spyOn($window, 'ga'); + inject(function(Analytics) { + expect($window.ga).toHaveBeenCalledWith('create', trackers[0].tracker, 'auto', { name: trackers[0].name }); + expect($window.ga).toHaveBeenCalledWith('create', trackers[1].tracker, 'auto', { name: trackers[1].name }); + }); + }); + }); + + describe('#trackPage', function () { + it('should call ga send pageview event for each tracker', function () { inject(function($window) { - spyOn($window, 'ga'); - inject(function(Analytics) { - expect($window.ga).toHaveBeenCalledWith('create', trackers[0].tracker, 'auto', { name: trackers[0].name }); - expect($window.ga).toHaveBeenCalledWith('create', trackers[1].tracker, 'auto', { name: trackers[1].name }); - }); + spyOn($window, 'ga'); + inject(function(Analytics) { + Analytics.trackPage('/mypage', 'My Page'); + expect($window.ga).toHaveBeenCalledWith(trackers[0].name + '.send', 'pageview', { page: '/mypage', title: 'My Page' }); + expect($window.ga).toHaveBeenCalledWith(trackers[1].name + '.send', 'pageview', { page: '/mypage', title: 'My Page' }); + }); }); + }); }); }); }); From 2e24ec16dddb02086588f60d9f3b11f2936bba0e Mon Sep 17 00:00:00 2001 From: ultrayoshi Date: Wed, 27 Aug 2014 18:39:37 +0200 Subject: [PATCH 04/18] Make new distribution --- dist/angular-google-analytics.js | 46 ++++++++++++++++++++++++---- dist/angular-google-analytics.min.js | 4 +-- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index 39de5b4..52ee788 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,6 +1,6 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.3 - 2014-06-05 + * @version v0.0.3 - 2014-08-27 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT @@ -135,7 +135,13 @@ angular.module('angular-google-analytics', []) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m); })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - $window.ga('create', accountId, cookieConfig); + if (angular.isArray(accountId)) { + accountId.forEach(function (trackerObj) { + $window.ga('create', trackerObj.tracker, cookieConfig, { name: trackerObj.name }); + }); + } else { + $window.ga('create', accountId, cookieConfig); + } if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); @@ -171,10 +177,19 @@ angular.module('angular-google-analytics', []) $window._gaq.push(['_trackPageview', trackPrefix + url]); this._log('_trackPageview', arguments); } else if (trackRoutes && analyticsJS && $window.ga) { - $window.ga('send', 'pageview', { - 'page': trackPrefix + url, - 'title': title - }); + if (angular.isArray(accountId)) { + accountId.forEach(function (trackerObj) { + $window.ga(trackerObj.name + '.send', 'pageview', { + 'page': trackPrefix + url, + 'title': title + }); + }); + } else { + $window.ga('send', 'pageview', { + 'page': trackPrefix + url, + 'title': title + }); + } this._log('pageview', arguments); } }; @@ -299,6 +314,22 @@ angular.module('angular-google-analytics', []) } }; + /** + * 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 + * @private + */ + this._set = function (name, value) { + if ($window.ga) { + $window.ga('set', name, value); + this._log('set', name, value); + } + }; + // creates the ganalytics tracker @@ -346,6 +377,9 @@ angular.module('angular-google-analytics', []) }, send: function (obj) { me._send(obj); + }, + set: function (name, value) { + me._set(name, value); } }; }]; diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index 5a6ecd1..492ee44 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,8 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.3 - 2014-06-05 + * @version v0.0.3 - 2014-08-27 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ -"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r=!1,i=!0,s="",c=!1,o="$routeChangeSuccess",g="auto",u=!1,m=!1,l=!1;this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return i=e,!0},this.trackPrefix=function(e){return s=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return c=!!e,!0},this.useEnhancedLinkAttribution=function(e){return m=!!e,!0},this.setPageEvent=function(e){return o=e,!0},this.setCookieConfig=function(e){return g=e,!0},this.useECommerce=function(e){return u=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){l=!!e},this.$get=["$document","$rootScope","$location","$window",function(_,d,h,f){function p(){e&&(f._gaq=[],f._gaq.push(["_setAccount",e]),m&&f._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),i&&!l&&(n?f._gaq.push(["_trackPageview",v()]):f._gaq.push(["_trackPageview"])),t&&f._gaq.push(["_setDomainName",t]),function(){var e=_[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),r=!0)}function k(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),f.ga("create",e,g),i&&!l&&f.ga("send","pageview",v()),f.ga&&(u&&f.ga("require","ecommerce","ecommerce.js"),m&&f.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var v=function(){var e=h.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(e,t){t=t?t:_[0].title,i&&!c&&f._gaq?(f._gaq.push(["_set","title",t]),f._gaq.push(["_trackPageview",s+e]),this._log("_trackPageview",arguments)):i&&c&&f.ga&&(f.ga("send","pageview",{page:s+e,title:t}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!c&&f._gaq?(f._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):f.ga&&(f.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,o,g){!c&&f._gaq?(f._gaq.push(["_addTrans",e,t,n,a,r,i,s,o]),this._log("_addTrans",arguments)):f.ga&&(u?(f.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!c&&f._gaq?(f._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):f.ga&&(f.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!c&&f._gaq?(f._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):f.ga&&(f.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){f.ga&&(f.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){f.ga&&(f.ga("send",e),this._log("send",e))},c?k():p();var w=this;return i&&d.$on(o,function(){w._trackPage(v())}),{_logs:w._logs,cookieConfig:g,ecommerce:u,enhancedLinkAttribution:m,getUrl:v,experimentId:a,ignoreFirstPageLoad:l,trackPage:function(e,t){w._trackPage(e,t)},trackEvent:function(e,t,n,a){w._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){w._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){w._addItem(e,t,n,a,r,i)},trackTrans:function(){w._trackTrans()},clearTrans:function(){w._clearTrans()},send:function(e){w._send(e)}}}]}); \ No newline at end of file +"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var a,b,c,d,e=!1,f=!0,g="",h=!1,i="$routeChangeSuccess",j="auto",k=!1,l=!1,m=!1;this._logs=[],this.setAccount=function(b){return a=b,!0},this.trackPages=function(a){return f=a,!0},this.trackPrefix=function(a){return g=a,!0},this.setDomainName=function(a){return b=a,!0},this.useAnalytics=function(a){return h=!!a,!0},this.useEnhancedLinkAttribution=function(a){return l=!!a,!0},this.setPageEvent=function(a){return i=a,!0},this.setCookieConfig=function(a){return j=a,!0},this.useECommerce=function(a){return k=!!a,!0},this.setRemoveRegExp=function(a){return a instanceof RegExp?(c=a,!0):!1},this.setExperimentId=function(a){return d=a,!0},this.ignoreFirstPageLoad=function(a){m=!!a},this.$get=["$document","$rootScope","$location","$window",function(n,o,p,q){function r(){a&&(q._gaq=[],q._gaq.push(["_setAccount",a]),l&&q._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),f&&!m&&q._gaq.push(c?["_trackPageview",t()]:["_trackPageview"]),b&&q._gaq.push(["_setDomainName",b]),function(){var a=n[0],b=a.createElement("script");b.type="text/javascript",b.async=!0,b.src=("https:"===a.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var c=a.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}(),e=!0)}function s(){if(!a)return console.warn("No account id set for Analytics.js");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)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(a)?a.forEach(function(a){q.ga("create",a.tracker,j,{name:a.name})}):q.ga("create",a,j),f&&!m&&q.ga("send","pageview",t()),q.ga&&(k&&q.ga("require","ecommerce","ecommerce.js"),l&&q.ga("require","linkid","linkid.js"),d)){var b=document.createElement("script"),c=document.getElementsByTagName("script")[0];b.src="//www.google-analytics.com/cx/api.js?experiment="+d,c.parentNode.insertBefore(b,c)}}var t=function(){var a=p.path();return c?a.replace(c,""):a};this._log=function(){this._logs.push(arguments)},this._trackPage=function(b,c){c=c?c:n[0].title,f&&!h&&q._gaq?(q._gaq.push(["_set","title",c]),q._gaq.push(["_trackPageview",g+b]),this._log("_trackPageview",arguments)):f&&h&&q.ga&&(angular.isArray(a)?a.forEach(function(a){q.ga(a.name+".send","pageview",{page:g+b,title:c})}):q.ga("send","pageview",{page:g+b,title:c}),this._log("pageview",arguments))},this._trackEvent=function(a,b,c,d){!h&&q._gaq?(q._gaq.push(["_trackEvent",a,b,c,d]),this._log("trackEvent",arguments)):q.ga&&(q.ga("send","event",a,b,c,d),this._log("event",arguments))},this._addTrans=function(a,b,c,d,e,f,g,i,j){!h&&q._gaq?(q._gaq.push(["_addTrans",a,b,c,d,e,f,g,i]),this._log("_addTrans",arguments)):q.ga&&(k?(q.ga("ecommerce:addTransaction",{id:a,affiliation:b,revenue:c,tax:d,shipping:e,currency:j||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(a,b,c,d,e,f){!h&&q._gaq?(q._gaq.push(["_addItem",a,b,c,d,e,f]),this._log("_addItem",arguments)):q.ga&&(q.ga("ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!h&&q._gaq?(q._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):q.ga&&(q.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){q.ga&&(q.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(a){q.ga&&(q.ga("send",a),this._log("send",a))},this._set=function(a,b){q.ga&&(q.ga("set",a,b),this._log("set",a,b))},h?s():r();var u=this;return f&&o.$on(i,function(){u._trackPage(t())}),{_logs:u._logs,cookieConfig:j,ecommerce:k,enhancedLinkAttribution:l,getUrl:t,experimentId:d,ignoreFirstPageLoad:m,trackPage:function(a,b){u._trackPage(a,b)},trackEvent:function(a,b,c,d){u._trackEvent(a,b,c,d)},addTrans:function(a,b,c,d,e,f,g,h,i){u._addTrans(a,b,c,d,e,f,g,h,i)},addItem:function(a,b,c,d,e,f){u._addItem(a,b,c,d,e,f)},trackTrans:function(){u._trackTrans()},clearTrans:function(){u._clearTrans()},send:function(a){u._send(a)},set:function(a,b){u._set(a,b)}}}]}); \ No newline at end of file From bbae6080e7024511180703cbd324bcec12fbff82 Mon Sep 17 00:00:00 2001 From: Warner Onstine Date: Wed, 27 Aug 2014 16:06:35 -0700 Subject: [PATCH 05/18] adding in cross link domain capabilities [https://github.com/revolunet/angular-google-analytics/issues/30] --- src/angular-google-analytics.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index aa3eb64..786d39c 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -16,7 +16,10 @@ angular.module('angular-google-analytics', []) enhancedLinkAttribution = false, removeRegExp, experimentId, - ignoreFirstPageLoad = false; + ignoreFirstPageLoad = false, + crossDomainLinker = false, + crossLinkDomains, + linkerConfig = {'allowLinker': true}; this._logs = []; @@ -50,6 +53,20 @@ angular.module('angular-google-analytics', []) return true; }; + this.useCrossDomainLinker = function(val) { + crossDomainLinker == !!val; + return true; + }; + + this.setCrossLinkDomains = function(domains) { + if(angular.isArray(domains) { + crossLinkDomains = domains; + } else { + crossLinkDomains = [domains]; + } + + }; + this.setPageEvent = function(name) { pageEvent = name; return true; @@ -128,7 +145,15 @@ angular.module('angular-google-analytics', []) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m); })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - $window.ga('create', accountId, cookieConfig); + if(crossDomainLinker) { + $window.ga('create', accountId, cookieConfig, linkerConfig); + $window.ga('require', 'linker'); + if(crossLinkDomains) { + ga('linker:autoLink', crossLinkDomains ); + } + } else { + $window.ga('create', accountId, cookieConfig); + } if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); From dcf8c0f9f1ac176cca5f31491eba40ee3c90da1e Mon Sep 17 00:00:00 2001 From: Warner Onstine Date: Wed, 27 Aug 2014 16:07:03 -0700 Subject: [PATCH 06/18] bumping version for use --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 384406a..7438c6a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-google-analytics", "description": "Angular Google Analytics - Easy tracking for your AngularJS application", - "version": "0.0.3", + "version": "0.0.4", "homepage": "http://revolunet.com.github.com/angular-google-analytics", "author": "Julien Bouquillon ", "repository": { From 8fbdea6e781de400eaa7f9bacf7a715e426b591e Mon Sep 17 00:00:00 2001 From: Warner Onstine Date: Wed, 27 Aug 2014 16:27:26 -0700 Subject: [PATCH 07/18] removed use of angular is array and just assume that it is an array. Add doc example in readme --- README.md | 5 +++++ src/angular-google-analytics.js | 8 ++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cc73afa..4a45948 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Proudly brought to you by [@revolunet](http://twitter.com/revolunet) and [@delta - e-commerce tracking - multiple-domains - ga.js and and analytics.js support + - cross-domain support ## install @@ -40,6 +41,10 @@ var app = angular.module('app', ['angular-google-analytics']) // Use analytics.js instead of ga.js AnalyticsProvider.useAnalytics(true); + // Use cross domain linking + AnalyticsProvider.useCrossDomainLinker(true); + AnalyticsProvider.setCrossLinkDomains(['domain-1.com', 'domain-2.com']); + // Ignore first page view... helpful when using hashes and whenever your bounce rate looks obscenely low. AnalyticsProvider.ignoreFirstPageLoad(true); diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index 786d39c..4aeeb73 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -59,12 +59,8 @@ angular.module('angular-google-analytics', []) }; this.setCrossLinkDomains = function(domains) { - if(angular.isArray(domains) { - crossLinkDomains = domains; - } else { - crossLinkDomains = [domains]; - } - + crossLinkDomains = domains; + return true; }; this.setPageEvent = function(name) { From e0eb3718b11406dfcf9954ca6cfee8ac9b46afd6 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 28 Aug 2014 02:01:49 +0200 Subject: [PATCH 08/18] chore: bump release --- Gruntfile.js | 1 + dist/angular-google-analytics.js | 46 +++++++++++++++++++++++++-- dist/angular-google-analytics.min.js | 4 +-- src/angular-google-analytics.js | 4 +-- test/unit/angular-google-analytics.js | 4 +-- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 3089c9d..9bf390d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -75,6 +75,7 @@ module.exports = function(grunt) { eqnull: true, expr: true, node: true, + '-W018': true, globals: { exports: true, angular: false, diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index 39de5b4..de3bafb 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,6 +1,6 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.3 - 2014-06-05 + * @version v0.0.4 - 2014-08-28 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT @@ -23,7 +23,10 @@ angular.module('angular-google-analytics', []) enhancedLinkAttribution = false, removeRegExp, experimentId, - ignoreFirstPageLoad = false; + ignoreFirstPageLoad = false, + crossDomainLinker = false, + crossLinkDomains, + linkerConfig = {'allowLinker': true}; this._logs = []; @@ -57,6 +60,16 @@ angular.module('angular-google-analytics', []) return true; }; + this.useCrossDomainLinker = function(val) { + crossDomainLinker === !!val; + return true; + }; + + this.setCrossLinkDomains = function(domains) { + crossLinkDomains = domains; + return true; + }; + this.setPageEvent = function(name) { pageEvent = name; return true; @@ -135,7 +148,15 @@ angular.module('angular-google-analytics', []) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m); })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - $window.ga('create', accountId, cookieConfig); + if(crossDomainLinker) { + $window.ga('create', accountId, cookieConfig, linkerConfig); + $window.ga('require', 'linker'); + if(crossLinkDomains) { + $window.ga('linker:autoLink', crossLinkDomains ); + } + } else { + $window.ga('create', accountId, cookieConfig); + } if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); @@ -299,6 +320,22 @@ angular.module('angular-google-analytics', []) } }; + /** + * 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 + * @private + */ + this._set = function (name, value) { + if ($window.ga) { + $window.ga('set', name, value); + this._log('set', name, value); + } + }; + // creates the ganalytics tracker @@ -346,6 +383,9 @@ angular.module('angular-google-analytics', []) }, send: function (obj) { me._send(obj); + }, + set: function (name, value) { + me._set(name, value); } }; }]; diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index 5a6ecd1..3153204 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,8 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.3 - 2014-06-05 + * @version v0.0.4 - 2014-08-28 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ -"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r=!1,i=!0,s="",c=!1,o="$routeChangeSuccess",g="auto",u=!1,m=!1,l=!1;this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return i=e,!0},this.trackPrefix=function(e){return s=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return c=!!e,!0},this.useEnhancedLinkAttribution=function(e){return m=!!e,!0},this.setPageEvent=function(e){return o=e,!0},this.setCookieConfig=function(e){return g=e,!0},this.useECommerce=function(e){return u=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){l=!!e},this.$get=["$document","$rootScope","$location","$window",function(_,d,h,f){function p(){e&&(f._gaq=[],f._gaq.push(["_setAccount",e]),m&&f._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),i&&!l&&(n?f._gaq.push(["_trackPageview",v()]):f._gaq.push(["_trackPageview"])),t&&f._gaq.push(["_setDomainName",t]),function(){var e=_[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),r=!0)}function k(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),f.ga("create",e,g),i&&!l&&f.ga("send","pageview",v()),f.ga&&(u&&f.ga("require","ecommerce","ecommerce.js"),m&&f.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var v=function(){var e=h.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(e,t){t=t?t:_[0].title,i&&!c&&f._gaq?(f._gaq.push(["_set","title",t]),f._gaq.push(["_trackPageview",s+e]),this._log("_trackPageview",arguments)):i&&c&&f.ga&&(f.ga("send","pageview",{page:s+e,title:t}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!c&&f._gaq?(f._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):f.ga&&(f.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,o,g){!c&&f._gaq?(f._gaq.push(["_addTrans",e,t,n,a,r,i,s,o]),this._log("_addTrans",arguments)):f.ga&&(u?(f.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!c&&f._gaq?(f._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):f.ga&&(f.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!c&&f._gaq?(f._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):f.ga&&(f.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){f.ga&&(f.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){f.ga&&(f.ga("send",e),this._log("send",e))},c?k():p();var w=this;return i&&d.$on(o,function(){w._trackPage(v())}),{_logs:w._logs,cookieConfig:g,ecommerce:u,enhancedLinkAttribution:m,getUrl:v,experimentId:a,ignoreFirstPageLoad:l,trackPage:function(e,t){w._trackPage(e,t)},trackEvent:function(e,t,n,a){w._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){w._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){w._addItem(e,t,n,a,r,i)},trackTrans:function(){w._trackTrans()},clearTrans:function(){w._clearTrans()},send:function(e){w._send(e)}}}]}); \ No newline at end of file +"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,i,s=!1,r=!0,c="",o=!1,g="$routeChangeSuccess",u="auto",m=!1,l=!1,_=!1,d=!1,h={allowLinker:!0};this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return r=e,!0},this.trackPrefix=function(e){return c=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return o=!!e,!0},this.useEnhancedLinkAttribution=function(e){return l=!!e,!0},this.useCrossDomainLinker=function(e){return!0},this.setCrossLinkDomains=function(e){return i=e,!0},this.setPageEvent=function(e){return g=e,!0},this.setCookieConfig=function(e){return u=e,!0},this.useECommerce=function(e){return m=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){_=!!e},this.$get=["$document","$rootScope","$location","$window",function(f,p,k,v){function w(){e&&(v._gaq=[],v._gaq.push(["_setAccount",e]),l&&v._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),r&&!_&&(n?v._gaq.push(["_trackPageview",y()]):v._gaq.push(["_trackPageview"])),t&&v._gaq.push(["_setDomainName",t]),function(){var e=f[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),s=!0)}function q(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,i,s,r){e.GoogleAnalyticsObject=i,e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},e[i].l=1*new Date,s=t.createElement(n),r=t.getElementsByTagName(n)[0],s.async=1,s.src=a,r.parentNode.insertBefore(s,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),d?(v.ga("create",e,u,h),v.ga("require","linker"),i&&v.ga("linker:autoLink",i)):v.ga("create",e,u),r&&!_&&v.ga("send","pageview",y()),v.ga&&(m&&v.ga("require","ecommerce","ecommerce.js"),l&&v.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var y=function(){var e=k.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(e,t){t=t?t:f[0].title,r&&!o&&v._gaq?(v._gaq.push(["_set","title",t]),v._gaq.push(["_trackPageview",c+e]),this._log("_trackPageview",arguments)):r&&o&&v.ga&&(v.ga("send","pageview",{page:c+e,title:t}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!o&&v._gaq?(v._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):v.ga&&(v.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,i,s,r,c,g){!o&&v._gaq?(v._gaq.push(["_addTrans",e,t,n,a,i,s,r,c]),this._log("_addTrans",arguments)):v.ga&&(m?(v.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:i,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,i,s){!o&&v._gaq?(v._gaq.push(["_addItem",e,t,n,a,i,s]),this._log("_addItem",arguments)):v.ga&&(v.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:i,quantity:s}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!o&&v._gaq?(v._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):v.ga&&(v.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){v.ga&&(v.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){v.ga&&(v.ga("send",e),this._log("send",e))},this._set=function(e,t){v.ga&&(v.ga("set",e,t),this._log("set",e,t))},o?q():w();var E=this;return r&&p.$on(g,function(){E._trackPage(y())}),{_logs:E._logs,cookieConfig:u,ecommerce:m,enhancedLinkAttribution:l,getUrl:y,experimentId:a,ignoreFirstPageLoad:_,trackPage:function(e,t){E._trackPage(e,t)},trackEvent:function(e,t,n,a){E._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,i,s,r,c,o){E._addTrans(e,t,n,a,i,s,r,c,o)},addItem:function(e,t,n,a,i,s){E._addItem(e,t,n,a,i,s)},trackTrans:function(){E._trackTrans()},clearTrans:function(){E._clearTrans()},send:function(e){E._send(e)},set:function(e,t){E._set(e,t)}}}]}); \ No newline at end of file diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index 4aeeb73..d5dbd4b 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -54,7 +54,7 @@ angular.module('angular-google-analytics', []) }; this.useCrossDomainLinker = function(val) { - crossDomainLinker == !!val; + crossDomainLinker === !!val; return true; }; @@ -145,7 +145,7 @@ angular.module('angular-google-analytics', []) $window.ga('create', accountId, cookieConfig, linkerConfig); $window.ga('require', 'linker'); if(crossLinkDomains) { - ga('linker:autoLink', crossLinkDomains ); + $window.ga('linker:autoLink', crossLinkDomains ); } } else { $window.ga('create', accountId, cookieConfig); diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index fb566cc..3b7c254 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -161,8 +161,8 @@ describe('angular-google-analytics', function(){ inject(function (Analytics) { var data = { name: "dimension1", - value: "value1", - } + value: "value1" + }; expect(Analytics._logs.length).toBe(0); Analytics.set(data.name, data.value); expect(Analytics._logs.length).toBe(1); From 9995bdddebe81dbf6048358ee90e4e2528e0131f Mon Sep 17 00:00:00 2001 From: ultrayoshi Date: Thu, 28 Aug 2014 10:43:40 +0200 Subject: [PATCH 09/18] Add multiple tracking objects usage to the README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cc73afa..553ff87 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Proudly brought to you by [@revolunet](http://twitter.com/revolunet) and [@delta - e-commerce tracking - multiple-domains - ga.js and and analytics.js support + - multiple tracking objects ## install @@ -26,6 +27,11 @@ var app = angular.module('app', ['angular-google-analytics']) .config(function(AnalyticsProvider) { // initial configuration AnalyticsProvider.setAccount('UA-XXXXX-xx'); + // using multiple tracking objects (analytics.js only) + // AnalyticsProvider.setAccount([ + // { tracker: 'UA-12345-12', name: "tracker1" }, + // { tracker: 'UA-12345-34', name: "tracker2" } + // ]); // track all routes (or not) AnalyticsProvider.trackPages(true); From 5b40b9c870ba872a34e3412ced7ce7f8bc73b122 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Wed, 3 Sep 2014 10:22:40 +0200 Subject: [PATCH 10/18] fix: crossDomainLinker bug --- bower.json | 2 +- dist/angular-google-analytics.js | 4 ++-- dist/angular-google-analytics.min.js | 4 ++-- src/angular-google-analytics.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bower.json b/bower.json index bf5b198..a62fa05 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,7 @@ "author": "revolunet", "name": "angular-google-analytics", "description": "Easy Analytics for your AngularJS application", - "version": "0.0.3", + "version": "0.0.4", "homepage": "https://github.com/revolunet/angular-google-analytics", "repository": { "type": "git", diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index 552b699..00a7531 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,6 +1,6 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.4 - 2014-08-28 + * @version v0.0.4 - 2014-09-03 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT @@ -61,7 +61,7 @@ angular.module('angular-google-analytics', []) }; this.useCrossDomainLinker = function(val) { - crossDomainLinker === !!val; + crossDomainLinker = !!val; return true; }; diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index 074bcd2..5c65bf1 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,8 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.4 - 2014-08-28 + * @version v0.0.4 - 2014-09-03 * @link http://revolunet.com.github.com/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ -"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r,i=!1,s=!0,c="",o=!1,g="$routeChangeSuccess",u="auto",m=!1,l=!1,_=!1,d=!1,h={allowLinker:!0};this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return s=e,!0},this.trackPrefix=function(e){return c=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return o=!!e,!0},this.useEnhancedLinkAttribution=function(e){return l=!!e,!0},this.useCrossDomainLinker=function(e){return!0},this.setCrossLinkDomains=function(e){return r=e,!0},this.setPageEvent=function(e){return g=e,!0},this.setCookieConfig=function(e){return u=e,!0},this.useECommerce=function(e){return m=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){_=!!e},this.$get=["$document","$rootScope","$location","$window",function(f,p,k,v){function w(){e&&(v._gaq=[],v._gaq.push(["_setAccount",e]),l&&v._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),s&&!_&&(n?v._gaq.push(["_trackPageview",y()]):v._gaq.push(["_trackPageview"])),t&&v._gaq.push(["_setDomainName",t]),function(){var e=f[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),i=!0)}function q(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(e)?e.forEach(function(e){v.ga("create",e.tracker,u,{name:e.name})}):d?(v.ga("create",e,u,h),v.ga("require","linker"),r&&v.ga("linker:autoLink",r)):v.ga("create",e,u),s&&!_&&v.ga("send","pageview",y()),v.ga&&(m&&v.ga("require","ecommerce","ecommerce.js"),l&&v.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var y=function(){var e=k.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(t,n){n=n?n:f[0].title,s&&!o&&v._gaq?(v._gaq.push(["_set","title",n]),v._gaq.push(["_trackPageview",c+t]),this._log("_trackPageview",arguments)):s&&o&&v.ga&&(angular.isArray(e)?e.forEach(function(e){v.ga(e.name+".send","pageview",{page:c+t,title:n})}):v.ga("send","pageview",{page:c+t,title:n}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!o&&v._gaq?(v._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):v.ga&&(v.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,c,g){!o&&v._gaq?(v._gaq.push(["_addTrans",e,t,n,a,r,i,s,c]),this._log("_addTrans",arguments)):v.ga&&(m?(v.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!o&&v._gaq?(v._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):v.ga&&(v.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!o&&v._gaq?(v._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):v.ga&&(v.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){v.ga&&(v.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){v.ga&&(v.ga("send",e),this._log("send",e))},this._set=function(e,t){v.ga&&(v.ga("set",e,t),this._log("set",e,t))},o?q():w();var E=this;return s&&p.$on(g,function(){E._trackPage(y())}),{_logs:E._logs,cookieConfig:u,ecommerce:m,enhancedLinkAttribution:l,getUrl:y,experimentId:a,ignoreFirstPageLoad:_,trackPage:function(e,t){E._trackPage(e,t)},trackEvent:function(e,t,n,a){E._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){E._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){E._addItem(e,t,n,a,r,i)},trackTrans:function(){E._trackTrans()},clearTrans:function(){E._clearTrans()},send:function(e){E._send(e)},set:function(e,t){E._set(e,t)}}}]}); \ No newline at end of file +"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r,i=!1,s=!0,c="",o=!1,g="$routeChangeSuccess",u="auto",m=!1,l=!1,_=!1,d=!1,h={allowLinker:!0};this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return s=e,!0},this.trackPrefix=function(e){return c=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return o=!!e,!0},this.useEnhancedLinkAttribution=function(e){return l=!!e,!0},this.useCrossDomainLinker=function(e){return d=!!e,!0},this.setCrossLinkDomains=function(e){return r=e,!0},this.setPageEvent=function(e){return g=e,!0},this.setCookieConfig=function(e){return u=e,!0},this.useECommerce=function(e){return m=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){_=!!e},this.$get=["$document","$rootScope","$location","$window",function(f,p,k,v){function w(){e&&(v._gaq=[],v._gaq.push(["_setAccount",e]),l&&v._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),s&&!_&&(n?v._gaq.push(["_trackPageview",y()]):v._gaq.push(["_trackPageview"])),t&&v._gaq.push(["_setDomainName",t]),function(){var e=f[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),i=!0)}function q(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(e)?e.forEach(function(e){v.ga("create",e.tracker,u,{name:e.name})}):d?(v.ga("create",e,u,h),v.ga("require","linker"),r&&v.ga("linker:autoLink",r)):v.ga("create",e,u),s&&!_&&v.ga("send","pageview",y()),v.ga&&(m&&v.ga("require","ecommerce","ecommerce.js"),l&&v.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var y=function(){var e=k.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(t,n){n=n?n:f[0].title,s&&!o&&v._gaq?(v._gaq.push(["_set","title",n]),v._gaq.push(["_trackPageview",c+t]),this._log("_trackPageview",arguments)):s&&o&&v.ga&&(angular.isArray(e)?e.forEach(function(e){v.ga(e.name+".send","pageview",{page:c+t,title:n})}):v.ga("send","pageview",{page:c+t,title:n}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!o&&v._gaq?(v._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):v.ga&&(v.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,c,g){!o&&v._gaq?(v._gaq.push(["_addTrans",e,t,n,a,r,i,s,c]),this._log("_addTrans",arguments)):v.ga&&(m?(v.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!o&&v._gaq?(v._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):v.ga&&(v.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!o&&v._gaq?(v._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):v.ga&&(v.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){v.ga&&(v.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){v.ga&&(v.ga("send",e),this._log("send",e))},this._set=function(e,t){v.ga&&(v.ga("set",e,t),this._log("set",e,t))},o?q():w();var E=this;return s&&p.$on(g,function(){E._trackPage(y())}),{_logs:E._logs,cookieConfig:u,ecommerce:m,enhancedLinkAttribution:l,getUrl:y,experimentId:a,ignoreFirstPageLoad:_,trackPage:function(e,t){E._trackPage(e,t)},trackEvent:function(e,t,n,a){E._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){E._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){E._addItem(e,t,n,a,r,i)},trackTrans:function(){E._trackTrans()},clearTrans:function(){E._clearTrans()},send:function(e){E._send(e)},set:function(e,t){E._set(e,t)}}}]}); \ No newline at end of file diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index ba75184..cf40742 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -54,7 +54,7 @@ angular.module('angular-google-analytics', []) }; this.useCrossDomainLinker = function(val) { - crossDomainLinker === !!val; + crossDomainLinker = !!val; return true; }; From 206c9b3f33a99f3d71b351c6ea2b4a63683b1d83 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Wed, 3 Sep 2014 10:29:12 +0200 Subject: [PATCH 11/18] chore: fix package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7438c6a..3375b23 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "angular-google-analytics", "description": "Angular Google Analytics - Easy tracking for your AngularJS application", "version": "0.0.4", - "homepage": "http://revolunet.com.github.com/angular-google-analytics", + "homepage": "http://github.com/revolunet/angular-google-analytics", "author": "Julien Bouquillon ", "repository": { "type": "git", From 45d70b8270d0d57e45c90163e91afe0d95cc175f Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Wed, 3 Sep 2014 10:49:38 +0200 Subject: [PATCH 12/18] chore: add package/main --- bower.json | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index a62fa05..6757099 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,7 @@ "author": "revolunet", "name": "angular-google-analytics", "description": "Easy Analytics for your AngularJS application", - "version": "0.0.4", + "version": "0.0.5", "homepage": "https://github.com/revolunet/angular-google-analytics", "repository": { "type": "git", diff --git a/package.json b/package.json index 3375b23..bdf3f65 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "angular-google-analytics", "description": "Angular Google Analytics - Easy tracking for your AngularJS application", - "version": "0.0.4", + "version": "0.0.5", "homepage": "http://github.com/revolunet/angular-google-analytics", "author": "Julien Bouquillon ", + "main": "./src/angular-google-analytics.js", "repository": { "type": "git", "url": "git://github.com/revolunet/angular-google-analytics.git" From ab2cd78ab54a2fae72766408293bd427141c8d3e Mon Sep 17 00:00:00 2001 From: Ji Chang Date: Thu, 11 Sep 2014 16:05:56 +0800 Subject: [PATCH 13/18] support displayFeatures of GA, both ga.js and analytics.js --- src/angular-google-analytics.js | 21 +++++++++++++++++++-- test/unit/angular-google-analytics.js | 17 ++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index cf40742..4fd1e34 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -7,6 +7,7 @@ angular.module('angular-google-analytics', []) var created = false, trackRoutes = true, accountId, + displayFeatures, trackPrefix = '', domainName, analyticsJS = false, @@ -43,6 +44,11 @@ angular.module('angular-google-analytics', []) return true; }; + this.useDisplayFeatures = function(val) { + displayFeatures = !!val; + return true; + } + this.useAnalytics = function(val) { analyticsJS = !!val; return true; @@ -123,12 +129,18 @@ angular.module('angular-google-analytics', []) } } if(domainName) $window._gaq.push(['_setDomainName', domainName]); + var gaSrc; + if(displayFeatures) { + gaSrc = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; + } else { + gaSrc = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + } (function() { var document = $document[0]; var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = gaSrc; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); + })(gaSrc); created = true; } @@ -156,6 +168,10 @@ angular.module('angular-google-analytics', []) $window.ga('create', accountId, cookieConfig); } + if(displayFeatures) { + $window.ga('require', 'displayfeatures'); + } + if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); } @@ -365,6 +381,7 @@ angular.module('angular-google-analytics', []) return { _logs: me._logs, cookieConfig: cookieConfig, + displayFeatures: displayFeatures, ecommerce: ecommerce, enhancedLinkAttribution: enhancedLinkAttribution, getUrl: getUrl, diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index fbb423b..7818b3e 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -9,7 +9,7 @@ describe('angular-google-analytics', function(){ AnalyticsProvider.setAccount('UA-XXXXXX-xx'); })); - describe('automatic trackPages', function() { + describe('automatic trackPages with ga.js', function() { it('should inject the GA script', function() { inject(function(Analytics) { @@ -35,6 +35,14 @@ describe('angular-google-analytics', function(){ }); }); + describe('supports dc.js', function() { + it('should inject the DC script', function() { + inject(function(Analytics) { + expect(document.querySelectorAll("script[src='http://stats.g.doubleclick.net/dc.js']").length).toBe(1); + }); + }); + }); + describe('e-commerce transactions', function() { it('should add transcation', function() { @@ -100,6 +108,7 @@ describe('angular-google-analytics', function(){ beforeEach(module(function(AnalyticsProvider) { AnalyticsProvider.useAnalytics(true); AnalyticsProvider.setCookieConfig(cookieConfig); + AnalyticsProvider.useDisplayFeatures(true); AnalyticsProvider.useECommerce(true); AnalyticsProvider.useEnhancedLinkAttribution(true); AnalyticsProvider.setExperimentId('12345'); @@ -111,6 +120,12 @@ describe('angular-google-analytics', function(){ }); }); + if('should support displayfeatures config', function() { + inject(function(Analytics) { + expect(Analytics.displayFeatures).toBe(true); + }); + }); + it('should support ecommerce config', function () { inject(function(Analytics) { expect(Analytics.ecommerce).toBe(true); From 582e3aad33ff92d4a88a2be44c1722ee803d668f Mon Sep 17 00:00:00 2001 From: debian Date: Fri, 12 Sep 2014 02:05:11 -0400 Subject: [PATCH 14/18] fix jshint warnings --- src/angular-google-analytics.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/angular-google-analytics.js b/src/angular-google-analytics.js index 4fd1e34..304e546 100644 --- a/src/angular-google-analytics.js +++ b/src/angular-google-analytics.js @@ -47,7 +47,7 @@ angular.module('angular-google-analytics', []) this.useDisplayFeatures = function(val) { displayFeatures = !!val; return true; - } + }; this.useAnalytics = function(val) { analyticsJS = !!val; @@ -131,9 +131,9 @@ angular.module('angular-google-analytics', []) if(domainName) $window._gaq.push(['_setDomainName', domainName]); var gaSrc; if(displayFeatures) { - gaSrc = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; + gaSrc = ('https:' === document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; } else { - gaSrc = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + gaSrc = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; } (function() { var document = $document[0]; From ff2e6f00f28097133817cf4aa40f9aace78633e0 Mon Sep 17 00:00:00 2001 From: debian Date: Fri, 12 Sep 2014 02:05:38 -0400 Subject: [PATCH 15/18] fix test case: missing configuration before testing existence of gc.js --- test/unit/angular-google-analytics.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index 7818b3e..037a12c 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -36,6 +36,10 @@ describe('angular-google-analytics', function(){ }); describe('supports dc.js', function() { + beforeEach(module(function(AnalyticsProvider) { + AnalyticsProvider.useDisplayFeatures(true); + })); + it('should inject the DC script', function() { inject(function(Analytics) { expect(document.querySelectorAll("script[src='http://stats.g.doubleclick.net/dc.js']").length).toBe(1); From bc5b22d8916ba6437d58fff285e96d181f884a6f Mon Sep 17 00:00:00 2001 From: debian Date: Fri, 12 Sep 2014 03:41:13 -0400 Subject: [PATCH 16/18] update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 33f7a76..64c1e06 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ var app = angular.module('app', ['angular-google-analytics']) //Optional set domain (Use 'none' for testing on localhost) //AnalyticsProvider.setDomainName('XXX'); + //Use display features plugin + AnalyticsProvider.useDisplayFeatures(true); + // url prefix (default is empty) // - for example: when an app doesn't run in the root directory AnalyticsProvider.trackPrefix('my-application'); @@ -113,6 +116,8 @@ AnalyticsProvider.setAccount('UA-XXXXX-xx'); AnalyticsProvider.trackPages(false); //Optional set domain (Use 'none' for testing on localhost) AnalyticsProvider.setDomainName('XXX'); +//Use display features plugin +AnalyticsProvider.useDisplayFeatures(true); //Use analytics.js instead of ga.js AnalyticsProvider.useAnalytics(true); // Ignore first page view. From 08ac203aa60a0ca04a4a9363f73e02db27fd8a2c Mon Sep 17 00:00:00 2001 From: "mrchangji@gmail.com" Date: Fri, 12 Sep 2014 03:44:10 -0400 Subject: [PATCH 17/18] update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 33f7a76..64c1e06 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ var app = angular.module('app', ['angular-google-analytics']) //Optional set domain (Use 'none' for testing on localhost) //AnalyticsProvider.setDomainName('XXX'); + //Use display features plugin + AnalyticsProvider.useDisplayFeatures(true); + // url prefix (default is empty) // - for example: when an app doesn't run in the root directory AnalyticsProvider.trackPrefix('my-application'); @@ -113,6 +116,8 @@ AnalyticsProvider.setAccount('UA-XXXXX-xx'); AnalyticsProvider.trackPages(false); //Optional set domain (Use 'none' for testing on localhost) AnalyticsProvider.setDomainName('XXX'); +//Use display features plugin +AnalyticsProvider.useDisplayFeatures(true); //Use analytics.js instead of ga.js AnalyticsProvider.useAnalytics(true); // Ignore first page view. From e61861aa2689ddedcce090b92c25e0351be7330b Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Tue, 7 Oct 2014 13:09:44 +0200 Subject: [PATCH 18/18] chore: bump release --- bower.json | 2 +- dist/angular-google-analytics.js | 25 +++++++++++++++++++++---- dist/angular-google-analytics.min.js | 6 +++--- package.json | 2 +- test/unit/angular-google-analytics.js | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/bower.json b/bower.json index 6757099..39e7af5 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,7 @@ "author": "revolunet", "name": "angular-google-analytics", "description": "Easy Analytics for your AngularJS application", - "version": "0.0.5", + "version": "0.0.6", "homepage": "https://github.com/revolunet/angular-google-analytics", "repository": { "type": "git", diff --git a/dist/angular-google-analytics.js b/dist/angular-google-analytics.js index 00a7531..f687345 100644 --- a/dist/angular-google-analytics.js +++ b/dist/angular-google-analytics.js @@ -1,7 +1,7 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.4 - 2014-09-03 - * @link http://revolunet.com.github.com/angular-google-analytics + * @version v0.0.6 - 2014-10-07 + * @link http://github.com/revolunet/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ @@ -14,6 +14,7 @@ angular.module('angular-google-analytics', []) var created = false, trackRoutes = true, accountId, + displayFeatures, trackPrefix = '', domainName, analyticsJS = false, @@ -50,6 +51,11 @@ angular.module('angular-google-analytics', []) return true; }; + this.useDisplayFeatures = function(val) { + displayFeatures = !!val; + return true; + }; + this.useAnalytics = function(val) { analyticsJS = !!val; return true; @@ -130,12 +136,18 @@ angular.module('angular-google-analytics', []) } } if(domainName) $window._gaq.push(['_setDomainName', domainName]); + var gaSrc; + if(displayFeatures) { + gaSrc = ('https:' === document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; + } else { + gaSrc = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + } (function() { var document = $document[0]; var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + ga.src = gaSrc; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); + })(gaSrc); created = true; } @@ -163,6 +175,10 @@ angular.module('angular-google-analytics', []) $window.ga('create', accountId, cookieConfig); } + if(displayFeatures) { + $window.ga('require', 'displayfeatures'); + } + if (trackRoutes && !ignoreFirstPageLoad) { $window.ga('send', 'pageview', getUrl()); } @@ -372,6 +388,7 @@ angular.module('angular-google-analytics', []) return { _logs: me._logs, cookieConfig: cookieConfig, + displayFeatures: displayFeatures, ecommerce: ecommerce, enhancedLinkAttribution: enhancedLinkAttribution, getUrl: getUrl, diff --git a/dist/angular-google-analytics.min.js b/dist/angular-google-analytics.min.js index 5c65bf1..8c3ec45 100644 --- a/dist/angular-google-analytics.min.js +++ b/dist/angular-google-analytics.min.js @@ -1,8 +1,8 @@ /** * Angular Google Analytics - Easy tracking for your AngularJS application - * @version v0.0.4 - 2014-09-03 - * @link http://revolunet.com.github.com/angular-google-analytics + * @version v0.0.6 - 2014-10-07 + * @link http://github.com/revolunet/angular-google-analytics * @author Julien Bouquillon * @license MIT License, http://www.opensource.org/licenses/MIT */ -"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r,i=!1,s=!0,c="",o=!1,g="$routeChangeSuccess",u="auto",m=!1,l=!1,_=!1,d=!1,h={allowLinker:!0};this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return s=e,!0},this.trackPrefix=function(e){return c=e,!0},this.setDomainName=function(e){return t=e,!0},this.useAnalytics=function(e){return o=!!e,!0},this.useEnhancedLinkAttribution=function(e){return l=!!e,!0},this.useCrossDomainLinker=function(e){return d=!!e,!0},this.setCrossLinkDomains=function(e){return r=e,!0},this.setPageEvent=function(e){return g=e,!0},this.setCookieConfig=function(e){return u=e,!0},this.useECommerce=function(e){return m=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(n=e,!0):!1},this.setExperimentId=function(e){return a=e,!0},this.ignoreFirstPageLoad=function(e){_=!!e},this.$get=["$document","$rootScope","$location","$window",function(f,p,k,v){function w(){e&&(v._gaq=[],v._gaq.push(["_setAccount",e]),l&&v._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),s&&!_&&(n?v._gaq.push(["_trackPageview",y()]):v._gaq.push(["_trackPageview"])),t&&v._gaq.push(["_setDomainName",t]),function(){var e=f[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===e.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(),i=!0)}function q(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(e)?e.forEach(function(e){v.ga("create",e.tracker,u,{name:e.name})}):d?(v.ga("create",e,u,h),v.ga("require","linker"),r&&v.ga("linker:autoLink",r)):v.ga("create",e,u),s&&!_&&v.ga("send","pageview",y()),v.ga&&(m&&v.ga("require","ecommerce","ecommerce.js"),l&&v.ga("require","linkid","linkid.js"),a)){var t=document.createElement("script"),n=document.getElementsByTagName("script")[0];t.src="//www.google-analytics.com/cx/api.js?experiment="+a,n.parentNode.insertBefore(t,n)}}var y=function(){var e=k.path();return n?e.replace(n,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(t,n){n=n?n:f[0].title,s&&!o&&v._gaq?(v._gaq.push(["_set","title",n]),v._gaq.push(["_trackPageview",c+t]),this._log("_trackPageview",arguments)):s&&o&&v.ga&&(angular.isArray(e)?e.forEach(function(e){v.ga(e.name+".send","pageview",{page:c+t,title:n})}):v.ga("send","pageview",{page:c+t,title:n}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!o&&v._gaq?(v._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):v.ga&&(v.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,c,g){!o&&v._gaq?(v._gaq.push(["_addTrans",e,t,n,a,r,i,s,c]),this._log("_addTrans",arguments)):v.ga&&(m?(v.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:g||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!o&&v._gaq?(v._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):v.ga&&(v.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!o&&v._gaq?(v._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):v.ga&&(v.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){v.ga&&(v.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){v.ga&&(v.ga("send",e),this._log("send",e))},this._set=function(e,t){v.ga&&(v.ga("set",e,t),this._log("set",e,t))},o?q():w();var E=this;return s&&p.$on(g,function(){E._trackPage(y())}),{_logs:E._logs,cookieConfig:u,ecommerce:m,enhancedLinkAttribution:l,getUrl:y,experimentId:a,ignoreFirstPageLoad:_,trackPage:function(e,t){E._trackPage(e,t)},trackEvent:function(e,t,n,a){E._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){E._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){E._addItem(e,t,n,a,r,i)},trackTrans:function(){E._trackTrans()},clearTrans:function(){E._clearTrans()},send:function(e){E._send(e)},set:function(e,t){E._set(e,t)}}}]}); \ No newline at end of file +"use strict";angular.module("angular-google-analytics",[]).provider("Analytics",function(){var e,t,n,a,r,i,s=!1,c=!0,o="",g=!1,u="$routeChangeSuccess",m="auto",l=!1,d=!1,_=!1,h=!1,f={allowLinker:!0};this._logs=[],this.setAccount=function(t){return e=t,!0},this.trackPages=function(e){return c=e,!0},this.trackPrefix=function(e){return o=e,!0},this.setDomainName=function(e){return n=e,!0},this.useDisplayFeatures=function(e){return t=!!e,!0},this.useAnalytics=function(e){return g=!!e,!0},this.useEnhancedLinkAttribution=function(e){return d=!!e,!0},this.useCrossDomainLinker=function(e){return h=!!e,!0},this.setCrossLinkDomains=function(e){return i=e,!0},this.setPageEvent=function(e){return u=e,!0},this.setCookieConfig=function(e){return m=e,!0},this.useECommerce=function(e){return l=!!e,!0},this.setRemoveRegExp=function(e){return e instanceof RegExp?(a=e,!0):!1},this.setExperimentId=function(e){return r=e,!0},this.ignoreFirstPageLoad=function(e){_=!!e},this.$get=["$document","$rootScope","$location","$window",function(p,k,v,w){function q(){if(e){w._gaq=[],w._gaq.push(["_setAccount",e]),d&&w._gaq.push(["_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"]),c&&!_&&(a?w._gaq.push(["_trackPageview",E()]):w._gaq.push(["_trackPageview"])),n&&w._gaq.push(["_setDomainName",n]);var r;r=t?("https:"===document.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===document.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",function(){var e=p[0],t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src=r;var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}(r),s=!0}}function y(){if(!e)return console.warn("No account id set for Analytics.js");if(function(e,t,n,a,r,i,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,i=t.createElement(n),s=t.getElementsByTagName(n)[0],i.async=1,i.src=a,s.parentNode.insertBefore(i,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),angular.isArray(e)?e.forEach(function(e){w.ga("create",e.tracker,m,{name:e.name})}):h?(w.ga("create",e,m,f),w.ga("require","linker"),i&&w.ga("linker:autoLink",i)):w.ga("create",e,m),t&&w.ga("require","displayfeatures"),c&&!_&&w.ga("send","pageview",E()),w.ga&&(l&&w.ga("require","ecommerce","ecommerce.js"),d&&w.ga("require","linkid","linkid.js"),r)){var n=document.createElement("script"),a=document.getElementsByTagName("script")[0];n.src="//www.google-analytics.com/cx/api.js?experiment="+r,a.parentNode.insertBefore(n,a)}}var E=function(){var e=v.path();return a?e.replace(a,""):e};this._log=function(){this._logs.push(arguments)},this._trackPage=function(t,n){n=n?n:p[0].title,c&&!g&&w._gaq?(w._gaq.push(["_set","title",n]),w._gaq.push(["_trackPageview",o+t]),this._log("_trackPageview",arguments)):c&&g&&w.ga&&(angular.isArray(e)?e.forEach(function(e){w.ga(e.name+".send","pageview",{page:o+t,title:n})}):w.ga("send","pageview",{page:o+t,title:n}),this._log("pageview",arguments))},this._trackEvent=function(e,t,n,a){!g&&w._gaq?(w._gaq.push(["_trackEvent",e,t,n,a]),this._log("trackEvent",arguments)):w.ga&&(w.ga("send","event",e,t,n,a),this._log("event",arguments))},this._addTrans=function(e,t,n,a,r,i,s,c,o){!g&&w._gaq?(w._gaq.push(["_addTrans",e,t,n,a,r,i,s,c]),this._log("_addTrans",arguments)):w.ga&&(l?(w.ga("ecommerce:addTransaction",{id:e,affiliation:t,revenue:n,tax:a,shipping:r,currency:o||"USD"}),this._log("ecommerce:addTransaction",arguments)):console.warn("ecommerce no set. Use AnalyticsProvider.setECommerce(true);"))},this._addItem=function(e,t,n,a,r,i){!g&&w._gaq?(w._gaq.push(["_addItem",e,t,n,a,r,i]),this._log("_addItem",arguments)):w.ga&&(w.ga("ecommerce:addItem",{id:e,name:n,sku:t,category:a,price:r,quantity:i}),this._log("ecommerce:addItem",arguments))},this._trackTrans=function(){!g&&w._gaq?(w._gaq.push(["_trackTrans"]),this._log("_trackTrans",arguments)):w.ga&&(w.ga("ecommerce:send"),this._log("ecommerce:send",arguments))},this._clearTrans=function(){w.ga&&(w.ga("ecommerce:clear"),this._log("ecommerce:clear",arguments))},this._send=function(e){w.ga&&(w.ga("send",e),this._log("send",e))},this._set=function(e,t){w.ga&&(w.ga("set",e,t),this._log("set",e,t))},g?y():q();var T=this;return c&&k.$on(u,function(){T._trackPage(E())}),{_logs:T._logs,cookieConfig:m,displayFeatures:t,ecommerce:l,enhancedLinkAttribution:d,getUrl:E,experimentId:r,ignoreFirstPageLoad:_,trackPage:function(e,t){T._trackPage(e,t)},trackEvent:function(e,t,n,a){T._trackEvent(e,t,n,a)},addTrans:function(e,t,n,a,r,i,s,c,o){T._addTrans(e,t,n,a,r,i,s,c,o)},addItem:function(e,t,n,a,r,i){T._addItem(e,t,n,a,r,i)},trackTrans:function(){T._trackTrans()},clearTrans:function(){T._clearTrans()},send:function(e){T._send(e)},set:function(e,t){T._set(e,t)}}}]}); \ No newline at end of file diff --git a/package.json b/package.json index bdf3f65..cbddb3f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-google-analytics", "description": "Angular Google Analytics - Easy tracking for your AngularJS application", - "version": "0.0.5", + "version": "0.0.6", "homepage": "http://github.com/revolunet/angular-google-analytics", "author": "Julien Bouquillon ", "main": "./src/angular-google-analytics.js", diff --git a/test/unit/angular-google-analytics.js b/test/unit/angular-google-analytics.js index 037a12c..d3fcb48 100644 --- a/test/unit/angular-google-analytics.js +++ b/test/unit/angular-google-analytics.js @@ -124,7 +124,7 @@ describe('angular-google-analytics', function(){ }); }); - if('should support displayfeatures config', function() { + it('should support displayfeatures config', function() { inject(function(Analytics) { expect(Analytics.displayFeatures).toBe(true); });