finalize-release: v1.0.0-beta.4 "antimony-antelope"

This commit is contained in:
Ionitron
2014-05-07 17:57:55 +00:00
parent e9ef78d48b
commit ab6fb75b0d
13 changed files with 11254 additions and 479 deletions

View File

@@ -2,7 +2,7 @@
* Copyright 2014 Drifty Co.
* http://drifty.com/
*
* Ionic, v1.0.0-beta.3
* Ionic, v1.0.0-beta.4
* A powerful HTML5 mobile app framework.
* http://ionicframework.com/
*
@@ -276,6 +276,68 @@ angular.element.prototype.removeClass = function(cssClasses) {
return this;
};
/**
* @ngdoc service
* @name $ionicAnimation
* @module ionic
* @description
*
* A powerful animation and transition system for Ionic apps.
*
* @usage
*
* ```js
* angular.module('mySuperApp', ['ionic'])
* .controller(function($scope, $ionicAnimation) {
* var anim = $ionicAnimate({
* // A unique, reusable name
* name: 'popIn',
*
* // The duration of an auto playthrough
* duration: 0.5,
*
* // How long to wait before running the animation
* delay: 0,
*
* // Whether to reverse after doing one run through
* autoReverse: false,
*
* // How many times to repeat? -1 or null for infinite
* repeat: -1,
*
* // Timing curve to use (same as CSS timing functions), or a function of time "t" to handle it yourself
* curve: 'ease-in-out'
*
* onStart: function() {
* // Callback on start
* },
* onEnd: function() {
* // Callback on end
* },
* step: function(amt) {
*
* }
* })
* });
* ```
*
*/
IonicModule
.provider('$ionicAnimation', function() {
var useSlowAnimations = false;
this.setSlowAnimations = function(isSlow) {
useSlowAnimations = isSlow;
};
this.$get = [function() {
return function(opts) {
opts.useSlowAnimations = useSlowAnimations;
return ionic.Animation.create(opts);
}
}]
});
/**
* @ngdoc service
* @name $ionicBackdrop
@@ -534,6 +596,7 @@ function($cacheFactory, $parse) {
this.transcludeParent[0].appendChild(item.element[0]);
}
reconnectScope(item.scope);
!item.scope.$$phase && item.scope.$digest();
},
getLength: function() {
return this.data && this.data.length || 0;
@@ -808,7 +871,7 @@ function($rootScope, $timeout) {
this.renderItem(i, rect.primaryPos - startPos, rect.secondaryPos);
i++;
}
var bufferEndIndex = i -1;
var bufferEndIndex = i - 1;
for (i in this.renderedItems) {
if (i < bufferStartIndex || i > bufferEndIndex) {
@@ -827,9 +890,6 @@ function($rootScope, $timeout) {
primaryPos, secondaryPos, secondaryPos
);
this.renderedItems[dataIndex] = item;
if (item.scope && !item.scope.$$phase) {
item.scope.$digest();
}
} else {
delete this.renderedItems[dataIndex];
}
@@ -1035,10 +1095,12 @@ IonicModule
'$q',
'$log',
'$compile',
function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $compile) {
'$ionicPlatform',
function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $compile, $ionicPlatform) {
var loaderInstance;
//default value
//default values
var deregisterBackAction = angular.noop;
var loadingShowDelay = $q.when();
return {
@@ -1075,7 +1137,6 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
appendTo: $document[0].body
})
.then(function(loader) {
var self = loader;
loader.show = function(options) {
@@ -1132,10 +1193,11 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
$timeout.cancel(this.durationTimeout);
this.isShown = false;
};
return loader;
});
}
return $q.when(loaderInstance);
return loaderInstance;
}
function showLoader(options) {
@@ -1143,10 +1205,16 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
var delay = options.delay || options.showDelay || 0;
//If loading.show() was called previously, cancel it and show with our new options
$timeout.cancel(loadingShowDelay);
loadingShowDelay && $timeout.cancel(loadingShowDelay);
loadingShowDelay = $timeout(angular.noop, delay);
loadingShowDelay.then(getLoader).then(function(loader) {
deregisterBackAction();
//Disable hardware back button while loading
deregisterBackAction = $ionicPlatform.registerBackButtonAction(
angular.noop,
PLATFORM_BACK_BUTTON_PRIORITY_LOADING
);
return loader.show(options);
});
@@ -1164,6 +1232,7 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
}
function hideLoader() {
deregisterBackAction();
$timeout.cancel(loadingShowDelay);
getLoader().then(function(loader) {
loader.hide();
@@ -1267,7 +1336,10 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
var modalEl = angular.element(self.modalEl);
self.el.classList.remove('hide');
$document[0].body.classList.add('modal-open');
$timeout(function(){
$document[0].body.classList.add('modal-open');
}, 400)
if(!self.el.parentElement) {
modalEl.addClass(self.animation);
@@ -1291,7 +1363,14 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
self.el.classList.add('active');
}, 20);
return $timeout(angular.noop, 400);
return $timeout(function() {
//After animating in, allow hide on backdrop click
self.$el.on('click', function(e) {
if (e.target === self.el) {
self.hide();
}
});
}, 400);
},
/**
@@ -1312,6 +1391,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
.removeClass('ng-enter ng-enter-active active');
}, 20);
self.$el.off('click');
self._isShown = false;
self.scope.$parent && self.scope.$parent.$broadcast('modal.hidden', self);
self._deregisterBackButton && self._deregisterBackButton();
@@ -1336,7 +1416,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
return self.hide().then(function() {
self.scope.$destroy();
angular.element(self.el).remove();
self.$el.remove();
});
},
@@ -1366,6 +1446,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
// Compile the template
var element = $compile('<ion-modal>' + templateString + '</ion-modal>')(scope);
options.$el = element;
options.el = element[0];
options.modalEl = options.el.querySelector('.modal');
var modal = new ModalView(options);
@@ -1525,8 +1606,10 @@ IonicModule
]));
var PLATFORM_BACK_BUTTON_PRIORITY_VIEW = 100;
var PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU = 150;
var PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET = 300;
var PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 500;
var PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 400;
var PLATFORM_BACK_BUTTON_PRIORITY_LOADING = 500;
/**
* @ngdoc service
* @name $ionicPlatform
@@ -3602,15 +3685,17 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
var viewId = historyData && historyData.viewId;
if (viewId) {
self.rememberScrollPosition(viewId);
self.scrollToRememberedPosition();
$timeout(function() {
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();
}
});
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();
}
});
}, 1, false);
}
});
@@ -3716,9 +3801,13 @@ IonicModule
'$scope',
'$attrs',
'$ionicSideMenuDelegate',
function($scope, $attrs, $ionicSideMenuDelegate) {
'$ionicPlatform',
function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) {
var self = this;
angular.extend(this, ionic.controllers.SideMenuController.prototype);
this.$scope = $scope;
ionic.controllers.SideMenuController.call(this, {
left: { width: 275 },
right: { width: 275 }
@@ -3741,10 +3830,28 @@ function($scope, $attrs, $ionicSideMenuDelegate) {
$scope.sideMenuContentTranslateX = 0;
var deregisterBackButtonAction = angular.noop;
var closeSideMenu = angular.bind(this, this.close);
$scope.$watch(function() {
return self.getOpenAmount() !== 0;
}, function(isOpen) {
deregisterBackButtonAction();
if (isOpen) {
deregisterBackButtonAction = $ionicPlatform.registerBackButtonAction(
closeSideMenu,
PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU
);
}
});
var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
this, $attrs.delegateHandle
);
$scope.$on('$destroy', deregisterInstance);
$scope.$on('$destroy', function() {
deregisterInstance();
deregisterBackButtonAction();
});
}]);
IonicModule
@@ -3996,20 +4103,20 @@ IonicModule
* Here are a few things to keep in mind while using collection-repeat:
*
* 1. The data supplied to collection-repeat must be an array.
* 2. You must explicitly tell the directive what size your items will be in the DOM
* (pixel amount or percentage), using directive attributes (see below).
* 3. The elements rendered will be absolutely positioned: be sure to let your CSS work with this (see below).
* 4. Keep the HTML of your repeated elements as simple as possible. As the user scrolls down, elements
* will be lazily compiled. Resultingly, the more complicated your elements, the more likely it is that
* the on-demand compilation will cause jankiness in the user's scrolling.
* 5. The more elements you render on the screen at a time, the slower the scrolling will be.
* It is recommended to keep grids of collection-repeat list elements at 3-wide or less.
* 2. You must explicitly tell the directive what size your items will be in the DOM, using directive attributes. Pixel amounts or percentages are allowed (see below).
* 3. The elements rendered will be absolutely positioned: be sure to let your CSS work with
* this (see below).
* 4. Keep the HTML of your repeated elements as simple as possible. As the user scrolls down,
* elements will be lazily compiled. Resultingly, the more complicated your elements, the more
* likely it is that the on-demand compilation will cause some jerkiness in the user's scrolling.
* 5. The more elements you render on the screen per row, the more likelihood for scrolling to
* slow down. It is recommended to keep grids of collection-repeat list elements at 3-wide or less.
* For example, if you have a gallery of images just set their width to 33%.
* 6. Each collection-repeat list will take up all of its parent scrollView's space.
* If you wish to have multiple lists on one page, put each list within its own
* {@link ionic.directive:ionScroll ionScroll} container.
*
*
*
* @usage
*
* #### Basic Usage (single rows of items)
@@ -4105,6 +4212,11 @@ IonicModule
* @param {expression} collection-item-height The height of the repeated element. Can be a number (in pixels), or a percentage.
*
*/
var COLLECTION_REPEAT_SCROLLVIEW_XY_ERROR = "Cannot create a collection-repeat within a scrollView that is scrollable on both x and y axis. Choose either x direction or y direction.";
var COLLECTION_REPEAT_ATTR_HEIGHT_ERROR = "collection-repeat expected attribute collection-item-height to be a an expression that returns a number (in pixels) or percentage.";
var COLLECTION_REPEAT_ATTR_WIDTH_ERROR = "collection-repeat expected attribute collection-item-width to be a an expression that returns a number (in pixels) or percentage.";
var COLLECTION_REPEAT_ATTR_REPEAT_ERROR = "collection-repeat expected expression in form of '_item_ in _collection_[ track by _id_]' but got '%'";
IonicModule
.directive('collectionRepeat', [
'$collectionRepeatManager',
@@ -4120,14 +4232,14 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
link: function($scope, $element, $attr, scrollCtrl, $transclude) {
var scrollView = scrollCtrl.scrollView;
if (scrollView.options.scrollingX && scrollView.options.scrollingY) {
throw new Error("Cannot create a collection-repeat within a scrollView that is scrollable on both x and y axis. Choose either x direction or y direction.");
throw new Error(COLLECTION_REPEAT_SCROLLVIEW_XY_ERROR);
}
var isVertical = !!scrollView.options.scrollingY;
if (isVertical && !$attr.collectionItemHeight) {
throw new Error("collection-repeat expected attribute collection-item-height to be a an expression that returns a number.");
throw new Error(COLLECTION_REPEAT_ATTR_HEIGHT_ERROR);
} else if (!isVertical && !$attr.collectionItemWidth) {
throw new Error("collection-repeat expected attribute collection-item-width to be a an expression that returns a number.");
throw new Error(COLLECTION_REPEAT_ATTR_WIDTH_ERROR);
}
$attr.collectionItemHeight = $attr.collectionItemHeight || '"100%"';
$attr.collectionItemWidth = $attr.collectionItemWidth || '"100%"';
@@ -4156,16 +4268,20 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
var match = $attr.collectionRepeat.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
if (!match) {
throw new Error("collection-repeat expected expression in form of '_item_ in _collection_[ track by _id_]' but got '" + $attr.collectionRepeat + "'.");
throw new Error(COLLECTION_REPEAT_ATTR_REPEAT_ERROR
.replace('%', $attr.collectionRepeat));
}
var keyExpr = match[1];
var listExpr = match[2];
var trackByExpr = match[3];
var dataSource = new $collectionDataSource({
scope: $scope,
transcludeFn: $transclude,
transcludeParent: $element.parent(),
keyExpr: match[1],
listExpr: match[2],
trackByExpr: match[3],
keyExpr: keyExpr,
listExpr: listExpr,
trackByExpr: trackByExpr,
heightGetter: heightGetter,
widthGetter: widthGetter
});
@@ -4175,7 +4291,7 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
scrollView: scrollCtrl.scrollView,
});
$scope.$watchCollection(dataSource.listExpr, function(value) {
$scope.$watchCollection(listExpr, function(value) {
if (value && !angular.isArray(value)) {
throw new Error("collection-repeat expects an array to repeat over, but instead got '" + typeof value + "'.");
}
@@ -4187,15 +4303,16 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
dataSource.setData(value);
collectionRepeatManager.resize();
}
var resize = angular.bind(collectionRepeatManager, collectionRepeatManager.resize);
ionic.on('resize', function() {
rerender($scope.$eval(dataSource.listExpr));
}, window);
function onWindowResize() {
rerender($scope.$eval(listExpr));
}
ionic.on('resize', onWindowResize, window);
$scope.$on('$destroy', function() {
collectionRepeatManager.destroy();
dataSource.destroy();
ionic.off('resize', resize, window);
ionic.off('resize', onWindowResize, window);
});
}
};
@@ -4665,8 +4782,6 @@ function($animate, $compile) {
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);
@@ -5143,7 +5258,7 @@ IonicModule
replace: true,
template: '<div class="modal-backdrop">' +
'<div class="modal-wrapper" ng-transclude></div>' +
'</div>'
'</div>'
};
}]);
@@ -5212,7 +5327,14 @@ IonicModule
IonicModule
.directive('ionNavBackButton', [
'$animate',
function($animate) {
'$rootScope',
function($animate, $rootScope) {
var backIsShown = false;
//If the current viewstate does not allow a back button,
//always hide it.
$rootScope.$on('$viewHistory.historyChange', function(e, data) {
backIsShown = !!data.showBack;
});
return {
restrict: 'E',
require: '^ionNavBar',
@@ -5228,19 +5350,11 @@ function($animate) {
});
}
//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) {
$scope.$watch(function() {
return !!(backIsShown && $scope.backButtonShown);
}, ionic.animationFrameThrottle(function(show) {
if (show) $animate.removeClass($element, 'ng-hide');
else $animate.addClass($element, 'ng-hide');
}));
@@ -5286,6 +5400,33 @@ function($animate) {
* with {@link ionic.service:$ionicNavBarDelegate}.
* @param align-title {string=} Where to align the title of the navbar.
* Available: 'left', 'right', 'center'. Defaults to 'center'.
*
* </table><br/>
*
* ### Alternative Usage
*
* Alternatively, you may put ion-nav-bar inside of each individual view's ion-view element.
* This will allow you to have the whole navbar, not just its contents, transition every view change.
*
* This is similar to using a header bar inside your ion-view, except it will has all the power of a navbar.
*
* If you do this, simply put nav buttons inside the navbar itself; do not use `<ion-nav-buttons>`.
*
*
* ```html
* <ion-nav-bar class="bar-positive">
* <ion-nav-back-button>
* Back
* </ion-nav-back-button>
* <div class="buttons right-buttons">
* <button class="button">
* Right Button
* </button>
* </div>
* </ion-nav-bar>
* <ion-view title="myTitle">
* </ion-view>
* ```
*/
IonicModule
.directive('ionNavBar', [
@@ -5428,13 +5569,16 @@ IonicModule
* @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.
* nav-clear is an attribute directive which should be used with an element that changes
* the view on click, for example an `<a href>` or a `<button ui-sref>`.
*
* nav-clear will cause the given element, when clicked, to disable the next view transition.
* This directive is useful, for example, 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.
* Below is a link in a side menu, with the nav-clear directive added to it.
* Tapping this link will disable any animations that would normally occur
* between views.
*
* ```html
* <a nav-clear menu-close href="#/home" class="item">Home</a>
@@ -5861,7 +6005,8 @@ IonicModule
require: '^$ionicScroll',
template:
'<div class="scroll-refresher">' +
'<div class="ionic-refresher-content">' +
'<div class="ionic-refresher-content" ' +
'ng-class="{\'ionic-refresher-with-text\': pullingText || refreshingText}">' +
'<i class="icon {{pullingIcon}} icon-pulling"></i>' +
'<div class="text-pulling" ng-bind-html="pullingText"></div>' +
'<i class="icon {{refreshingIcon}} icon-refreshing"></i>' +
@@ -6271,7 +6416,6 @@ IonicModule
* @param {number=} slide-interval How many milliseconds to wait to change slides (if does-continue is true). Defaults to 4000.
* @param {boolean=} show-pager Whether a pager should be shown for this slide box.
* @param {expression=} pager-click Expression to call when a pager is clicked (if show-pager is true). Is passed the 'index' variable.
* @param {boolean=} disable-scroll Whether to disallow scrolling/dragging of the slide-box content.
* @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.
*/
@@ -6303,7 +6447,6 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
var slider = new ionic.views.Slider({
el: $element[0],
auto: slideInterval,
disableScroll: ($scope.$eval($scope.disableScroll) === true) || false,
continuous: continuous,
startSlide: $scope.activeSlide,
slidesChanged: function() {
@@ -6322,6 +6465,8 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
}
});
slider.enableSlide($scope.$eval($attrs.disableScroll) !== true);
$scope.$watch('activeSlide', function(nv) {
if(angular.isDefined(nv)){
slider.slide(nv);
@@ -6635,6 +6780,9 @@ IonicModule
* See the {@link ionic.directive:ionTab} directive's documentation for more details on
* individual tabs.
*
* Note: do not place ion-tabs inside of an ion-content element; it has been known to cause a
* certain CSS bug.
*
* @usage
* ```html
* <ion-tabs class="tabs-positive tabs-icon-only">
@@ -6714,6 +6862,15 @@ IonicModule
*
* The toggle behaves like any [AngularJS checkbox](http://docs.angularjs.org/api/ng/input/input[checkbox]) otherwise.
*
* @param toggle-class {string=} Sets the CSS class on the inner `label.toggle` element created by the directive.
*
* @usage
* Below is an example of a toggle directive which is wired up to the `airplaneMode` model
* and has the `toggle-calm` CSS class assigned to the inner element.
*
* ```html
* <ion-toggle ng-model="airplaneMode" toggle-class="toggle-calm">Airplane Mode</ion-toggle>
* ```
*/
IonicModule
.directive('ionToggle', [
@@ -6749,6 +6906,9 @@ function($ionicGesture, $timeout) {
if(attr.ngChecked) input.attr('ng-checked', 'ngChecked');
if(attr.ngTrueValue) input.attr('ng-true-value', attr.ngTrueValue);
if(attr.ngFalseValue) input.attr('ng-false-value', attr.ngFalseValue);
if(attr.toggleClass) {
element[0].getElementsByTagName('label')[0].classList.add(attr.toggleClass);
}
return function($scope, $element, $attr) {
var el, checkbox, track, handle;
@@ -6810,9 +6970,9 @@ function($ionicGesture, $timeout) {
* ```
*
* @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
* @param {boolean=} hide-back-button Whether to hide the back button on the parent
* {@link ionic.directive:ionNavBar} by default.
* @param {boolean=} hideNavBar Whether to hide the parent
* @param {boolean=} hide-nav-bar Whether to hide the parent
* {@link ionic.directive:ionNavBar} by default.
*/
IonicModule