diff options
Diffstat (limited to 'afb-client/bower_components/foundation-apps/js/angular/services')
5 files changed, 771 insertions, 0 deletions
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js new file mode 100644 index 0000000..535798a --- /dev/null +++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js @@ -0,0 +1,129 @@ +(function() { + 'use strict'; + + angular.module('foundation.core.animation', []) + .service('FoundationAnimation', FoundationAnimation) + ; + + function FoundationAnimation() { + var animations = []; + var service = {}; + + var initClasses = ['ng-enter', 'ng-leave']; + var activeClasses = ['ng-enter-active', 'ng-leave-active']; + var activeGenericClass = 'is-active'; + var events = [ + 'webkitAnimationEnd', 'mozAnimationEnd', + 'MSAnimationEnd', 'oanimationend', + 'animationend', 'webkitTransitionEnd', + 'otransitionend', 'transitionend' + ]; + + service.animate = animate; + service.toggleAnimation = toggleAnimation; + + return service; + + function toggleAnimation(element, futureState) { + if(futureState) { + element.addClass(activeGenericClass); + } else { + element.removeClass(activeGenericClass); + } + } + + function animate(element, futureState, animationIn, animationOut) { + var timedOut = true; + var self = this; + self.cancelAnimation = cancelAnimation; + + var animationClass = futureState ? animationIn: animationOut; + var activation = futureState; + var initClass = activation ? initClasses[0] : initClasses[1]; + var activeClass = activation ? activeClasses[0] : activeClasses[1]; + //stop animation + registerElement(element); + reset(); + element.addClass(animationClass); + element.addClass(initClass); + + element.addClass(activeGenericClass); + + //force a "tick" + reflow(); + + //activate + element[0].style.transitionDuration = ''; + element.addClass(activeClass); + + element.one(events.join(' '), function() { + finishAnimation(); + }); + + setTimeout(function() { + if(timedOut) { + finishAnimation(); + } + }, 3000); + + function finishAnimation() { + deregisterElement(element); + reset(); //reset all classes + element[0].style.transitionDuration = ''; + element.removeClass(!activation ? activeGenericClass : ''); //if not active, remove active class + reflow(); + timedOut = false; + } + + + function cancelAnimation(element) { + deregisterElement(element); + angular.element(element).off(events.join(' ')); //kill all animation event handlers + timedOut = false; + } + + function registerElement(el) { + var elObj = { + el: el, + animation: self + }; + + //kill in progress animations + var inProgress = animations.filter(function(obj) { + return obj.el === el; + }); + if(inProgress.length > 0) { + var target = inProgress[0].el[0]; + + inProgress[0].animation.cancelAnimation(target); + } + + animations.push(elObj); + } + + function deregisterElement(el) { + var index; + var currentAnimation = animations.filter(function(obj, ind) { + if(obj.el === el) { + index = ind; + } + }); + + if(index >= 0) { + animations.splice(index, 1); + } + + } + + function reflow() { + return element[0].offsetWidth; + } + + function reset() { + element[0].style.transitionDuration = 0; + element.removeClass(initClasses.join(' ') + ' ' + activeClasses.join(' ') + ' ' + animationIn + ' ' + animationOut); + } + } + } + +})(); diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js new file mode 100644 index 0000000..6aeb9da --- /dev/null +++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js @@ -0,0 +1,163 @@ +(function() { + 'use strict'; + + angular.module('foundation.core', [ + 'foundation.core.animation' + ]) + .service('FoundationApi', FoundationApi) + .service('FoundationAdapter', FoundationAdapter) + .factory('Utils', Utils) + ; + + FoundationApi.$inject = ['FoundationAnimation']; + + function FoundationApi(FoundationAnimation) { + var listeners = {}; + var settings = {}; + var uniqueIds = []; + var service = {}; + + service.subscribe = subscribe; + service.unsubscribe = unsubscribe; + service.publish = publish; + service.getSettings = getSettings; + service.modifySettings = modifySettings; + service.generateUuid = generateUuid; + service.toggleAnimate = toggleAnimate; + service.closeActiveElements = closeActiveElements; + service.animate = animate; + + return service; + + function subscribe(name, callback) { + if (!listeners[name]) { + listeners[name] = []; + } + + listeners[name].push(callback); + return true; + } + + function unsubscribe(name, callback) { + if (listeners[name] !== undefined) { + delete listeners[name]; + } + if (typeof callback == 'function') { + callback.call(this); + } + } + + function publish(name, msg) { + if (!listeners[name]) { + listeners[name] = []; + } + + listeners[name].forEach(function(cb) { + cb(msg); + }); + + return; + } + + function getSettings() { + return settings; + } + + function modifySettings(tree) { + settings = angular.extend(settings, tree); + return settings; + } + + function generateUuid() { + var uuid = ''; + + //little trick to produce semi-random IDs + do { + uuid += 'zf-uuid-'; + for (var i=0; i<15; i++) { + uuid += Math.floor(Math.random()*16).toString(16); + } + } while(!uniqueIds.indexOf(uuid)); + + uniqueIds.push(uuid); + return uuid; + } + + function toggleAnimate(element, futureState) { + FoundationAnimation.toggleAnimate(element, futureState); + } + + function closeActiveElements(options) { + var self = this; + options = options || {}; + var activeElements = document.querySelectorAll('.is-active[zf-closable]'); + // action sheets are nested zf-closable elements, so we have to target the parent + var nestedActiveElements = document.querySelectorAll('[zf-closable] > .is-active') + + if (activeElements.length) { + angular.forEach(activeElements, function(el) { + if (options.exclude !== el.id) { + self.publish(el.id, 'close'); + } + }); + } + if (nestedActiveElements.length) { + angular.forEach(nestedActiveElements, function(el) { + var parentId = el.parentNode.id; + if (options.exclude !== parentId) { + self.publish(parentId, 'close'); + } + }) + } + } + + function animate(element, futureState, animationIn, animationOut) { + FoundationAnimation.animate(element, futureState, animationIn, animationOut); + } + } + + FoundationAdapter.$inject = ['FoundationApi']; + + function FoundationAdapter(foundationApi) { + + var service = {}; + + service.activate = activate; + service.deactivate = deactivate; + + return service; + + function activate(target) { + foundationApi.publish(target, 'show'); + } + + function deactivate(target) { + foundationApi.publish(target, 'hide'); + } + } + + + function Utils() { + var utils = {}; + + utils.throttle = throttleUtil; + + return utils; + + function throttleUtil(func, delay) { + var timer = null; + + return function () { + var context = this, args = arguments; + + if (timer === null) { + timer = setTimeout(function () { + func.apply(context, args); + timer = null; + }, delay); + } + }; + } + } + +})(); diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js new file mode 100644 index 0000000..ba79c52 --- /dev/null +++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js @@ -0,0 +1,125 @@ +(function() { + 'use strict'; + + angular.module('foundation.dynamicRouting.animations', ['foundation.dynamicRouting']) + .directive('uiView', uiView) + ; + + uiView.$inject = ['$rootScope', '$state']; + + function uiView($rootScope, $state) { + var directive = { + restrict : 'ECA', + priority : -400, + link : link + }; + + return directive; + + function link(scope, element) { + var animation = {}; + var animationEnded = false; + var presetHeight; + + var cleanup = [ + $rootScope.$on('$stateChangeStart', onStateChangeStart), + $rootScope.$on('$stateChangeError', onStateChangeError), + scope.$on('$stateChangeSuccess', onStateChangeSuccess), + scope.$on('$viewContentAnimationEnded', onViewContentAnimationEnded) + ]; + + var destroyed = scope.$on('$destroy', function onDestroy() { + angular.forEach(cleanup, function (cb) { + if (angular.isFunction(cb)) { + cb(); + } + }); + + destroyed(); + }); + + function onStateChangeStart(event, toState, toParams, fromState, fromParams) { + + if (fromState.animation) { + if (!fromState.animation.leave && !toState.animation.leave) { + return; + } + else { + animationRouter(event, toState, fromState); + } + } + } + + function animationRouter(event, toState, fromState) { + if (!animationEnded) { + resetParent(); + prepareParent(); + + element.removeClass(fromState.animation.leave); + } + else { + prepareParent(); + + element.addClass(fromState.animation.leave); + } + + } + + function onStateChangeError() { + if(animation.leave) { + element.removeClass(animation.leave); + } + + resetParent(); //reset parent if state change fails + } + + function onStateChangeSuccess() { + resetParent(); + if ($state.includes(getState()) && animation.enter) { + element.addClass(animation.enter); + } + } + + function onViewContentAnimationEnded(event) { + if (event.targetScope === scope && animation.enter) { + element.removeClass(animation.enter); + } + + animationEnded = true; + + } + + function getState() { + var view = element.data('$uiView'); + var state = view && view.state && view.state.self; + + if (state) { + angular.extend(animation, state.animation); + } + + return state; + } + + function resetParent() { + element.parent().removeClass('position-absolute'); + if(presetHeight !== true) { + element.parent()[0].style.height = null; + } + } + + function prepareParent() { + var parentHeight = parseInt(element.parent()[0].style.height); + var elHeight = parseInt(window.getComputedStyle(element[0], null).getPropertyValue('height')); + var tempHeight = parentHeight > 0 ? parentHeight : elHeight > 0 ? elHeight : ''; + + if(parentHeight > 0) { + presetHeight = true; + } + + element.parent()[0].style.height = tempHeight + 'px'; + element.parent().addClass('position-absolute'); + } + } + } + +})();
\ No newline at end of file diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js new file mode 100644 index 0000000..27e3767 --- /dev/null +++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js @@ -0,0 +1,156 @@ +(function() { + 'use strict'; + + angular.module('foundation.dynamicRouting', ['ui.router']) + .provider('$FoundationState', FoundationState) + .controller('DefaultController', DefaultController) + .config(DynamicRoutingConfig) + .run(DynamicRoutingRun) + ; + + FoundationState.$inject = ['$stateProvider']; + + function FoundationState($stateProvider) { + var complexViews = {}; + + this.registerDynamicRoutes = function(routes) { + var dynamicRoutes = routes || foundationRoutes; + + angular.forEach(dynamicRoutes, function(page) { + if (page.hasComposed) { + if (!angular.isDefined(complexViews[page.parent])) { + complexViews[page.parent] = { children: {} }; + } + + if (page.controller) { + page.controller = getController(page); + } + + complexViews[page.parent].children[page.name] = page; + + } else if (page.composed) { + if(!angular.isDefined(complexViews[page.name])) { + complexViews[page.name] = { children: {} }; + } + + if (page.controller) { + page.controller = getController(page); + } + + angular.extend(complexViews[page.name], page); + } else { + var state = { + url: page.url, + templateUrl: page.path, + abstract: page.abstract || false, + parent: page.parent || '', + controller: getController(page), + data: getData(page), + animation: buildAnimations(page), + }; + + $stateProvider.state(page.name, state); + } + }); + + angular.forEach(complexViews, function(page) { + var state = { + url: page.url, + parent: page.parent || '', + abstract: page.abstract || false, + data: getData(page), + animation: buildAnimations(page), + views: { + '': buildState(page.path, page) + } + }; + + angular.forEach(page.children, function(sub) { + state.views[sub.name + '@' + page.name] = buildState(sub.path, page); + }); + + $stateProvider.state(page.name, state); + }); + }; + + this.$get = angular.noop; + + function getData(page) { + var data = { vars: {} }; + if (page.data) { + if (typeof page.data.vars === "object") { + data.vars = page.data.vars; + } + delete page.data.vars; + angular.extend(data, page.data); + } + delete page.data; + angular.extend(data.vars, page); + return data; + } + + function buildState(path, state) { + return { + templateUrl: path, + controller: getController(state), + }; + } + + function getController(state) { + var ctrl = state.controller || 'DefaultController'; + + if (!/\w\s+as\s+\w/.test(ctrl)) { + ctrl += ' as PageCtrl'; + } + + return ctrl; + } + + function buildAnimations(state) { + var animations = {}; + + if (state.animationIn) { + animations.enter = state.animationIn; + } + + if (state.animationOut) { + animations.leave = state.animationOut; + } + + return animations; + } + } + + DefaultController.$inject = ['$scope', '$stateParams', '$state']; + + function DefaultController($scope, $stateParams, $state) { + var params = {}; + angular.forEach($stateParams, function(value, key) { + params[key] = value; + }); + + $scope.params = params; + $scope.current = $state.current.name; + + if($state.current.views) { + $scope.vars = $state.current.data.vars; + $scope.composed = $state.current.data.vars.children; + } else { + $scope.vars = $state.current.data.vars; + } + } + + DynamicRoutingConfig.$inject = ['$FoundationStateProvider']; + + function DynamicRoutingConfig(FoundationStateProvider) { + FoundationStateProvider.registerDynamicRoutes(foundationRoutes); + } + + DynamicRoutingRun.$inject = ['$rootScope', '$state', '$stateParams']; + + function DynamicRoutingRun($rootScope, $state, $stateParams) { + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + } + +})(); diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js new file mode 100644 index 0000000..12715f6 --- /dev/null +++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js @@ -0,0 +1,198 @@ +(function() { + 'use strict'; + + angular.module('foundation.mediaquery', ['foundation.core']) + .run(mqInitRun) + .factory('FoundationMQInit', FoundationMQInit) + .factory('mqHelpers', mqHelpers) + .service('FoundationMQ', FoundationMQ) + ; + + mqInitRun.$inject = ['FoundationMQInit']; + + function mqInitRun(mqInit) { + mqInit.init(); + } + + FoundationMQInit.$inject = ['mqHelpers', 'FoundationApi', 'Utils']; + + function FoundationMQInit(helpers, foundationApi, u){ + var factory = {}; + var namedQueries = { + 'default' : 'only screen', + landscape : 'only screen and (orientation: landscape)', + portrait : 'only screen and (orientation: portrait)', + retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' + + 'only screen and (min--moz-device-pixel-ratio: 2),' + + 'only screen and (-o-min-device-pixel-ratio: 2/1),' + + 'only screen and (min-device-pixel-ratio: 2),' + + 'only screen and (min-resolution: 192dpi),' + + 'only screen and (min-resolution: 2dppx)' + }; + + factory.init = init; + + return factory; + + function init() { + var mediaQueries; + var extractedMedia; + var mediaObject; + + helpers.headerHelper(['foundation-mq']); + extractedMedia = helpers.getStyle('.foundation-mq', 'font-family'); + + mediaQueries = helpers.parseStyleToObject((extractedMedia)); + + for(var key in mediaQueries) { + mediaQueries[key] = 'only screen and (min-width: ' + mediaQueries[key].replace('rem', 'em') + ')'; + } + + + foundationApi.modifySettings({ + mediaQueries: angular.extend(mediaQueries, namedQueries) + }); + + window.addEventListener('resize', u.throttle(function() { + foundationApi.publish('resize', 'window resized'); + }, 50)); + + } + } + + + function mqHelpers() { + var factory = {}; + + factory.headerHelper = headerHelper; + factory.getStyle = getStyle; + factory.parseStyleToObject = parseStyleToObject; + + return factory; + + function headerHelper(classArray) { + var i = classArray.length; + var head = angular.element(document.querySelectorAll('head')); + + while(i--) { + head.append('<meta class="' + classArray[i] + '" />'); + } + + return; + } + + function getStyle(selector, styleName) { + var elem = document.querySelectorAll(selector)[0]; + var style = window.getComputedStyle(elem, null); + + return style.getPropertyValue('font-family'); + } + + // https://github.com/sindresorhus/query-string + function parseStyleToObject(str) { + var styleObject = {}; + + if (typeof str !== 'string') { + return styleObject; + } + + str = str.trim().slice(1, -1); // browsers re-quote string style values + + if (!str) { + return styleObject; + } + + styleObject = str.split('&').reduce(function(ret, param) { + var parts = param.replace(/\+/g, ' ').split('='); + var key = parts[0]; + var val = parts[1]; + key = decodeURIComponent(key); + + // missing `=` should be `null`: + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + val = val === undefined ? null : decodeURIComponent(val); + + if (!ret.hasOwnProperty(key)) { + ret[key] = val; + } else if (Array.isArray(ret[key])) { + ret[key].push(val); + } else { + ret[key] = [ret[key], val]; + } + return ret; + }, {}); + + return styleObject; + } + } + + FoundationMQ.$inject = ['FoundationApi']; + + function FoundationMQ(foundationApi) { + var service = []; + + service.getMediaQueries = getMediaQueries; + service.match = match; + service.collectScenariosFromElement = collectScenariosFromElement; + + return service; + + function getMediaQueries() { + return foundationApi.getSettings().mediaQueries; + } + + function match(scenarios) { + var count = scenarios.length; + var queries = service.getMediaQueries(); + var matches = []; + + if (count > 0) { + while (count--) { + var mq; + var rule = scenarios[count].media; + + if (queries[rule]) { + mq = matchMedia(queries[rule]); + } else { + mq = matchMedia(rule); + } + + if (mq.matches) { + matches.push({ ind: count}); + } + } + } + + return matches; + } + + // Collects a scenario object and templates from element + function collectScenariosFromElement(parentElement) { + var scenarios = []; + var templates = []; + + var elements = parentElement.children(); + var i = 0; + + angular.forEach(elements, function(el) { + var elem = angular.element(el); + + + //if no source or no html, capture element itself + if (!elem.attr('src') || !elem.attr('src').match(/.html$/)) { + templates[i] = elem; + scenarios[i] = { media: elem.attr('media'), templ: i }; + } else { + scenarios[i] = { media: elem.attr('media'), src: elem.attr('src') }; + } + + i++; + }); + + return { + scenarios: scenarios, + templates: templates + }; + } + } +})(); |