/** * Create a wrapping module to ease having to include too many * modules. */ angular.module('ionic.ui', ['ionic.ui.content', 'ionic.ui.tabs', 'ionic.ui.nav', 'ionic.ui.sideMenu', 'ionic.ui.list', 'ionic.ui.checkbox', 'ionic.ui.toggle' ]); ; angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.ui.actionSheet']) .factory('ActionSheet', ['$rootScope', '$document', '$compile', 'TemplateLoader', function($rootScope, $document, $compile, TemplateLoader) { return { /** * Load an action sheet with the given template string. * * A new isolated scope will be created for the * action sheet and the new element will be appended into the body. * * @param {object} opts the options for this ActionSheet (see docs) */ show: function(opts) { var scope = $rootScope.$new(true); angular.extend(scope, opts); scope.cancel = function() { scope.sheet.hide(); //scope.$destroy(); opts.cancel(); }; scope.buttonClicked = function(index) { // Check if the button click event returned true, which means // we can close the action sheet if((opts.buttonClicked && opts.buttonClicked(index)) === true) { scope.sheet.hide(); //scope.$destroy(); } }; scope.destructiveButtonClicked = function() { // Check if the destructive button click event returned true, which means // we can close the action sheet if((opts.destructiveButtonClicked && opts.destructiveButtonClicked()) === true) { scope.sheet.hide(); //scope.$destroy(); } }; // Compile the template var element = $compile('')(scope); var s = element.scope(); $document[0].body.appendChild(element[0]); var sheet = new ionic.views.ActionSheet({el: element[0] }); s.sheet = sheet; sheet.show(); return sheet; } }; }]); ; angular.module('ionic.service.gesture', []) .factory('Gesture', [function() { return { on: function(eventType, cb, element) { return window.ionic.onGesture(eventType, cb, element); } }; }]); ; angular.module('ionic.service.loading', ['ionic.ui.loading']) .factory('Loading', ['$rootScope', '$document', '$compile', function($rootScope, $document, $compile) { return { /** * Load an action sheet with the given template string. * * A new isolated scope will be created for the * action sheet and the new element will be appended into the body. * * @param {object} opts the options for this ActionSheet (see docs) */ show: function(opts) { var defaults = { content: '', animation: 'fade-in', showBackdrop: true, maxWidth: 200, showDelay: 2000 }; opts = angular.extend(defaults, opts); var scope = $rootScope.$new(true); angular.extend(scope, opts); // Make sure there is only one loading element on the page at one point in time var existing = angular.element($document[0].querySelector('.loading-backdrop')); if(existing.length) { var scope = existing.scope(); if(scope.loading) { scope.loading.show(); return scope.loading; } } // Compile the template var element = $compile('' + opts.content + '')(scope); $document[0].body.appendChild(element[0]); var loading = new ionic.views.Loading({ el: element[0], maxWidth: opts.maxWidth, showDelay: opts.showDelay }); loading.show(); scope.loading = loading; return loading; } }; }]); ; angular.module('ionic.service.modal', ['ionic.service.templateLoad']) .factory('Modal', ['$rootScope', '$document', '$compile', 'TemplateLoader', function($rootScope, $document, $compile, TemplateLoader) { return { /** * Load a modal with the given template string. * * A new isolated scope will be created for the * modal and the new element will be appended into the body. */ fromTemplate: function(templateString) { // Create a new isolated scope for the modal var scope = $rootScope.$new(true); // Compile the template var element = $compile(templateString)(scope); $document[0].body.appendChild(element[0]); var modal = new ionic.views.Modal({el: element[0] }); scope.modal = modal; return modal; }, fromTemplateUrl: function(url, cb) { TemplateLoader.load(url).then(function(templateString) { // Create a new isolated scope for the modal var scope = $rootScope.$new(true); // Compile the template var element = $compile(templateString)(scope); $document[0].body.appendChild(element[0]); var modal = new ionic.views.Modal({ el: element[0] }); scope.modal = modal; cb(modal); }); } }; }]); ; angular.module('ionic.service.popup', ['ionic.service.templateLoad']) .factory('Popup', ['$rootScope', '$document', '$compile', 'TemplateLoader', function($rootScope, $document, $compile, TemplateLoader) { var getPopup = function() { // Make sure there is only one loading element on the page at one point in time var existing = angular.element($document[0].querySelector('.popup')); if(existing.length) { var scope = existing.scope(); if(scope.popup) { return scope; } } }; return { alert: function(message) { // If there is an existing popup, just show that one var existing = getPopup(); if(existing) { return existing.popup.alert(message); } var defaults = { title: message, animation: 'fade-in', }; opts = angular.extend(defaults, opts); var scope = $rootScope.$new(true); angular.extend(scope, opts); // Compile the template var element = $compile('' + opts.content + '')(scope); $document[0].body.appendChild(element[0]); var popup = new ionic.views.Popup({el: element[0] }); popup.alert(message); scope.popup = popup; return popup; }, confirm: function(cb) { }, prompt: function(cb) { }, show: function(data) { // data.title // data.template // data.buttons } }; }]); ; angular.module('ionic.service.templateLoad', []) .factory('TemplateLoader', ['$q', '$http', '$templateCache', function($q, $http, $templateCache) { return { load: function(url) { var deferred = $q.defer(); $http.get(url, { cache: $templateCache }).success(function(html) { deferred.resolve(html && html.trim()); }); return deferred.promise; } }; }]); ; (function() { 'use strict'; angular.module('ionic.ui.actionSheet', []) .directive('actionSheet', function() { return { restrict: 'E', scope: true, replace: true, link: function($scope, $element){ $scope.$on('$destroy', function() { $element.remove(); }); }, template: '
' + '
' + '
{{titleText}}
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' }; }); })(); ; (function() { 'use strict'; angular.module('ionic.ui.checkbox', []) .directive('checkbox', function() { return { restrict: 'E', replace: true, require: '?ngModel', scope: true, template: '
', link: function($scope, $element, $attr, ngModel) { var checkbox, handle; if(!ngModel) { return; } checkbox = $element.children().eq(0); handle = $element.children().eq(1); if(!checkbox.length || !handle.length) { return; } $scope.checkbox = new ionic.views.Checkbox({ el: $element[0], checkbox: checkbox[0], handle: handle[0] }); $element.bind('click', function(e) { $scope.checkbox.tap(e); $scope.$apply(function() { ngModel.$setViewValue(checkbox[0].checked); }); }); ngModel.$render = function() { $scope.checkbox.val(ngModel.$viewValue); }; } }; }); })(); ; (function() { 'use strict'; angular.module('ionic.ui.content', []) // The content directive is a core scrollable content area // that is part of many View hierarchies .directive('content', function() { return { restrict: 'E', replace: true, template: '
', transclude: true, compile: function(element, attr, transclude) { return function($scope, $element, $attr) { var c = $element.eq(0); if(attr.padded) { c.addClass('padding'); } if(attr.hasHeader) { c.addClass('has-header'); } if(attr.hasFooter) { c.addClass('has-footer'); } if(attr.hasTabs) { c.addClass('has-tabs'); } $element.append(transclude($scope)); }; } }; }); })(); ; (function() { 'use strict'; angular.module('ionic.ui.list', ['ngAnimate']) .directive('listItem', function() { return { restrict: 'E', require: '^list', replace: true, transclude: true, scope: { item: '=', onSelect: '&', onDelete: '&', canDelete: '@', canReorder: '@', canSwipe: '@', buttons: '=', }, template: '\
\
\
\ \
\
', /* template: '
  • \
    \ \
    \
    \
    \
    \ \
    \
    \ \
    \
  • ',*/ link: function($scope, $element, $attr, list) { $scope.isEditing = false; $scope.deleteIcon = list.scope.deleteIcon; $scope.reorderIcon = list.scope.reorderIcon; $scope.buttonClicked = function(button) { button.onButtonClicked && button.onButtonClicked($scope.item, button); }; list.scope.$watch('isEditing', function(v) { $scope.isEditing = v; }); } }; }) .directive('list', function() { return { restrict: 'E', replace: true, transclude: true, scope: { isEditing: '=', deleteIcon: '@', reorderIcon: '@' }, // So we can require being under this controller: function($scope) { var _this = this; this.scope = $scope; $scope.$watch('isEditing', function(v) { _this.isEditing = true; }); }, template: '', compile: function(element, attr, transclude) { return function($scope, $element, $attr) { var lv = new ionic.views.List({el: $element[0]}); if(attr.animation) { $element.addClass(attr.animation); } }; } }; }); })(); ; (function() { 'use strict'; angular.module('ionic.ui.loading', []) .directive('loading', function() { return { restrict: 'E', replace: true, transclude: true, link: function($scope, $element){ $scope.$on('$destroy', function() { $element.remove(); }); $element.addClass($scope.animation || ''); }, template: '
    ' + '
    ' + '
    ' + '
    ' }; }); })(); ; (function() { 'use strict'; angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.gesture', 'ngAnimate']) .controller('NavCtrl', ['$scope', '$element', '$animate', '$compile', 'TemplateLoader', function($scope, $element, $animate, $compile, TemplateLoader) { var _this = this; angular.extend(this, ionic.controllers.NavController.prototype); ionic.controllers.NavController.call(this, { content: { }, navBar: { shouldGoBack: function() { }, show: function() { this.isVisible = true; }, hide: function() { this.isVisible = false; }, setTitle: function(title) { $scope.navController.title = title; }, showBackButton: function(show) { }, } }); this.handleDrag = function(e) { }; this.endDrag = function(e) { }; /** * Push a template onto the navigation stack. * @param {string} templateUrl the URL of the template to load. */ this.pushFromTemplate = function(templateUrl) { var childScope = $scope.$new(); childScope.isVisible = true; // Load the given template TemplateLoader.load(templateUrl).then(function(templateString) { // Compile the template with the new scrope, and append it to the navigation's content area var el = $compile(templateString)(childScope, function(cloned, scope) { var content = $element[0].querySelector('.content'); angular.element(content).append(cloned); }); }); }; /** * Push a controller to the stack. This is called by the child * nav-content directive when it is linked to a scope on the page. */ $scope.pushController = function(scope, element) { _this.push(scope); }; $scope.navController = this; }]) .directive('navs', function() { return { restrict: 'E', replace: true, transclude: true, controller: 'NavCtrl', //templateUrl: 'ext/angular/tmpl/ionicTabBar.tmpl.html', template: '
    ', }; }) .directive('navBar', function() { return { restrict: 'E', require: '^navs', replace: true, scope: true, template: '', link: function(scope, element, attrs, navCtrl) { scope.navController = navCtrl; scope.$watch('navController.controllers.length', function(value) { }); scope.goBack = function() { navCtrl.pop(); }; } }; }) .directive('navContent', ['Gesture', '$animate', function(Gesture, $animate) { return { restrict: 'ECA', require: '^navs', scope: true, transclude: 'element', compile: function(element, attr, transclude) { return function($scope, $element, $attr, navCtrl) { var lastParent, lastIndex, childScope, childElement; $scope.title = $attr.title; if($attr.navBar === "false") { navCtrl.hideNavBar(); } else { navCtrl.showNavBar(); } $scope.pushController($scope, $element); $scope.$watch('isVisible', function(value) { if(childElement) { $animate.leave(childElement); childElement = undefined; } if(childScope) { childScope.$destroy(); childScope = undefined; } if(value) { childScope = $scope.$new(); transclude(childScope, function(clone) { childElement = clone; Gesture.on('drag', function(e) { //navCtrl.handleDrag(e); console.log('Content drag', e); }, childElement[0]); Gesture.on('release', function(e) { //navCtrl._endDrag(e); }, childElement[0]); var title = $element.parent().parent().parent()[0].querySelector('.title'); $animate.enter(clone, $element.parent(), $element); $animate.addClass(angular.element(title), 'slide-left-fade', function() { $animate.removeClass(angular.element(title), 'slide-left-fade', function() { }); }); }); } }); } } }; }]); })(); ; ; (function() { 'use strict'; /** * @description * The sideMenuCtrl lets you quickly have a draggable side * left and/or right menu, which a center content area. */ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture']) /** * The internal controller for the side menu controller. This * extends our core Ionic side menu controller and exposes * some side menu stuff on the current scope. */ .controller('SideMenuCtrl', function($scope) { var _this = this; angular.extend(this, ionic.controllers.SideMenuController.prototype); ionic.controllers.SideMenuController.call(this, { left: { width: 270, pushDown: function() { $scope.leftZIndex = -1; }, bringUp: function() { $scope.leftZIndex = 0; } }, right: { width: 270, pushDown: function() { $scope.rightZIndex = -1; }, bringUp: function() { $scope.rightZIndex = 0; } } }); $scope.contentTranslateX = 0; $scope.sideMenuCtrl = this; }) .directive('sideMenuCtrl', function() { return { restrict: 'CA', controller: 'SideMenuCtrl', }; }) .directive('sideMenuContent', ['Gesture', function(Gesture) { return { restrict: 'CA', require: '^sideMenuCtrl', scope: true, compile: function(element, attr, transclude) { return function($scope, $element, $attr, sideMenuCtrl) { Gesture.on('drag', function(e) { sideMenuCtrl._handleDrag(e); }, $element[0]); Gesture.on('release', function(e) { sideMenuCtrl._endDrag(e); }, $element[0]); sideMenuCtrl.setContent({ onDrag: function(e) {}, endDrag: function(e) {}, getTranslateX: function() { return $scope.contentTranslateX || 0; }, setTranslateX: function(amount) { $scope.contentTranslateX = amount; $element[0].style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)'; }, enableAnimation: function() { //this.el.classList.add(this.animateClass); $scope.animationEnabled = true; $element[0].classList.add('menu-animated'); }, disableAnimation: function() { //this.el.classList.remove(this.animateClass); $scope.animationEnabled = false; $element[0].classList.remove('menu-animated'); } }); }; } }; }]) .directive('menu', function() { return { restrict: 'E', require: '^sideMenuCtrl', replace: true, transclude: true, scope: { side: '@' }, template: '', compile: function(element, attr, transclude) { return function($scope, $element, $attr, sideMenuCtrl) { if($scope.side == 'left') { sideMenuCtrl.left.isEnabled = true; } else if($scope.side == 'right') { sideMenuCtrl.right.isEnabled = true; } $element.append(transclude($scope)); }; } }; }); })(); ; (function() { 'use strict'; /** * @description * The sideMenuCtrl lets you quickly have a draggable side * left and/or right menu, which a center content area. */ angular.module('ionic.ui.slideBox', []) /** * The internal controller for the side menu controller. This * extends our core Ionic side menu controller and exposes * some side menu stuff on the current scope. */ .controller('SlideBoxCtrl', ['$scope', '$element', function($scope, $element) { $scope.slides = []; this.slideAdded = function() { $scope.slides.push({}); }; }]) .directive('slideBox', ['$compile', function($compile) { return { restrict: 'E', replace: true, transclude: true, controller: 'SlideBoxCtrl', scope: {}, template: '
    \
    \
    \
    ', postLink: function() { console.log('POST LINK'); }, link: function($scope, $element, $attr, slideBoxCtrl) { // If the pager should show, append it to the slide box if($attr.showPager !== "false") { var childScope = $scope.$new(); var pager = $compile('')(childScope); $element.append(pager); $scope.slideBox = new ionic.views.SlideBox({ el: $element[0] }); } } } }]) .directive('slide', function() { return { restrict: 'E', replace: true, require: '^slideBox', transclude: true, template: '
    ', compile: function(element, attr, transclude) { return function($scope, $element, $attr, slideBoxCtrl) { slideBoxCtrl.slideAdded(); } } } }) .directive('pager', function() { return { restrict: 'E', replace: true, require: '^slideBox', template: '
    ' } }); })(); ; angular.module('ionic.ui.tabs', ['ngAnimate']) .controller('TabsCtrl', ['$scope', '$element', '$animate', function($scope, $element, $animate) { var _this = this; angular.extend(this, ionic.controllers.TabBarController.prototype); ionic.controllers.TabBarController.call(this, { controllerChanged: function(oldC, oldI, newC, newI) { $scope.controllerChanged && $scope.controllerChanged({ oldController: oldC, oldIndex: oldI, newController: newC, newIndex: newI }); }, tabBar: { tryTabSelect: function() {}, setSelectedItem: function(index) {}, addItem: function(item) {} } }); this.add = function(controller) { this.addController(controller); this.select(0); }; this.select = function(controllerIndex) { //var oldIndex = _this.getSelectedIndex(); $scope.activeAnimation = $scope.animation; /* if(controllerIndex > oldIndex) { } else if(controllerIndex < oldIndex) { $scope.activeAnimation = $scope.animation + '-reverse'; } */ _this.selectController(controllerIndex); }; $scope.controllers = this.controllers; }]) .directive('tabs', function() { return { restrict: 'E', replace: true, scope: { animation: '@', controllerChanged: '&' }, transclude: true, controller: 'TabsCtrl', //templateUrl: 'ext/angular/tmpl/ionicTabBar.tmpl.html', template: '
    ', compile: function(element, attr, transclude, tabsCtrl) { return function($scope, $element, $attr) { $scope.$watch('activeAnimation', function(value) { //$element.removeClass($scope.animation + ' ' + $scope.animation + '-reverse'); $element.addClass($scope.activeAnimation); }); transclude($scope, function(cloned) { $element.prepend(cloned); }); }; } }; }) // Generic controller directive .directive('tab', ['$animate', function($animate) { return { restrict: 'E', replace: true, require: '^tabs', scope: true, transclude: 'element', compile: function(element, attr, transclude) { return function($scope, $element, $attr, tabsCtrl) { var childScope, childElement; $scope.$watch('isVisible', function(value) { if(childElement) { $animate.leave(childElement); childElement = undefined; } if(childScope) { childScope.$destroy(); childScope = undefined; } if(value) { childScope = $scope.$new(); transclude(childScope, function(clone) { childElement = clone; childElement.addClass('view-full'); $animate.enter(clone, $element.parent(), $element); }); } }); $scope.title = $attr.title; $scope.icon = $attr.icon; $scope.iconOn = $attr.iconOn; $scope.iconOff = $attr.iconOff; tabsCtrl.add($scope); } } }; }]) .directive('tabControllerBar', function() { return { restrict: 'E', require: '^tabs', transclude: true, replace: true, scope: true, template: '
    ' + '' + '
    ' }; }) .directive('tabControllerItem', function() { return { restrict: 'E', replace: true, require: '^tabs', scope: { title: '@', icon: '@', iconOn: '@', iconOff: '@', active: '=', tabSelected: '@', index: '=' }, link: function(scope, element, attrs, tabsCtrl) { if(attrs.icon) { scope.iconOn = scope.iconOff = attrs.icon; } scope.selectTab = function(index) { tabsCtrl.select(scope.index); }; }, template: '' + '' + '' + ' {{title}}' + '' }; }) .directive('tabBar', function() { return { restrict: 'E', replace: true, transclude: true, template: '
    ' + '
    ' } }) .directive('tabItem', function() { return { restrict: 'E', replace: true, scope: { title: '@', iconOn: '@', iconOff: '@', active: '=', tabSelected: '@', index: '=' }, link: function(scope, element, attrs) { }, template: '' + '' + '' + ' {{title}}' + '' }; }); ; angular.module('ionic.ui.toggle', []) // The content directive is a core scrollable content area // that is part of many View hierarchies .directive('toggle', function() { return { restrict: 'E', replace: true, require: '?ngModel', scope: true, template: '
    ', link: function($scope, $element, $attr, ngModel) { var checkbox, handle; if(!ngModel) { return; } checkbox = $element.children().eq(0); handle = $element.children().eq(1); if(!checkbox.length || !handle.length) { return; } $scope.toggle = new ionic.views.Toggle({ el: $element[0], checkbox: checkbox[0], handle: handle[0] }); $element.bind('click', function(e) { $scope.toggle.tap(e); $scope.$apply(function() { ngModel.$setViewValue(checkbox[0].checked); }); }); ngModel.$render = function() { $scope.toggle.val(ngModel.$viewValue); }; } }; });