diff --git a/config/build.config.js b/config/build.config.js
index ceef7187a5..dae8d1b532 100644
--- a/config/build.config.js
+++ b/config/build.config.js
@@ -45,34 +45,25 @@ module.exports = {
// Views
'js/views/view.js',
-
'js/views/scrollView.js',
-
'js/views/actionSheetView.js',
'js/views/headerBarView.js',
'js/views/listView.js',
- 'js/views/loadingView.js',
'js/views/modalView.js',
- 'js/views/navBarView.js',
'js/views/sideMenuView.js',
'js/views/sliderView.js',
- 'js/views/tabBarView.js',
'js/views/toggleView.js',
// Controllers
'js/controllers/viewController.js',
-
- 'js/controllers/navController.js',
'js/controllers/sideMenuController.js',
- 'js/controllers/tabBarController.js'
-
],
angularIonicFiles: [
- 'js/ext/angular/src/*.js',
- 'js/ext/angular/src/service/**/*.js',
- 'js/ext/angular/src/directive/**/*.js',
- 'js/ext/angular/src/controller/**/*.js'
+ 'js/angular/*.js',
+ 'js/angular/service/**/*.js',
+ 'js/angular/controller/**/*.js',
+ 'js/angular/directive/**/*.js',
],
//Which vendor files to include in dist, used by build
diff --git a/config/karma.conf.js b/config/karma.conf.js
index 9f4393e547..f1d9db898f 100644
--- a/config/karma.conf.js
+++ b/config/karma.conf.js
@@ -25,8 +25,7 @@ module.exports = function(config) {
.concat(buildConfig.ionicFiles)
.concat(buildConfig.angularIonicFiles)
.concat([
- 'test/unit/**/*.js',
- 'js/ext/angular/test/**/*.js'
+ 'test/unit/**/*.js'
]),
// list of files to exclude
diff --git a/js/angular/controller/listController.js b/js/angular/controller/listController.js
new file mode 100644
index 0000000000..2f4f4ac825
--- /dev/null
+++ b/js/angular/controller/listController.js
@@ -0,0 +1,115 @@
+
+/**
+ * @ngdoc service
+ * @name $ionicListDelegate
+ * @module ionic
+ *
+ * @description
+ * Delegate for controlling the {@link ionic.directive:ionList} directive.
+ *
+ * Methods called directly on the $ionicListDelegate service will control all lists.
+ * Use the {@link ionic.service:$ionicListDelegate#$getByHandle $getByHandle}
+ * method to control specific ionList instances.
+ *
+ * @usage
+ *
+ * ````html
+ *
+ *
+ *
+ * >
+ * {% raw %}Hello, {{i}}!{% endraw %}
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicListDelegate) {
+ * $scope.showDeleteButtons = function() {
+ * $ionicListDelegate.showDelete(true);
+ * };
+ * }
+ * ```
+ */
+IonicModule
+.service('$ionicListDelegate', delegateService([
+ /**
+ * @ngdoc method
+ * @name $ionicListDelegate#showReorder
+ * @param {boolean=} showReorder Set whether or not this list is showing its reorder buttons.
+ * @returns {boolean} Whether the reorder buttons are shown.
+ */
+ 'showReorder',
+ /**
+ * @ngdoc method
+ * @name $ionicListDelegate#showDelete
+ * @param {boolean=} showReorder Set whether or not this list is showing its delete buttons.
+ * @returns {boolean} Whether the delete buttons are shown.
+ */
+ 'showDelete',
+ /**
+ * @ngdoc method
+ * @name $ionicListDelegate#canSwipeItems
+ * @param {boolean=} showReorder Set whether or not this list is able to swipe to show
+ * option buttons.
+ * @returns {boolean} Whether the list is able to swipe to show option buttons.
+ */
+ 'canSwipeItems',
+ /**
+ * @ngdoc method
+ * @name $ionicListDelegate#closeOptionButtons
+ * @description Closes any option buttons on the list that are swiped open.
+ */
+ 'closeOptionButtons',
+ /**
+ * @ngdoc method
+ * @name $ionicListDelegate#$getByHandle
+ * @param {string} handle
+ * @returns `delegateInstance` A delegate instance that controls only the
+ * {@link ionic.directive:ionList} directives with `delegate-handle` matching
+ * the given handle.
+ *
+ * Example: `$ionicListDelegate.$getByHandle('my-handle').showReorder(true);`
+ */
+]))
+
+.controller('$ionicList', [
+ '$scope',
+ '$attrs',
+ '$parse',
+ '$ionicListDelegate',
+function($scope, $attrs, $parse, $ionicListDelegate) {
+
+ var isSwipeable = true;
+ var isReorderShown = false;
+ var isDeleteShown = false;
+
+ var deregisterInstance = $ionicListDelegate._registerInstance(this, $attrs.delegateHandle);
+ $scope.$on('$destroy', deregisterInstance);
+
+ this.showReorder = function(show) {
+ if (arguments.length) {
+ isReorderShown = !!show;
+ }
+ return isReorderShown;
+ };
+
+ this.showDelete = function(show) {
+ if (arguments.length) {
+ isDeleteShown = !!show;
+ }
+ return isDeleteShown;
+ };
+
+ this.canSwipeItems = function(can) {
+ if (arguments.length) {
+ isSwipeable = !!can;
+ }
+ return isSwipeable;
+ };
+
+ this.closeOptionButtons = function() {
+ this.listView && this.listView.clearDragEffects();
+ };
+}]);
diff --git a/js/angular/controller/navBarController.js b/js/angular/controller/navBarController.js
new file mode 100644
index 0000000000..5fe099bd18
--- /dev/null
+++ b/js/angular/controller/navBarController.js
@@ -0,0 +1,129 @@
+IonicModule
+.controller('$ionicNavBar', [
+ '$scope',
+ '$element',
+ '$attrs',
+ '$ionicViewService',
+ '$animate',
+ '$compile',
+ '$ionicNavBarDelegate',
+function($scope, $element, $attrs, $ionicViewService, $animate, $compile, $ionicNavBarDelegate) {
+ //Let the parent know about our controller too so that children of
+ //sibling content elements can know about us
+ $element.parent().data('$ionNavBarController', this);
+
+ var deregisterInstance = $ionicNavBarDelegate._registerInstance(this, $attrs.delegateHandle);
+
+ $scope.$on('$destroy', deregisterInstance);
+
+ var self = this;
+
+ this.leftButtonsElement = angular.element(
+ $element[0].querySelector('.buttons.left-buttons')
+ );
+ this.rightButtonsElement = angular.element(
+ $element[0].querySelector('.buttons.right-buttons')
+ );
+
+ this.back = function(e) {
+ var backView = $ionicViewService.getBackView();
+ backView && backView.go();
+ e && (e.alreadyHandled = true);
+ return false;
+ };
+
+ this.align = function(direction) {
+ this._headerBarView.align(direction);
+ };
+
+ this.showBackButton = function(show) {
+ if (arguments.length) {
+ $scope.backButtonShown = !!show;
+ }
+ return !!($scope.hasBackButton && $scope.backButtonShown);
+ };
+
+ this.showBar = function(show) {
+ if (arguments.length) {
+ $scope.isInvisible = !show;
+ $scope.$parent.$hasHeader = !!show;
+ }
+ return !$scope.isInvisible;
+ };
+
+ this.setTitle = function(title) {
+ $scope.oldTitle = $scope.title;
+ $scope.title = title || '';
+ };
+
+ this.changeTitle = function(title, direction) {
+ if ($scope.title === title) {
+ return false;
+ }
+ this.setTitle(title);
+ $scope.isReverse = direction == 'back';
+ $scope.shouldAnimate = !!direction;
+
+ if (!$scope.shouldAnimate) {
+ //We're done!
+ this._headerBarView.align();
+ } else {
+ this._animateTitles();
+ }
+ return true;
+ };
+
+ this.getTitle = function() {
+ return $scope.title || '';
+ };
+
+ this.getPreviousTitle = function() {
+ return $scope.oldTitle || '';
+ };
+
+ /**
+ * Exposed for testing
+ */
+ this._animateTitles = function() {
+ var oldTitleEl, newTitleEl, currentTitles;
+
+ //If we have any title right now
+ //(or more than one, they could be transitioning on switch),
+ //replace the first one with an oldTitle element
+ currentTitles = $element[0].querySelectorAll('.title');
+ if (currentTitles.length) {
+ oldTitleEl = $compile('
')($scope);
+ angular.element(currentTitles[0]).replaceWith(oldTitleEl);
+ }
+ //Compile new title
+ newTitleEl = $compile('')($scope);
+
+ //Animate in on next frame
+ ionic.requestAnimationFrame(function() {
+
+ oldTitleEl && $animate.leave(angular.element(oldTitleEl));
+
+ var insert = oldTitleEl && angular.element(oldTitleEl) || null;
+ $animate.enter(newTitleEl, $element, insert, function() {
+ self._headerBarView.align();
+ });
+
+ //Cleanup any old titles leftover (besides the one we already did replaceWith on)
+ angular.forEach(currentTitles, function(el) {
+ if (el && el.parentNode) {
+ //Use .remove() to cleanup things like .data()
+ angular.element(el).remove();
+ }
+ });
+
+ //$apply so bindings fire
+ $scope.$digest();
+
+ //Stop flicker of new title on ios7
+ ionic.requestAnimationFrame(function() {
+ newTitleEl[0].classList.remove('invisible');
+ });
+ });
+ };
+}])
+
diff --git a/js/angular/controller/scrollController.js b/js/angular/controller/scrollController.js
new file mode 100644
index 0000000000..3c128e4e1b
--- /dev/null
+++ b/js/angular/controller/scrollController.js
@@ -0,0 +1,186 @@
+/**
+ * @private
+ */
+IonicModule
+
+.factory('$$scrollValueCache', function() {
+ return {};
+})
+
+.controller('$ionicScroll', [
+ '$scope',
+ 'scrollViewOptions',
+ '$timeout',
+ '$window',
+ '$$scrollValueCache',
+ '$location',
+ '$rootScope',
+ '$document',
+ '$ionicScrollDelegate',
+function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $rootScope, $document, $ionicScrollDelegate) {
+
+ var self = this;
+
+ this._scrollViewOptions = scrollViewOptions; //for testing
+
+ var element = this.element = scrollViewOptions.el;
+ var $element = this.$element = angular.element(element);
+ var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions);
+
+ //Attach self to element as a controller so other directives can require this controller
+ //through `require: '$ionicScroll'
+ //Also attach to parent so that sibling elements can require this
+ ($element.parent().length ? $element.parent() : $element)
+ .data('$$ionicScrollController', this);
+
+ var deregisterInstance = $ionicScrollDelegate._registerInstance(
+ this, scrollViewOptions.delegateHandle
+ );
+
+ if (!angular.isDefined(scrollViewOptions.bouncing)) {
+ ionic.Platform.ready(function() {
+ scrollView.options.bouncing = !ionic.Platform.isAndroid();
+ });
+ }
+
+ var resize = angular.bind(scrollView, scrollView.resize);
+ ionic.on('resize', resize, $window);
+
+ // set by rootScope listener if needed
+ var backListenDone = angular.noop;
+
+ $scope.$on('$destroy', function() {
+ deregisterInstance();
+ ionic.off('resize', resize, $window);
+ $window.removeEventListener('resize', resize);
+ backListenDone();
+ if (self._rememberScrollId) {
+ $$scrollValueCache[self._rememberScrollId] = scrollView.getValues();
+ }
+ });
+
+ $element.on('scroll', function(e) {
+ var detail = (e.originalEvent || e).detail || {};
+ $scope.$onScroll && $scope.$onScroll({
+ event: e,
+ scrollTop: detail.scrollTop || 0,
+ scrollLeft: detail.scrollLeft || 0
+ });
+ });
+
+ $scope.$on('$viewContentLoaded', function(e, historyData) {
+ //only the top-most scroll area under a view should remember that view's
+ //scroll position
+ if (e.defaultPrevented) { return; }
+ e.preventDefault();
+
+ var viewId = historyData && historyData.viewId;
+ if (viewId) {
+ self.rememberScrollPosition(viewId);
+ self.scrollToRememberedPosition();
+
+ backListenDone = $rootScope.$on('$viewHistory.viewBack', function(e, fromViewId, toViewId) {
+ //When going back from this view, forget its saved scroll position
+ if (viewId === fromViewId) {
+ self.forgetScrollPosition();
+ }
+ });
+ }
+ });
+
+ $timeout(function() {
+ scrollView.run();
+ });
+
+ this._rememberScrollId = null;
+
+ this.getScrollView = function() {
+ return this.scrollView;
+ };
+
+ this.getScrollPosition = function() {
+ return this.scrollView.getValues();
+ };
+
+ this.resize = function() {
+ return $timeout(resize);
+ };
+
+ this.scrollTop = function(shouldAnimate) {
+ this.resize().then(function() {
+ scrollView.scrollTo(0, 0, !!shouldAnimate);
+ });
+ };
+
+ this.scrollBottom = function(shouldAnimate) {
+ this.resize().then(function() {
+ var max = scrollView.getScrollMax();
+ scrollView.scrollTo(max.left, max.top, !!shouldAnimate);
+ });
+ };
+
+ this.scrollTo = function(left, top, shouldAnimate) {
+ this.resize().then(function() {
+ scrollView.scrollTo(left, top, !!shouldAnimate);
+ });
+ };
+
+ this.scrollBy = function(left, top, shouldAnimate) {
+ this.resize().then(function() {
+ scrollView.scrollBy(left, top, !!shouldAnimate);
+ });
+ };
+
+ this.anchorScroll = function(shouldAnimate) {
+ this.resize().then(function() {
+ var hash = $location.hash();
+ var elm = hash && $document[0].getElementById(hash);
+ if (hash && elm) {
+ var scroll = ionic.DomUtil.getPositionInParent(elm, self.$element);
+ scrollView.scrollTo(scroll.left, scroll.top, !!shouldAnimate);
+ } else {
+ scrollView.scrollTo(0,0, !!shouldAnimate);
+ }
+ });
+ };
+
+ this.rememberScrollPosition = function(id) {
+ if (!id) {
+ throw new Error("Must supply an id to remember the scroll by!");
+ }
+ this._rememberScrollId = id;
+ };
+ this.forgetScrollPosition = function() {
+ delete $$scrollValueCache[this._rememberScrollId];
+ this._rememberScrollId = null;
+ };
+ this.scrollToRememberedPosition = function(shouldAnimate) {
+ var values = $$scrollValueCache[this._rememberScrollId];
+ if (values) {
+ this.resize().then(function() {
+ scrollView.scrollTo(+values.left, +values.top, shouldAnimate);
+ });
+ }
+ };
+
+
+
+ /**
+ * @private
+ */
+ this._setRefresher = function(refresherScope, refresherElement) {
+ var refresher = this.refresher = refresherElement;
+ var refresherHeight = self.refresher.clientHeight || 0;
+ scrollView.activatePullToRefresh(refresherHeight, function() {
+ refresher.classList.add('active');
+ refresherScope.$onPulling();
+ }, function() {
+ refresher.classList.remove('refreshing');
+ refresher.classList.remove('active');
+ }, function() {
+ refresher.classList.add('refreshing');
+ refresherScope.$onRefresh();
+ });
+ };
+}]);
+
diff --git a/js/angular/controller/sideMenuController.js b/js/angular/controller/sideMenuController.js
new file mode 100644
index 0000000000..e333c463f4
--- /dev/null
+++ b/js/angular/controller/sideMenuController.js
@@ -0,0 +1,35 @@
+IonicModule
+.controller('$ionicSideMenus', [
+ '$scope',
+ '$attrs',
+ '$ionicSideMenuDelegate',
+function($scope, $attrs, $ionicSideMenuDelegate) {
+ angular.extend(this, ionic.controllers.SideMenuController.prototype);
+
+ ionic.controllers.SideMenuController.call(this, {
+ left: { width: 275 },
+ right: { width: 275 }
+ });
+
+ this.canDragContent = function(canDrag) {
+ if (arguments.length) {
+ $scope.dragContent = !!canDrag;
+ }
+ return $scope.dragContent;
+ };
+
+ this.isDraggableTarget = function(e) {
+ return $scope.dragContent &&
+ (!e.gesture.srcEvent.defaultPrevented &&
+ !e.target.tagName.match(/input|textarea|select|object|embed/i) &&
+ !e.target.isContentEditable &&
+ !(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default') == 'true'));
+ };
+
+ $scope.sideMenuContentTranslateX = 0;
+
+ var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
+ this, $attrs.delegateHandle
+ );
+ $scope.$on('$destroy', deregisterInstance);
+}]);
diff --git a/js/angular/controller/tabController.js b/js/angular/controller/tabController.js
new file mode 100644
index 0000000000..d6074a14e2
--- /dev/null
+++ b/js/angular/controller/tabController.js
@@ -0,0 +1,27 @@
+IonicModule
+.controller('$ionicTab', [
+ '$scope',
+ '$ionicViewService',
+ '$attrs',
+ '$location',
+ '$state',
+function($scope, $ionicViewService, $attrs, $location, $state) {
+ this.$scope = $scope;
+
+ //All of these exposed for testing
+ this.hrefMatchesState = function() {
+ return $attrs.href && $location.path().indexOf(
+ $attrs.href.replace(/^#/, '').replace(/\/$/, '')
+ ) === 0;
+ };
+ this.srefMatchesState = function() {
+ return $attrs.uiSref && $state.includes( $attrs.uiSref.split('(')[0] );
+ };
+ this.navNameMatchesState = function() {
+ return this.navViewName && $ionicViewService.isCurrentStateNavView(this.navViewName);
+ };
+
+ this.tabMatchesState = function() {
+ return this.hrefMatchesState() || this.srefMatchesState() || this.navNameMatchesState();
+ };
+}]);
diff --git a/js/angular/controller/tabsController.js b/js/angular/controller/tabsController.js
new file mode 100644
index 0000000000..cf68e4ad79
--- /dev/null
+++ b/js/angular/controller/tabsController.js
@@ -0,0 +1,97 @@
+IonicModule
+.controller('$ionicTabs', [
+ '$scope',
+ '$ionicViewService',
+ '$element',
+function($scope, $ionicViewService, $element) {
+ var _selectedTab = null;
+ var self = this;
+ self.tabs = [];
+
+ self.selectedIndex = function() {
+ return self.tabs.indexOf(_selectedTab);
+ };
+ self.selectedTab = function() {
+ return _selectedTab;
+ };
+
+ self.add = function(tab) {
+ $ionicViewService.registerHistory(tab);
+ self.tabs.push(tab);
+ if(self.tabs.length === 1) {
+ self.select(tab);
+ }
+ };
+
+ self.remove = function(tab) {
+ var tabIndex = self.tabs.indexOf(tab);
+ if (tabIndex === -1) {
+ return;
+ }
+ //Use a field like '$tabSelected' so developers won't accidentally set it in controllers etc
+ if (tab.$tabSelected) {
+ self.deselect(tab);
+ //Try to select a new tab if we're removing a tab
+ if (self.tabs.length === 1) {
+ //do nothing if there are no other tabs to select
+ } else {
+ //Select previous tab if it's the last tab, else select next tab
+ var newTabIndex = tabIndex === self.tabs.length - 1 ? tabIndex - 1 : tabIndex + 1;
+ self.select(self.tabs[newTabIndex]);
+ }
+ }
+ self.tabs.splice(tabIndex, 1);
+ };
+
+ self.deselect = function(tab) {
+ if (tab.$tabSelected) {
+ _selectedTab = null;
+ tab.$tabSelected = false;
+ (tab.onDeselect || angular.noop)();
+ }
+ };
+
+ self.select = function(tab, shouldEmitEvent) {
+ var tabIndex;
+ if (angular.isNumber(tab)) {
+ tabIndex = tab;
+ tab = self.tabs[tabIndex];
+ } else {
+ tabIndex = self.tabs.indexOf(tab);
+ }
+ if (!tab || tabIndex == -1) {
+ throw new Error('Cannot select tab "' + tabIndex + '"!');
+ }
+
+ if (_selectedTab && _selectedTab.$historyId == tab.$historyId) {
+ if (shouldEmitEvent) {
+ $ionicViewService.goToHistoryRoot(tab.$historyId);
+ }
+ } else {
+ angular.forEach(self.tabs, function(tab) {
+ self.deselect(tab);
+ });
+
+ _selectedTab = tab;
+ //Use a funny name like $tabSelected so the developer doesn't overwrite the var in a child scope
+ tab.$tabSelected = true;
+ (tab.onSelect || angular.noop)();
+
+ if (shouldEmitEvent) {
+ var viewData = {
+ type: 'tab',
+ tabIndex: tabIndex,
+ historyId: tab.$historyId,
+ navViewName: tab.navViewName,
+ hasNavView: !!tab.navViewName,
+ title: tab.title,
+ //Skip the first character of href if it's #
+ url: tab.href,
+ uiSref: tab.uiSref
+ };
+ $scope.$emit('viewState.changeHistory', viewData);
+ }
+ }
+ };
+}]);
+
diff --git a/js/ext/angular/src/deprecated.js b/js/angular/deprecated.js
similarity index 100%
rename from js/ext/angular/src/deprecated.js
rename to js/angular/deprecated.js
diff --git a/js/ext/angular/src/directive/ionicActionSheet.js b/js/angular/directive/actionSheet.js
similarity index 95%
rename from js/ext/angular/src/directive/ionicActionSheet.js
rename to js/angular/directive/actionSheet.js
index 6615c7ff8a..b618b5dd12 100644
--- a/js/ext/angular/src/directive/ionicActionSheet.js
+++ b/js/angular/directive/actionSheet.js
@@ -1,12 +1,8 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.actionSheet', [])
-
/*
* We don't document the ionActionSheet directive, we instead document
* the $ionicActionSheet service
*/
+IonicModule
.directive('ionActionSheet', ['$document', function($document) {
return {
restrict: 'E',
@@ -52,5 +48,3 @@ angular.module('ionic.ui.actionSheet', [])
''
};
}]);
-
-})();
diff --git a/js/ext/angular/src/directive/ionicCheckbox.js b/js/angular/directive/checkbox.js
similarity index 95%
rename from js/ext/angular/src/directive/ionicCheckbox.js
rename to js/angular/directive/checkbox.js
index f183dd10b7..5b9c8af3d1 100644
--- a/js/ext/angular/src/directive/ionicCheckbox.js
+++ b/js/angular/directive/checkbox.js
@@ -1,7 +1,3 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.checkbox', [])
/**
* @ngdoc directive
@@ -19,6 +15,7 @@ angular.module('ionic.ui.checkbox', [])
* Checkbox Label
* ```
*/
+IonicModule
.directive('ionCheckbox', function() {
return {
restrict: 'E',
@@ -52,5 +49,3 @@ angular.module('ionic.ui.checkbox', [])
};
});
-
-})();
diff --git a/js/angular/directive/content.js b/js/angular/directive/content.js
new file mode 100644
index 0000000000..610dd677c1
--- /dev/null
+++ b/js/angular/directive/content.js
@@ -0,0 +1,129 @@
+/**
+ * @ngdoc directive
+ * @name ionContent
+ * @module ionic
+ * @delegate ionic.service:$ionicScrollDelegate
+ * @restrict E
+ *
+ * @description
+ * The ionContent directive provides an easy to use content area that can be configured
+ * to use Ionic's custom Scroll View, or the built in overflow scrolling of the browser.
+ *
+ * While we recommend using the custom Scroll features in Ionic in most cases, sometimes
+ * (for performance reasons) only the browser's native overflow scrolling will suffice,
+ * and so we've made it easy to toggle between the Ionic scroll implementation and
+ * overflow scrolling.
+ *
+ * You can implement pull-to-refresh with the {@link ionic.directive:ionRefresher}
+ * directive, and infinite scrolling with the {@link ionic.directive:ionInfiniteScroll}
+ * directive.
+ *
+ * @param {string=} delegate-handle The handle used to identify this scrollView
+ * with {@link ionic.service:$ionicScrollDelegate}.
+ * @param {boolean=} padding Whether to add padding to the content.
+ * of the content. Defaults to true on iOS, false on Android.
+ * @param {boolean=} scroll Whether to allow scrolling of content. Defaults to true.
+ * @param {boolean=} overflow-scroll Whether to use overflow-scrolling instead of
+ * Ionic scroll.
+ * @param {boolean=} has-bouncing Whether to allow scrolling to bounce past the edges
+ * of the content. Defaults to true on iOS, false on Android.
+ * @param {expression=} on-scroll Expression to evaluate when the content is scrolled.
+ * @param {expression=} on-scroll-complete Expression to evaluate when a scroll action completes.
+ */
+IonicModule
+.directive('ionContent', [
+ '$timeout',
+ '$controller',
+ '$ionicBind',
+function($timeout, $controller, $ionicBind) {
+ return {
+ restrict: 'E',
+ require: '^?ionNavView',
+ scope: true,
+ compile: function(element, attr) {
+ var innerElement;
+
+ element.addClass('scroll-content');
+
+ if (attr.scroll != 'false') {
+ //We cannot use normal transclude here because it breaks element.data()
+ //inheritance on compile
+ innerElement = angular.element('');
+ innerElement.append(element.contents());
+ element.append(innerElement);
+ }
+
+ return { pre: prelink };
+ function prelink($scope, $element, $attr, navViewCtrl) {
+ var parentScope = $scope.$parent;
+ $scope.$watch(function() {
+ return (parentScope.$hasHeader ? ' has-header' : '') +
+ (parentScope.$hasSubheader ? ' has-subheader' : '') +
+ (parentScope.$hasFooter ? ' has-footer' : '') +
+ (parentScope.$hasSubfooter ? ' has-subfooter' : '') +
+ (parentScope.$hasTabs ? ' has-tabs' : '') +
+ (parentScope.$hasTabsTop ? ' has-tabs-top' : '');
+ }, function(className, oldClassName) {
+ $element.removeClass(oldClassName);
+ $element.addClass(className);
+ });
+
+ //Only this ionContent should use these variables from parent scopes
+ $scope.$hasHeader = $scope.$hasSubheader =
+ $scope.$hasFooter = $scope.$hasSubfooter =
+ $scope.$hasTabs = $scope.$hasTabsTop =
+ false;
+
+ $ionicBind($scope, $attr, {
+ $onScroll: '&onScroll',
+ $onScrollComplete: '&onScrollComplete',
+ hasBouncing: '@',
+ scroll: '@',
+ padding: '@',
+ hasScrollX: '@',
+ hasScrollY: '@',
+ scrollbarX: '@',
+ scrollbarY: '@',
+ startX: '@',
+ startY: '@',
+ scrollEventInterval: '@'
+ });
+
+ if (angular.isDefined($attr.padding)) {
+ $scope.$watch($attr.padding, function(newVal) {
+ (innerElement || $element).toggleClass('padding', !!newVal);
+ });
+ }
+
+ if ($scope.scroll === "false") {
+ //do nothing
+ } else if(attr.overflowScroll === "true") {
+ $element.addClass('overflow-scroll');
+ } else {
+ $controller('$ionicScroll', {
+ $scope: $scope,
+ scrollViewOptions: {
+ el: $element[0],
+ delegateHandle: attr.delegateHandle,
+ bouncing: $scope.$eval($scope.hasBouncing),
+ startX: $scope.$eval($scope.startX) || 0,
+ startY: $scope.$eval($scope.startY) || 0,
+ scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
+ scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
+ scrollingX: $scope.$eval($scope.hasScrollX) === true,
+ scrollingY: $scope.$eval($scope.hasScrollY) !== false,
+ scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 20,
+ scrollingComplete: function() {
+ $scope.$onScrollComplete({
+ scrollTop: this.__scrollTop,
+ scrollLeft: this.__scrollLeft
+ });
+ }
+ }
+ });
+ }
+
+ }
+ }
+ };
+}]);
diff --git a/js/ext/angular/src/directive/ionicBar.js b/js/angular/directive/headerFooterBar.js
similarity index 94%
rename from js/ext/angular/src/directive/ionicBar.js
rename to js/angular/directive/headerFooterBar.js
index 1cfd765d41..b2e1b1b3df 100644
--- a/js/ext/angular/src/directive/ionicBar.js
+++ b/js/angular/directive/headerFooterBar.js
@@ -1,8 +1,5 @@
-(function(ionic) {
-'use strict';
-
-angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
+IonicModule
.directive('ionNavBar', tapScrollToTopDirective())
.directive('ionHeaderBar', tapScrollToTopDirective())
@@ -37,7 +34,7 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
*
* ```
*/
-.directive('ionHeaderBar', barDirective(true))
+.directive('ionHeaderBar', headerFooterBarDirective(true))
/**
* @ngdoc directive
@@ -70,7 +67,7 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
*
* ```
*/
-.directive('ionFooterBar', barDirective(false));
+.directive('ionFooterBar', headerFooterBarDirective(false));
function tapScrollToTopDirective() {
return ['$ionicScrollDelegate', function($ionicScrollDelegate) {
@@ -101,8 +98,7 @@ function tapScrollToTopDirective() {
}];
}
-
-function barDirective(isHeader) {
+function headerFooterBarDirective(isHeader) {
return [function() {
return {
restrict: 'E',
@@ -147,5 +143,3 @@ function barDirective(isHeader) {
};
}];
}
-
-})(ionic);
diff --git a/js/angular/directive/infiniteScroll.js b/js/angular/directive/infiniteScroll.js
new file mode 100644
index 0000000000..631fffcf83
--- /dev/null
+++ b/js/angular/directive/infiniteScroll.js
@@ -0,0 +1,128 @@
+/**
+ * @ngdoc directive
+ * @name ionInfiniteScroll
+ * @module ionic
+ * @parent ionic.directive:ionContent, ionic.directive:ionScroll
+ * @restrict E
+ *
+ * @description
+ * The ionInfiniteScroll directive allows you to call a function whenever
+ * the user gets to the bottom of the page or near the bottom of the page.
+ *
+ * The expression you pass in for `on-infinite` is called when the user scrolls
+ * greater than `distance` away from the bottom of the content.
+ *
+ * @param {expression} on-infinite What to call when the scroller reaches the
+ * bottom.
+ * @param {string=} distance The distance from the bottom that the scroll must
+ * reach to trigger the on-infinite expression. Default: 1%.
+ * @param {string=} icon The icon to show while loading. Default: 'ion-loading-d'.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MyController($scope, $http) {
+ * $scope.items = [];
+ * $scope.loadMore = function() {
+ * $http.get('/more-items').success(function(items) {
+ * useItems(items);
+ * $scope.$broadcast('scroll.infiniteScrollComplete');
+ * });
+ * };
+ * }
+ * ```
+ *
+ * An easy to way to stop infinite scroll once there is no more data to load
+ * is to use angular's `ng-if` directive:
+ *
+ * ```html
+ *
+ *
+ * ```
+ */
+IonicModule
+.directive('ionInfiniteScroll', ['$timeout', function($timeout) {
+ function calculateMaxValue(distance, maximum, isPercent) {
+ return isPercent ?
+ maximum * (1 - parseInt(distance,10) / 100) :
+ maximum - parseInt(distance, 10);
+ }
+ return {
+ restrict: 'E',
+ require: ['^$ionicScroll', 'ionInfiniteScroll'],
+ template:
+ '
' +
+ '
' +
+ '' +
+ '
' +
+ '
',
+ scope: true,
+ controller: ['$scope', '$attrs', function($scope, $attrs) {
+ this.isLoading = false;
+ this.scrollView = null; //given by link function
+ this.getMaxScroll = function() {
+ var distance = ($attrs.distance || '1%').trim();
+ var isPercent = distance.indexOf('%') !== -1;
+ var maxValues = this.scrollView.getScrollMax();
+ return {
+ left: this.scrollView.options.scrollingX ?
+ calculateMaxValue(distance, maxValues.left, isPercent) :
+ -1,
+ top: this.scrollView.options.scrollingY ?
+ calculateMaxValue(distance, maxValues.top, isPercent) :
+ -1
+ };
+ };
+ }],
+ link: function($scope, $element, $attrs, ctrls) {
+ var scrollCtrl = ctrls[0];
+ var infiniteScrollCtrl = ctrls[1];
+ var scrollView = infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;
+
+ $scope.icon = function() {
+ return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-loading-d';
+ };
+
+ $scope.$on('scroll.infiniteScrollComplete', function() {
+ $element[0].classList.remove('active');
+ $timeout(function() {
+ scrollView.resize();
+ }, 0, false);
+ infiniteScrollCtrl.isLoading = false;
+ });
+ $scope.$on('$destroy', function() {
+ scrollCtrl.$element.off('scroll', checkBounds);
+ });
+
+ var checkBounds = ionic.animationFrameThrottle(checkInfiniteBounds);
+
+ //Check bounds on start, after scrollView is fully rendered
+ setTimeout(checkBounds);
+ scrollCtrl.$element.on('scroll', checkBounds);
+
+ function checkInfiniteBounds() {
+ if (infiniteScrollCtrl.isLoading) return;
+
+ var scrollValues = scrollView.getValues();
+ var maxScroll = infiniteScrollCtrl.getMaxScroll();
+
+ if ((maxScroll.left !== -1 && scrollValues.left >= maxScroll.left) ||
+ (maxScroll.top !== -1 && scrollValues.top >= maxScroll.top)) {
+ $element[0].classList.add('active');
+ infiniteScrollCtrl.isLoading = true;
+ $scope.$parent && $scope.$parent.$apply($attrs.onInfinite || '');
+ }
+ }
+ }
+ };
+}]);
diff --git a/js/angular/directive/item.js b/js/angular/directive/item.js
new file mode 100644
index 0000000000..3f0d52412e
--- /dev/null
+++ b/js/angular/directive/item.js
@@ -0,0 +1,65 @@
+var ITEM_TPL_CONTENT_ANCHOR =
+ '';
+var ITEM_TPL_CONTENT =
+ '';
+/**
+* @ngdoc directive
+* @name ionItem
+* @parent ionic.directive:ionList
+* @module ionic
+* @restrict E
+* Creates a list-item that can easily be swiped,
+* deleted, reordered, edited, and more.
+*
+* See {@link ionic.directive:ionList} for a complete example & explanation.
+*
+* Can be assigned any item class name. See the
+* [list CSS documentation](/docs/components/#list).
+*
+* @usage
+*
+* ```html
+*
+* Hello!
+*
+* ```
+*/
+IonicModule
+.directive('ionItem', [
+ '$animate',
+ '$compile',
+function($animate, $compile) {
+ return {
+ restrict: 'E',
+ controller: ['$scope', '$element', function($scope, $element) {
+ this.$scope = $scope;
+ this.$element = $element;
+ }],
+ priorty: Number.MAX_VALUE,
+ require: ['ionItem', '^ionList'],
+ scope: true,
+ compile: function($element, $attrs) {
+ var isAnchor = angular.isDefined($attrs.href) || angular.isDefined($attrs.ngHref);
+ var isComplexItem = isAnchor ||
+ //Lame way of testing, but we have to know at compile what to do with the element
+ /ion-(delete|option|reorder)-button/.test($element.html());
+
+ if (isComplexItem) {
+ var innerElement = angular.element(isAnchor ? ITEM_TPL_CONTENT_ANCHOR : ITEM_TPL_CONTENT);
+ innerElement.append($element.contents());
+
+ $element.append(innerElement);
+ $element.addClass('item item-complex');
+ } else {
+ $element.addClass('item');
+ }
+
+ return function link($scope, $element, $attrs) {
+ $scope.$href = function() {
+ return $attrs.href || $attrs.ngHref;
+ };
+ };
+ }
+ };
+}]);
+
diff --git a/js/angular/directive/itemDeleteButton.js b/js/angular/directive/itemDeleteButton.js
new file mode 100644
index 0000000000..19059e3c24
--- /dev/null
+++ b/js/angular/directive/itemDeleteButton.js
@@ -0,0 +1,51 @@
+var ITEM_TPL_DELETE_BUTTON =
+ '
' +
+ '
';
+/**
+* @ngdoc directive
+* @name ionDeleteButton
+* @parent ionic.directive:ionItem
+* @module ionic
+* @restrict E
+* Creates a delete button inside a list item, that is visible when the
+* {@link ionic.directive:ionList ionList parent's} `show-delete` evaluates to true or
+* `$ionicListDelegate.showDelete(true)` is called.
+*
+* Takes any ionicon as a class.
+*
+* See {@link ionic.directive:ionList} for a complete example & explanation.
+*
+* @usage
+*
+* ```html
+*
+*
+*
+* Hello, list item!
+*
+*
+*
+* Show Delete?
+*
+* ```
+*/
+IonicModule
+.directive('ionDeleteButton', [function() {
+ return {
+ restrict: 'E',
+ require: '^ionItem',
+ //Run before anything else, so we can move it before other directives process
+ //its location (eg ngIf relies on the location of the directive in the dom)
+ priority: Number.MAX_VALUE,
+ compile: function($element, $attr) {
+ //Add the classes we need during the compile phase, so that they stay
+ //even if something else like ngIf removes the element and re-addss it
+ $attr.$set('class', ($attr.class || '') + ' button icon button-icon', true);
+ return function($scope, $element, $attr, itemCtrl) {
+ var container = angular.element(ITEM_TPL_DELETE_BUTTON);
+ container.append($element);
+ itemCtrl.$element.append(container).addClass('item-left-editable');
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/itemOptionButton.js b/js/angular/directive/itemOptionButton.js
new file mode 100644
index 0000000000..758ed19b9d
--- /dev/null
+++ b/js/angular/directive/itemOptionButton.js
@@ -0,0 +1,47 @@
+var ITEM_TPL_OPTION_BUTTONS =
+ '
' +
+ '
';
+/**
+* @ngdoc directive
+* @name ionOptionButton
+* @parent ionic.directive:ionItem
+* @module ionic
+* @restrict E
+* Creates an option button inside a list item, that is visible when the item is swiped
+* to the left by the user. Swiped open option buttons can be hidden with
+* {@link ionic.directive:$ionicListDelegate#closeOptionButtons $ionicListDelegate#closeOptionButtons}.
+*
+* Can be assigned any button class.
+*
+* See {@link ionic.directive:ionList} for a complete example & explanation.
+*
+* @usage
+*
+* ```html
+*
+*
+* I love kittens!
+* Share
+* Edit
+*
+*
+* ```
+*/
+IonicModule
+.directive('ionOptionButton', ['$compile', function($compile) {
+return {
+ restrict: 'E',
+ require: '^ionItem',
+ priority: Number.MAX_VALUE,
+ compile: function($element, $attr) {
+ $attr.$set('class', ($attr.class || '') + ' button', true);
+ return function($scope, $element, $attr, itemCtrl) {
+ if (!itemCtrl.optionsContainer) {
+ itemCtrl.optionsContainer = angular.element(ITEM_TPL_OPTION_BUTTONS);
+ itemCtrl.$element.append(itemCtrl.optionsContainer);
+ }
+ itemCtrl.optionsContainer.append($element);
+ };
+ }
+};
+}]);
diff --git a/js/angular/directive/itemReorderButton.js b/js/angular/directive/itemReorderButton.js
new file mode 100644
index 0000000000..85ff338a31
--- /dev/null
+++ b/js/angular/directive/itemReorderButton.js
@@ -0,0 +1,71 @@
+var ITEM_TPL_REORDER_BUTTON =
+ '
' +
+ '
';
+
+/**
+* @ngdoc directive
+* @name ionReorderButton
+* @parent ionic.directive:ionItem
+* @module ionic
+* @restrict E
+* Creates a reorder button inside a list item, that is visible when the
+* {@link ionic.directive:ionList ionList parent's} `show-reorder` evaluates to true or
+* `$ionicListDelegate.showReorder(true)` is called.
+*
+* Can be dragged to reorder items in the list. Takes any ionicon class.
+*
+* When an item reorder is complete, the `on-reorder` callback given in the attribute is called
+* (see below).
+*
+* See {@link ionic.directive:ionList} for a complete example.
+*
+* @usage
+*
+* ```html
+*
+*
+* Item {{$index}}
+*
+*
+*
+*
+* ```
+* ```js
+* function MyCtrl($scope) {
+* $scope.items = [1, 2, 3, 4];
+* $scope.moveItem = function(item, fromIndex, toIndex) {
+* //Move the item in the array
+* $scope.items.splice(fromIndex, 1);
+* $scope.items.splice(toIndex, 0, item);
+* };
+* }
+* ```
+*
+* @param {expression=} on-reorder Expression to call when an item is reordered.
+* Parameters given: $fromIndex, $toIndex.
+*/
+IonicModule
+.directive('ionReorderButton', [function() {
+ return {
+ restrict: 'E',
+ require: '^ionItem',
+ priority: Number.MAX_VALUE,
+ compile: function($element, $attr) {
+ $attr.$set('class', ($attr.class || '') + ' button icon button-icon', true);
+ $element[0].setAttribute('data-prevent-scroll', true);
+ return function($scope, $element, $attr, itemCtrl) {
+ $scope.$onReorder = function(oldIndex, newIndex) {
+ $scope.$eval($attr.onReorder, {
+ $fromIndex: oldIndex,
+ $toIndex: newIndex
+ });
+ };
+
+ var container = angular.element(ITEM_TPL_REORDER_BUTTON);
+ container.append($element);
+ itemCtrl.$element.append(container).addClass('item-right-editable');
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/list.js b/js/angular/directive/list.js
new file mode 100644
index 0000000000..1410639036
--- /dev/null
+++ b/js/angular/directive/list.js
@@ -0,0 +1,165 @@
+/**
+* @ngdoc directive
+* @name ionList
+* @module ionic
+* @delegate ionic.service:$ionicListDelegate
+* @codepen JsHjf
+* @restrict E
+* @description
+* The List is a widely used interface element in almost any mobile app, and can include
+* content ranging from basic text all the way to buttons, toggles, icons, and thumbnails.
+*
+* Both the list, which contains items, and the list items themselves can be any HTML
+* element. The containing element requires the `list` class and each list item requires
+* the `item` class.
+*
+* However, using the ionList and ionItem directives make it easy to support various
+* interaction modes such as swipe to edit, drag to reorder, and removing items.
+*
+* Related: {@link ionic.directive:ionItem}, {@link ionic.directive:ionOptionButton}
+* {@link ionic.directive:ionReorderButton}, {@link ionic.directive:ionDeleteButton}, [`list CSS documentation`](/docs/components/#list).
+*
+* @usage
+*
+* Basic Usage:
+*
+* ```html
+*
+*
+* {% raw %}Hello, {{item}}!{% endraw %}
+*
+*
+* ```
+*
+* Advanced Usage: Thumbnails, Delete buttons, Reordering, Swiping
+*
+* ```html
+*
+*
+*
+* {% raw %}
+*
{{item.title}}
+*
{{item.description}}
{% endraw %}
+*
+* Share
+*
+*
+* Edit
+*
+*
+*
+*
+*
+*
+*
+*
+* ```
+*
+* @param {string=} delegate-handle The handle used to identify this list with
+* {@link ionic.service:$ionicListDelegate}.
+* @param show-delete {boolean=} Whether the delete buttons for the items in the list are
+* currently shown or hidden.
+* @param show-reorder {boolean=} Whether the reorder buttons for the items in the list are
+* currently shown or hidden.
+* @param can-swipe {boolean=} Whether the items in the list are allowed to be swiped to reveal
+* option buttons. Default: true.
+*/
+IonicModule
+.directive('ionList', [
+'$animate',
+'$timeout',
+function($animate, $timeout) {
+ return {
+ restrict: 'E',
+ require: ['ionList', '^?$ionicScroll'],
+ controller: '$ionicList',
+ compile: function($element, $attr) {
+ var listEl = angular.element('
')
+ .append( $element.contents() );
+ $element.append(listEl);
+
+ return function($scope, $element, $attrs, ctrls) {
+ var listCtrl = ctrls[0];
+ var scrollCtrl = ctrls[1];
+
+ //Wait for child elements to render...
+ $timeout(init);
+
+ function init() {
+ var listView = listCtrl.listView = new ionic.views.ListView({
+ el: $element[0],
+ listEl: $element.children()[0],
+ scrollEl: scrollCtrl && scrollCtrl.element,
+ scrollView: scrollCtrl && scrollCtrl.scrollView,
+ onReorder: function(el, oldIndex, newIndex) {
+ var itemScope = angular.element(el).scope();
+ if (itemScope && itemScope.$onReorder) {
+ itemScope.$onReorder(oldIndex, newIndex);
+ }
+ },
+ canSwipe: function() {
+ return listCtrl.canSwipeItems();
+ }
+ });
+
+ if (angular.isDefined($attr.canSwipe)) {
+ $scope.$watch('!!(' + $attr.canSwipe + ')', function(value) {
+ listCtrl.canSwipeItems(value);
+ });
+ }
+
+ if (angular.isDefined($attr.showDelete)) {
+ $scope.$watch('!!(' + $attr.showDelete + ')', function(value) {
+ listCtrl.showDelete(value);
+ });
+ }
+ if (angular.isDefined($attr.showReorder)) {
+ $scope.$watch('!!(' + $attr.showReorder + ')', function(value) {
+ listCtrl.showReorder(value);
+ });
+ }
+
+ $scope.$watch(function() {
+ return listCtrl.showDelete();
+ }, function(isShown, wasShown) {
+ //Only use isShown=false if it was already shown
+ if (!isShown && !wasShown) { return; }
+
+ if (isShown) listCtrl.closeOptionButtons();
+
+ $element.children().toggleClass('list-left-editing', isShown);
+ toggleNgHide('.item-delete.item-left-edit', isShown);
+ });
+ $scope.$watch(function() {
+ return listCtrl.showReorder();
+ }, function(isShown, wasShown) {
+ //Only use isShown=false if it was already shown
+ if (!isShown && !wasShown) { return; }
+
+ if (isShown) listCtrl.closeOptionButtons();
+ listCtrl.showReorder(isShown);
+
+ $element.children().toggleClass('list-right-editing', isShown);
+ toggleNgHide('.item-reorder.item-right-edit', isShown);
+ });
+
+ function toggleNgHide(selector, shouldShow) {
+ angular.forEach($element[0].querySelectorAll(selector), function(node) {
+ if (shouldShow) $animate.removeClass(angular.element(node), 'ng-hide');
+ else $animate.addClass(angular.element(node), 'ng-hide');
+ });
+ }
+ }
+
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/menuClose.js b/js/angular/directive/menuClose.js
new file mode 100644
index 0000000000..801ca34391
--- /dev/null
+++ b/js/angular/directive/menuClose.js
@@ -0,0 +1,29 @@
+/**
+ * @ngdoc directive
+ * @name menuClose
+ * @module ionic
+ * @restrict AC
+ *
+ * @description
+ * Closes a side menu which is currently opened.
+ *
+ * @usage
+ * Below is an example of a link within a side menu. Tapping this link would
+ * automatically close the currently opened menu
+ *
+ * ```html
+ * Home
+ * ```
+ */
+IonicModule
+.directive('menuClose', ['$ionicViewService', function($ionicViewService) {
+ return {
+ restrict: 'AC',
+ require: '^ionSideMenus',
+ link: function($scope, $element, $attr, sideMenuCtrl) {
+ $element.bind('click', function(){
+ sideMenuCtrl.close();
+ });
+ }
+ };
+}]);
diff --git a/js/angular/directive/menuToggle.js b/js/angular/directive/menuToggle.js
new file mode 100644
index 0000000000..6ed0a0e38d
--- /dev/null
+++ b/js/angular/directive/menuToggle.js
@@ -0,0 +1,40 @@
+/**
+ * @ngdoc directive
+ * @name menuToggle
+ * @module ionic
+ * @restrict AC
+ *
+ * @description
+ * Toggle a side menu on the given side
+ *
+ * @usage
+ * Below is an example of a link within a nav bar. Tapping this link would
+ * automatically open the given side menu
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ * ...
+ *
+ * ```
+ */
+IonicModule
+.directive('menuToggle', ['$ionicViewService', function($ionicViewService) {
+ return {
+ restrict: 'AC',
+ require: '^ionSideMenus',
+ link: function($scope, $element, $attr, sideMenuCtrl) {
+ var side = $attr.menuToggle || 'left';
+ $element.bind('click', function(){
+ if(side === 'left') {
+ sideMenuCtrl.toggleLeft();
+ } else if(side === 'right') {
+ sideMenuCtrl.toggleRight();
+ }
+ });
+ }
+ };
+}])
+
diff --git a/js/ext/angular/src/directive/ionicModal.js b/js/angular/directive/modal.js
similarity index 82%
rename from js/ext/angular/src/directive/ionicModal.js
rename to js/angular/directive/modal.js
index ebfb8391f5..416eb570eb 100644
--- a/js/ext/angular/src/directive/ionicModal.js
+++ b/js/angular/directive/modal.js
@@ -1,12 +1,8 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.modal', [])
-
/*
* We don't document the ionModal directive, we instead document
* the $ionicModal service
*/
+IonicModule
.directive('ionModal', [function() {
return {
restrict: 'E',
@@ -17,5 +13,3 @@ angular.module('ionic.ui.modal', [])
'
'
};
}]);
-
-})();
diff --git a/js/angular/directive/navBackButton.js b/js/angular/directive/navBackButton.js
new file mode 100644
index 0000000000..267ebf5e43
--- /dev/null
+++ b/js/angular/directive/navBackButton.js
@@ -0,0 +1,98 @@
+/**
+ * @ngdoc directive
+ * @name ionNavBackButton
+ * @module ionic
+ * @restrict E
+ * @parent ionNavBar
+ * @description
+ * Creates a back button inside an {@link ionic.directive:ionNavBar}.
+ *
+ * Will show up when the user is able to go back in the current navigation stack.
+ *
+ * By default, will go back when clicked. If you wish for more advanced behavior, see the
+ * examples below.
+ *
+ * @usage
+ *
+ * With default click action:
+ *
+ * ```html
+ *
+ *
+ * Back!
+ *
+ *
+ * ```
+ *
+ * With custom click action, using {@link ionic.service:$ionicNavBarDelegate}:
+ *
+ * ```html
+ *
+ *
+ * Back
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicNavBarDelegate) {
+ * $scope.goBack = function() {
+ * $ionicNavBarDelegate.back();
+ * };
+ * }
+ * ```
+ *
+ * Displaying the previous title on the back button, again using
+ * {@link ionic.service:$ionicNavBarDelegate}.
+ *
+ * ```html
+ *
+ *
+ * {% raw %}{{getPreviousTitle() || 'Back'}}{% endraw %}
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicNavBarDelegate) {
+ * $scope.getPreviousTitle = function() {
+ * return $ionicNavBarDelegate.getPreviousTitle();
+ * };
+ * }
+ * ```
+ */
+IonicModule
+.directive('ionNavBackButton', [
+ '$ionicNgClick',
+ '$animate',
+function($ionicNgClick, $animate) {
+ return {
+ restrict: 'E',
+ require: '^ionNavBar',
+ compile: function(tElement, tAttrs) {
+ tElement.addClass('button back-button ng-hide');
+ return function($scope, $element, $attr, navBarCtrl) {
+ if (!$attr.ngClick) {
+ $scope.$navBack = navBarCtrl.back;
+ $ionicNgClick($scope, $element, '$navBack($event)');
+ }
+
+ //If the current viewstate does not allow a back button,
+ //always hide it.
+ var deregisterListener = $scope.$parent.$on(
+ '$viewHistory.historyChange',
+ function(e, data) {
+ $scope.hasBackButton = !!data.showBack;
+ }
+ );
+ $scope.$on('$destroy', deregisterListener);
+
+ //Make sure both that a backButton is allowed in the first place,
+ //and that it is shown by the current view.
+ $scope.$watch('!!(backButtonShown && hasBackButton)', ionic.animationFrameThrottle(function(show) {
+ if (show) $animate.removeClass($element, 'ng-hide');
+ else $animate.addClass($element, 'ng-hide');
+ }));
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/navBar.js b/js/angular/directive/navBar.js
new file mode 100644
index 0000000000..92b7d61b34
--- /dev/null
+++ b/js/angular/directive/navBar.js
@@ -0,0 +1,93 @@
+
+/**
+ * @ngdoc directive
+ * @name ionNavBar
+ * @module ionic
+ * @delegate ionic.service:$ionicNavBarDelegate
+ * @restrict E
+ *
+ * @description
+ * If we have an {@link ionic.directive:ionNavView} directive, we can also create an
+ * ``, which will create a topbar that updates as the application state changes.
+ *
+ * We can add a back button by putting an {@link ionic.directive:ionNavBackButton} inside.
+ *
+ * We can add buttons depending on the currently visible view using
+ * {@link ionic.directive:ionNavButtons}.
+ *
+ * Assign an [animation class](/docs/components#animations) to the element to
+ * enable animated changing of titles (recommended: 'nav-title-slide-ios7')
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ *
+ * @param {string=} delegate-handle The handle used to identify this navBar
+ * with {@link ionic.service:$ionicNavBarDelegate}.
+ * @param align-title {string=} Where to align the title of the navbar.
+ * Available: 'left', 'right', 'center'. Defaults to 'center'.
+ */
+IonicModule
+.directive('ionNavBar', [
+ '$ionicViewService',
+ '$rootScope',
+ '$animate',
+ '$compile',
+function($ionicViewService, $rootScope, $animate, $compile) {
+
+ return {
+ restrict: 'E',
+ controller: '$ionicNavBar',
+ scope: true,
+ compile: function(tElement, tAttrs) {
+ //We cannot transclude here because it breaks element.data() inheritance on compile
+ tElement
+ .addClass('bar bar-header nav-bar')
+ .append(
+ '
' +
+ '
' +
+ '' +
+ '
' +
+ '
'
+ );
+
+ return { pre: prelink };
+ function prelink($scope, $element, $attr, navBarCtrl) {
+ navBarCtrl._headerBarView = new ionic.views.HeaderBar({
+ el: $element[0],
+ alignTitle: $attr.alignTitle || 'center'
+ });
+
+ //defaults
+ $scope.backButtonShown = false;
+ $scope.shouldAnimate = true;
+ $scope.isReverse = false;
+ $scope.isInvisible = true;
+
+ $scope.$on('$destroy', function() {
+ $scope.$parent.$hasHeader = false;
+ });
+
+ $scope.$watch(function() {
+ return ($scope.isReverse ? ' reverse' : '') +
+ ($scope.isInvisible ? ' invisible' : '') +
+ (!$scope.shouldAnimate ? ' no-animation' : '');
+ }, function(className, oldClassName) {
+ $element.removeClass(oldClassName);
+ $element.addClass(className);
+ });
+
+ }
+ }
+ };
+}]);
+
diff --git a/js/angular/directive/navButtons.js b/js/angular/directive/navButtons.js
new file mode 100644
index 0000000000..40e195b206
--- /dev/null
+++ b/js/angular/directive/navButtons.js
@@ -0,0 +1,74 @@
+/**
+ * @ngdoc directive
+ * @name ionNavButtons
+ * @module ionic
+ * @restrict E
+ * @parent ionNavView
+ *
+ * @description
+ * Use ionNavButtons to set the buttons on your {@link ionic.directive:ionNavBar}
+ * from within an {@link ionic.directive:ionView}.
+ *
+ * Any buttons you declare will be placed onto the navbar's corresponding side,
+ * and then destroyed when the user leaves their parent view.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Some super content here!
+ *
+ *
+ *
+ * ```
+ *
+ * @param {string} side The side to place the buttons on in the parent
+ * {@link ionic.directive:ionNavBar}. Available: 'left' or 'right'.
+ */
+IonicModule
+.directive('ionNavButtons', ['$compile', '$animate', function($compile, $animate) {
+ return {
+ require: '^ionNavBar',
+ restrict: 'E',
+ compile: function($element, $attrs) {
+ var content = $element.contents().remove();
+ return function($scope, $element, $attrs, navBarCtrl) {
+ var navElement = $attrs.side === 'right' ?
+ navBarCtrl.rightButtonsElement :
+ navBarCtrl.leftButtonsElement;
+
+ //Put all of our inside buttons into their own span,
+ //so we can remove them all when this element dies -
+ //even if the buttons have changed through an ng-repeat or the like,
+ //we just remove their div parent and they are gone.
+ var buttons = angular.element('').append(content);
+
+ //Compile buttons inside content so they have access to everything
+ //something inside content does (eg parent ionicScroll)
+ $element.append(buttons);
+ $compile(buttons)($scope);
+
+ //Append buttons to navbar
+ $animate.enter(buttons, navElement);
+
+ //When our ion-nav-buttons container is destroyed,
+ //destroy everything in the navbar
+ $scope.$on('$destroy', function() {
+ $animate.leave(buttons);
+ });
+
+ // The original element is just a completely empty element.
+ // make it invisible just to be sure it doesn't change any layout
+ $element.css('display', 'none');
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/navClear.js b/js/angular/directive/navClear.js
new file mode 100644
index 0000000000..79588c0514
--- /dev/null
+++ b/js/angular/directive/navClear.js
@@ -0,0 +1,54 @@
+
+/**
+ * @ngdoc directive
+ * @name navClear
+ * @module ionic
+ * @restrict AC
+ *
+ * @description
+ * Disables any transition animations between views, along with removing the back
+ * button which would normally show on the next view. This directive is useful for
+ * links within a sideMenu.
+ *
+ * @usage
+ * Below is an example of a link within a side menu. Tapping this link would disable
+ * any animations which would normally occur between views.
+ *
+ * ```html
+ * Home
+ * ```
+ */
+IonicModule
+.directive('navClear', [
+ '$ionicViewService',
+ '$state',
+ '$location',
+ '$window',
+ '$rootScope',
+function($ionicViewService, $location, $state, $window, $rootScope) {
+ $rootScope.$on('$stateChangeError', function() {
+ $ionicViewService.nextViewOptions(null);
+ });
+ return {
+ priority: 100,
+ restrict: 'AC',
+ compile: function($element) {
+ return { pre: prelink };
+ function prelink($scope, $element, $attrs) {
+ var unregisterListener;
+ function listenForStateChange() {
+ unregisterListener = $scope.$on('$stateChangeStart', function() {
+ $ionicViewService.nextViewOptions({
+ disableAnimate: true,
+ disableBack: true
+ });
+ unregisterListener();
+ });
+ $window.setTimeout(unregisterListener, 300);
+ }
+
+ $element.on('click', listenForStateChange);
+ }
+ }
+ };
+}]);
diff --git a/js/ext/angular/src/directive/ionicViewState.js b/js/angular/directive/navView.js
similarity index 62%
rename from js/ext/angular/src/directive/ionicViewState.js
rename to js/angular/directive/navView.js
index 4e48ac7c41..5b99343914 100644
--- a/js/ext/angular/src/directive/ionicViewState.js
+++ b/js/angular/directive/navView.js
@@ -1,84 +1,3 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gesture', 'ngSanitize'])
-
-/**
- * @ngdoc directive
- * @name ionView
- * @module ionic
- * @restrict E
- * @parent ionNavView
- *
- * @description
- * A container for content, used to tell a parent {@link ionic.directive:ionNavBar}
- * about the current view.
- *
- * @usage
- * Below is an example where our page will load with a navbar containing "My Page" as the title.
- *
- * ```html
- *
- *
- *
- *
- * Hello!
- *
- *
- *
- * ```
- *
- * @param {string=} title The title to display on the parent {@link ionic.directive:ionNavBar}.
- * @param {boolean=} hideBackButton Whether to hide the back button on the parent
- * {@link ionic.directive:ionNavBar} by default.
- * @param {boolean=} hideNavBar Whether to hide the parent
- * {@link ionic.directive:ionNavBar} by default.
- */
-.directive('ionView', ['$ionicViewService', '$rootScope', '$animate',
- function( $ionicViewService, $rootScope, $animate) {
- return {
- restrict: 'EA',
- priority: 1000,
- require: '^?ionNavBar',
- compile: function(tElement, tAttrs, transclude) {
- tElement.addClass('pane');
- tElement[0].removeAttribute('title');
-
- return function link($scope, $element, $attr, navBarCtrl) {
- if (!navBarCtrl) {
- return;
- }
-
- if (angular.isDefined($attr.title)) {
-
- var initialTitle = $attr.title;
- navBarCtrl.changeTitle(initialTitle, $scope.$navDirection);
-
- // watch for changes in the title, don't set initial value as changeTitle does that
- $attr.$observe('title', function(val, oldVal) {
- if (val !== initialTitle) {
- navBarCtrl.setTitle(val);
- }
- });
-
- }
-
- $scope.$watch($attr.hideBackButton, function(value) {
- // Should we hide a back button when this tab is shown
- navBarCtrl.showBackButton(!value);
- });
-
- $scope.$watch($attr.hideNavBar, function(value) {
- // Should the nav bar be hidden for this view or not?
- navBarCtrl.showBar(!value);
- });
-
- };
- }
- };
-}])
-
-
/**
* @ngdoc directive
* @name ionNavView
@@ -172,8 +91,14 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
* same state. You can have views of the same name that live in different states. For more
* information, see ui-router's [ui-view documentation](http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view).
*/
-.directive('ionNavView', ['$ionicViewService', '$state', '$compile', '$controller', '$animate',
- function( $ionicViewService, $state, $compile, $controller, $animate) {
+IonicModule
+.directive('ionNavView', [
+ '$ionicViewService',
+ '$state',
+ '$compile',
+ '$controller',
+ '$animate',
+function( $ionicViewService, $state, $compile, $controller, $animate) {
// IONIC's fork of Angular UI Router, v0.2.7
// the navView handles registering views in the history, which animation to use, and which
var viewIsUpdating = false;
@@ -183,14 +108,13 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
terminal: true,
priority: 2000,
transclude: true,
- controller: [function(){
- }],
+ controller: function(){},
compile: function (element, attr, transclude) {
return function(scope, element, attr, navViewCtrl) {
var viewScope, viewLocals,
- name = attr[directive.name] || attr.name || '',
- onloadExp = attr.onload || '',
- initialView = transclude(scope);
+ name = attr[directive.name] || attr.name || '',
+ onloadExp = attr.onload || '',
+ initialView = transclude(scope);
// Put back the compiled initial view
element.append(initialView);
@@ -215,7 +139,7 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
};
scope.$on('$stateChangeSuccess', eventHook);
- scope.$on('$viewContentLoading', eventHook);
+ // scope.$on('$viewContentLoading', eventHook);
updateView(false);
function updateView(doAnimate) {
@@ -276,60 +200,5 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu
}
};
return directive;
-}])
-
-
-/**
- * @ngdoc directive
- * @name navClear
- * @module ionic
- * @restrict AC
- *
- * @description
- * Disables any transition animations between views, along with removing the back
- * button which would normally show on the next view. This directive is useful for
- * links within a sideMenu.
- *
- * @usage
- * Below is an example of a link within a side menu. Tapping this link would disable
- * any animations which would normally occur between views.
- *
- * ```html
- * Home
- * ```
- */
-.directive('navClear', [
- '$ionicViewService',
- '$state',
- '$location',
- '$window',
- '$rootScope',
-function($ionicViewService, $location, $state, $window, $rootScope) {
- $rootScope.$on('$stateChangeError', function() {
- $ionicViewService.nextViewOptions(null);
- });
- return {
- priority: 100,
- restrict: 'AC',
- compile: function($element) {
- return { pre: prelink };
- function prelink($scope, $element, $attrs) {
- var unregisterListener;
- function listenForStateChange() {
- unregisterListener = $scope.$on('$stateChangeStart', function() {
- $ionicViewService.nextViewOptions({
- disableAnimate: true,
- disableBack: true
- });
- unregisterListener();
- });
- $window.setTimeout(unregisterListener, 300);
- }
-
- $element.on('click', listenForStateChange);
- }
- }
- };
}]);
-})();
diff --git a/js/angular/directive/ngClick.js b/js/angular/directive/ngClick.js
new file mode 100644
index 0000000000..d1f63913b5
--- /dev/null
+++ b/js/angular/directive/ngClick.js
@@ -0,0 +1,59 @@
+// Similar to Angular's ngTouch, however it uses Ionic's tap detection
+// and click simulation. ngClick
+
+IonicModule
+
+.config(['$provide', function($provide) {
+ $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
+ // drop the default ngClick directive
+ $delegate.shift();
+ return $delegate;
+ }]);
+}])
+
+/**
+ * @private
+ */
+.factory('$ionicNgClick', ['$parse', function($parse) {
+ function onRelease(e) {
+ // wire this up to Ionic's tap/click simulation
+ ionic.tap.simulateClick(e.target, e);
+ }
+ return function(scope, element, clickExpr) {
+ var clickHandler = $parse(clickExpr);
+
+ element.on('click', function(event) {
+ scope.$apply(function() {
+ clickHandler(scope, {$event: (event)});
+ });
+ });
+
+ ionic.on("release", onRelease, element[0]);
+
+ // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
+ // something else nearby.
+ element.onclick = function(event) { };
+
+ scope.$on('$destroy', function () {
+ ionic.off("release", onRelease, element[0]);
+ });
+ };
+}])
+
+.directive('ngClick', ['$ionicNgClick', function($ionicNgClick) {
+ return function(scope, element, attr) {
+ $ionicNgClick(scope, element, attr.ngClick);
+ };
+}])
+
+.directive('ionStopEvent', function () {
+ function stopEvent(e) {
+ e.stopPropagation();
+ }
+ return {
+ restrict: 'A',
+ link: function (scope, element, attr) {
+ element.bind(attr.ionStopEvent, stopEvent);
+ }
+ };
+});
diff --git a/js/angular/directive/pane.js b/js/angular/directive/pane.js
new file mode 100644
index 0000000000..119e865ac0
--- /dev/null
+++ b/js/angular/directive/pane.js
@@ -0,0 +1,18 @@
+
+/**
+ * @ngdoc directive
+ * @name ionPane
+ * @module ionic
+ * @restrict E
+ *
+ * @description A simple container that fits content, with no side effects. Adds the 'pane' class to the element.
+ */
+IonicModule
+.directive('ionPane', function() {
+ return {
+ restrict: 'E',
+ link: function(scope, element, attr) {
+ element.addClass('pane');
+ }
+ };
+});
diff --git a/js/angular/directive/radio.js b/js/angular/directive/radio.js
new file mode 100644
index 0000000000..fb7ee36bb1
--- /dev/null
+++ b/js/angular/directive/radio.js
@@ -0,0 +1,44 @@
+/**
+ * @ngdoc directive
+ * @name ionRadio
+ * @module ionic
+ * @restrict E
+ * @codepen saoBG
+ * @description
+ * The radio directive is no different than the HTML radio input, except it's styled differently.
+ *
+ * Radio behaves like any [AngularJS radio](http://docs.angularjs.org/api/ng/input/input[radio]).
+ *
+ * @usage
+ * ```html
+ * Choose A
+ * Choose B
+ * Choose C
+ * ```
+ */
+IonicModule
+.directive('ionRadio', function() {
+ return {
+ restrict: 'E',
+ replace: true,
+ require: '?ngModel',
+ scope: {
+ ngModel: '=?',
+ ngValue: '=?',
+ ngChange: '&',
+ icon: '@'
+ },
+ transclude: true,
+ template: '',
+
+ compile: function(element, attr) {
+ if(attr.name) element.children().eq(0).attr('name', attr.name);
+ if(attr.icon) element.children().eq(2).removeClass('ion-checkmark').addClass(attr.icon);
+ }
+ };
+});
diff --git a/js/angular/directive/refresher.js b/js/angular/directive/refresher.js
new file mode 100644
index 0000000000..a82221ead5
--- /dev/null
+++ b/js/angular/directive/refresher.js
@@ -0,0 +1,100 @@
+
+/**
+ * @ngdoc directive
+ * @name ionRefresher
+ * @module ionic
+ * @restrict E
+ * @parent ionic.directive:ionContent, ionic.directive:ionScroll
+ * @description
+ * Allows you to add pull-to-refresh to a scrollView.
+ *
+ * Place it as the first child of your {@link ionic.directive:ionContent} or
+ * {@link ionic.directive:ionScroll} element.
+ *
+ * When refreshing is complete, $broadcast the 'scroll.refreshComplete' event
+ * from your controller.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * angular.module('testApp', ['ionic'])
+ * .controller('MyController', function($scope, $http) {
+ * $scope.items = [1,2,3];
+ * $scope.doRefresh = function() {
+ * $http.get('/new-items')
+ * .success(function(newItems) {
+ * $scope.items = newItems;
+ * })
+ * .finally(function() {
+ * // Stop the ion-refresher from spinning
+ * $scope.$broadcast('scroll.refreshComplete');
+ * });
+ * };
+ * });
+ * ```
+ *
+ * @param {expression=} on-refresh Called when the user pulls down enough and lets go
+ * of the refresher.
+ * @param {expression=} on-pulling Called when the user starts to pull down
+ * on the refresher.
+ * @param {string=} pulling-icon The icon to display while the user is pulling down.
+ * Default: 'ion-arrow-down-c'.
+ * @param {string=} pulling-text The text to display while the user is pulling down.
+ * @param {string=} refreshing-icon The icon to display after user lets go of the
+ * refresher.
+ * @param {string=} refreshing-text The text to display after the user lets go of
+ * the refresher.
+ *
+ */
+IonicModule
+.directive('ionRefresher', ['$ionicBind', function($ionicBind) {
+ return {
+ restrict: 'E',
+ replace: true,
+ require: '^$ionicScroll',
+ template:
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '
',
+ compile: function($element, $attrs) {
+ if (angular.isUndefined($attrs.pullingIcon)) {
+ $attrs.$set('pullingIcon', 'ion-arrow-down-c');
+ }
+ if (angular.isUndefined($attrs.refreshingIcon)) {
+ $attrs.$set('refreshingIcon', 'ion-loading-d');
+ }
+ return function($scope, $element, $attrs, scrollCtrl) {
+ $ionicBind($scope, $attrs, {
+ pullingIcon: '@',
+ pullingText: '@',
+ refreshingIcon: '@',
+ refreshingText: '@',
+ $onRefresh: '&onRefresh',
+ $onPulling: '&onPulling'
+ });
+
+ scrollCtrl._setRefresher($scope, $element[0]);
+ $scope.$on('scroll.refreshComplete', function() {
+ $element[0].classList.remove('active');
+ scrollCtrl.scrollView.finishPullToRefresh();
+ });
+ };
+ }
+ };
+}]);
diff --git a/js/ext/angular/src/directive/ionicScroll.js b/js/angular/directive/scroll.js
similarity index 97%
rename from js/ext/angular/src/directive/ionicScroll.js
rename to js/angular/directive/scroll.js
index 008e3c873f..9ad0ce4728 100644
--- a/js/ext/angular/src/directive/ionicScroll.js
+++ b/js/angular/directive/scroll.js
@@ -1,8 +1,3 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.scroll', [])
-
/**
* @ngdoc directive
* @name ionScroll
@@ -22,6 +17,7 @@ angular.module('ionic.ui.scroll', [])
* @param {boolean=} scrollbar-x Whether to show the horizontal scrollbar. Default false.
* @param {boolean=} scrollbar-y Whether to show the vertical scrollbar. Default true.
*/
+IonicModule
.directive('ionScroll', [
'$timeout',
'$controller',
@@ -87,5 +83,3 @@ function($timeout, $controller, $ionicBind) {
}
};
}]);
-
-})();
diff --git a/js/angular/directive/sideMenu.js b/js/angular/directive/sideMenu.js
new file mode 100644
index 0000000000..2b6a3a3608
--- /dev/null
+++ b/js/angular/directive/sideMenu.js
@@ -0,0 +1,59 @@
+/**
+ * @ngdoc directive
+ * @name ionSideMenu
+ * @module ionic
+ * @restrict E
+ * @parent ionic.directive:ionSideMenus
+ *
+ * @description
+ * A container for a side menu, sibling to an {@link ionic.directive:ionSideMenuContent} directive.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ * ```
+ * For a complete side menu example, see the
+ * {@link ionic.directive:ionSideMenus} documentation.
+ *
+ * @param {string} side Which side the side menu is currently on. Allowed values: 'left' or 'right'.
+ * @param {boolean=} is-enabled Whether this side menu is enabled.
+ * @param {number=} width How many pixels wide the side menu should be. Defaults to 275.
+ */
+IonicModule
+.directive('ionSideMenu', function() {
+ return {
+ restrict: 'E',
+ require: '^ionSideMenus',
+ scope: true,
+ compile: function(element, attr) {
+ angular.isUndefined(attr.isEnabled) && attr.$set('isEnabled', 'true');
+ angular.isUndefined(attr.width) && attr.$set('width', '275');
+
+ element.addClass('menu menu-' + attr.side);
+
+ return function($scope, $element, $attr, sideMenuCtrl) {
+ $scope.side = $attr.side || 'left';
+
+ var sideMenu = sideMenuCtrl[$scope.side] = new ionic.views.SideMenu({
+ width: 275,
+ el: $element[0],
+ isEnabled: true
+ });
+
+ $scope.$watch($attr.width, function(val) {
+ var numberVal = +val;
+ if (numberVal && numberVal == val) {
+ sideMenu.setWidth(+val);
+ }
+ });
+ $scope.$watch($attr.isEnabled, function(val) {
+ sideMenu.setIsEnabled(!!val);
+ });
+ };
+ }
+ };
+});
diff --git a/js/angular/directive/sideMenuContent.js b/js/angular/directive/sideMenuContent.js
new file mode 100644
index 0000000000..168d15cb5c
--- /dev/null
+++ b/js/angular/directive/sideMenuContent.js
@@ -0,0 +1,125 @@
+/**
+ * @ngdoc directive
+ * @name ionSideMenuContent
+ * @module ionic
+ * @restrict E
+ * @parent ionic.directive:ionSideMenus
+ *
+ * @description
+ * A container for the main visible content, sibling to one or more
+ * {@link ionic.directive:ionSideMenu} directives.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ * ```
+ * For a complete side menu example, see the
+ * {@link ionic.directive:ionSideMenus} documentation.
+ *
+ * @param {boolean=} drag-content Whether the content can be dragged. Default true.
+ *
+ */
+IonicModule
+.directive('ionSideMenuContent', [
+ '$timeout',
+ '$ionicGesture',
+function($timeout, $ionicGesture) {
+
+ return {
+ restrict: 'EA', //DEPRECATED 'A'
+ require: '^ionSideMenus',
+ scope: true,
+ compile: function(element, attr) {
+ return { pre: prelink };
+ function prelink($scope, $element, $attr, sideMenuCtrl) {
+
+ $element.addClass('menu-content pane');
+
+ if (angular.isDefined(attr.dragContent)) {
+ $scope.$watch(attr.dragContent, function(value) {
+ sideMenuCtrl.canDragContent(value);
+ });
+ } else {
+ sideMenuCtrl.canDragContent(true);
+ }
+
+ var defaultPrevented = false;
+ var isDragging = false;
+
+ // Listen for taps on the content to close the menu
+ function contentTap(e) {
+ if(sideMenuCtrl.getOpenAmount() !== 0) {
+ sideMenuCtrl.close();
+ e.gesture.srcEvent.preventDefault();
+ }
+ }
+ ionic.on('tap', contentTap, $element[0]);
+
+ var dragFn = function(e) {
+ if(defaultPrevented || !sideMenuCtrl.isDraggableTarget(e)) return;
+ isDragging = true;
+ sideMenuCtrl._handleDrag(e);
+ e.gesture.srcEvent.preventDefault();
+ };
+
+ var dragVertFn = function(e) {
+ if(isDragging) {
+ e.gesture.srcEvent.preventDefault();
+ }
+ };
+
+ //var dragGesture = Gesture.on('drag', dragFn, $element);
+ var dragRightGesture = $ionicGesture.on('dragright', dragFn, $element);
+ var dragLeftGesture = $ionicGesture.on('dragleft', dragFn, $element);
+ var dragUpGesture = $ionicGesture.on('dragup', dragVertFn, $element);
+ var dragDownGesture = $ionicGesture.on('dragdown', dragVertFn, $element);
+
+ var dragReleaseFn = function(e) {
+ isDragging = false;
+ if(!defaultPrevented) {
+ sideMenuCtrl._endDrag(e);
+ }
+ defaultPrevented = false;
+ };
+
+ var releaseGesture = $ionicGesture.on('release', dragReleaseFn, $element);
+
+ sideMenuCtrl.setContent({
+ onDrag: function(e) {},
+ endDrag: function(e) {},
+ getTranslateX: function() {
+ return $scope.sideMenuContentTranslateX || 0;
+ },
+ setTranslateX: ionic.animationFrameThrottle(function(amount) {
+ $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + amount + 'px, 0, 0)';
+ $timeout(function() {
+ $scope.sideMenuContentTranslateX = amount;
+ });
+ }),
+ 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');
+ }
+ });
+
+ // Cleanup
+ $scope.$on('$destroy', function() {
+ $ionicGesture.off(dragLeftGesture, 'dragleft', dragFn);
+ $ionicGesture.off(dragRightGesture, 'dragright', dragFn);
+ $ionicGesture.off(dragUpGesture, 'dragup', dragFn);
+ $ionicGesture.off(dragDownGesture, 'dragdown', dragFn);
+ $ionicGesture.off(releaseGesture, 'release', dragReleaseFn);
+ ionic.off('tap', contentTap, $element[0]);
+ });
+ }
+ }
+ };
+}]);
diff --git a/js/angular/directive/sideMenus.js b/js/angular/directive/sideMenus.js
new file mode 100644
index 0000000000..bee5470534
--- /dev/null
+++ b/js/angular/directive/sideMenus.js
@@ -0,0 +1,61 @@
+IonicModule
+
+/**
+ * @ngdoc directive
+ * @name ionSideMenus
+ * @module ionic
+ * @delegate ionic.service:$ionicSideMenuDelegate
+ * @restrict E
+ *
+ * @description
+ * A container element for side menu(s) and the main content. Allows the left
+ * and/or right side menu to be toggled by dragging the main content area side
+ * to side.
+ *
+ * 
+ *
+ * For more information on side menus, check out the documenation for
+ * {@link ionic.directive:ionSideMenuContent} and
+ * {@link ionic.directive:ionSideMenu}.
+ *
+ * @usage
+ * To use side menus, add an `` parent element,
+ * an `` for the center content,
+ * and one or more `` directives.
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function ContentController($scope, $ionicSideMenuDelegate) {
+ * $scope.toggleLeft = function() {
+ * $ionicSideMenuDelegate.toggleLeft();
+ * };
+ * }
+ * ```
+ *
+ * @param {string=} delegate-handle The handle used to identify this side menu
+ * with {@link ionic.service:$ionicSideMenuDelegate}.
+ *
+ */
+.directive('ionSideMenus', [function() {
+ return {
+ restrict: 'ECA',
+ replace: true,
+ transclude: true,
+ controller: '$ionicSideMenus',
+ template: ''
+ };
+}]);
diff --git a/js/ext/angular/src/directive/ionicSlideBox.js b/js/angular/directive/slideBox.js
similarity index 67%
rename from js/ext/angular/src/directive/ionicSlideBox.js
rename to js/angular/directive/slideBox.js
index 88a04e3fdf..c30dea308d 100644
--- a/js/ext/angular/src/directive/ionicSlideBox.js
+++ b/js/angular/directive/slideBox.js
@@ -1,107 +1,3 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.slideBox', [])
-
-/**
- * @ngdoc service
- * @name $ionicSlideBoxDelegate
- * @module ionic
- * @description
- * Delegate that controls the {@link ionic.directive:ionSlideBox} directive.
- *
- * Methods called directly on the $ionicSlideBoxDelegate service will control all side
- * menus. Use the {@link ionic.service:$ionicSlideBoxDelegate#$getByHandle $getByHandle}
- * method to control specific slide box instances.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * Slide 2!
- *
- *
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicSlideBoxDelegate) {
- * $scope.nextSlide = function() {
- * $ionicSlideBoxDelegate.next();
- * }
- * }
- * ```
- */
-.service('$ionicSlideBoxDelegate', delegateService([
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#update
- * @description
- * Update the slidebox (for example if using Angular with ng-repeat,
- * resize it for the elements inside).
- */
- 'update',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#slide
- * @param {number} to The index to slide to.
- * @param {number=} speed The number of milliseconds for the change to take.
- */
- 'slide',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#previous
- * @description Go to the previous slide. Wraps around if at the beginning.
- */
- 'previous',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#next
- * @description Go to the next slide. Wraps around if at the end.
- */
- 'next',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#stop
- * @description Stop sliding. The slideBox will not move again until
- * explicitly told to do so.
- */
- 'stop',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#currentIndex
- * @returns number The index of the current slide.
- */
- 'currentIndex',
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#slidesCount
- * @returns number The number of slides there are currently.
- */
- 'slidesCount'
- /**
- * @ngdoc method
- * @name $ionicSlideBoxDelegate#$getByHandle
- * @param {string} handle
- * @returns `delegateInstance` A delegate instance that controls only the
- * {@link ionic.directive:ionSlideBox} directives with `delegate-handle` matching
- * the given handle.
- *
- * Example: `$ionicSlideBoxDelegate.$getByHandle('my-handle').stop();`
- */
-]))
-
-/**
- * The internal controller for the slide box controller.
- */
/**
* @ngdoc directive
@@ -139,6 +35,7 @@ angular.module('ionic.ui.slideBox', [])
* @param {expression=} on-slide-changed Expression called whenever the slide is changed. Is passed an 'index' variable.
* @param {expression=} active-slide Model to bind the current slide to.
*/
+IonicModule
.directive('ionSlideBox', [
'$timeout',
'$compile',
@@ -238,7 +135,6 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
}
};
}])
-
.directive('ionSlide', function() {
return {
restrict: 'E',
@@ -285,5 +181,3 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
};
});
-
-})();
diff --git a/js/angular/directive/tab.js b/js/angular/directive/tab.js
new file mode 100644
index 0000000000..bc01d983a7
--- /dev/null
+++ b/js/angular/directive/tab.js
@@ -0,0 +1,136 @@
+/**
+ * @ngdoc directive
+ * @name ionTab
+ * @module ionic
+ * @restrict E
+ * @parent ionic.directive:ionTabs
+ *
+ * @description
+ * Contains a tab's content. The content only exists while the given tab is selected.
+ *
+ * Each ionTab has its own view history.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ * ```
+ * For a complete, working tab bar example, see the {@link ionic.directive:ionTabs} documentation.
+ *
+ * @param {string} title The title of the tab.
+ * @param {string=} href The link that this tab will navigate to when tapped.
+ * @param {string=} icon The icon of the tab. If given, this will become the default for icon-on and icon-off.
+ * @param {string=} icon-on The icon of the tab while it is selected.
+ * @param {string=} icon-off The icon of the tab while it is not selected.
+ * @param {expression=} badge The badge to put on this tab (usually a number).
+ * @param {expression=} badge-style The style of badge to put on this tab (eg tabs-positive).
+ * @param {expression=} on-select Called when this tab is selected.
+ * @param {expression=} on-deselect Called when this tab is deselected.
+ * @param {expression=} ng-click By default, the tab will be selected on click. If ngClick is set, it will not. You can explicitly switch tabs using {@link ionic.service:$ionicTabsDelegate#select $ionicTabsDelegate.select()}.
+ */
+IonicModule
+.directive('ionTab', [
+ '$rootScope',
+ '$animate',
+ '$ionicBind',
+ '$compile',
+function($rootScope, $animate, $ionicBind, $compile) {
+
+ //Returns ' key="value"' if value exists
+ function attrStr(k,v) {
+ return angular.isDefined(v) ? ' ' + k + '="' + v + '"' : '';
+ }
+ return {
+ restrict: 'E',
+ require: ['^ionTabs', 'ionTab'],
+ replace: true,
+ controller: '$ionicTab',
+ scope: true,
+ compile: function(element, attr) {
+ var navView = element[0].querySelector('ion-nav-view') ||
+ element[0].querySelector('data-ion-nav-view');
+ var navViewName = navView && navView.getAttribute('name');
+
+
+ //We create the tabNavElement in the compile phase so that the
+ //attributes we pass down won't be interpolated yet - we want
+ //to pass down the 'raw' versions of the attributes
+ var tabNavElement = angular.element(
+ ''
+ );
+
+ //Remove the contents of the element so we can compile them later, if tab is selected
+ //We don't use regular transclusion because it breaks element inheritance
+ var tabContent = angular.element('
')
+ .append( element.contents().remove() );
+
+ return function link($scope, $element, $attr, ctrls) {
+ var childScope;
+ var childElement;
+ var tabsCtrl = ctrls[0];
+ var tabCtrl = ctrls[1];
+
+ $ionicBind($scope, $attr, {
+ animate: '=',
+ onSelect: '&',
+ onDeselect: '&',
+ title: '@',
+ uiSref: '@',
+ href: '@',
+ });
+
+ tabsCtrl.add($scope);
+ $scope.$on('$destroy', function() {
+ tabsCtrl.remove($scope);
+ tabNavElement.isolateScope().$destroy();
+ tabNavElement.remove();
+ });
+
+ //Remove title attribute so browser-tooltip does not apear
+ $element[0].removeAttribute('title');
+
+ if (navViewName) {
+ tabCtrl.navViewName = navViewName;
+ }
+ $scope.$on('$stateChangeSuccess', selectIfMatchesState);
+ selectIfMatchesState();
+ function selectIfMatchesState() {
+ if (tabCtrl.tabMatchesState()) {
+ tabsCtrl.select($scope);
+ }
+ }
+
+ tabNavElement.data('$ionTabsController', tabsCtrl);
+ tabNavElement.data('$ionTabController', tabCtrl);
+ tabsCtrl.$tabsElement.append($compile(tabNavElement)($scope));
+
+ $scope.$watch('$tabSelected', function(value) {
+ childScope && childScope.$destroy();
+ childScope = null;
+ childElement && $animate.leave(childElement);
+ childElement = null;
+ if (value) {
+ childScope = $scope.$new();
+ childElement = tabContent.clone();
+ $animate.enter(childElement, tabsCtrl.$element);
+ $compile(childElement)(childScope);
+ }
+ });
+
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/tabNav.js b/js/angular/directive/tabNav.js
new file mode 100644
index 0000000000..c80792e583
--- /dev/null
+++ b/js/angular/directive/tabNav.js
@@ -0,0 +1,52 @@
+IonicModule
+.directive('ionTabNav', ['$ionicNgClick', function($ionicNgClick) {
+ return {
+ restrict: 'E',
+ replace: true,
+ require: ['^ionTabs', '^ionTab'],
+ template:
+ '' +
+ '{{badge}}' +
+ '' +
+ '' +
+ '' +
+ '',
+ scope: {
+ title: '@',
+ icon: '@',
+ iconOn: '@',
+ iconOff: '@',
+ badge: '=',
+ badgeStyle: '@'
+ },
+ compile: function(element, attr, transclude) {
+ return function link($scope, $element, $attrs, ctrls) {
+ var tabsCtrl = ctrls[0],
+ tabCtrl = ctrls[1];
+
+ //Remove title attribute so browser-tooltip does not apear
+ $element[0].removeAttribute('title');
+
+ $scope.selectTab = function(e) {
+ e.preventDefault();
+ tabsCtrl.select(tabCtrl.$scope, true);
+ };
+ if (!$attrs.ngClick) {
+ $ionicNgClick($scope, $element, 'selectTab($event)');
+ }
+
+ $scope.getIconOn = function() {
+ return $scope.iconOn || $scope.icon;
+ };
+ $scope.getIconOff = function() {
+ return $scope.iconOff || $scope.icon;
+ };
+
+ $scope.isTabActive = function() {
+ return tabsCtrl.selectedTab() === tabCtrl.$scope;
+ };
+ };
+ }
+ };
+}]);
diff --git a/js/angular/directive/tabs.js b/js/angular/directive/tabs.js
new file mode 100644
index 0000000000..67c354be13
--- /dev/null
+++ b/js/angular/directive/tabs.js
@@ -0,0 +1,83 @@
+
+/**
+ * @ngdoc directive
+ * @name ionTabs
+ * @module ionic
+ * @delegate ionic.service:$ionicTabsDelegate
+ * @restrict E
+ * @codepen KbrzJ
+ *
+ * @description
+ * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed
+ * through.
+ *
+ * Assign any [tabs class](/docs/components#tabs) or
+ * [animation class](/docs/components#animation) to the element to define
+ * its look and feel.
+ *
+ * See the {@link ionic.directive:ionTab} directive's documentation for more details on
+ * individual tabs.
+ *
+ * @usage
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ *
+ * @param {string=} delegate-handle The handle used to identify these tabs
+ * with {@link ionic.service:$ionicTabsDelegate}.
+ */
+IonicModule
+
+.directive('ionTabs', ['$ionicViewService', '$ionicTabsDelegate', function($ionicViewService, $ionicTabsDelegate) {
+ return {
+ restrict: 'E',
+ scope: true,
+ controller: '$ionicTabs',
+ compile: function(element, attr) {
+ element.addClass('view');
+ //We cannot use regular transclude here because it breaks element.data()
+ //inheritance on compile
+ var innerElement = angular.element('');
+ innerElement.append(element.contents());
+ element.append(innerElement);
+
+ return { pre: prelink };
+ function prelink($scope, $element, $attr, tabsCtrl) {
+ var deregisterInstance = $ionicTabsDelegate._registerInstance(
+ tabsCtrl, $attr.delegateHandle
+ );
+
+ $scope.$on('$destroy', deregisterInstance);
+
+ tabsCtrl.$scope = $scope;
+ tabsCtrl.$element = $element;
+ tabsCtrl.$tabsElement = angular.element($element[0].querySelector('.tabs'));
+
+ var el = $element[0];
+ $scope.$watch(function() { return el.className; }, function(value) {
+ var isTabsTop = value.indexOf('tabs-top') !== -1;
+ var isHidden = value.indexOf('tabs-item-hide') !== -1;
+ $scope.$hasTabs = !isTabsTop && !isHidden;
+ $scope.$hasTabsTop = isTabsTop && !isHidden;
+ });
+ $scope.$on('$destroy', function() {
+ $scope.$hasTabs = $scope.$hasTabsTop = null;
+ });
+ }
+ }
+ };
+}]);
diff --git a/js/ext/angular/src/directive/ionicToggle.js b/js/angular/directive/toggle.js
similarity index 92%
rename from js/ext/angular/src/directive/ionicToggle.js
rename to js/angular/directive/toggle.js
index 35d343f7be..d6d683cfab 100644
--- a/js/ext/angular/src/directive/ionicToggle.js
+++ b/js/angular/directive/toggle.js
@@ -1,8 +1,3 @@
-(function(ionic) {
-'use strict';
-
-angular.module('ionic.ui.toggle', [])
-
/**
* @ngdoc directive
* @name ionToggle
@@ -18,7 +13,11 @@ angular.module('ionic.ui.toggle', [])
* The toggle behaves like any [AngularJS checkbox](http://docs.angularjs.org/api/ng/input/input[checkbox]) otherwise.
*
*/
-.directive('ionToggle', ['$ionicGesture', '$timeout', function($ionicGesture, $timeout) {
+IonicModule
+.directive('ionToggle', [
+ '$ionicGesture',
+ '$timeout',
+function($ionicGesture, $timeout) {
return {
restrict: 'E',
@@ -82,5 +81,3 @@ angular.module('ionic.ui.toggle', [])
};
}]);
-
-})(window.ionic);
diff --git a/js/ext/angular/src/directive/ionicTouch.js b/js/angular/directive/touch.js
similarity index 100%
rename from js/ext/angular/src/directive/ionicTouch.js
rename to js/angular/directive/touch.js
diff --git a/js/angular/directive/view.js b/js/angular/directive/view.js
new file mode 100644
index 0000000000..7721c54b4e
--- /dev/null
+++ b/js/angular/directive/view.js
@@ -0,0 +1,75 @@
+/**
+ * @ngdoc directive
+ * @name ionView
+ * @module ionic
+ * @restrict E
+ * @parent ionNavView
+ *
+ * @description
+ * A container for content, used to tell a parent {@link ionic.directive:ionNavBar}
+ * about the current view.
+ *
+ * @usage
+ * Below is an example where our page will load with a navbar containing "My Page" as the title.
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ * Hello!
+ *
+ *
+ *
+ * ```
+ *
+ * @param {string=} title The title to display on the parent {@link ionic.directive:ionNavBar}.
+ * @param {boolean=} hideBackButton Whether to hide the back button on the parent
+ * {@link ionic.directive:ionNavBar} by default.
+ * @param {boolean=} hideNavBar Whether to hide the parent
+ * {@link ionic.directive:ionNavBar} by default.
+ */
+IonicModule
+.directive('ionView', ['$ionicViewService', '$rootScope', '$animate',
+ function( $ionicViewService, $rootScope, $animate) {
+ return {
+ restrict: 'EA',
+ priority: 1000,
+ require: '^?ionNavBar',
+ compile: function(tElement, tAttrs, transclude) {
+ tElement.addClass('pane');
+ tElement[0].removeAttribute('title');
+
+ return function link($scope, $element, $attr, navBarCtrl) {
+ if (!navBarCtrl) {
+ return;
+ }
+
+ if (angular.isDefined($attr.title)) {
+
+ var initialTitle = $attr.title;
+ navBarCtrl.changeTitle(initialTitle, $scope.$navDirection);
+
+ // watch for changes in the title, don't set initial value as changeTitle does that
+ $attr.$observe('title', function(val, oldVal) {
+ if (val !== initialTitle) {
+ navBarCtrl.setTitle(val);
+ }
+ });
+
+ }
+
+ $scope.$watch($attr.hideBackButton, function(value) {
+ // Should we hide a back button when this tab is shown
+ navBarCtrl.showBackButton(!value);
+ });
+
+ $scope.$watch($attr.hideNavBar, function(value) {
+ // Should the nav bar be hidden for this view or not?
+ navBarCtrl.showBar(!value);
+ });
+
+ };
+ }
+ };
+}]);
diff --git a/js/angular/main.js b/js/angular/main.js
new file mode 100644
index 0000000000..0932ee66c3
--- /dev/null
+++ b/js/angular/main.js
@@ -0,0 +1,10 @@
+/**
+ * Create a wrapping module to ease having to include too many
+ * modules.
+ */
+var IonicModule = angular.module('ionic', [
+ // Angular deps
+ 'ngAnimate',
+ 'ngSanitize',
+ 'ui.router'
+]);
diff --git a/js/ext/angular/src/service/ionicActionSheet.js b/js/angular/service/actionSheet.js
similarity index 94%
rename from js/ext/angular/src/service/ionicActionSheet.js
rename to js/angular/service/actionSheet.js
index 2ea1350cfe..5ed61d8ead 100644
--- a/js/ext/angular/src/service/ionicActionSheet.js
+++ b/js/angular/service/actionSheet.js
@@ -1,5 +1,3 @@
-angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.service.platform', 'ionic.ui.actionSheet', 'ngAnimate'])
-
/**
* @ngdoc service
* @name $ionicActionSheet
@@ -42,7 +40,15 @@ angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ioni
* ```
*
*/
-.factory('$ionicActionSheet', ['$rootScope', '$document', '$compile', '$animate', '$timeout', '$ionicTemplateLoader', '$ionicPlatform',
+IonicModule
+.factory('$ionicActionSheet', [
+ '$rootScope',
+ '$document',
+ '$compile',
+ '$animate',
+ '$timeout',
+ '$ionicTemplateLoader',
+ '$ionicPlatform',
function($rootScope, $document, $compile, $animate, $timeout, $ionicTemplateLoader, $ionicPlatform) {
return {
diff --git a/js/ext/angular/src/service/angularOverrides.js b/js/angular/service/angularOverrides.js
similarity index 100%
rename from js/ext/angular/src/service/angularOverrides.js
rename to js/angular/service/angularOverrides.js
diff --git a/js/ext/angular/src/service/ionicBackdrop.js b/js/angular/service/backdrop.js
similarity index 97%
rename from js/ext/angular/src/service/ionicBackdrop.js
rename to js/angular/service/backdrop.js
index c9c3b6d6c5..25e35c4436 100644
--- a/js/ext/angular/src/service/ionicBackdrop.js
+++ b/js/angular/service/backdrop.js
@@ -1,5 +1,3 @@
-angular.module('ionic')
-
/**
* @ngdoc service
* @name $ionicBackdrop
@@ -17,7 +15,7 @@ angular.module('ionic')
*
* For each time `retain` is called, the backdrop will be shown until `release` is called.
*
- * For example, if `retain` is called three times, the backdrop will be shown until `release`
+ * For example, if `retain` is called three times, the backdrop will be shown until `release`
* is called three times.
*
* @usage
@@ -34,6 +32,7 @@ angular.module('ionic')
* }
* ```
*/
+IonicModule
.factory('$ionicBackdrop', [
'$document',
function($document) {
diff --git a/js/ext/angular/src/service/ionicBind.js b/js/angular/service/bind.js
similarity index 97%
rename from js/ext/angular/src/service/ionicBind.js
rename to js/angular/service/bind.js
index f76eb8f81d..6e90f9ff2f 100644
--- a/js/ext/angular/src/service/ionicBind.js
+++ b/js/angular/service/bind.js
@@ -1,7 +1,7 @@
-angular.module('ionic.service.bind', [])
/**
* @private
*/
+IonicModule
.factory('$ionicBind', ['$parse', '$interpolate', function($parse, $interpolate) {
var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
return function(scope, attrs, bindDefinition) {
diff --git a/js/ext/angular/src/service/decorators/location.js b/js/angular/service/decorators/location.js
similarity index 88%
rename from js/ext/angular/src/service/decorators/location.js
rename to js/angular/service/decorators/location.js
index 53d25acc53..58887d2dc5 100644
--- a/js/ext/angular/src/service/decorators/location.js
+++ b/js/angular/service/decorators/location.js
@@ -1,9 +1,9 @@
-angular.module('ionic.decorator.location', [])
-
/**
* @private
*/
-.config(['$provide', function($provide) {
+IonicModule.config([
+ '$provide',
+function($provide) {
function $LocationDecorator($location, $timeout) {
$location.__hash = $location.hash;
@@ -23,6 +23,6 @@ angular.module('ionic.decorator.location', [])
return $location;
}
-
+
$provide.decorator('$location', ['$delegate', '$timeout', $LocationDecorator]);
}]);
diff --git a/js/ext/angular/src/service/delegateService.js b/js/angular/service/delegateService.js
similarity index 100%
rename from js/ext/angular/src/service/delegateService.js
rename to js/angular/service/delegateService.js
diff --git a/js/ext/angular/src/service/ionicGesture.js b/js/angular/service/gesture.js
similarity index 96%
rename from js/ext/angular/src/service/ionicGesture.js
rename to js/angular/service/gesture.js
index b2abe42c92..4566034b62 100644
--- a/js/ext/angular/src/service/ionicGesture.js
+++ b/js/angular/service/gesture.js
@@ -1,5 +1,3 @@
-angular.module('ionic.service.gesture', [])
-
/**
* @ngdoc service
* @name $ionicGesture
@@ -7,6 +5,7 @@ angular.module('ionic.service.gesture', [])
* @description An angular service exposing ionic
* {@link ionic.utility:ionic.EventController}'s gestures.
*/
+IonicModule
.factory('$ionicGesture', [function() {
return {
/**
diff --git a/js/ext/angular/src/service/ionicLoading.js b/js/angular/service/loading.js
similarity index 89%
rename from js/ext/angular/src/service/ionicLoading.js
rename to js/angular/service/loading.js
index 34bd4a3768..f07adbb64e 100644
--- a/js/ext/angular/src/service/ionicLoading.js
+++ b/js/angular/service/loading.js
@@ -1,13 +1,11 @@
-var TPL_LOADING =
+var LOADING_TPL =
'
' +
'
';
-var HIDE_LOADING_DEPRECATED = '$ionicLoading instance.hide() has been deprecated. Use $ionicLoading.hide().';
-var SHOW_LOADING_DEPRECATED = '$ionicLoading instance.show() has been deprecated. Use $ionicLoading.show().';
-var SET_LOADING_DEPRECATED = '$ionicLoading instance.setContent() has been deprecated. Use $ionicLoading.show({ template: \'my content\' }).';
-
-angular.module('ionic.service.loading', [])
+var LOADING_HIDE_DEPRECATED = '$ionicLoading instance.hide() has been deprecated. Use $ionicLoading.hide().';
+var LOADING_SHOW_DEPRECATED = '$ionicLoading instance.show() has been deprecated. Use $ionicLoading.show().';
+var LOADING_SET_DEPRECATED = '$ionicLoading instance.setContent() has been deprecated. Use $ionicLoading.show({ template: \'my content\' }).';
/**
* @ngdoc service
@@ -32,6 +30,7 @@ angular.module('ionic.service.loading', [])
* });
* ```
*/
+IonicModule
.factory('$ionicLoading', [
'$document',
'$ionicTemplateLoader',
@@ -57,7 +56,7 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
* - `{string=}` `templateUrl` The url of an html template to load as the content of the indicator.
* - `{boolean=}` `noBackdrop` Whether to hide the backdrop.
* - `{number=}` `delay` How many milliseconds to delay showing the indicator.
- * - `{number=} `duration` How many milliseconds to wait until automatically
+ * - `{number=}` `duration` How many milliseconds to wait until automatically
* hiding the indicator.
*/
show: showLoader,
@@ -76,7 +75,7 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
function getLoader() {
if (!loaderInstance) {
loaderInstance = $ionicTemplateLoader.compile({
- template: TPL_LOADING,
+ template: LOADING_TPL,
appendTo: $document[0].body
})
.then(function(loader) {
@@ -152,11 +151,11 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
});
return {
- hide: deprecated.method(HIDE_LOADING_DEPRECATED, $log.error, hideLoader),
- show: deprecated.method(SHOW_LOADING_DEPRECATED, $log.error, function() {
+ hide: deprecated.method(LOADING_HIDE_DEPRECATED, $log.error, hideLoader),
+ show: deprecated.method(LOADING_SHOW_DEPRECATED, $log.error, function() {
showLoader(options);
}),
- setContent: deprecated.method(SET_LOADING_DEPRECATED, $log.error, function(content) {
+ setContent: deprecated.method(LOADING_SET_DEPRECATED, $log.error, function(content) {
getLoader().then(function(loader) {
loader.show({ template: content });
});
diff --git a/js/ext/angular/src/service/ionicModal.js b/js/angular/service/modal.js
similarity index 98%
rename from js/ext/angular/src/service/ionicModal.js
rename to js/angular/service/modal.js
index 4bb5d5ebed..1c353a43d3 100644
--- a/js/ext/angular/src/service/ionicModal.js
+++ b/js/angular/service/modal.js
@@ -1,5 +1,3 @@
-angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.service.platform', 'ionic.ui.modal'])
-
/**
* @ngdoc service
* @name $ionicModal
@@ -43,6 +41,7 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv
* });
* ```
*/
+IonicModule
.factory('$ionicModal', [
'$rootScope',
'$document',
@@ -105,7 +104,6 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
modalEl.addClass('ng-enter active')
.removeClass('ng-leave ng-leave-active');
-
self._isShown = true;
self._deregisterBackButton = $ionicPlatform.registerBackButtonAction(function(){
self.hide();
@@ -161,7 +159,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
*/
remove: function() {
var self = this;
- self.scope.$parent && self.scope.$parent.$broadcast('modal.removed');
+ self.scope.$parent && self.scope.$parent.$broadcast('modal.removed', self);
return self.hide().then(function() {
self.scope.$destroy();
diff --git a/js/angular/service/navBarDelegate.js b/js/angular/service/navBarDelegate.js
new file mode 100644
index 0000000000..1acd18cc09
--- /dev/null
+++ b/js/angular/service/navBarDelegate.js
@@ -0,0 +1,103 @@
+
+/**
+ * @ngdoc service
+ * @name $ionicNavBarDelegate
+ * @module ionic
+ * @description
+ * Delegate for controlling the {@link ionic.directive:ionNavBar} directive.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicNavBarDelegate) {
+ * $scope.setNavTitle = function(title) {
+ * $ionicNavBarDelegate.setTitle(title);
+ * }
+ * }
+ * ```
+ */
+IonicModule
+.service('$ionicNavBarDelegate', delegateService([
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#back
+ * @description Goes back in the view history.
+ * @param {DOMEvent=} event The event object (eg from a tap event)
+ */
+ 'back',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#align
+ * @description Aligns the title with the buttons in a given direction.
+ * @param {string=} direction The direction to the align the title text towards.
+ * Available: 'left', 'right', 'center'. Default: 'center'.
+ */
+ 'align',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#showBackButton
+ * @description
+ * Set/get whether the {@link ionic.directive:ionNavBackButton} is shown
+ * (if it exists).
+ * @param {boolean=} show Whether to show the back button.
+ * @returns {boolean} Whether the back button is shown.
+ */
+ 'showBackButton',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#showBar
+ * @description
+ * Set/get whether the {@link ionic.directive:ionNavBar} is shown.
+ * @param {boolean} show Whether to show the bar.
+ * @returns {boolean} Whether the bar is shown.
+ */
+ 'showBar',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#setTitle
+ * @description
+ * Set the title for the {@link ionic.directive:ionNavBar}.
+ * @param {string} title The new title to show.
+ */
+ 'setTitle',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#changeTitle
+ * @description
+ * Change the title, transitioning the new title in and the old one out in a given direction.
+ * @param {string} title The new title to show.
+ * @param {string} direction The direction to transition the new title in.
+ * Available: 'forward', 'back'.
+ */
+ 'changeTitle',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#getTitle
+ * @returns {string} The current title of the navbar.
+ */
+ 'getTitle',
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#getPreviousTitle
+ * @returns {string} The previous title of the navbar.
+ */
+ 'getPreviousTitle'
+ /**
+ * @ngdoc method
+ * @name $ionicNavBarDelegate#$getByHandle
+ * @param {string} handle
+ * @returns `delegateInstance` A delegate instance that controls only the
+ * navBars with delegate-handle matching the given handle.
+ *
+ * Example: `$ionicNavBarDelegate.$getByHandle('myHandle').setTitle('newTitle')`
+ */
+]));
diff --git a/js/ext/angular/src/service/ionicPlatform.js b/js/angular/service/platform.js
similarity index 88%
rename from js/ext/angular/src/service/ionicPlatform.js
rename to js/angular/service/platform.js
index 1506dd6b8f..1ef66589ba 100644
--- a/js/ext/angular/src/service/ionicPlatform.js
+++ b/js/angular/service/platform.js
@@ -1,7 +1,3 @@
-(function(ionic) {'use strict';
-
-angular.module('ionic.service.platform', [])
-
/**
* @ngdoc service
* @name $ionicPlatform
@@ -12,11 +8,12 @@ angular.module('ionic.service.platform', [])
* Used to detect the current platform, as well as do things like override the
* Android back button in PhoneGap/Cordova.
*/
+IonicModule
.provider('$ionicPlatform', function() {
return {
$get: ['$q', '$rootScope', function($q, $rootScope) {
- return {
+ var self = {
/**
* @ngdoc method
* @name $ionicPlatform#onHardwareBackButton
@@ -65,12 +62,12 @@ angular.module('ionic.service.platform', [])
* @returns {function} A function that, when called, will deregister
* this backButtonAction.
*/
+ $backButtonActions: {},
registerBackButtonAction: function(fn, priority, actionId) {
- var self = this;
if(!self._hasBackButtonHandler) {
// add a back button listener if one hasn't been setup yet
- $rootScope.$backButtonActions = {};
+ self.$backButtonActions = {};
self.onHardwareBackButton(self.hardwareBackButtonClick);
self._hasBackButtonHandler = true;
}
@@ -80,11 +77,11 @@ angular.module('ionic.service.platform', [])
priority: (priority ? priority : 0),
fn: fn
};
- $rootScope.$backButtonActions[action.id] = action;
+ self.$backButtonActions[action.id] = action;
// return a function to de-register this back button action
return function() {
- delete $rootScope.$backButtonActions[action.id];
+ delete self.$backButtonActions[action.id];
};
},
@@ -95,9 +92,9 @@ angular.module('ionic.service.platform', [])
// loop through all the registered back button actions
// and only run the last one of the highest priority
var priorityAction, actionId;
- for(actionId in $rootScope.$backButtonActions) {
- if(!priorityAction || $rootScope.$backButtonActions[actionId].priority >= priorityAction.priority) {
- priorityAction = $rootScope.$backButtonActions[actionId];
+ for(actionId in self.$backButtonActions) {
+ if(!priorityAction || self.$backButtonActions[actionId].priority >= priorityAction.priority) {
+ priorityAction = self.$backButtonActions[actionId];
}
}
if(priorityAction) {
@@ -130,9 +127,8 @@ angular.module('ionic.service.platform', [])
return q.promise;
}
};
+ return self;
}]
};
});
-
-})(ionic);
diff --git a/js/ext/angular/src/service/ionicPopup.js b/js/angular/service/popup.js
similarity index 98%
rename from js/ext/angular/src/service/ionicPopup.js
rename to js/angular/service/popup.js
index beb212e84f..7f6ffe2a3a 100644
--- a/js/ext/angular/src/service/ionicPopup.js
+++ b/js/angular/service/popup.js
@@ -1,5 +1,5 @@
-var TPL_POPUP =
+var POPUP_TPL =
'
' +
'
' +
'' +
@@ -12,9 +12,7 @@ var TPL_POPUP =
'
' +
'
';
-var CONTENT_POPUP_DEPRECATED = '$ionicPopup options.content has been deprecated. Use options.template instead.';
-
-angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
+var POPUP_CONTENT_DEPRECATED = '$ionicPopup options.content has been deprecated. Use options.template instead.';
/**
* @ngdoc service
@@ -99,9 +97,8 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
* };
*});
*```
-
-
*/
+IonicModule
.factory('$ionicPopup', [
'$animate',
'$ionicTemplateLoader',
@@ -274,10 +271,10 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $ro
buttons: [],
}, options || {});
- deprecated.field(CONTENT_POPUP_DEPRECATED, $log.warn, options, 'content', options.content);
+ deprecated.field(POPUP_CONTENT_DEPRECATED, $log.warn, options, 'content', options.content);
var popupPromise = $ionicTemplateLoader.compile({
- template: TPL_POPUP,
+ template: POPUP_TPL,
scope: options.scope && options.scope.$new(),
appendTo: $document[0].body
});
diff --git a/js/ext/angular/src/controller/ionicScrollController.js b/js/angular/service/scrollDelegate.js
similarity index 53%
rename from js/ext/angular/src/controller/ionicScrollController.js
rename to js/angular/service/scrollDelegate.js
index c047f4abfb..7675f6d6fd 100644
--- a/js/ext/angular/src/controller/ionicScrollController.js
+++ b/js/angular/service/scrollDelegate.js
@@ -1,4 +1,3 @@
-angular.module('ionic.ui.scroll')
/**
* @ngdoc service
@@ -58,7 +57,7 @@ angular.module('ionic.ui.scroll')
* }
* ```
*/
-
+IonicModule
.service('$ionicScrollDelegate', delegateService([
/**
* @ngdoc method
@@ -190,189 +189,5 @@ angular.module('ionic.ui.scroll')
*
* Example: `$ionicScrollDelegate.$getByHandle('my-handle').scrollTop();`
*/
-]))
-
-/**
- * @private
- */
-.factory('$$scrollValueCache', function() {
- return {};
-})
-
-.controller('$ionicScroll', [
- '$scope',
- 'scrollViewOptions',
- '$timeout',
- '$window',
- '$$scrollValueCache',
- '$location',
- '$rootScope',
- '$document',
- '$ionicScrollDelegate',
-function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $rootScope, $document, $ionicScrollDelegate) {
-
- var self = this;
-
- this._scrollViewOptions = scrollViewOptions; //for testing
-
- var element = this.element = scrollViewOptions.el;
- var $element = this.$element = angular.element(element);
- var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions);
-
- //Attach self to element as a controller so other directives can require this controller
- //through `require: '$ionicScroll'
- //Also attach to parent so that sibling elements can require this
- ($element.parent().length ? $element.parent() : $element)
- .data('$$ionicScrollController', this);
-
- var deregisterInstance = $ionicScrollDelegate._registerInstance(
- this, scrollViewOptions.delegateHandle
- );
-
- if (!angular.isDefined(scrollViewOptions.bouncing)) {
- ionic.Platform.ready(function() {
- scrollView.options.bouncing = !ionic.Platform.isAndroid();
- });
- }
-
- var resize = angular.bind(scrollView, scrollView.resize);
- ionic.on('resize', resize, $window);
-
- // set by rootScope listener if needed
- var backListenDone = angular.noop;
-
- $scope.$on('$destroy', function() {
- deregisterInstance();
- ionic.off('resize', resize, $window);
- $window.removeEventListener('resize', resize);
- backListenDone();
- if (self._rememberScrollId) {
- $$scrollValueCache[self._rememberScrollId] = scrollView.getValues();
- }
- });
-
- $element.on('scroll', function(e) {
- var detail = (e.originalEvent || e).detail || {};
- $scope.$onScroll && $scope.$onScroll({
- event: e,
- scrollTop: detail.scrollTop || 0,
- scrollLeft: detail.scrollLeft || 0
- });
- });
-
- $scope.$on('$viewContentLoaded', function(e, historyData) {
- //only the top-most scroll area under a view should remember that view's
- //scroll position
- if (e.defaultPrevented) { return; }
- e.preventDefault();
-
- var viewId = historyData && historyData.viewId;
- if (viewId) {
- self.rememberScrollPosition(viewId);
- self.scrollToRememberedPosition();
-
- backListenDone = $rootScope.$on('$viewHistory.viewBack', function(e, fromViewId, toViewId) {
- //When going back from this view, forget its saved scroll position
- if (viewId === fromViewId) {
- self.forgetScrollPosition();
- }
- });
- }
- });
-
- $timeout(function() {
- scrollView.run();
- });
-
- this._rememberScrollId = null;
-
- this.getScrollView = function() {
- return this.scrollView;
- };
-
- this.getScrollPosition = function() {
- return this.scrollView.getValues();
- };
-
- this.resize = function() {
- return $timeout(resize);
- };
-
- this.scrollTop = function(shouldAnimate) {
- this.resize().then(function() {
- scrollView.scrollTo(0, 0, !!shouldAnimate);
- });
- };
-
- this.scrollBottom = function(shouldAnimate) {
- this.resize().then(function() {
- var max = scrollView.getScrollMax();
- scrollView.scrollTo(max.left, max.top, !!shouldAnimate);
- });
- };
-
- this.scrollTo = function(left, top, shouldAnimate) {
- this.resize().then(function() {
- scrollView.scrollTo(left, top, !!shouldAnimate);
- });
- };
-
- this.scrollBy = function(left, top, shouldAnimate) {
- this.resize().then(function() {
- scrollView.scrollBy(left, top, !!shouldAnimate);
- });
- };
-
- this.anchorScroll = function(shouldAnimate) {
- this.resize().then(function() {
- var hash = $location.hash();
- var elm = hash && $document[0].getElementById(hash);
- if (hash && elm) {
- var scroll = ionic.DomUtil.getPositionInParent(elm, self.$element);
- scrollView.scrollTo(scroll.left, scroll.top, !!shouldAnimate);
- } else {
- scrollView.scrollTo(0,0, !!shouldAnimate);
- }
- });
- };
-
- this.rememberScrollPosition = function(id) {
- if (!id) {
- throw new Error("Must supply an id to remember the scroll by!");
- }
- this._rememberScrollId = id;
- };
- this.forgetScrollPosition = function() {
- delete $$scrollValueCache[this._rememberScrollId];
- this._rememberScrollId = null;
- };
- this.scrollToRememberedPosition = function(shouldAnimate) {
- var values = $$scrollValueCache[this._rememberScrollId];
- if (values) {
- this.resize().then(function() {
- scrollView.scrollTo(+values.left, +values.top, shouldAnimate);
- });
- }
- };
-
-
-
- /**
- * @private
- */
- this._setRefresher = function(refresherScope, refresherElement) {
- var refresher = this.refresher = refresherElement;
- var refresherHeight = self.refresher.clientHeight || 0;
- scrollView.activatePullToRefresh(refresherHeight, function() {
- refresher.classList.add('active');
- refresherScope.$onPulling();
- }, function() {
- refresher.classList.remove('refreshing');
- refresher.classList.remove('active');
- }, function() {
- refresher.classList.add('refreshing');
- refresherScope.$onRefresh();
- });
- };
-}]);
+]));
diff --git a/js/angular/service/sideMenuDelegate.js b/js/angular/service/sideMenuDelegate.js
new file mode 100644
index 0000000000..728833592e
--- /dev/null
+++ b/js/angular/service/sideMenuDelegate.js
@@ -0,0 +1,104 @@
+/**
+ * @ngdoc service
+ * @name $ionicSideMenuDelegate
+ * @module ionic
+ *
+ * @description
+ * Delegate for controlling the {@link ionic.directive:ionSideMenus} directive.
+ *
+ * Methods called directly on the $ionicSideMenuDelegate service will control all side
+ * menus. Use the {@link ionic.service:$ionicSideMenuDelegate#$getByHandle $getByHandle}
+ * method to control specific ionSideMenus instances.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ * Content!
+ *
+ *
+ *
+ * Left Menu!
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MainCtrl($scope, $ionicSideMenuDelegate) {
+ * $scope.toggleLeftSideMenu = function() {
+ * $ionicSideMenuDelegate.toggleLeft();
+ * };
+ * }
+ * ```
+ */
+IonicModule
+.service('$ionicSideMenuDelegate', delegateService([
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#toggleLeft
+ * @description Toggle the left side menu (if it exists).
+ * @param {boolean=} isOpen Whether to open or close the menu.
+ * Default: Toggles the menu.
+ */
+ 'toggleLeft',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#toggleRight
+ * @description Toggle the right side menu (if it exists).
+ * @param {boolean=} isOpen Whether to open or close the menu.
+ * Default: Toggles the menu.
+ */
+ 'toggleRight',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#getOpenRatio
+ * @description Gets the ratio of open amount over menu width. For example, a
+ * menu of width 100 that is opened by 50 pixels is 50% opened, and would return
+ * a ratio of 0.5.
+ *
+ * @returns {float} 0 if nothing is open, between 0 and 1 if left menu is
+ * opened/opening, and between 0 and -1 if right menu is opened/opening.
+ */
+ 'getOpenRatio',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#isOpen
+ * @returns {boolean} Whether either the left or right menu is currently opened.
+ */
+ 'isOpen',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#isOpenLeft
+ * @returns {boolean} Whether the left menu is currently opened.
+ */
+ 'isOpenLeft',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#isOpenRight
+ * @returns {boolean} Whether the right menu is currently opened.
+ */
+ 'isOpenRight',
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#canDragContent
+ * @param {boolean=} canDrag Set whether the content can or cannot be dragged to open
+ * side menus.
+ * @returns {boolean} Whether the content can be dragged to open side menus.
+ */
+ 'canDragContent'
+ /**
+ * @ngdoc method
+ * @name $ionicSideMenuDelegate#$getByHandle
+ * @param {string} handle
+ * @returns `delegateInstance` A delegate instance that controls only the
+ * {@link ionic.directive:ionSideMenus} directives with `delegate-handle` matching
+ * the given handle.
+ *
+ * Example: `$ionicSideMenuDelegate.$getByHandle('my-handle').toggleLeft();`
+ */
+]));
+
diff --git a/js/angular/service/slideBoxDelegate.js b/js/angular/service/slideBoxDelegate.js
new file mode 100644
index 0000000000..7d0b29d664
--- /dev/null
+++ b/js/angular/service/slideBoxDelegate.js
@@ -0,0 +1,97 @@
+/**
+ * @ngdoc service
+ * @name $ionicSlideBoxDelegate
+ * @module ionic
+ * @description
+ * Delegate that controls the {@link ionic.directive:ionSlideBox} directive.
+ *
+ * Methods called directly on the $ionicSlideBoxDelegate service will control all side
+ * menus. Use the {@link ionic.service:$ionicSlideBoxDelegate#$getByHandle $getByHandle}
+ * method to control specific slide box instances.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Slide 2!
+ *
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicSlideBoxDelegate) {
+ * $scope.nextSlide = function() {
+ * $ionicSlideBoxDelegate.next();
+ * }
+ * }
+ * ```
+ */
+IonicModule
+.service('$ionicSlideBoxDelegate', delegateService([
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#update
+ * @description
+ * Update the slidebox (for example if using Angular with ng-repeat,
+ * resize it for the elements inside).
+ */
+ 'update',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#slide
+ * @param {number} to The index to slide to.
+ * @param {number=} speed The number of milliseconds for the change to take.
+ */
+ 'slide',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#previous
+ * @description Go to the previous slide. Wraps around if at the beginning.
+ */
+ 'previous',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#next
+ * @description Go to the next slide. Wraps around if at the end.
+ */
+ 'next',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#stop
+ * @description Stop sliding. The slideBox will not move again until
+ * explicitly told to do so.
+ */
+ 'stop',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#currentIndex
+ * @returns number The index of the current slide.
+ */
+ 'currentIndex',
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#slidesCount
+ * @returns number The number of slides there are currently.
+ */
+ 'slidesCount'
+ /**
+ * @ngdoc method
+ * @name $ionicSlideBoxDelegate#$getByHandle
+ * @param {string} handle
+ * @returns `delegateInstance` A delegate instance that controls only the
+ * {@link ionic.directive:ionSlideBox} directives with `delegate-handle` matching
+ * the given handle.
+ *
+ * Example: `$ionicSlideBoxDelegate.$getByHandle('my-handle').stop();`
+ */
+]));
+
diff --git a/js/angular/service/tabsDelegate.js b/js/angular/service/tabsDelegate.js
new file mode 100644
index 0000000000..0d740539e8
--- /dev/null
+++ b/js/angular/service/tabsDelegate.js
@@ -0,0 +1,68 @@
+/**
+ * @ngdoc service
+ * @name $ionicTabsDelegate
+ * @module ionic
+ *
+ * @description
+ * Delegate for controlling the {@link ionic.directive:ionTabs} directive.
+ *
+ * Methods called directly on the $ionicTabsDelegate service will control all ionTabs
+ * directives. Use the {@link ionic.service:$ionicTabsDelegate#$getByHandle $getByHandle}
+ * method to control specific ionTabs instances.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ * Hello tab 1!
+ *
+ *
+ * Hello tab 2!
+ *
+ *
+ *
+ * ```
+ * ```js
+ * function MyCtrl($scope, $ionicTabsDelegate) {
+ * $scope.selectTabWithIndex = function(index) {
+ * $ionicTabsDelegate.select(index);
+ * }
+ * }
+ * ```
+ */
+IonicModule
+.service('$ionicTabsDelegate', delegateService([
+ /**
+ * @ngdoc method
+ * @name $ionicTabsDelegate#select
+ * @description Select the tab matching the given index.
+ *
+ * @param {number} index Index of the tab to select.
+ * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's
+ * view history (if it exists) and use it, or just load the default page.
+ * Default false.
+ * Hint: you probably want this to be true if you have an
+ * {@link ionic.directive:ionNavView} inside your tab.
+ */
+ 'select',
+ /**
+ * @ngdoc method
+ * @name $ionicTabsDelegate#selectedIndex
+ * @returns `number` The index of the selected tab, or -1.
+ */
+ 'selectedIndex'
+ /**
+ * @ngdoc method
+ * @name $ionicTabsDelegate#$getByHandle
+ * @param {string} handle
+ * @returns `delegateInstance` A delegate instance that controls only the
+ * {@link ionic.directive:ionTabs} directives with `delegate-handle` matching
+ * the given handle.
+ *
+ * Example: `$ionicTabsDelegate.$getByHandle('my-handle').select(0);`
+ */
+]))
+
diff --git a/js/ext/angular/src/service/ionicTemplateLoader.js b/js/angular/service/templateLoader.js
similarity index 95%
rename from js/ext/angular/src/service/ionicTemplateLoader.js
rename to js/angular/service/templateLoader.js
index b97e47b0e6..d0b957f764 100644
--- a/js/ext/angular/src/service/ionicTemplateLoader.js
+++ b/js/angular/service/templateLoader.js
@@ -1,8 +1,4 @@
-angular.module('ionic.service.templateLoad', [])
-
-/**
- * @private
- */
+IonicModule
.factory('$ionicTemplateLoader', [
'$compile',
'$controller',
diff --git a/js/ext/angular/src/service/ionicView.js b/js/angular/service/viewService.js
similarity index 95%
rename from js/ext/angular/src/service/ionicView.js
rename to js/angular/service/viewService.js
index 0e79afe1be..304ac1c044 100644
--- a/js/ext/angular/src/service/ionicView.js
+++ b/js/angular/service/viewService.js
@@ -1,12 +1,17 @@
-angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform'])
-
-
/**
* @private
* TODO document
*/
-.run(['$rootScope', '$state', '$location', '$document', '$animate', '$ionicPlatform',
- function( $rootScope, $state, $location, $document, $animate, $ionicPlatform) {
+IonicModule
+.run([
+ '$rootScope',
+ '$state',
+ '$location',
+ '$document',
+ '$animate',
+ '$ionicPlatform',
+ '$ionicViewService',
+function($rootScope, $state, $location, $document, $animate, $ionicPlatform, $ionicViewService) {
// init the variables that keep track of the view history
$rootScope.$viewHistory = {
@@ -18,6 +23,13 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform'])
disabledRegistrableTagNames: []
};
+ // set that these directives should not animate when transitioning
+ // to it. Instead, the children directives would animate
+ if ($ionicViewService.disableRegisterByTagName) {
+ $ionicViewService.disableRegisterByTagName('ion-tabs');
+ $ionicViewService.disableRegisterByTagName('ion-side-menus');
+ }
+
$rootScope.$on('viewState.changeHistory', function(e, data) {
if(!data) return;
@@ -71,9 +83,14 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform'])
}])
-.factory('$ionicViewService', ['$rootScope', '$state', '$location', '$window', '$injector',
- function( $rootScope, $state, $location, $window, $injector) {
- var $animate = $injector.has('$animate') ? $injector.get('$animate') : false;
+.factory('$ionicViewService', [
+ '$rootScope',
+ '$state',
+ '$location',
+ '$window',
+ '$injector',
+ '$animate',
+function($rootScope, $state, $location, $window, $injector, $animate) {
var View = function(){};
View.prototype.initialize = function(data) {
@@ -412,11 +429,7 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform'])
var doAnimation;
// climb up the DOM and see which animation classname to use, if any
- var animationClass = angular.isDefined(navViewScope.$nextAnimation) ?
- navViewScope.$nextAnimation :
- getParentAnimationClass(navViewElement[0]);
-
- navViewScope.$nextAnimation = undefined;
+ var animationClass = getParentAnimationClass(navViewElement[0]);
function getParentAnimationClass(el) {
var className = '';
diff --git a/js/controllers/navController.js b/js/controllers/navController.js
deleted file mode 100644
index 29460f5670..0000000000
--- a/js/controllers/navController.js
+++ /dev/null
@@ -1,152 +0,0 @@
-(function(ionic) {
-'use strict';
-
-/**
- * The NavController makes it easy to have a stack
- * of views or screens that can be pushed and popped
- * for a dynamic navigation flow. This API is modelled
- * off of the UINavigationController in iOS.
- *
- * The NavController can drive a nav bar to show a back button
- * if the stack can be poppped to go back to the last view, and
- * it will handle updating the title of the nav bar and processing animations.
- */
-ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
- initialize: function(opts) {
- var _this = this;
-
- this.navBar = opts.navBar;
- this.content = opts.content;
- this.controllers = opts.controllers || [];
-
- this._updateNavBar();
-
- // TODO: Is this the best way?
- this.navBar.shouldGoBack = function() {
- _this.pop();
- };
- },
-
- /**
- * @return {array} the array of controllers on the stack.
- */
- getControllers: function() {
- return this.controllers;
- },
-
- /**
- * @return {object} the controller at the top of the stack.
- */
- getTopController: function() {
- return this.controllers[this.controllers.length-1];
- },
-
- /**
- * Push a new controller onto the navigation stack. The new controller
- * will automatically become the new visible view.
- *
- * @param {object} controller the controller to push on the stack.
- */
- push: function(controller) {
- var last = this.controllers[this.controllers.length - 1];
-
- this.controllers.push(controller);
-
- // Indicate we are switching controllers
- var shouldSwitch = this.switchingController && this.switchingController(controller) || true;
-
- // Return if navigation cancelled
- if(shouldSwitch === false)
- return;
-
- // Actually switch the active controllers
- if(last) {
- last.isVisible = false;
- last.visibilityChanged && last.visibilityChanged('push');
- }
-
- // Grab the top controller on the stack
- var next = this.controllers[this.controllers.length - 1];
-
- next.isVisible = true;
- // Trigger visibility change, but send 'first' if this is the first page
- next.visibilityChanged && next.visibilityChanged(last ? 'push' : 'first');
-
- this._updateNavBar();
-
- return controller;
- },
-
- /**
- * Pop the top controller off the stack, and show the last one. This is the
- * "back" operation.
- *
- * @return {object} the last popped controller
- */
- pop: function() {
- var next, last;
-
- // Make sure we keep one on the stack at all times
- if(this.controllers.length < 2) {
- return;
- }
-
- // Grab the controller behind the top one on the stack
- last = this.controllers.pop();
- if(last) {
- last.isVisible = false;
- last.visibilityChanged && last.visibilityChanged('pop');
- }
-
- // Remove the old one
- //last && last.detach();
-
- next = this.controllers[this.controllers.length - 1];
-
- // TODO: No DOM stuff here
- //this.content.el.appendChild(next.el);
- next.isVisible = true;
- next.visibilityChanged && next.visibilityChanged('pop');
-
- // Switch to it (TODO: Animate or such things here)
-
- this._updateNavBar();
-
- return last;
- },
-
- /**
- * Show the NavBar (if any)
- */
- showNavBar: function() {
- if(this.navBar) {
- this.navBar.show();
- }
- },
-
- /**
- * Hide the NavBar (if any)
- */
- hideNavBar: function() {
- if(this.navBar) {
- this.navBar.hide();
- }
- },
-
- // Update the nav bar after a push or pop
- _updateNavBar: function() {
- if(!this.getTopController() || !this.navBar) {
- return;
- }
-
- this.navBar.setTitle(this.getTopController().title);
-
- if(this.controllers.length > 1) {
- this.navBar.showBackButton(true);
- } else {
- this.navBar.showBackButton(false);
- }
- }
-});
-
-})(window.ionic);
diff --git a/js/controllers/tabBarController.js b/js/controllers/tabBarController.js
deleted file mode 100644
index 5144b196d9..0000000000
--- a/js/controllers/tabBarController.js
+++ /dev/null
@@ -1,143 +0,0 @@
-(function(ionic) {
-'use strict';
-
-/**
- * The TabBarController handles a set of view controllers powered by a tab strip
- * at the bottom (or possibly top) of a screen.
- *
- * The API here is somewhat modelled off of UITabController in the sense that the
- * controllers actually define what the tab will look like (title, icon, etc.).
- *
- * Tabs shouldn't be interacted with through your own code. Instead, use the controller
- * methods which will power the tab bar.
- */
-ionic.controllers.TabBarController = ionic.controllers.ViewController.inherit({
- initialize: function(options) {
- this.tabBar = options.tabBar;
-
- this._bindEvents();
-
- this.controllers = [];
-
- var controllers = options.controllers || [];
-
- for(var i = 0; i < controllers.length; i++) {
- this.addController(controllers[i]);
- }
-
- // Bind or set our tabWillChange callback
- this.controllerWillChange = options.controllerWillChange || function(controller) {};
- this.controllerChanged = options.controllerChanged || function(controller) {};
-
- // Try to select the first controller if we have one
- this.setSelectedController(0);
- },
- // Start listening for events on our tab bar
- _bindEvents: function() {
- var _this = this;
-
- this.tabBar.tryTabSelect = function(index) {
- _this.setSelectedController(index);
- };
- },
-
-
- selectController: function(index) {
- var shouldChange = true;
-
- // Check if we should switch to this tab. This lets the app
- // cancel tab switches if the context isn't right, for example.
- if(this.controllerWillChange) {
- if(this.controllerWillChange(this.controllers[index], index) === false) {
- shouldChange = false;
- }
- }
-
- if(shouldChange) {
- this.setSelectedController(index);
- }
- },
-
- // Force the selection of a controller at the given index
- setSelectedController: function(index) {
- if(index >= this.controllers.length) {
- return;
- }
- var lastController = this.selectedController;
- var lastIndex = this.selectedIndex;
-
- this.selectedController = this.controllers[index];
- this.selectedIndex = index;
-
- this._showController(index);
- this.tabBar.setSelectedItem(index);
-
- this.controllerChanged && this.controllerChanged(lastController, lastIndex, this.selectedController, this.selectedIndex);
- },
-
- _showController: function(index) {
- var c;
-
- for(var i = 0, j = this.controllers.length; i < j; i ++) {
- c = this.controllers[i];
- //c.detach && c.detach();
- c.isVisible = false;
- c.visibilityChanged && c.visibilityChanged();
- }
-
- c = this.controllers[index];
- //c.attach && c.attach();
- c.isVisible = true;
- c.visibilityChanged && c.visibilityChanged();
- },
-
- _clearSelected: function() {
- this.selectedController = null;
- this.selectedIndex = -1;
- },
-
- // Return the tab at the given index
- getController: function(index) {
- return this.controllers[index];
- },
-
- // Return the current tab list
- getControllers: function() {
- return this.controllers;
- },
-
- // Get the currently selected controller
- getSelectedController: function() {
- return this.selectedController;
- },
-
- // Get the index of the currently selected controller
- getSelectedControllerIndex: function() {
- return this.selectedIndex;
- },
-
- // Add a tab
- addController: function(controller) {
- this.controllers.push(controller);
-
- this.tabBar.addItem({
- title: controller.title,
- icon: controller.icon,
- badge: controller.badge
- });
-
- // If we don't have a selected controller yet, select the first one.
- if(!this.selectedController) {
- this.setSelectedController(0);
- }
- },
-
- // Set the tabs and select the first
- setControllers: function(controllers) {
- this.controllers = controllers;
- this._clearSelected();
- this.selectController(0);
- },
-});
-
-})(window.ionic);
diff --git a/js/ext/angular/src/directive/ionicContent.js b/js/ext/angular/src/directive/ionicContent.js
deleted file mode 100644
index 8c7f65b9c4..0000000000
--- a/js/ext/angular/src/directive/ionicContent.js
+++ /dev/null
@@ -1,383 +0,0 @@
-(function() {
-'use strict';
-
-angular.module('ionic.ui.content', ['ionic.ui.scroll'])
-
-/**
- * Panel is a simple 100% width and height, fixed panel. It's meant for content to be
- * added to it, or animated around.
- */
-/**
- * @ngdoc directive
- * @name ionPane
- * @module ionic
- * @restrict E
- *
- * @description A simple container that fits content, with no side effects. Adds the 'pane' class to the element.
- */
-.directive('ionPane', function() {
- return {
- restrict: 'E',
- link: function(scope, element, attr) {
- element.addClass('pane');
- }
- };
-})
-
-/**
- * @ngdoc directive
- * @name ionContent
- * @module ionic
- * @delegate ionic.service:$ionicScrollDelegate
- * @restrict E
- *
- * @description
- * The ionContent directive provides an easy to use content area that can be configured
- * to use Ionic's custom Scroll View, or the built in overflow scrolling of the browser.
- *
- * While we recommend using the custom Scroll features in Ionic in most cases, sometimes
- * (for performance reasons) only the browser's native overflow scrolling will suffice,
- * and so we've made it easy to toggle between the Ionic scroll implementation and
- * overflow scrolling.
- *
- * You can implement pull-to-refresh with the {@link ionic.directive:ionRefresher}
- * directive, and infinite scrolling with the {@link ionic.directive:ionInfiniteScroll}
- * directive.
- *
- * @param {string=} delegate-handle The handle used to identify this scrollView
- * with {@link ionic.service:$ionicScrollDelegate}.
- * @param {boolean=} padding Whether to add padding to the content.
- * of the content. Defaults to true on iOS, false on Android.
- * @param {boolean=} scroll Whether to allow scrolling of content. Defaults to true.
- * @param {boolean=} overflow-scroll Whether to use overflow-scrolling instead of
- * Ionic scroll.
- * @param {boolean=} has-bouncing Whether to allow scrolling to bounce past the edges
- * of the content. Defaults to true on iOS, false on Android.
- * @param {expression=} on-scroll Expression to evaluate when the content is scrolled.
- * @param {expression=} on-scroll-complete Expression to evaluate when a scroll action completes.
- */
-.directive('ionContent', [
- '$timeout',
- '$controller',
- '$ionicBind',
-function($timeout, $controller, $ionicBind) {
- return {
- restrict: 'E',
- require: '^?ionNavView',
- scope: true,
- compile: function(element, attr) {
- var innerElement;
-
- element.addClass('scroll-content');
-
- if (attr.scroll != 'false') {
- //We cannot use normal transclude here because it breaks element.data()
- //inheritance on compile
- innerElement = angular.element('');
- innerElement.append(element.contents());
- element.append(innerElement);
- }
-
- return { pre: prelink };
- function prelink($scope, $element, $attr, navViewCtrl) {
- var parentScope = $scope.$parent;
- $scope.$watch(function() {
- return (parentScope.$hasHeader ? ' has-header' : '') +
- (parentScope.$hasSubheader ? ' has-subheader' : '') +
- (parentScope.$hasFooter ? ' has-footer' : '') +
- (parentScope.$hasSubfooter ? ' has-subfooter' : '') +
- (parentScope.$hasTabs ? ' has-tabs' : '') +
- (parentScope.$hasTabsTop ? ' has-tabs-top' : '');
- }, function(className, oldClassName) {
- $element.removeClass(oldClassName);
- $element.addClass(className);
- });
-
- //Only this ionContent should use these variables from parent scopes
- $scope.$hasHeader = $scope.$hasSubheader =
- $scope.$hasFooter = $scope.$hasSubfooter =
- $scope.$hasTabs = $scope.$hasTabsTop =
- false;
-
- $ionicBind($scope, $attr, {
- $onScroll: '&onScroll',
- $onScrollComplete: '&onScrollComplete',
- hasBouncing: '@',
- scroll: '@',
- padding: '@',
- hasScrollX: '@',
- hasScrollY: '@',
- scrollbarX: '@',
- scrollbarY: '@',
- startX: '@',
- startY: '@',
- scrollEventInterval: '@'
- });
-
- if (angular.isDefined($attr.padding)) {
- $scope.$watch($attr.padding, function(newVal) {
- (innerElement || $element).toggleClass('padding', !!newVal);
- });
- }
-
- if ($scope.scroll === "false") {
- //do nothing
- } else if(attr.overflowScroll === "true") {
- $element.addClass('overflow-scroll');
- } else {
- $controller('$ionicScroll', {
- $scope: $scope,
- scrollViewOptions: {
- el: $element[0],
- delegateHandle: attr.delegateHandle,
- bouncing: $scope.$eval($scope.hasBouncing),
- startX: $scope.$eval($scope.startX) || 0,
- startY: $scope.$eval($scope.startY) || 0,
- scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
- scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
- scrollingX: $scope.$eval($scope.hasScrollX) === true,
- scrollingY: $scope.$eval($scope.hasScrollY) !== false,
- scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 20,
- scrollingComplete: function() {
- $scope.$onScrollComplete({
- scrollTop: this.__scrollTop,
- scrollLeft: this.__scrollLeft
- });
- }
- }
- });
- }
-
- }
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionRefresher
- * @module ionic
- * @restrict E
- * @parent ionic.directive:ionContent, ionic.directive:ionScroll
- * @description
- * Allows you to add pull-to-refresh to a scrollView.
- *
- * Place it as the first child of your {@link ionic.directive:ionContent} or
- * {@link ionic.directive:ionScroll} element.
- *
- * When refreshing is complete, $broadcast the 'scroll.refreshComplete' event
- * from your controller.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- *
- *
- *
- *
- * ```
- * ```js
- * angular.module('testApp', ['ionic'])
- * .controller('MyController', function($scope, $http) {
- * $scope.items = [1,2,3];
- * $scope.doRefresh = function() {
- * $http.get('/new-items')
- * .success(function(newItems) {
- * $scope.items = newItems;
- * })
- * .finally(function() {
- * // Stop the ion-refresher from spinning
- * $scope.$broadcast('scroll.refreshComplete');
- * });
- * };
- * });
- * ```
- *
- * @param {expression=} on-refresh Called when the user pulls down enough and lets go
- * of the refresher.
- * @param {expression=} on-pulling Called when the user starts to pull down
- * on the refresher.
- * @param {string=} pulling-icon The icon to display while the user is pulling down.
- * Default: 'ion-arrow-down-c'.
- * @param {string=} pulling-text The text to display while the user is pulling down.
- * @param {string=} refreshing-icon The icon to display after user lets go of the
- * refresher.
- * @param {string=} refreshing-text The text to display after the user lets go of
- * the refresher.
- *
- */
-.directive('ionRefresher', ['$ionicBind', function($ionicBind) {
- return {
- restrict: 'E',
- replace: true,
- require: '^$ionicScroll',
- template:
- '
' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '
' +
- '
',
- compile: function($element, $attrs) {
- if (angular.isUndefined($attrs.pullingIcon)) {
- $attrs.$set('pullingIcon', 'ion-arrow-down-c');
- }
- if (angular.isUndefined($attrs.refreshingIcon)) {
- $attrs.$set('refreshingIcon', 'ion-loading-d');
- }
- return function($scope, $element, $attrs, scrollCtrl) {
- $ionicBind($scope, $attrs, {
- pullingIcon: '@',
- pullingText: '@',
- refreshingIcon: '@',
- refreshingText: '@',
- $onRefresh: '&onRefresh',
- $onPulling: '&onPulling'
- });
-
- scrollCtrl._setRefresher($scope, $element[0]);
- $scope.$on('scroll.refreshComplete', function() {
- $element[0].classList.remove('active');
- scrollCtrl.scrollView.finishPullToRefresh();
- });
- };
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionInfiniteScroll
- * @module ionic
- * @parent ionic.directive:ionContent, ionic.directive:ionScroll
- * @restrict E
- *
- * @description
- * The ionInfiniteScroll directive allows you to call a function whenever
- * the user gets to the bottom of the page or near the bottom of the page.
- *
- * The expression you pass in for `on-infinite` is called when the user scrolls
- * greater than `distance` away from the bottom of the content.
- *
- * @param {expression} on-infinite What to call when the scroller reaches the
- * bottom.
- * @param {string=} distance The distance from the bottom that the scroll must
- * reach to trigger the on-infinite expression. Default: 1%.
- * @param {string=} icon The icon to show while loading. Default: 'ion-loading-d'.
- *
- * @usage
- * ```html
- *
- *
- *
- *
- * ```
- * ```js
- * function MyController($scope, $http) {
- * $scope.items = [];
- * $scope.loadMore = function() {
- * $http.get('/more-items').success(function(items) {
- * useItems(items);
- * $scope.$broadcast('scroll.infiniteScrollComplete');
- * });
- * };
- * }
- * ```
- *
- * An easy to way to stop infinite scroll once there is no more data to load
- * is to use angular's `ng-if` directive:
- *
- * ```html
- *
- *
- * ```
- */
-.directive('ionInfiniteScroll', ['$timeout', function($timeout) {
- function calculateMaxValue(distance, maximum, isPercent) {
- return isPercent ?
- maximum * (1 - parseInt(distance,10) / 100) :
- maximum - parseInt(distance, 10);
- }
- return {
- restrict: 'E',
- require: ['^$ionicScroll', 'ionInfiniteScroll'],
- template:
- '
';
-
- angular.module('ionic.ui.list', ['ngAnimate'])
-
- /**
- * @ngdoc service
- * @name $ionicListDelegate
- * @module ionic
- *
- * @description
- * Delegate for controlling the {@link ionic.directive:ionList} directive.
- *
- * Methods called directly on the $ionicListDelegate service will control all lists.
- * Use the {@link ionic.service:$ionicListDelegate#$getByHandle $getByHandle}
- * method to control specific ionList instances.
- *
- * @usage
- *
- * ````html
- *
- *
- *
- * >
- * {% raw %}Hello, {{i}}!{% endraw %}
- *
- *
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicListDelegate) {
- * $scope.showDeleteButtons = function() {
- * $ionicListDelegate.showDelete(true);
- * };
- * }
- * ```
- */
- .service('$ionicListDelegate', delegateService([
- /**
- * @ngdoc method
- * @name $ionicListDelegate#showReorder
- * @param {boolean=} showReorder Set whether or not this list is showing its reorder buttons.
- * @returns {boolean} Whether the reorder buttons are shown.
- */
- 'showReorder',
- /**
- * @ngdoc method
- * @name $ionicListDelegate#showDelete
- * @param {boolean=} showReorder Set whether or not this list is showing its delete buttons.
- * @returns {boolean} Whether the delete buttons are shown.
- */
- 'showDelete',
- /**
- * @ngdoc method
- * @name $ionicListDelegate#canSwipeItems
- * @param {boolean=} showReorder Set whether or not this list is able to swipe to show
- * option buttons.
- * @returns {boolean} Whether the list is able to swipe to show option buttons.
- */
- 'canSwipeItems',
- /**
- * @ngdoc method
- * @name $ionicListDelegate#closeOptionButtons
- * @description Closes any option buttons on the list that are swiped open.
- */
- 'closeOptionButtons',
- /**
- * @ngdoc method
- * @name $ionicListDelegate#$getByHandle
- * @param {string} handle
- * @returns `delegateInstance` A delegate instance that controls only the
- * {@link ionic.directive:ionList} directives with `delegate-handle` matching
- * the given handle.
- *
- * Example: `$ionicListDelegate.$getByHandle('my-handle').showReorder(true);`
- */
- ]))
-
- .controller('$ionicList', [
- '$scope',
- '$attrs',
- '$parse',
- '$ionicListDelegate',
- function($scope, $attrs, $parse, $ionicListDelegate) {
-
- var isSwipeable = true;
- var isReorderShown = false;
- var isDeleteShown = false;
-
- var deregisterInstance = $ionicListDelegate._registerInstance(this, $attrs.delegateHandle);
- $scope.$on('$destroy', deregisterInstance);
-
- this.showReorder = function(show) {
- if (arguments.length) {
- isReorderShown = !!show;
- }
- return isReorderShown;
- };
-
- this.showDelete = function(show) {
- if (arguments.length) {
- isDeleteShown = !!show;
- }
- return isDeleteShown;
- };
-
- this.canSwipeItems = function(can) {
- if (arguments.length) {
- isSwipeable = !!can;
- }
- return isSwipeable;
- };
-
- this.closeOptionButtons = function() {
- this.listView && this.listView.clearDragEffects();
- };
- }])
-
-/**
- * @ngdoc directive
- * @name ionList
- * @module ionic
- * @delegate ionic.service:$ionicListDelegate
- * @codepen JsHjf
- * @restrict E
- * @description
- * The List is a widely used interface element in almost any mobile app, and can include
- * content ranging from basic text all the way to buttons, toggles, icons, and thumbnails.
- *
- * Both the list, which contains items, and the list items themselves can be any HTML
- * element. The containing element requires the `list` class and each list item requires
- * the `item` class.
- *
- * However, using the ionList and ionItem directives make it easy to support various
- * interaction modes such as swipe to edit, drag to reorder, and removing items.
- *
- * Related: {@link ionic.directive:ionItem}, {@link ionic.directive:ionOptionButton}
- * {@link ionic.directive:ionReorderButton}, {@link ionic.directive:ionDeleteButton}, [`list CSS documentation`](/docs/components/#list).
- *
- * @usage
- *
- * Basic Usage:
- *
- * ```html
- *
- *
- * {% raw %}Hello, {{item}}!{% endraw %}
- *
- *
- * ```
- *
- * Advanced Usage: Thumbnails, Delete buttons, Reordering, Swiping
- *
- * ```html
- *
- *
- *
- * {% raw %}
- *
{{item.title}}
- *
{{item.description}}
{% endraw %}
- *
- * Share
- *
- *
- * Edit
- *
- *
- *
- *
- *
- *
- *
- *
- * ```
- *
- * @param {string=} delegate-handle The handle used to identify this list with
- * {@link ionic.service:$ionicListDelegate}.
- * @param show-delete {boolean=} Whether the delete buttons for the items in the list are
- * currently shown or hidden.
- * @param show-reorder {boolean=} Whether the reorder buttons for the items in the list are
- * currently shown or hidden.
- * @param can-swipe {boolean=} Whether the items in the list are allowed to be swiped to reveal
- * option buttons. Default: true.
- */
-.directive('ionList', [
- '$animate',
- '$timeout',
-function($animate, $timeout) {
- return {
- restrict: 'E',
- require: ['ionList', '^?$ionicScroll'],
- controller: '$ionicList',
- compile: function($element, $attr) {
- var listEl = angular.element('
')
- .append( $element.contents() );
- $element.append(listEl);
-
- return function($scope, $element, $attrs, ctrls) {
- var listCtrl = ctrls[0];
- var scrollCtrl = ctrls[1];
-
- //Wait for child elements to render...
- $timeout(init);
-
- function init() {
- var listView = listCtrl.listView = new ionic.views.ListView({
- el: $element[0],
- listEl: $element.children()[0],
- scrollEl: scrollCtrl && scrollCtrl.element,
- scrollView: scrollCtrl && scrollCtrl.scrollView,
- onReorder: function(el, oldIndex, newIndex) {
- var itemScope = angular.element(el).scope();
- if (itemScope && itemScope.$onReorder) {
- itemScope.$onReorder(oldIndex, newIndex);
- }
- },
- canSwipe: function() {
- return listCtrl.canSwipeItems();
- }
- });
-
- if (angular.isDefined($attr.canSwipe)) {
- $scope.$watch('!!(' + $attr.canSwipe + ')', function(value) {
- listCtrl.canSwipeItems(value);
- });
- }
-
- if (angular.isDefined($attr.showDelete)) {
- $scope.$watch('!!(' + $attr.showDelete + ')', function(value) {
- listCtrl.showDelete(value);
- });
- }
- if (angular.isDefined($attr.showReorder)) {
- $scope.$watch('!!(' + $attr.showReorder + ')', function(value) {
- listCtrl.showReorder(value);
- });
- }
-
- $scope.$watch(function() {
- return listCtrl.showDelete();
- }, function(isShown, wasShown) {
- //Only use isShown=false if it was already shown
- if (!isShown && !wasShown) { return; }
-
- if (isShown) listCtrl.closeOptionButtons();
-
- $element.children().toggleClass('list-left-editing', isShown);
- toggleNgHide('.item-delete.item-left-edit', isShown);
- });
- $scope.$watch(function() {
- return listCtrl.showReorder();
- }, function(isShown, wasShown) {
- //Only use isShown=false if it was already shown
- if (!isShown && !wasShown) { return; }
-
- if (isShown) listCtrl.closeOptionButtons();
- listCtrl.showReorder(isShown);
-
- $element.children().toggleClass('list-right-editing', isShown);
- toggleNgHide('.item-reorder.item-right-edit', isShown);
- });
-
- function toggleNgHide(selector, shouldShow) {
- angular.forEach($element[0].querySelectorAll(selector), function(node) {
- if (shouldShow) $animate.removeClass(angular.element(node), 'ng-hide');
- else $animate.addClass(angular.element(node), 'ng-hide');
- });
- }
- }
-
- };
- }
- };
-}])
-
-.controller('$ionicItem', [
- '$scope',
- '$element',
-function($scope, $element) {
- this.$element = $element;
- this.$scope = $scope;
-}])
-
-/**
- * @ngdoc directive
- * @name ionItem
- * @parent ionic.directive:ionList
- * @module ionic
- * @restrict E
- * Creates a list-item that can easily be swiped,
- * deleted, reordered, edited, and more.
- *
- * See {@link ionic.directive:ionList} for a complete example & explanation.
- *
- * Can be assigned any item class name. See the
- * [list CSS documentation](/docs/components/#list).
- *
- * @usage
- *
- * ```html
- *
- * Hello!
- *
- * ```
- */
-.directive('ionItem', ['$animate', '$compile', function($animate, $compile) {
- return {
- restrict: 'E',
- controller: '$ionicItem',
- priorty: Number.MAX_VALUE,
- require: ['ionItem', '^ionList'],
- scope: true,
- compile: function($element, $attrs) {
- var isAnchor = angular.isDefined($attrs.href) || angular.isDefined($attrs.ngHref);
- var isComplexItem = isAnchor ||
- //Lame way of testing, but we have to know at compile what to do with the element
- /ion-(delete|option|reorder)-button/.test($element.html());
-
- if (isComplexItem) {
- var innerElement = angular.element(isAnchor ? TPL_CONTENT_ANCHOR : TPL_CONTENT);
- innerElement.append($element.contents());
-
- $element.append(innerElement);
- $element.addClass('item item-complex');
- } else {
- $element.addClass('item');
- }
-
- return function link($scope, $element, $attrs) {
- $scope.$href = function() {
- return $attrs.href || $attrs.ngHref;
- };
- };
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionDeleteButton
- * @parent ionic.directive:ionItem
- * @module ionic
- * @restrict E
- * Creates a delete button inside a list item, that is visible when the
- * {@link ionic.directive:ionList ionList parent's} `show-delete` evaluates to true or
- * `$ionicListDelegate.showDelete(true)` is called.
- *
- * Takes any ionicon as a class.
- *
- * See {@link ionic.directive:ionList} for a complete example & explanation.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- * Hello, list item!
- *
- *
- *
- * Show Delete?
- *
- * ```
- */
-.directive('ionDeleteButton', [function() {
- return {
- restrict: 'E',
- require: '^ionItem',
- //Run before anything else, so we can move it before other directives process
- //its location (eg ngIf relies on the location of the directive in the dom)
- priority: Number.MAX_VALUE,
- compile: function($element, $attr) {
- //Add the classes we need during the compile phase, so that they stay
- //even if something else like ngIf removes the element and re-addss it
- $attr.$set('class', ($attr.class || '') + ' button icon button-icon', true);
- return function($scope, $element, $attr, itemCtrl) {
- var container = angular.element(TPL_DELETE_BUTTON);
- container.append($element);
- itemCtrl.$element.append(container).addClass('item-left-editable');
- };
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionReorderButton
- * @parent ionic.directive:ionItem
- * @module ionic
- * @restrict E
- * Creates a reorder button inside a list item, that is visible when the
- * {@link ionic.directive:ionList ionList parent's} `show-reorder` evaluates to true or
- * `$ionicListDelegate.showReorder(true)` is called.
- *
- * Can be dragged to reorder items in the list. Takes any ionicon class.
- *
- * When an item reorder is complete, the `on-reorder` callback given in the attribute is called
- * (see below).
- *
- * See {@link ionic.directive:ionList} for a complete example.
- *
- * @usage
- *
- * ```html
- *
- *
- * Item {{$index}}
- *
- *
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope) {
- * $scope.items = [1, 2, 3, 4];
- * $scope.moveItem = function(item, fromIndex, toIndex) {
- * //Move the item in the array
- * $scope.items.splice(fromIndex, 1);
- * $scope.items.splice(toIndex, 0, item);
- * };
- * }
- * ```
- *
- * @param {expression=} on-reorder Expression to call when an item is reordered.
- * Parameters given: $fromIndex, $toIndex.
- */
-.directive('ionReorderButton', [function() {
- return {
- restrict: 'E',
- require: '^ionItem',
- priority: Number.MAX_VALUE,
- compile: function($element, $attr) {
- $attr.$set('class', ($attr.class || '') + ' button icon button-icon', true);
- $element[0].setAttribute('data-prevent-scroll', true);
- return function($scope, $element, $attr, itemCtrl) {
- $scope.$onReorder = function(oldIndex, newIndex) {
- $scope.$eval($attr.onReorder, {
- $fromIndex: oldIndex,
- $toIndex: newIndex
- });
- };
-
- var container = angular.element(TPL_REORDER_BUTTON);
- container.append($element);
- itemCtrl.$element.append(container).addClass('item-right-editable');
- };
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionOptionButton
- * @parent ionic.directive:ionItem
- * @module ionic
- * @restrict E
- * Creates an option button inside a list item, that is visible when the item is swiped
- * to the left by the user. Swiped open option buttons can be hidden with
- * {@link ionic.directive:$ionicListDelegate#closeOptionButtons $ionicListDelegate#closeOptionButtons}.
- *
- * Can be assigned any button class.
- *
- * See {@link ionic.directive:ionList} for a complete example & explanation.
- *
- * @usage
- *
- * ```html
- *
- *
- * I love kittens!
- * Share
- * Edit
- *
- *
- * ```
- */
-.directive('ionOptionButton', ['$compile', function($compile) {
- return {
- restrict: 'E',
- require: '^ionItem',
- priority: Number.MAX_VALUE,
- compile: function($element, $attr) {
- $attr.$set('class', ($attr.class || '') + ' button', true);
- return function($scope, $element, $attr, itemCtrl) {
- if (!itemCtrl.optionsContainer) {
- itemCtrl.optionsContainer = angular.element(TPL_OPTION_BUTTONS);
- itemCtrl.$element.append(itemCtrl.optionsContainer);
- }
- itemCtrl.optionsContainer.append($element);
- };
- }
- };
-}]);
-
-})();
diff --git a/js/ext/angular/src/directive/ionicNavBar.js b/js/ext/angular/src/directive/ionicNavBar.js
deleted file mode 100644
index ce6119ba62..0000000000
--- a/js/ext/angular/src/directive/ionicNavBar.js
+++ /dev/null
@@ -1,491 +0,0 @@
-
-angular.module('ionic.ui.navBar', ['ionic.service.view', 'ngSanitize'])
-
-/**
- * @ngdoc service
- * @name $ionicNavBarDelegate
- * @module ionic
- * @description
- * Delegate for controlling the {@link ionic.directive:ionNavBar} directive.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicNavBarDelegate) {
- * $scope.setNavTitle = function(title) {
- * $ionicNavBarDelegate.setTitle(title);
- * }
- * }
- * ```
- */
-.service('$ionicNavBarDelegate', delegateService([
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#back
- * @description Goes back in the view history.
- * @param {DOMEvent=} event The event object (eg from a tap event)
- */
- 'back',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#align
- * @description Aligns the title with the buttons in a given direction.
- * @param {string=} direction The direction to the align the title text towards.
- * Available: 'left', 'right', 'center'. Default: 'center'.
- */
- 'align',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#showBackButton
- * @description
- * Set/get whether the {@link ionic.directive:ionNavBackButton} is shown
- * (if it exists).
- * @param {boolean=} show Whether to show the back button.
- * @returns {boolean} Whether the back button is shown.
- */
- 'showBackButton',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#showBar
- * @description
- * Set/get whether the {@link ionic.directive:ionNavBar} is shown.
- * @param {boolean} show Whether to show the bar.
- * @returns {boolean} Whether the bar is shown.
- */
- 'showBar',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#setTitle
- * @description
- * Set the title for the {@link ionic.directive:ionNavBar}.
- * @param {string} title The new title to show.
- */
- 'setTitle',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#changeTitle
- * @description
- * Change the title, transitioning the new title in and the old one out in a given direction.
- * @param {string} title The new title to show.
- * @param {string} direction The direction to transition the new title in.
- * Available: 'forward', 'back'.
- */
- 'changeTitle',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#getTitle
- * @returns {string} The current title of the navbar.
- */
- 'getTitle',
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#getPreviousTitle
- * @returns {string} The previous title of the navbar.
- */
- 'getPreviousTitle'
- /**
- * @ngdoc method
- * @name $ionicNavBarDelegate#$getByHandle
- * @param {string} handle
- * @returns `delegateInstance` A delegate instance that controls only the
- * navBars with delegate-handle matching the given handle.
- *
- * Example: `$ionicNavBarDelegate.$getByHandle('myHandle').setTitle('newTitle')`
- */
-]))
-
-.controller('$ionicNavBar', [
- '$scope',
- '$element',
- '$attrs',
- '$ionicViewService',
- '$animate',
- '$compile',
- '$ionicNavBarDelegate',
-function($scope, $element, $attrs, $ionicViewService, $animate, $compile, $ionicNavBarDelegate) {
- //Let the parent know about our controller too so that children of
- //sibling content elements can know about us
- $element.parent().data('$ionNavBarController', this);
-
- var deregisterInstance = $ionicNavBarDelegate._registerInstance(this, $attrs.delegateHandle);
-
- $scope.$on('$destroy', deregisterInstance);
-
- var self = this;
-
- this.leftButtonsElement = angular.element(
- $element[0].querySelector('.buttons.left-buttons')
- );
- this.rightButtonsElement = angular.element(
- $element[0].querySelector('.buttons.right-buttons')
- );
-
- this.back = function(e) {
- var backView = $ionicViewService.getBackView();
- backView && backView.go();
- e && (e.alreadyHandled = true);
- return false;
- };
-
- this.align = function(direction) {
- this._headerBarView.align(direction);
- };
-
- this.showBackButton = function(show) {
- if (arguments.length) {
- $scope.backButtonShown = !!show;
- }
- return !!($scope.hasBackButton && $scope.backButtonShown);
- };
-
- this.showBar = function(show) {
- if (arguments.length) {
- $scope.isInvisible = !show;
- $scope.$parent.$hasHeader = !!show;
- }
- return !$scope.isInvisible;
- };
-
- this.setTitle = function(title) {
- $scope.oldTitle = $scope.title;
- $scope.title = title || '';
- };
-
- this.changeTitle = function(title, direction) {
- if ($scope.title === title) {
- return false;
- }
- this.setTitle(title);
- $scope.isReverse = direction == 'back';
- $scope.shouldAnimate = !!direction;
-
- if (!$scope.shouldAnimate) {
- //We're done!
- this._headerBarView.align();
- } else {
- this._animateTitles();
- }
- return true;
- };
-
- this.getTitle = function() {
- return $scope.title || '';
- };
-
- this.getPreviousTitle = function() {
- return $scope.oldTitle || '';
- };
-
- /**
- * Exposed for testing
- */
- this._animateTitles = function() {
- var oldTitleEl, newTitleEl, currentTitles;
-
- //If we have any title right now
- //(or more than one, they could be transitioning on switch),
- //replace the first one with an oldTitle element
- currentTitles = $element[0].querySelectorAll('.title');
- if (currentTitles.length) {
- oldTitleEl = $compile('')($scope);
- angular.element(currentTitles[0]).replaceWith(oldTitleEl);
- }
- //Compile new title
- newTitleEl = $compile('')($scope);
-
- //Animate in on next frame
- ionic.requestAnimationFrame(function() {
-
- oldTitleEl && $animate.leave(angular.element(oldTitleEl));
-
- var insert = oldTitleEl && angular.element(oldTitleEl) || null;
- $animate.enter(newTitleEl, $element, insert, function() {
- self._headerBarView.align();
- });
-
- //Cleanup any old titles leftover (besides the one we already did replaceWith on)
- angular.forEach(currentTitles, function(el) {
- if (el && el.parentNode) {
- //Use .remove() to cleanup things like .data()
- angular.element(el).remove();
- }
- });
-
- //$apply so bindings fire
- $scope.$digest();
-
- //Stop flicker of new title on ios7
- ionic.requestAnimationFrame(function() {
- newTitleEl[0].classList.remove('invisible');
- });
- });
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionNavBar
- * @module ionic
- * @delegate ionic.service:$ionicNavBarDelegate
- * @restrict E
- *
- * @description
- * If we have an {@link ionic.directive:ionNavView} directive, we can also create an
- * ``, which will create a topbar that updates as the application state changes.
- *
- * We can add a back button by putting an {@link ionic.directive:ionNavBackButton} inside.
- *
- * We can add buttons depending on the currently visible view using
- * {@link ionic.directive:ionNavButtons}.
- *
- * Assign an [animation class](/docs/components#animations) to the element to
- * enable animated changing of titles (recommended: 'nav-title-slide-ios7')
- *
- * @usage
- *
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- * ```
- *
- * @param {string=} delegate-handle The handle used to identify this navBar
- * with {@link ionic.service:$ionicNavBarDelegate}.
- * @param align-title {string=} Where to align the title of the navbar.
- * Available: 'left', 'right', 'center'. Defaults to 'center'.
- */
-.directive('ionNavBar', ['$ionicViewService', '$rootScope', '$animate', '$compile',
-function($ionicViewService, $rootScope, $animate, $compile) {
-
- return {
- restrict: 'E',
- controller: '$ionicNavBar',
- scope: true,
- compile: function(tElement, tAttrs) {
- //We cannot transclude here because it breaks element.data() inheritance on compile
- tElement
- .addClass('bar bar-header nav-bar')
- .append(
- '
' +
- '
' +
- '' +
- '
' +
- '
'
- );
-
- return { pre: prelink };
- function prelink($scope, $element, $attr, navBarCtrl) {
- navBarCtrl._headerBarView = new ionic.views.HeaderBar({
- el: $element[0],
- alignTitle: $attr.alignTitle || 'center'
- });
-
- //defaults
- $scope.backButtonShown = false;
- $scope.shouldAnimate = true;
- $scope.isReverse = false;
- $scope.isInvisible = true;
-
- $scope.$on('$destroy', function() {
- $scope.$parent.$hasHeader = false;
- });
-
- $scope.$watch(function() {
- return ($scope.isReverse ? ' reverse' : '') +
- ($scope.isInvisible ? ' invisible' : '') +
- (!$scope.shouldAnimate ? ' no-animation' : '');
- }, function(className, oldClassName) {
- $element.removeClass(oldClassName);
- $element.addClass(className);
- });
-
- }
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionNavBackButton
- * @module ionic
- * @restrict E
- * @parent ionNavBar
- * @description
- * Creates a back button inside an {@link ionic.directive:ionNavBar}.
- *
- * Will show up when the user is able to go back in the current navigation stack.
- *
- * By default, will go back when clicked. If you wish for more advanced behavior, see the
- * examples below.
- *
- * @usage
- *
- * With default click action:
- *
- * ```html
- *
- *
- * Back!
- *
- *
- * ```
- *
- * With custom click action, using {@link ionic.service:$ionicNavBarDelegate}:
- *
- * ```html
- *
- *
- * Back
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicNavBarDelegate) {
- * $scope.goBack = function() {
- * $ionicNavBarDelegate.back();
- * };
- * }
- * ```
- *
- * Displaying the previous title on the back button, again using
- * {@link ionic.service:$ionicNavBarDelegate}.
- *
- * ```html
- *
- *
- * {% raw %}{{getPreviousTitle() || 'Back'}}{% endraw %}
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicNavBarDelegate) {
- * $scope.getPreviousTitle = function() {
- * return $ionicNavBarDelegate.getPreviousTitle();
- * };
- * }
- * ```
- */
-.directive('ionNavBackButton', [
- '$ionicNgClick',
- '$animate',
-function($ionicNgClick, $animate) {
- return {
- restrict: 'E',
- require: '^ionNavBar',
- compile: function(tElement, tAttrs) {
- tElement.addClass('button back-button ng-hide');
- return function($scope, $element, $attr, navBarCtrl) {
- if (!$attr.ngClick) {
- $scope.$navBack = navBarCtrl.back;
- $ionicNgClick($scope, $element, '$navBack($event)');
- }
-
- //If the current viewstate does not allow a back button,
- //always hide it.
- var deregisterListener = $scope.$parent.$on(
- '$viewHistory.historyChange',
- function(e, data) {
- $scope.hasBackButton = !!data.showBack;
- }
- );
- $scope.$on('$destroy', deregisterListener);
-
- //Make sure both that a backButton is allowed in the first place,
- //and that it is shown by the current view.
- $scope.$watch('!!(backButtonShown && hasBackButton)', ionic.animationFrameThrottle(function(show) {
- if (show) $animate.removeClass($element, 'ng-hide');
- else $animate.addClass($element, 'ng-hide');
- }));
- };
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionNavButtons
- * @module ionic
- * @restrict E
- * @parent ionNavView
- *
- * @description
- * Use ionNavButtons to set the buttons on your {@link ionic.directive:ionNavBar}
- * from within an {@link ionic.directive:ionView}.
- *
- * Any buttons you declare will be placed onto the navbar's corresponding side,
- * and then destroyed when the user leaves their parent view.
- *
- * @usage
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- * Some super content here!
- *
- *
- *
- * ```
- *
- * @param {string} side The side to place the buttons on in the parent
- * {@link ionic.directive:ionNavBar}. Available: 'left' or 'right'.
- */
-.directive('ionNavButtons', ['$compile', '$animate', function($compile, $animate) {
- return {
- require: '^ionNavBar',
- restrict: 'E',
- compile: function($element, $attrs) {
- var content = $element.contents().remove();
- return function($scope, $element, $attrs, navBarCtrl) {
- var navElement = $attrs.side === 'right' ?
- navBarCtrl.rightButtonsElement :
- navBarCtrl.leftButtonsElement;
-
- //Put all of our inside buttons into their own span,
- //so we can remove them all when this element dies -
- //even if the buttons have changed through an ng-repeat or the like,
- //we just remove their div parent and they are gone.
- var buttons = angular.element('').append(content);
-
- //Compile buttons inside content so they have access to everything
- //something inside content does (eg parent ionicScroll)
- $element.append(buttons);
- $compile(buttons)($scope);
-
- //Append buttons to navbar
- $animate.enter(buttons, navElement);
-
- //When our ion-nav-buttons container is destroyed,
- //destroy everything in the navbar
- $scope.$on('$destroy', function() {
- $animate.leave(buttons);
- });
-
- // The original element is just a completely empty element.
- // make it invisible just to be sure it doesn't change any layout
- $element.css('display', 'none');
- };
- }
- };
-}]);
diff --git a/js/ext/angular/src/directive/ionicRadio.js b/js/ext/angular/src/directive/ionicRadio.js
deleted file mode 100644
index 9cc7576d27..0000000000
--- a/js/ext/angular/src/directive/ionicRadio.js
+++ /dev/null
@@ -1,130 +0,0 @@
-(function(ionic) {
-'use strict';
-
-angular.module('ionic.ui.radio', [])
-
-/**
- * @ngdoc directive
- * @name ionRadio
- * @module ionic
- * @restrict E
- * @codepen saoBG
- * @description
- * The radio directive is no different than the HTML radio input, except it's styled differently.
- *
- * Radio behaves like any [AngularJS radio](http://docs.angularjs.org/api/ng/input/input[radio]).
- *
- * @usage
- * ```html
- * Choose A
- * Choose B
- * Choose C
- * ```
- */
-.directive('ionRadio', function() {
- return {
- restrict: 'E',
- replace: true,
- require: '?ngModel',
- scope: {
- ngModel: '=?',
- ngValue: '=?',
- ngChange: '&',
- icon: '@'
- },
- transclude: true,
- template: '',
-
- compile: function(element, attr) {
- if(attr.name) element.children().eq(0).attr('name', attr.name);
- if(attr.icon) element.children().eq(2).removeClass('ion-checkmark').addClass(attr.icon);
- }
- };
-})
-
-// The radio button is a radio powered element with only
-// one possible selection in a set of options.
-.directive('ionRadioButtons', function() {
- return {
- restrict: 'E',
- replace: true,
- require: '?ngModel',
- scope: {
- value: '@'
- },
- transclude: true,
- template: '',
-
- controller: ['$scope', '$element', function($scope, $element) {
-
- this.select = function(element) {
- var c, children = $element.children();
- for(var i = 0; i < children.length; i++) {
- c = children[i];
- if(c != element[0]) {
- c.classList.remove('active');
- }
- }
- };
-
- }],
-
- link: function($scope, $element, $attr, ngModel) {
- var radio;
-
- if(ngModel) {
- //$element.bind('tap', tapHandler);
-
- ngModel.$render = function() {
- var children = $element.children();
- for(var i = 0; i < children.length; i++) {
- children[i].classList.remove('active');
- }
- $scope.$parent.$broadcast('radioButton.select', ngModel.$viewValue);
- };
- }
- }
- };
-})
-
-.directive('ionButtonRadio', function() {
- return {
- restrict: 'CA',
- require: ['?^ngModel', '?^ionRadioButtons'],
- link: function($scope, $element, $attr, ctrls) {
- var ngModel = ctrls[0];
- var radioButtons = ctrls[1];
- if(!ngModel || !radioButtons) { return; }
-
- var setIt = function() {
- $element.addClass('active');
- ngModel.$setViewValue($scope.$eval($attr.ngValue));
-
- radioButtons.select($element);
- };
-
- var clickHandler = function(e) {
- setIt();
- };
-
- $scope.$on('radioButton.select', function(e, val) {
- if(val == $scope.$eval($attr.ngValue)) {
- $element.addClass('active');
- }
- });
-
- ionic.on('tap', clickHandler, $element[0]);
-
- $scope.$on('$destroy', function() {
- ionic.off('tap', clickHandler);
- });
- }
- };
-});
-
-})(window.ionic);
diff --git a/js/ext/angular/src/directive/ionicSideMenu.js b/js/ext/angular/src/directive/ionicSideMenu.js
deleted file mode 100644
index 9c86f4c464..0000000000
--- a/js/ext/angular/src/directive/ionicSideMenu.js
+++ /dev/null
@@ -1,465 +0,0 @@
-(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', 'ionic.service.view'])
-
-/**
- * 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.
- */
-
-.run(['$ionicViewService', function($ionicViewService) {
- // set that the side-menus directive should not animate when transitioning to it
- $ionicViewService.disableRegisterByTagName('ion-side-menus');
-}])
-
-/**
- * @ngdoc service
- * @name $ionicSideMenuDelegate
- * @module ionic
- *
- * @description
- * Delegate for controlling the {@link ionic.directive:ionSideMenus} directive.
- *
- * Methods called directly on the $ionicSideMenuDelegate service will control all side
- * menus. Use the {@link ionic.service:$ionicSideMenuDelegate#$getByHandle $getByHandle}
- * method to control specific ionSideMenus instances.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- * Content!
- *
- *
- *
- * Left Menu!
- *
- *
- *
- * ```
- * ```js
- * function MainCtrl($scope, $ionicSideMenuDelegate) {
- * $scope.toggleLeftSideMenu = function() {
- * $ionicSideMenuDelegate.toggleLeft();
- * };
- * }
- * ```
- */
-.service('$ionicSideMenuDelegate', delegateService([
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#toggleLeft
- * @description Toggle the left side menu (if it exists).
- * @param {boolean=} isOpen Whether to open or close the menu.
- * Default: Toggles the menu.
- */
- 'toggleLeft',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#toggleRight
- * @description Toggle the right side menu (if it exists).
- * @param {boolean=} isOpen Whether to open or close the menu.
- * Default: Toggles the menu.
- */
- 'toggleRight',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#getOpenRatio
- * @description Gets the ratio of open amount over menu width. For example, a
- * menu of width 100 that is opened by 50 pixels is 50% opened, and would return
- * a ratio of 0.5.
- *
- * @returns {float} 0 if nothing is open, between 0 and 1 if left menu is
- * opened/opening, and between 0 and -1 if right menu is opened/opening.
- */
- 'getOpenRatio',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#isOpen
- * @returns {boolean} Whether either the left or right menu is currently opened.
- */
- 'isOpen',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#isOpenLeft
- * @returns {boolean} Whether the left menu is currently opened.
- */
- 'isOpenLeft',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#isOpenRight
- * @returns {boolean} Whether the right menu is currently opened.
- */
- 'isOpenRight',
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#canDragContent
- * @param {boolean=} canDrag Set whether the content can or cannot be dragged to open
- * side menus.
- * @returns {boolean} Whether the content can be dragged to open side menus.
- */
- 'canDragContent'
- /**
- * @ngdoc method
- * @name $ionicSideMenuDelegate#$getByHandle
- * @param {string} handle
- * @returns `delegateInstance` A delegate instance that controls only the
- * {@link ionic.directive:ionSideMenus} directives with `delegate-handle` matching
- * the given handle.
- *
- * Example: `$ionicSideMenuDelegate.$getByHandle('my-handle').toggleLeft();`
- */
-]))
-
-/**
- * @ngdoc directive
- * @name ionSideMenus
- * @module ionic
- * @delegate ionic.service:$ionicSideMenuDelegate
- * @restrict E
- *
- * @description
- * A container element for side menu(s) and the main content. Allows the left
- * and/or right side menu to be toggled by dragging the main content area side
- * to side.
- *
- * 
- *
- * For more information on side menus, check out the documenation for
- * {@link ionic.directive:ionSideMenuContent} and
- * {@link ionic.directive:ionSideMenu}.
- *
- * @usage
- * To use side menus, add an `` parent element,
- * an `` for the center content,
- * and one or more `` directives.
- *
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * ```
- * ```js
- * function ContentController($scope, $ionicSideMenuDelegate) {
- * $scope.toggleLeft = function() {
- * $ionicSideMenuDelegate.toggleLeft();
- * };
- * }
- * ```
- *
- * @param {string=} delegate-handle The handle used to identify this side menu
- * with {@link ionic.service:$ionicSideMenuDelegate}.
- *
- */
-.directive('ionSideMenus', function() {
- return {
- restrict: 'ECA',
- controller: ['$scope', '$attrs', '$ionicSideMenuDelegate', function($scope, $attrs, $ionicSideMenuDelegate) {
- angular.extend(this, ionic.controllers.SideMenuController.prototype);
-
- ionic.controllers.SideMenuController.call(this, {
- left: { width: 275 },
- right: { width: 275 }
- });
-
- this.canDragContent = function(canDrag) {
- if (arguments.length) {
- $scope.dragContent = !!canDrag;
- }
- return $scope.dragContent;
- };
-
- this.isDraggableTarget = function(e) {
- return $scope.dragContent &&
- (!e.gesture.srcEvent.defaultPrevented &&
- !e.target.tagName.match(/input|textarea|select|object|embed/i) &&
- !e.target.isContentEditable &&
- !(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default') == 'true'));
- };
-
- $scope.sideMenuContentTranslateX = 0;
-
- var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
- this, $attrs.delegateHandle
- );
-
- $scope.$on('$destroy', deregisterInstance);
- }],
- replace: true,
- transclude: true,
- template: ''
- };
-})
-
-/**
- * @ngdoc directive
- * @name ionSideMenuContent
- * @module ionic
- * @restrict E
- * @parent ionic.directive:ionSideMenus
- *
- * @description
- * A container for the main visible content, sibling to one or more
- * {@link ionic.directive:ionSideMenu} directives.
- *
- * @usage
- * ```html
- *
- *
- * ```
- * For a complete side menu example, see the
- * {@link ionic.directive:ionSideMenus} documentation.
- *
- * @param {boolean=} drag-content Whether the content can be dragged. Default true.
- *
- */
-.directive('ionSideMenuContent', ['$timeout', '$ionicGesture', function($timeout, $ionicGesture) {
-
- return {
- restrict: 'EA', //DEPRECATED 'A'
- require: '^ionSideMenus',
- scope: true,
- compile: function(element, attr) {
- return { pre: prelink };
- function prelink($scope, $element, $attr, sideMenuCtrl) {
-
- $element.addClass('menu-content pane');
-
- if (angular.isDefined(attr.dragContent)) {
- $scope.$watch(attr.dragContent, function(value) {
- sideMenuCtrl.canDragContent(value);
- });
- } else {
- sideMenuCtrl.canDragContent(true);
- }
-
- var defaultPrevented = false;
- var isDragging = false;
-
- // Listen for taps on the content to close the menu
- function contentTap(e) {
- if(sideMenuCtrl.getOpenAmount() !== 0) {
- sideMenuCtrl.close();
- e.gesture.srcEvent.preventDefault();
- }
- }
- ionic.on('tap', contentTap, $element[0]);
-
- var dragFn = function(e) {
- if(defaultPrevented || !sideMenuCtrl.isDraggableTarget(e)) return;
- isDragging = true;
- sideMenuCtrl._handleDrag(e);
- e.gesture.srcEvent.preventDefault();
- };
-
- var dragVertFn = function(e) {
- if(isDragging) {
- e.gesture.srcEvent.preventDefault();
- }
- };
-
- //var dragGesture = Gesture.on('drag', dragFn, $element);
- var dragRightGesture = $ionicGesture.on('dragright', dragFn, $element);
- var dragLeftGesture = $ionicGesture.on('dragleft', dragFn, $element);
- var dragUpGesture = $ionicGesture.on('dragup', dragVertFn, $element);
- var dragDownGesture = $ionicGesture.on('dragdown', dragVertFn, $element);
-
- var dragReleaseFn = function(e) {
- isDragging = false;
- if(!defaultPrevented) {
- sideMenuCtrl._endDrag(e);
- }
- defaultPrevented = false;
- };
-
- var releaseGesture = $ionicGesture.on('release', dragReleaseFn, $element);
-
- sideMenuCtrl.setContent({
- onDrag: function(e) {},
- endDrag: function(e) {},
- getTranslateX: function() {
- return $scope.sideMenuContentTranslateX || 0;
- },
- setTranslateX: ionic.animationFrameThrottle(function(amount) {
- $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + amount + 'px, 0, 0)';
- $timeout(function() {
- $scope.sideMenuContentTranslateX = amount;
- });
- }),
- 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');
- }
- });
-
- // Cleanup
- $scope.$on('$destroy', function() {
- $ionicGesture.off(dragLeftGesture, 'dragleft', dragFn);
- $ionicGesture.off(dragRightGesture, 'dragright', dragFn);
- $ionicGesture.off(dragUpGesture, 'dragup', dragFn);
- $ionicGesture.off(dragDownGesture, 'dragdown', dragFn);
- $ionicGesture.off(releaseGesture, 'release', dragReleaseFn);
- ionic.off('tap', contentTap, $element[0]);
- });
- }
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionSideMenu
- * @module ionic
- * @restrict E
- * @parent ionic.directive:ionSideMenus
- *
- * @description
- * A container for a side menu, sibling to an {@link ionic.directive:ionSideMenuContent} directive.
- *
- * @usage
- * ```html
- *
- *
- * ```
- * For a complete side menu example, see the
- * {@link ionic.directive:ionSideMenus} documentation.
- *
- * @param {string} side Which side the side menu is currently on. Allowed values: 'left' or 'right'.
- * @param {boolean=} is-enabled Whether this side menu is enabled.
- * @param {number=} width How many pixels wide the side menu should be. Defaults to 275.
- */
-.directive('ionSideMenu', function() {
- return {
- restrict: 'E',
- require: '^ionSideMenus',
- scope: true,
- compile: function(element, attr) {
- angular.isUndefined(attr.isEnabled) && attr.$set('isEnabled', 'true');
- angular.isUndefined(attr.width) && attr.$set('width', '275');
-
- element.addClass('menu menu-' + attr.side);
-
- return function($scope, $element, $attr, sideMenuCtrl) {
- $scope.side = $attr.side || 'left';
-
- var sideMenu = sideMenuCtrl[$scope.side] = new ionic.views.SideMenu({
- width: 275,
- el: $element[0],
- isEnabled: true
- });
-
- $scope.$watch($attr.width, function(val) {
- var numberVal = +val;
- if (numberVal && numberVal == val) {
- sideMenu.setWidth(+val);
- }
- });
- $scope.$watch($attr.isEnabled, function(val) {
- sideMenu.setIsEnabled(!!val);
- });
- };
- }
- };
-})
-
-/**
- * @ngdoc directive
- * @name menuToggle
- * @module ionic
- * @restrict AC
- *
- * @description
- * Toggle a side menu on the given side
- *
- * @usage
- * Below is an example of a link within a nav bar. Tapping this link would
- * automatically open the given side menu
- *
- * ```html
- *
- *
- *
- *
- * ...
- *
- * ```
- */
-.directive('menuToggle', ['$ionicViewService', function($ionicViewService) {
- return {
- restrict: 'AC',
- require: '^ionSideMenus',
- link: function($scope, $element, $attr, sideMenuCtrl) {
- var side = $attr.menuToggle || 'left';
- $element.bind('click', function(){
- if(side === 'left') {
- sideMenuCtrl.toggleLeft();
- } else if(side === 'right') {
- sideMenuCtrl.toggleRight();
- }
- });
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name menuClose
- * @module ionic
- * @restrict AC
- *
- * @description
- * Closes a side menu which is currently opened.
- *
- * @usage
- * Below is an example of a link within a side menu. Tapping this link would
- * automatically close the currently opened menu
- *
- * ```html
- * Home
- * ```
- */
-.directive('menuClose', ['$ionicViewService', function($ionicViewService) {
- return {
- restrict: 'AC',
- require: '^ionSideMenus',
- link: function($scope, $element, $attr, sideMenuCtrl) {
- $element.bind('click', function(){
- sideMenuCtrl.close();
- });
- }
- };
-}]);
-
-})();
diff --git a/js/ext/angular/src/directive/ionicTabBar.js b/js/ext/angular/src/directive/ionicTabBar.js
deleted file mode 100644
index 36042c2ebc..0000000000
--- a/js/ext/angular/src/directive/ionicTabBar.js
+++ /dev/null
@@ -1,454 +0,0 @@
-angular.module('ionic.ui.tabs', ['ionic.service.view'])
-
-.run(['$ionicViewService', function($ionicViewService) {
- // set that the tabs directive should not animate when transitioning
- // to it. Instead, the children directives would animate
- $ionicViewService.disableRegisterByTagName('ion-tabs');
-}])
-
-/**
- * @ngdoc service
- * @name $ionicTabsDelegate
- * @module ionic
- *
- * @description
- * Delegate for controlling the {@link ionic.directive:ionTabs} directive.
- *
- * Methods called directly on the $ionicTabsDelegate service will control all ionTabs
- * directives. Use the {@link ionic.service:$ionicTabsDelegate#$getByHandle $getByHandle}
- * method to control specific ionTabs instances.
- *
- * @usage
- *
- * ```html
- *
- *
- *
- *
- * Hello tab 1!
- *
- *
- * Hello tab 2!
- *
- *
- *
- * ```
- * ```js
- * function MyCtrl($scope, $ionicTabsDelegate) {
- * $scope.selectTabWithIndex = function(index) {
- * $ionicTabsDelegate.select(index);
- * }
- * }
- * ```
- */
-.service('$ionicTabsDelegate', delegateService([
- /**
- * @ngdoc method
- * @name $ionicTabsDelegate#select
- * @description Select the tab matching the given index.
- *
- * @param {number} index Index of the tab to select.
- * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's
- * view history (if it exists) and use it, or just load the default page.
- * Default false.
- * Hint: you probably want this to be true if you have an
- * {@link ionic.directive:ionNavView} inside your tab.
- */
- 'select',
- /**
- * @ngdoc method
- * @name $ionicTabsDelegate#selectedIndex
- * @returns `number` The index of the selected tab, or -1.
- */
- 'selectedIndex'
- /**
- * @ngdoc method
- * @name $ionicTabsDelegate#$getByHandle
- * @param {string} handle
- * @returns `delegateInstance` A delegate instance that controls only the
- * {@link ionic.directive:ionTabs} directives with `delegate-handle` matching
- * the given handle.
- *
- * Example: `$ionicTabsDelegate.$getByHandle('my-handle').select(0);`
- */
-]))
-
-.controller('ionicTabs', ['$scope', '$ionicViewService', '$element', function($scope, $ionicViewService, $element) {
- var _selectedTab = null;
- var self = this;
- self.tabs = [];
-
- self.selectedIndex = function() {
- return self.tabs.indexOf(_selectedTab);
- };
- self.selectedTab = function() {
- return _selectedTab;
- };
-
- self.add = function(tab) {
- $ionicViewService.registerHistory(tab);
- self.tabs.push(tab);
- if(self.tabs.length === 1) {
- self.select(tab);
- }
- };
-
- self.remove = function(tab) {
- var tabIndex = self.tabs.indexOf(tab);
- if (tabIndex === -1) {
- return;
- }
- //Use a field like '$tabSelected' so developers won't accidentally set it in controllers etc
- if (tab.$tabSelected) {
- self.deselect(tab);
- //Try to select a new tab if we're removing a tab
- if (self.tabs.length === 1) {
- //do nothing if there are no other tabs to select
- } else {
- //Select previous tab if it's the last tab, else select next tab
- var newTabIndex = tabIndex === self.tabs.length - 1 ? tabIndex - 1 : tabIndex + 1;
- self.select(self.tabs[newTabIndex]);
- }
- }
- self.tabs.splice(tabIndex, 1);
- };
-
- self.deselect = function(tab) {
- if (tab.$tabSelected) {
- _selectedTab = null;
- tab.$tabSelected = false;
- (tab.onDeselect || angular.noop)();
- }
- };
-
- self.select = function(tab, shouldEmitEvent) {
- var tabIndex;
- if (angular.isNumber(tab)) {
- tabIndex = tab;
- tab = self.tabs[tabIndex];
- } else {
- tabIndex = self.tabs.indexOf(tab);
- }
- if (!tab || tabIndex == -1) {
- throw new Error('Cannot select tab "' + tabIndex + '"!');
- }
-
- if (_selectedTab && _selectedTab.$historyId == tab.$historyId) {
- if (shouldEmitEvent) {
- $ionicViewService.goToHistoryRoot(tab.$historyId);
- }
- } else {
- angular.forEach(self.tabs, function(tab) {
- self.deselect(tab);
- });
-
- _selectedTab = tab;
- //Use a funny name like $tabSelected so the developer doesn't overwrite the var in a child scope
- tab.$tabSelected = true;
- (tab.onSelect || angular.noop)();
-
- if (shouldEmitEvent) {
- var viewData = {
- type: 'tab',
- tabIndex: tabIndex,
- historyId: tab.$historyId,
- navViewName: tab.navViewName,
- hasNavView: !!tab.navViewName,
- title: tab.title,
- //Skip the first character of href if it's #
- url: tab.href,
- uiSref: tab.uiSref
- };
- $scope.$emit('viewState.changeHistory', viewData);
- }
- }
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionTabs
- * @module ionic
- * @delegate ionic.service:$ionicTabsDelegate
- * @restrict E
- * @codepen KbrzJ
- *
- * @description
- * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed
- * through.
- *
- * Assign any [tabs class](/docs/components#tabs) or
- * [animation class](/docs/components#animation) to the element to define
- * its look and feel.
- *
- * See the {@link ionic.directive:ionTab} directive's documentation for more details on
- * individual tabs.
- *
- * @usage
- * ```html
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * ```
- *
- * @param {string=} delegate-handle The handle used to identify these tabs
- * with {@link ionic.service:$ionicTabsDelegate}.
- */
-
-.directive('ionTabs', ['$ionicViewService', '$ionicTabsDelegate', function($ionicViewService, $ionicTabsDelegate) {
- return {
- restrict: 'E',
- scope: true,
- controller: 'ionicTabs',
- compile: function(element, attr) {
- element.addClass('view');
- //We cannot use regular transclude here because it breaks element.data()
- //inheritance on compile
- var innerElement = angular.element('');
- innerElement.append(element.contents());
- element.append(innerElement);
-
- return { pre: prelink };
- function prelink($scope, $element, $attr, tabsCtrl) {
- var deregisterInstance = $ionicTabsDelegate._registerInstance(
- tabsCtrl, $attr.delegateHandle
- );
-
- $scope.$on('$destroy', deregisterInstance);
-
- tabsCtrl.$scope = $scope;
- tabsCtrl.$element = $element;
- tabsCtrl.$tabsElement = angular.element($element[0].querySelector('.tabs'));
-
- var el = $element[0];
- $scope.$watch(function() { return el.className; }, function(value) {
- var isTabsTop = value.indexOf('tabs-top') !== -1;
- var isHidden = value.indexOf('tabs-item-hide') !== -1;
- $scope.$hasTabs = !isTabsTop && !isHidden;
- $scope.$hasTabsTop = isTabsTop && !isHidden;
- });
- $scope.$on('$destroy', function() {
- $scope.$hasTabs = $scope.$hasTabsTop = null;
- });
- }
- }
- };
-}])
-
-.controller('ionicTab', ['$scope', '$ionicViewService', '$attrs', '$location', '$state',
-function($scope, $ionicViewService, $attrs, $location, $state) {
- this.$scope = $scope;
-
- //All of these exposed for testing
- this.hrefMatchesState = function() {
- return $attrs.href && $location.path().indexOf(
- $attrs.href.replace(/^#/, '').replace(/\/$/, '')
- ) === 0;
- };
- this.srefMatchesState = function() {
- return $attrs.uiSref && $state.includes( $attrs.uiSref.split('(')[0] );
- };
- this.navNameMatchesState = function() {
- return this.navViewName && $ionicViewService.isCurrentStateNavView(this.navViewName);
- };
-
- this.tabMatchesState = function() {
- return this.hrefMatchesState() || this.srefMatchesState() || this.navNameMatchesState();
- };
-}])
-
-/**
- * @ngdoc directive
- * @name ionTab
- * @module ionic
- * @restrict E
- * @parent ionic.directive:ionTabs
- *
- * @description
- * Contains a tab's content. The content only exists while the given tab is selected.
- *
- * Each ionTab has its own view history.
- *
- * @usage
- * ```html
- *
- *
- * ```
- * For a complete, working tab bar example, see the {@link ionic.directive:ionTabs} documentation.
- *
- * @param {string} title The title of the tab.
- * @param {string=} href The link that this tab will navigate to when tapped.
- * @param {string=} icon The icon of the tab. If given, this will become the default for icon-on and icon-off.
- * @param {string=} icon-on The icon of the tab while it is selected.
- * @param {string=} icon-off The icon of the tab while it is not selected.
- * @param {expression=} badge The badge to put on this tab (usually a number).
- * @param {expression=} badge-style The style of badge to put on this tab (eg tabs-positive).
- * @param {expression=} on-select Called when this tab is selected.
- * @param {expression=} on-deselect Called when this tab is deselected.
- * @param {expression=} ng-click By default, the tab will be selected on click. If ngClick is set, it will not. You can explicitly switch tabs using {@link ionic.service:$ionicTabsDelegate#select $ionicTabsDelegate.select()}.
- */
-.directive('ionTab', ['$rootScope', '$animate', '$ionicBind', '$compile', '$ionicViewService', '$state', '$location',
-function($rootScope, $animate, $ionicBind, $compile, $ionicViewService, $state, $location) {
-
- //Returns ' key="value"' if value exists
- function attrStr(k,v) {
- return angular.isDefined(v) ? ' ' + k + '="' + v + '"' : '';
- }
- return {
- restrict: 'E',
- require: ['^ionTabs', 'ionTab'],
- replace: true,
- controller: 'ionicTab',
- scope: true,
- compile: function(element, attr) {
- var navView = element[0].querySelector('ion-nav-view') ||
- element[0].querySelector('data-ion-nav-view');
- var navViewName = navView && navView.getAttribute('name');
-
-
- //We create the tabNavElement in the compile phase so that the
- //attributes we pass down won't be interpolated yet - we want
- //to pass down the 'raw' versions of the attributes
- var tabNavElement = angular.element(
- ''
- );
-
- //Remove the contents of the element so we can compile them later, if tab is selected
- //We don't use regular transclusion because it breaks element inheritance
- var tabContent = angular.element('
')
- .append( element.contents().remove() );
-
- return function link($scope, $element, $attr, ctrls) {
- var childScope;
- var childElement;
- var tabsCtrl = ctrls[0];
- var tabCtrl = ctrls[1];
-
- $ionicBind($scope, $attr, {
- animate: '=',
- onSelect: '&',
- onDeselect: '&',
- title: '@',
- uiSref: '@',
- href: '@',
- });
-
- tabsCtrl.add($scope);
- $scope.$on('$destroy', function() {
- tabsCtrl.remove($scope);
- tabNavElement.isolateScope().$destroy();
- tabNavElement.remove();
- });
-
- //Remove title attribute so browser-tooltip does not apear
- $element[0].removeAttribute('title');
-
- if (navViewName) {
- tabCtrl.navViewName = navViewName;
- }
- $scope.$on('$stateChangeSuccess', selectIfMatchesState);
- selectIfMatchesState();
- function selectIfMatchesState() {
- if (tabCtrl.tabMatchesState()) {
- tabsCtrl.select($scope);
- }
- }
-
- tabNavElement.data('$ionTabsController', tabsCtrl);
- tabNavElement.data('$ionTabController', tabCtrl);
- tabsCtrl.$tabsElement.append($compile(tabNavElement)($scope));
-
- $scope.$watch('$tabSelected', function(value) {
- childScope && childScope.$destroy();
- childScope = null;
- childElement && $animate.leave(childElement);
- childElement = null;
- if (value) {
- childScope = $scope.$new();
- childElement = tabContent.clone();
- $animate.enter(childElement, tabsCtrl.$element);
- $compile(childElement)(childScope);
- }
- });
-
- };
- }
- };
-}])
-
-.directive('ionTabNav', ['$ionicNgClick', function($ionicNgClick) {
- return {
- restrict: 'E',
- replace: true,
- require: ['^ionTabs', '^ionTab'],
- template:
- '' +
- '{{badge}}' +
- '' +
- '' +
- '' +
- '',
- scope: {
- title: '@',
- icon: '@',
- iconOn: '@',
- iconOff: '@',
- badge: '=',
- badgeStyle: '@'
- },
- compile: function(element, attr, transclude) {
- return function link($scope, $element, $attrs, ctrls) {
- var tabsCtrl = ctrls[0],
- tabCtrl = ctrls[1];
-
- //Remove title attribute so browser-tooltip does not apear
- $element[0].removeAttribute('title');
-
- $scope.selectTab = function(e) {
- e.preventDefault();
- tabsCtrl.select(tabCtrl.$scope, true);
- };
- if (!$attrs.ngClick) {
- $ionicNgClick($scope, $element, 'selectTab($event)');
- }
-
- $scope.getIconOn = function() {
- return $scope.iconOn || $scope.icon;
- };
- $scope.getIconOff = function() {
- return $scope.iconOff || $scope.icon;
- };
-
- $scope.isTabActive = function() {
- return tabsCtrl.selectedTab() === tabCtrl.$scope;
- };
- };
- }
- };
-}]);
diff --git a/js/ext/angular/src/directive/ionicVirtRepeat.js b/js/ext/angular/src/directive/ionicVirtRepeat.js
deleted file mode 100644
index 9418e131f4..0000000000
--- a/js/ext/angular/src/directive/ionicVirtRepeat.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-(function() {
-'use strict';
-
-angular.module('ionic.ui.virtRepeat', [])
-
-.directive('ionVirtRepeat', function() {
- return {
- require: ['?ngModel', '^virtualList'],
- transclude: 'element',
- priority: 1000,
- terminal: true,
- compile: function(element, attr, transclude) {
- return function($scope, $element, $attr, ctrls) {
- var virtualList = ctrls[1];
-
- virtualList.listView.renderViewport = function(high, low, start, end) {
- };
- };
- }
- };
-});
-})(ionic);
-*/
diff --git a/js/ext/angular/src/directive/ionicVirtualRepeat.js b/js/ext/angular/src/directive/ionicVirtualRepeat.js
deleted file mode 100644
index d3797a8c73..0000000000
--- a/js/ext/angular/src/directive/ionicVirtualRepeat.js
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
-(function() {
-'use strict';
-
-// Turn the expression supplied to the directive:
-//
-// a in b
-//
-// into `{ value: "a", collection: "b" }`
-function parseRepeatExpression(expression){
- var match = expression.match(/^\s*([\$\w]+)\s+in\s+(\S*)\s*$/);
- if (! match) {
- throw new Error("Expected sfVirtualRepeat in form of '_item_ in _collection_' but got '" +
- expression + "'.");
- }
- return {
- value: match[1],
- collection: match[2]
- };
-}
-
-// Utility to filter out elements by tag name
-function isTagNameInList(element, list){
- var t, tag = element.tagName.toUpperCase();
- for( t = 0; t < list.length; t++ ){
- if( list[t] === tag ){
- return true;
- }
- }
- return false;
-}
-
-
-// Utility to find the viewport/content elements given the start element:
-function findViewportAndContent(startElement){
- var root = $rootElement[0];
- var e, n;
- // Somewhere between the grandparent and the root node
- for( e = startElement.parent().parent()[0]; e !== root; e = e.parentNode ){
- // is an element
- if( e.nodeType != 1 ) break;
- // that isn't in the blacklist (tables etc.),
- if( isTagNameInList(e, DONT_WORK_AS_VIEWPORTS) ) continue;
- // has a single child element (the content),
- if( e.childElementCount != 1 ) continue;
- // which is not in the blacklist
- if( isTagNameInList(e.firstElementChild, DONT_WORK_AS_CONTENT) ) continue;
- // and no text.
- for( n = e.firstChild; n; n = n.nextSibling ){
- if( n.nodeType == 3 && /\S/g.test(n.textContent) ){
- break;
- }
- }
- if( n === null ){
- // That element should work as a viewport.
- return {
- viewport: angular.element(e),
- content: angular.element(e.firstElementChild)
- };
- }
- }
- throw new Error("No suitable viewport element");
-}
-
-// Apply explicit height and overflow styles to the viewport element.
-//
-// If the viewport has a max-height (inherited or otherwise), set max-height.
-// Otherwise, set height from the current computed value or use
-// window.innerHeight as a fallback
-//
-function setViewportCss(viewport){
- var viewportCss = {'overflow': 'auto'},
- style = window.getComputedStyle ?
- window.getComputedStyle(viewport[0]) :
- viewport[0].currentStyle,
- maxHeight = style && style.getPropertyValue('max-height'),
- height = style && style.getPropertyValue('height');
-
- if( maxHeight && maxHeight !== '0px' ){
- viewportCss.maxHeight = maxHeight;
- }else if( height && height !== '0px' ){
- viewportCss.height = height;
- }else{
- viewportCss.height = window.innerHeight;
- }
- viewport.css(viewportCss);
-}
-
-// Apply explicit styles to the content element to prevent pesky padding
-// or borders messing with our calculations:
-function setContentCss(content){
- var contentCss = {
- margin: 0,
- padding: 0,
- border: 0,
- 'box-sizing': 'border-box'
- };
- content.css(contentCss);
-}
-
-// TODO: compute outerHeight (padding + border unless box-sizing is border)
-function computeRowHeight(element){
- var style = window.getComputedStyle ? window.getComputedStyle(element)
- : element.currentStyle,
- maxHeight = style && style.getPropertyValue('max-height'),
- height = style && style.getPropertyValue('height');
-
- if( height && height !== '0px' && height !== 'auto' ){
- $log.info('Row height is "%s" from css height', height);
- }else if( maxHeight && maxHeight !== '0px' && maxHeight !== 'none' ){
- height = maxHeight;
- $log.info('Row height is "%s" from css max-height', height);
- }else if( element.clientHeight ){
- height = element.clientHeight+'px';
- $log.info('Row height is "%s" from client height', height);
- }else{
- throw new Error("Unable to compute height of row");
- }
- angular.element(element).css('height', height);
- return parseInt(height, 10);
-}
-
-angular.module('ionic.ui.virtualRepeat', [])
-
-//
-// A replacement for ng-repeat that supports virtual lists.
-// This is not a 1 to 1 replacement for ng-repeat. However, in situations
-// where you have huge lists, this repeater will work with our virtual
-// scrolling to only render items that are showing or will be showing
-// if a scroll is made.
-//
-.directive('ionVirtualRepeat', ['$log', function($log) {
- return {
- require: ['?ngModel, ^virtualList'],
- transclude: 'element',
- priority: 1000,
- terminal: true,
- compile: function(element, attr, transclude) {
- var ident = parseRepeatExpression(attr.sfVirtualRepeat);
-
- return function(scope, iterStartElement, attrs, ctrls, b) {
- var virtualList = ctrls[1];
-
- var rendered = [];
- var rowHeight = 0;
- var sticky = false;
-
- var dom = virtualList.element;
- //var dom = findViewportAndContent(iterStartElement);
-
- // The list structure is controlled by a few simple (visible) variables:
- var state = 'ngModel' in attrs ? scope.$eval(attrs.ngModel) : {};
-
- function makeNewScope (idx, collection, containerScope) {
- var childScope = containerScope.$new();
- childScope[ident.value] = collection[idx];
- childScope.$index = idx;
- childScope.$first = (idx === 0);
- childScope.$last = (idx === (collection.length - 1));
- childScope.$middle = !(childScope.$first || childScope.$last);
- childScope.$watch(function updateChildScopeItem(){
- childScope[ident.value] = collection[idx];
- });
- return childScope;
- }
-
- // Given the collection and a start and end point, add the current
- function addElements (start, end, collection, containerScope, insPoint) {
- var frag = document.createDocumentFragment();
- var newElements = [], element, idx, childScope;
- for( idx = start; idx !== end; idx ++ ){
- childScope = makeNewScope(idx, collection, containerScope);
- element = linker(childScope, angular.noop);
- //setElementCss(element);
- newElements.push(element);
- frag.appendChild(element[0]);
- }
- insPoint.after(frag);
- return newElements;
- }
-
- function recomputeActive() {
- // We want to set the start to the low water mark unless the current
- // start is already between the low and high water marks.
- var start = clip(state.firstActive, state.firstVisible - state.lowWater, state.firstVisible - state.highWater);
- // Similarly for the end
- var end = clip(state.firstActive + state.active,
- state.firstVisible + state.visible + state.lowWater,
- state.firstVisible + state.visible + state.highWater );
- state.firstActive = Math.max(0, start);
- state.active = Math.min(end, state.total) - state.firstActive;
- }
-
- function sfVirtualRepeatOnScroll(evt){
- if( !rowHeight ){
- return;
- }
- // Enter the angular world for the state change to take effect.
- scope.$apply(function(){
- state.firstVisible = Math.floor(evt.target.scrollTop / rowHeight);
- state.visible = Math.ceil(dom.viewport[0].clientHeight / rowHeight);
- $log.log('scroll to row %o', state.firstVisible);
- sticky = evt.target.scrollTop + evt.target.clientHeight >= evt.target.scrollHeight;
- recomputeActive();
- $log.log(' state is now %o', state);
- $log.log(' sticky = %o', sticky);
- });
- }
-
- function sfVirtualRepeatWatchExpression(scope){
- var coll = scope.$eval(ident.collection);
- if( coll.length !== state.total ){
- state.total = coll.length;
- recomputeActive();
- }
- return {
- start: state.firstActive,
- active: state.active,
- len: coll.length
- };
- }
-
- function destroyActiveElements (action, count) {
- var dead, ii, remover = Array.prototype[action];
- for( ii = 0; ii < count; ii++ ){
- dead = remover.call(rendered);
- dead.scope().$destroy();
- dead.remove();
- }
- }
-
- // When the watch expression for the repeat changes, we may need to add
- // and remove scopes and elements
- function sfVirtualRepeatListener(newValue, oldValue, scope){
- var oldEnd = oldValue.start + oldValue.active,
- collection = scope.$eval(ident.collection),
- newElements;
- if(newValue === oldValue) {
- $log.info('initial listen');
- newElements = addElements(newValue.start, oldEnd, collection, scope, iterStartElement);
- rendered = newElements;
- if(rendered.length) {
- rowHeight = computeRowHeight(newElements[0][0]);
- }
- } else {
- var newEnd = newValue.start + newValue.active;
- var forward = newValue.start >= oldValue.start;
- var delta = forward ? newValue.start - oldValue.start
- : oldValue.start - newValue.start;
- var endDelta = newEnd >= oldEnd ? newEnd - oldEnd : oldEnd - newEnd;
- var contiguous = delta < (forward ? oldValue.active : newValue.active);
- $log.info('change by %o,%o rows %s', delta, endDelta, forward ? 'forward' : 'backward');
- if(!contiguous) {
- $log.info('non-contiguous change');
- destroyActiveElements('pop', rendered.length);
- rendered = addElements(newValue.start, newEnd, collection, scope, iterStartElement);
- } else {
- if(forward) {
- $log.info('need to remove from the top');
- destroyActiveElements('shift', delta);
- } else if(delta) {
- $log.info('need to add at the top');
- newElements = addElements(
- newValue.start,
- oldValue.start,
- collection, scope, iterStartElement);
- rendered = newElements.concat(rendered);
- }
-
- if(newEnd < oldEnd) {
- $log.info('need to remove from the bottom');
- destroyActiveElements('pop', oldEnd - newEnd);
- } else if(endDelta) {
- var lastElement = rendered[rendered.length-1];
- $log.info('need to add to the bottom');
- newElements = addElements(
- oldEnd,
- newEnd,
- collection, scope, lastElement);
- rendered = rendered.concat(newElements);
- }
- }
- if(!rowHeight && rendered.length) {
- rowHeight = computeRowHeight(rendered[0][0]);
- }
- dom.content.css({'padding-top': newValue.start * rowHeight + 'px'});
- }
- dom.content.css({'height': newValue.len * rowHeight + 'px'});
- if(sticky) {
- dom.viewport[0].scrollTop = dom.viewport[0].clientHeight + dom.viewport[0].scrollHeight;
- }
- }
-
- // - The index of the first active element
- state.firstActive = 0;
- // - The index of the first visible element
- state.firstVisible = 0;
- // - The number of elements visible in the viewport.
- state.visible = 0;
- // - The number of active elements
- state.active = 0;
- // - The total number of elements
- state.total = 0;
- // - The point at which we add new elements
- state.lowWater = state.lowWater || 100;
- // - The point at which we remove old elements
- state.highWater = state.highWater || 300;
- // TODO: now watch the water marks
-
- setContentCss(dom.content);
- setViewportCss(dom.viewport);
- // When the user scrolls, we move the `state.firstActive`
- dom.bind('momentumScrolled', sfVirtualRepeatOnScroll);
-
- scope.$on('$destroy', function () {
- dom.unbind('momentumScrolled', sfVirtualRepeatOnScroll);
- });
-
- // The watch on the collection is just a watch on the length of the
- // collection. We don't care if the content changes.
- scope.$watch(sfVirtualRepeatWatchExpression, sfVirtualRepeatListener, true);
- };
- }
- };
- }]);
-
-})(ionic);
-*/
diff --git a/js/ext/angular/src/ionicAngular.js b/js/ext/angular/src/ionicAngular.js
deleted file mode 100644
index 4b15fa2872..0000000000
--- a/js/ext/angular/src/ionicAngular.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Create a wrapping module to ease having to include too many
- * modules.
- */
-
-/**
- * @ngdoc module
- * @name ionic
- * @description
- * Ionic main module.
- */
-
-angular.module('ionic.service', [
- 'ionic.service.bind',
- 'ionic.service.platform',
- 'ionic.service.actionSheet',
- 'ionic.service.gesture',
- 'ionic.service.loading',
- 'ionic.service.modal',
- 'ionic.service.popup',
- 'ionic.service.templateLoad',
- 'ionic.service.view',
- 'ionic.decorator.location'
-]);
-
-angular.module('ionic.ui', [
- 'ionic.ui.checkbox',
- 'ionic.ui.content',
- 'ionic.ui.header',
- 'ionic.ui.list',
- 'ionic.ui.navBar',
- 'ionic.ui.radio',
- 'ionic.ui.scroll',
- 'ionic.ui.sideMenu',
- 'ionic.ui.slideBox',
- 'ionic.ui.tabs',
- 'ionic.ui.toggle',
- 'ionic.ui.touch',
- 'ionic.ui.viewState'
-]);
-
-angular.module('ionic', [
- 'ionic.service',
- 'ionic.ui',
-
- // Angular deps
- 'ngAnimate',
- 'ngSanitize',
- 'ui.router'
-]);
diff --git a/js/ext/angular/test/actionSheet.html b/js/ext/angular/test/actionSheet.html
deleted file mode 100644
index 2ff5d42bf0..0000000000
--- a/js/ext/angular/test/actionSheet.html
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
- Action Sheet
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/test/html/bars-clear.html b/test/css/bars-clear.html
similarity index 100%
rename from test/html/bars-clear.html
rename to test/css/bars-clear.html
diff --git a/test/html/biglists.html b/test/css/biglists.html
similarity index 100%
rename from test/html/biglists.html
rename to test/css/biglists.html
diff --git a/test/html/button-bar.html b/test/css/button-bar.html
similarity index 100%
rename from test/html/button-bar.html
rename to test/css/button-bar.html
diff --git a/test/html/buttons.html b/test/css/buttons.html
similarity index 100%
rename from test/html/buttons.html
rename to test/css/buttons.html
diff --git a/test/html/cards.html b/test/css/cards.html
similarity index 100%
rename from test/html/cards.html
rename to test/css/cards.html
diff --git a/test/html/colors.html b/test/css/colors.html
similarity index 100%
rename from test/html/colors.html
rename to test/css/colors.html
diff --git a/test/html/footers.html b/test/css/footers.html
similarity index 100%
rename from test/html/footers.html
rename to test/css/footers.html
diff --git a/test/html/grid.html b/test/css/grid.html
similarity index 100%
rename from test/html/grid.html
rename to test/css/grid.html
diff --git a/test/html/headers.html b/test/css/headers.html
similarity index 100%
rename from test/html/headers.html
rename to test/css/headers.html
diff --git a/test/html/input-checkbox.html b/test/css/input-checkbox.html
similarity index 100%
rename from test/html/input-checkbox.html
rename to test/css/input-checkbox.html
diff --git a/test/html/input-radio.html b/test/css/input-radio.html
similarity index 100%
rename from test/html/input-radio.html
rename to test/css/input-radio.html
diff --git a/test/html/input-range.html b/test/css/input-range.html
similarity index 100%
rename from test/html/input-range.html
rename to test/css/input-range.html
diff --git a/test/html/input-select.html b/test/css/input-select.html
similarity index 100%
rename from test/html/input-select.html
rename to test/css/input-select.html
diff --git a/test/html/input-text.html b/test/css/input-text.html
similarity index 100%
rename from test/html/input-text.html
rename to test/css/input-text.html
diff --git a/test/html/input-textarea.html b/test/css/input-textarea.html
similarity index 100%
rename from test/html/input-textarea.html
rename to test/css/input-textarea.html
diff --git a/test/html/input-toggle.html b/test/css/input-toggle.html
similarity index 100%
rename from test/html/input-toggle.html
rename to test/css/input-toggle.html
diff --git a/test/html/lists.html b/test/css/lists.html
similarity index 100%
rename from test/html/lists.html
rename to test/css/lists.html
diff --git a/test/css/loading.html b/test/css/loading.html
new file mode 100644
index 0000000000..2b24d8dd93
--- /dev/null
+++ b/test/css/loading.html
@@ -0,0 +1,24 @@
+
+
+
+ Loading
+
+
+
+
+
+
Loading
+
+
+
+
+
+
+
diff --git a/test/html/modals.html b/test/css/modals.html
similarity index 100%
rename from test/html/modals.html
rename to test/css/modals.html
diff --git a/test/html/progress.html b/test/css/progress.html
similarity index 100%
rename from test/html/progress.html
rename to test/css/progress.html
diff --git a/test/css/scroll.html b/test/css/scroll.html
new file mode 100644
index 0000000000..d89cbdd5ba
--- /dev/null
+++ b/test/css/scroll.html
@@ -0,0 +1,49 @@
+
+
+
+ Scroll
+
+
+
+
+
+
+