UNPKG

ionic-cordova-gulp-seed

Version:

Ionic & Cordova & Gulp seed with organized code, tests, bower support and some other stuff. Originated from ionic-angular-cordova-seed.

267 lines (243 loc) 9.51 kB
/** * @license Angulartics v0.17.2 * (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics * License: MIT */ (function(angular, analytics) { 'use strict'; var angulartics = window.angulartics || (window.angulartics = {}); angulartics.waitForVendorCount = 0; angulartics.waitForVendorApi = function (objectName, delay, containsField, registerFn, onTimeout) { if (!onTimeout) { angulartics.waitForVendorCount++; } if (!registerFn) { registerFn = containsField; containsField = undefined; } if (!Object.prototype.hasOwnProperty.call(window, objectName) || (containsField !== undefined && window[objectName][containsField] === undefined)) { setTimeout(function () { angulartics.waitForVendorApi(objectName, delay, containsField, registerFn, true); }, delay); } else { angulartics.waitForVendorCount--; registerFn(window[objectName]); } }; /** * @ngdoc overview * @name angulartics */ angular.module('angulartics', []) .provider('$analytics', function () { var settings = { pageTracking: { autoTrackFirstPage: true, autoTrackVirtualPages: true, trackRelativePath: false, autoBasePath: false, basePath: '' }, eventTracking: {}, bufferFlushDelay: 1000, // Support only one configuration for buffer flush delay to simplify buffering developerMode: false // Prevent sending data in local/development environment }; // List of known handlers that plugins can register themselves for var knownHandlers = [ 'pageTrack', 'eventTrack', 'setAlias', 'setUsername', 'setAlias', 'setUserProperties', 'setUserPropertiesOnce', 'setSuperProperties', 'setSuperPropertiesOnce' ]; // Cache and handler properties will match values in 'knownHandlers' as the buffering functons are installed. var cache = {}; var handlers = {}; // General buffering handler var bufferedHandler = function(handlerName){ return function(){ if(angulartics.waitForVendorCount){ if(!cache[handlerName]){ cache[handlerName] = []; } cache[handlerName].push(arguments); } }; }; // As handlers are installed by plugins, they get pushed into a list and invoked in order. var updateHandlers = function(handlerName, fn){ if(!handlers[handlerName]){ handlers[handlerName] = []; } handlers[handlerName].push(fn); return function(){ var handlerArgs = arguments; angular.forEach(handlers[handlerName], function(handler){ handler.apply(this, handlerArgs); }, this); }; }; // The api (returned by this provider) gets populated with handlers below. var api = { settings: settings }; // Will run setTimeout if delay is > 0 // Runs immediately if no delay to make sure cache/buffer is flushed before anything else. // Plugins should take care to register handlers by order of precedence. var onTimeout = function(fn, delay){ if(delay){ setTimeout(fn, delay); } else { fn(); } }; var provider = { $get: function() { return api; }, api: api, settings: settings, virtualPageviews: function (value) { this.settings.pageTracking.autoTrackVirtualPages = value; }, firstPageview: function (value) { this.settings.pageTracking.autoTrackFirstPage = value; }, withBase: function (value) { this.settings.pageTracking.basePath = (value) ? angular.element('base').attr('href').slice(0, -1) : ''; }, withAutoBase: function (value) { this.settings.pageTracking.autoBasePath = value; }, developerMode: function(value) { this.settings.developerMode = value; } }; // General function to register plugin handlers. Flushes buffers immediately upon registration according to the specified delay. var register = function(handlerName, fn){ api[handlerName] = updateHandlers(handlerName, fn); var handlerSettings = settings[handlerName]; var handlerDelay = (handlerSettings) ? handlerSettings.bufferFlushDelay : null; var delay = (handlerDelay !== null) ? handlerDelay : settings.bufferFlushDelay; angular.forEach(cache[handlerName], function (args, index) { onTimeout(function () { fn.apply(this, args); }, index * delay); }); }; var capitalize = function (input) { return input.replace(/^./, function (match) { return match.toUpperCase(); }); }; // Adds to the provider a 'register#{handlerName}' function that manages multiple plugins and buffer flushing. var installHandlerRegisterFunction = function(handlerName){ var registerName = 'register'+capitalize(handlerName); provider[registerName] = function(fn){ register(handlerName, fn); }; api[handlerName] = updateHandlers(handlerName, bufferedHandler(handlerName)); }; // Set up register functions for each known handler angular.forEach(knownHandlers, installHandlerRegisterFunction); return provider; }) .run(['$rootScope', '$window', '$analytics', '$injector', function ($rootScope, $window, $analytics, $injector) { if ($analytics.settings.pageTracking.autoTrackFirstPage) { $injector.invoke(['$location', function ($location) { /* Only track the 'first page' if there are no routes or states on the page */ var noRoutesOrStates = true; if ($injector.has('$route')) { var $route = $injector.get('$route'); for (var route in $route.routes) { noRoutesOrStates = false; break; } } else if ($injector.has('$state')) { var $state = $injector.get('$state'); for (var state in $state.get()) { noRoutesOrStates = false; break; } } if (noRoutesOrStates) { if ($analytics.settings.pageTracking.autoBasePath) { $analytics.settings.pageTracking.basePath = $window.location.pathname; } if ($analytics.settings.trackRelativePath) { var url = $analytics.settings.pageTracking.basePath + $location.url(); $analytics.pageTrack(url, $location); } else { $analytics.pageTrack($location.absUrl(), $location); } } }]); } if ($analytics.settings.pageTracking.autoTrackVirtualPages) { $injector.invoke(['$location', function ($location) { if ($analytics.settings.pageTracking.autoBasePath) { /* Add the full route to the base. */ $analytics.settings.pageTracking.basePath = $window.location.pathname + "#"; } if ($injector.has('$route')) { $rootScope.$on('$routeChangeSuccess', function (event, current) { if (current && (current.$$route||current).redirectTo) return; var url = $analytics.settings.pageTracking.basePath + $location.url(); $analytics.pageTrack(url, $location); }); } if ($injector.has('$state')) { $rootScope.$on('$stateChangeSuccess', function (event, current) { var url = $analytics.settings.pageTracking.basePath + $location.url(); $analytics.pageTrack(url, $location); }); } }]); } if ($analytics.settings.developerMode) { angular.forEach($analytics, function(attr, name) { if (typeof attr === 'function') { $analytics[name] = function(){}; } }); } }]) .directive('analyticsOn', ['$analytics', function ($analytics) { function isCommand(element) { return ['a:','button:','button:button','button:submit','input:button','input:submit'].indexOf( element.tagName.toLowerCase()+':'+(element.type||'')) >= 0; } function inferEventType(element) { if (isCommand(element)) return 'click'; return 'click'; } function inferEventName(element) { if (isCommand(element)) return element.innerText || element.value; return element.id || element.name || element.tagName; } function isProperty(name) { return name.substr(0, 9) === 'analytics' && ['On', 'Event', 'If', 'Properties', 'EventType'].indexOf(name.substr(9)) === -1; } function propertyName(name) { var s = name.slice(9); // slice off the 'analytics' prefix if (typeof s !== 'undefined' && s!==null && s.length > 0) { return s.substring(0, 1).toLowerCase() + s.substring(1); } else { return s; } } return { restrict: 'A', link: function ($scope, $element, $attrs) { var eventType = $attrs.analyticsOn || inferEventType($element[0]); var trackingData = {}; angular.forEach($attrs.$attr, function(attr, name) { if (isProperty(name)) { trackingData[propertyName(name)] = $attrs[name]; $attrs.$observe(name, function(value){ trackingData[propertyName(name)] = value; }); } }); angular.element($element[0]).bind(eventType, function ($event) { var eventName = $attrs.analyticsEvent || inferEventName($element[0]); trackingData.eventType = $event.type; if($attrs.analyticsIf){ if(! $scope.$eval($attrs.analyticsIf)){ return; // Cancel this event if we don't pass the analytics-if condition } } // Allow components to pass through an expression that gets merged on to the event properties // eg. analytics-properites='myComponentScope.someConfigExpression.$analyticsProperties' if($attrs.analyticsProperties){ angular.extend(trackingData, $scope.$eval($attrs.analyticsProperties)); } $analytics.eventTrack(eventName, trackingData); }); } }; }]); })(angular);