mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
release: v1.0.0-beta.10 "gadolinium-gator"
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Copyright 2014 Drifty Co.
|
||||
* http://drifty.com/
|
||||
*
|
||||
* Ionic, v1.0.0-beta.9
|
||||
* Ionic, v1.0.0-beta.10
|
||||
* A powerful HTML5 mobile app framework.
|
||||
* http://ionicframework.com/
|
||||
*
|
||||
@@ -99,6 +99,9 @@ var IonicModule = angular.module('ionic', ['ngAnimate', 'ngSanitize', 'ui.router
|
||||
* destructiveText: 'Delete',
|
||||
* titleText: 'Modify your album',
|
||||
* cancelText: 'Cancel',
|
||||
* cancel: function() {
|
||||
// add cancel code..
|
||||
},
|
||||
* buttonClicked: function(index) {
|
||||
* return true;
|
||||
* }
|
||||
@@ -321,7 +324,7 @@ jqLite.prototype.removeClass = function(cssClasses) {
|
||||
* ```js
|
||||
* angular.module('mySuperApp', ['ionic'])
|
||||
* .controller(function($scope, $ionicAnimation) {
|
||||
* var anim = $ionicAnimate({
|
||||
* var anim = $ionicAnimation({
|
||||
* // A unique, reusable name
|
||||
* name: 'popIn',
|
||||
*
|
||||
@@ -596,13 +599,11 @@ function($cacheFactory, $parse, $rootScope) {
|
||||
return item;
|
||||
},
|
||||
getItem: function(hash) {
|
||||
window.AMOUNT = window.AMOUNT || 0;
|
||||
if ( (item = this.attachedItems[hash]) ) {
|
||||
//do nothing, the item is good
|
||||
} else if ( (item = this.backupItemsArray.pop()) ) {
|
||||
reconnectScope(item.scope);
|
||||
} else {
|
||||
AMOUNT++;
|
||||
item = this.createItem();
|
||||
}
|
||||
return item;
|
||||
@@ -1171,6 +1172,7 @@ IonicModule
|
||||
* @param {function(e)} callback The function to call when the gesture
|
||||
* happens.
|
||||
* @param {element} $element The angular element to listen for the event on.
|
||||
* @returns {ionic.Gesture} The gesture object (use this to remove the gesture later on).
|
||||
*/
|
||||
on: function(eventType, cb, $element) {
|
||||
return window.ionic.onGesture(eventType, cb, $element[0]);
|
||||
@@ -1179,9 +1181,9 @@ IonicModule
|
||||
* @ngdoc method
|
||||
* @name $ionicGesture#off
|
||||
* @description Remove an event listener for a gesture on an element. See {@link ionic.utility:ionic.EventController#offGesture}.
|
||||
* @param {ionic.Gesture} gesture The gesture that should be removed.
|
||||
* @param {string} eventType The gesture event to remove the listener for.
|
||||
* @param {function(e)} callback The listener to remove.
|
||||
* @param {element} $element The angular element that was listening for the event.
|
||||
*/
|
||||
off: function(gesture, eventType, cb) {
|
||||
return window.ionic.offGesture(gesture, eventType, cb);
|
||||
@@ -1191,7 +1193,9 @@ IonicModule
|
||||
|
||||
|
||||
var LOADING_TPL =
|
||||
'<div class="loading">' +
|
||||
'<div class="loading-container">' +
|
||||
'<div class="loading">' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
var LOADING_HIDE_DEPRECATED = '$ionicLoading instance.hide() has been deprecated. Use $ionicLoading.hide().';
|
||||
@@ -1221,8 +1225,32 @@ var LOADING_SET_DEPRECATED = '$ionicLoading instance.setContent() has been depre
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name $ionicLoadingConfig
|
||||
* @module ionic
|
||||
* @description
|
||||
* Set the default options to be passed to the {@link ionic.service:$ionicLoading} service.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* var app = angular.module('myApp', ['ionic'])
|
||||
* app.constant('$ionicLoadingConfig', {
|
||||
* template: 'Default Loading Template...'
|
||||
* });
|
||||
* app.controller('AppCtrl', function($scope, $ionicLoading) {
|
||||
* $scope.showLoading = function() {
|
||||
* $ionicLoading.show(); //options default to values in $ionicLoadingConfig
|
||||
* };
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
IonicModule
|
||||
.constant('$ionicLoadingConfig', {
|
||||
template: '<i class="ion-loading-d"></i>'
|
||||
})
|
||||
.factory('$ionicLoading', [
|
||||
'$ionicLoadingConfig',
|
||||
'$document',
|
||||
'$ionicTemplateLoader',
|
||||
'$ionicBackdrop',
|
||||
@@ -1231,7 +1259,7 @@ IonicModule
|
||||
'$log',
|
||||
'$compile',
|
||||
'$ionicPlatform',
|
||||
function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $compile, $ionicPlatform) {
|
||||
function($ionicLoadingConfig, $document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $compile, $ionicPlatform) {
|
||||
|
||||
var loaderInstance;
|
||||
//default values
|
||||
@@ -1300,17 +1328,17 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
|
||||
|
||||
templatePromise.then(function(html) {
|
||||
if (html) {
|
||||
self.element.html(html);
|
||||
$compile(self.element.contents())(self.scope);
|
||||
var loading = self.element.children();
|
||||
loading.html(html);
|
||||
$compile(loading.contents())(self.scope);
|
||||
}
|
||||
|
||||
//Don't show until template changes
|
||||
if (self.isShown) {
|
||||
self.element.addClass('visible');
|
||||
ionic.DomUtil.centerElementByMarginTwice(self.element[0]);
|
||||
ionic.requestAnimationFrame(function() {
|
||||
self.isShown && self.element.addClass('active');
|
||||
ionic.DomUtil.centerElementByMarginTwice(self.element[0]);
|
||||
$document[0].body.classList.add('loading-active');
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1324,6 +1352,7 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
|
||||
$ionicBackdrop.getElement().removeClass('backdrop-loading');
|
||||
}
|
||||
self.element.removeClass('active');
|
||||
$document[0].body.classList.remove('loading-active');
|
||||
setTimeout(function() {
|
||||
!self.isShown && self.element.removeClass('visible');
|
||||
}, 200);
|
||||
@@ -1339,7 +1368,7 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
|
||||
}
|
||||
|
||||
function showLoader(options) {
|
||||
options || (options = {});
|
||||
options = extend($ionicLoadingConfig || {}, options || {});
|
||||
var delay = options.delay || options.showDelay || 0;
|
||||
|
||||
//If loading.show() was called previously, cancel it and show with our new options
|
||||
@@ -1388,7 +1417,8 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
|
||||
*
|
||||
* The Modal is a content pane that can go over the user's main view
|
||||
* temporarily. Usually used for making a choice or editing an item.
|
||||
* Note that you need to put the content of the modal inside a div with the class `modal`.
|
||||
*
|
||||
* Put the content of the modal inside of an `<ion-modal-view>` element.
|
||||
*
|
||||
* Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
|
||||
* scope, passing in itself as an event argument. Both the modal.removed and modal.hidden events are
|
||||
@@ -1397,14 +1427,14 @@ function($document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q, $log, $c
|
||||
* @usage
|
||||
* ```html
|
||||
* <script id="my-modal.html" type="text/ng-template">
|
||||
* <div class="modal">
|
||||
* <ion-modal-view>
|
||||
* <ion-header-bar>
|
||||
* <h1 class="title">My Modal title</h1>
|
||||
* </ion-header-bar>
|
||||
* <ion-content>
|
||||
* Hello!
|
||||
* </ion-content>
|
||||
* </div>
|
||||
* </ion-modal-view>
|
||||
* </script>
|
||||
* ```
|
||||
* ```js
|
||||
@@ -1456,7 +1486,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
|
||||
* @description
|
||||
* Instantiated by the {@link ionic.service:$ionicModal} service.
|
||||
*
|
||||
* Hint: Be sure to call [remove()](#remove) when you are done with each modal
|
||||
* Be sure to call [remove()](#remove) when you are done with each modal
|
||||
* to clean it up and avoid memory leaks.
|
||||
*
|
||||
* Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
|
||||
@@ -1527,6 +1557,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
|
||||
|
||||
$timeout(function(){
|
||||
modalEl.addClass('ng-enter-active');
|
||||
ionic.trigger('resize');
|
||||
self.scope.$parent && self.scope.$parent.$broadcast('modal.shown', self);
|
||||
self.el.classList.add('active');
|
||||
}, 20);
|
||||
@@ -2751,7 +2782,17 @@ IonicModule
|
||||
* side menus.
|
||||
* @returns {boolean} Whether the content can be dragged to open side menus.
|
||||
*/
|
||||
'canDragContent'
|
||||
'canDragContent',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicSideMenuDelegate#edgeDragThreshold
|
||||
* @param {boolean|number=} value Set whether the content drag can only start if it is below a certain threshold distance from the edge of the screen. Accepts three different values:
|
||||
* - If a non-zero number is given, that many pixels is used as the maximum allowed distance from the edge that starts dragging the side menu.
|
||||
* - If true is given, the default number of pixels (25) is used as the maximum allowed distance.
|
||||
* - If false or 0 is given, the edge drag threshold is disabled, and dragging from anywhere on the content is allowed.
|
||||
* @returns {boolean} Whether the drag can start only from within the edge of screen threshold.
|
||||
*/
|
||||
'edgeDragThreshold',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicSideMenuDelegate#$getByHandle
|
||||
@@ -3093,7 +3134,7 @@ function($rootScope, $state, $location, $document, $animate, $ionicPlatform, $io
|
||||
return false;
|
||||
}
|
||||
$ionicPlatform.registerBackButtonAction(
|
||||
onHardwareBackButton,
|
||||
onHardwareBackButton,
|
||||
PLATFORM_BACK_BUTTON_PRIORITY_VIEW
|
||||
);
|
||||
|
||||
@@ -3499,6 +3540,8 @@ function($rootScope, $state, $location, $window, $injector, $animate, $ionicNavV
|
||||
}
|
||||
});
|
||||
return;
|
||||
} else if(!doAnimation) {
|
||||
document.body.classList.remove('disable-pointer-events');
|
||||
}
|
||||
|
||||
// no animation
|
||||
@@ -3935,7 +3978,6 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
backListenDone();
|
||||
if (self._rememberScrollId) {
|
||||
$$scrollValueCache[self._rememberScrollId] = scrollView.getValues();
|
||||
void 0;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3960,8 +4002,6 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
self.rememberScrollPosition(viewId);
|
||||
self.scrollToRememberedPosition();
|
||||
|
||||
void 0;
|
||||
|
||||
backListenDone = $rootScope.$on('$viewHistory.viewBack', function(e, fromViewId, toViewId) {
|
||||
//When going back from this view, forget its saved scroll position
|
||||
if (viewId === fromViewId) {
|
||||
@@ -4019,12 +4059,19 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
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 {
|
||||
if (!(hash && elm)) {
|
||||
scrollView.scrollTo(0,0, !!shouldAnimate);
|
||||
return;
|
||||
}
|
||||
var curElm = elm;
|
||||
var scrollLeft = 0, scrollTop = 0, levelsClimbed = 0;
|
||||
do {
|
||||
if(curElm !== null)scrollLeft += curElm.offsetLeft;
|
||||
if(curElm !== null)scrollTop += curElm.offsetTop;
|
||||
curElm = curElm.offsetParent;
|
||||
levelsClimbed++;
|
||||
} while (curElm.attributes != self.element.attributes && curElm.offsetParent);
|
||||
scrollView.scrollTo(scrollLeft, scrollTop, !!shouldAnimate);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4091,12 +4138,36 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) {
|
||||
return $scope.dragContent;
|
||||
};
|
||||
|
||||
this.edgeThreshold = 25;
|
||||
this.edgeThresholdEnabled = false;
|
||||
this.edgeDragThreshold = function(value) {
|
||||
if (arguments.length) {
|
||||
if (angular.isNumber(value) && value > 0) {
|
||||
this.edgeThreshold = value;
|
||||
this.edgeThresholdEnabled = true;
|
||||
} else {
|
||||
this.edgeThresholdEnabled = !!value;
|
||||
}
|
||||
}
|
||||
return this.edgeThresholdEnabled;
|
||||
};
|
||||
|
||||
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'));
|
||||
//Only restrict edge when sidemenu is closed and restriction is enabled
|
||||
var shouldOnlyAllowEdgeDrag = self.edgeThresholdEnabled && !self.isOpen();
|
||||
var startX = e.gesture.startEvent && e.gesture.startEvent.center &&
|
||||
e.gesture.startEvent.center.pageX;
|
||||
|
||||
var dragIsWithinBounds = !shouldOnlyAllowEdgeDrag ||
|
||||
startX <= self.edgeThreshold ||
|
||||
startX >= self.content.offsetWidth - self.edgeThreshold;
|
||||
|
||||
return ($scope.dragContent || self.isOpen()) &&
|
||||
dragIsWithinBounds &&
|
||||
!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;
|
||||
@@ -4327,13 +4398,14 @@ IonicModule
|
||||
replace: true,
|
||||
require: '?ngModel',
|
||||
transclude: true,
|
||||
template: '<label class="item item-checkbox">' +
|
||||
'<div class="checkbox checkbox-input-hidden disable-pointer-events">' +
|
||||
'<input type="checkbox">' +
|
||||
'<i class="checkbox-icon"></i>' +
|
||||
'</div>' +
|
||||
'<div class="item-content disable-pointer-events" ng-transclude></div>' +
|
||||
'</label>',
|
||||
template:
|
||||
'<label class="item item-checkbox">' +
|
||||
'<div class="checkbox checkbox-input-hidden disable-pointer-events">' +
|
||||
'<input type="checkbox">' +
|
||||
'<i class="checkbox-icon"></i>' +
|
||||
'</div>' +
|
||||
'<div class="item-content disable-pointer-events" ng-transclude></div>' +
|
||||
'</label>',
|
||||
compile: function(element, attr) {
|
||||
var input = element.find('input');
|
||||
forEach({
|
||||
@@ -4375,19 +4447,19 @@ 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, using directive attributes.
|
||||
* 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.
|
||||
* The more complicated your elements, the more likely it is that the on-demand compilation will cause
|
||||
* The more complicated your elements, the more likely it is that the on-demand compilation will cause
|
||||
* some jerkiness in the user's scrolling.
|
||||
* 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.
|
||||
* 7. You should not use the ng-show and ng-hide directives on your ion-content/ion-scroll elements that
|
||||
* have a collection-repeat inside. ng-show and ng-hide apply the `display: none` css rule to the content's
|
||||
* style, causing the scrollView to read the width and height of the content as 0. Resultingly,
|
||||
* style, causing the scrollView to read the width and height of the content as 0. Resultingly,
|
||||
* collection-repeat will render elements that have just been un-hidden incorrectly.
|
||||
*
|
||||
*
|
||||
@@ -4445,7 +4517,7 @@ IonicModule
|
||||
* </div>
|
||||
* </ion-content>
|
||||
* ```
|
||||
* Percentage of total visible list dimensions. This example shows a 3 by 3 matrix that fits on the screen (3 rows and 3 colums). Note that dimensions are used in the creation of the element and therefore a measurement of the item cannnot be used as an input dimension.
|
||||
* Percentage of total visible list dimensions. This example shows a 3 by 3 matrix that fits on the screen (3 rows and 3 colums). Note that dimensions are used in the creation of the element and therefore a measurement of the item cannnot be used as an input dimension.
|
||||
* ```css
|
||||
* .my-image-item img {
|
||||
* height: 33%;
|
||||
@@ -4493,6 +4565,11 @@ var COLLECTION_REPEAT_ATTR_WIDTH_ERROR = "collection-repeat expected attribute c
|
||||
var COLLECTION_REPEAT_ATTR_REPEAT_ERROR = "collection-repeat expected expression in form of '_item_ in _collection_[ track by _id_]' but got '%'";
|
||||
|
||||
IonicModule
|
||||
.directive({
|
||||
ngSrc: collectionRepeatSrcDirective('ngSrc', 'src'),
|
||||
ngSrcset: collectionRepeatSrcDirective('ngSrcset', 'srcset'),
|
||||
ngHref: collectionRepeatSrcDirective('ngHref', 'href')
|
||||
})
|
||||
.directive('collectionRepeat', [
|
||||
'$collectionRepeatManager',
|
||||
'$collectionDataSource',
|
||||
@@ -4504,6 +4581,7 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
|
||||
terminal: true,
|
||||
$$tlb: true,
|
||||
require: '^$ionicScroll',
|
||||
controller: [function(){}],
|
||||
link: function($scope, $element, $attr, scrollCtrl, $transclude) {
|
||||
var scrollView = scrollCtrl.scrollView;
|
||||
if (scrollView.options.scrollingX && scrollView.options.scrollingY) {
|
||||
@@ -4587,6 +4665,31 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
|
||||
};
|
||||
}]);
|
||||
|
||||
// Fix for #1674
|
||||
// Problem: if an ngSrc or ngHref expression evaluates to a falsy value, it will
|
||||
// not erase the previous truthy value of the href.
|
||||
// In collectionRepeat, we re-use elements from before. So if the ngHref expression
|
||||
// evaluates to truthy for item 1 and then falsy for item 2, if an element changes
|
||||
// from representing item 1 to representing item 2, item 2 will still have
|
||||
// item 1's href value.
|
||||
// Solution: erase the href or src attribute if ngHref/ngSrc are falsy.
|
||||
function collectionRepeatSrcDirective(ngAttrName, attrName) {
|
||||
return [function() {
|
||||
return {
|
||||
priority: '99', // it needs to run after the attributes are interpolated
|
||||
require: '^?collectionRepeat',
|
||||
link: function(scope, element, attr, collectionRepeatCtrl) {
|
||||
if (!collectionRepeatCtrl) return;
|
||||
attr.$observe(ngAttrName, function(value) {
|
||||
if (!value) {
|
||||
element.removeAttr(attrName);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ionContent
|
||||
@@ -4625,6 +4728,8 @@ function($collectionRepeatManager, $collectionDataSource, $parse) {
|
||||
* 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.
|
||||
* @param {boolean=} has-bouncing Whether to allow scrolling to bounce past the edges
|
||||
* of the content. Defaults to true on iOS, false on Android.
|
||||
*/
|
||||
IonicModule
|
||||
.directive('ionContent', [
|
||||
@@ -4725,13 +4830,11 @@ function($timeout, $controller, $ionicBind) {
|
||||
};
|
||||
}]);
|
||||
|
||||
var GESTURE_DIRECTIVES = 'onHold onTap onTouch onRelease onDrag onDragUp onDragRight onDragDown onDragLeft onSwipe onSwipeUp onSwipeRight onSwipeDown onSwipeLeft'.split(' ');
|
||||
|
||||
forEach(
|
||||
'onHold onTap onTouch onRelease onDrag onDragUp onDragRight onDragDown onDragLeft onSwipe onSwipeUp onSwipeRight onSwipeBottom onSwipeLeft'.split(' '),
|
||||
function(name) {
|
||||
IonicModule.directive(name, gestureDirective(name));
|
||||
}
|
||||
);
|
||||
GESTURE_DIRECTIVES.forEach(function(name) {
|
||||
IonicModule.directive(name, gestureDirective(name));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
@@ -5006,11 +5109,12 @@ IonicModule
|
||||
* Note: If you use ionHeaderBar in combination with ng-if, the surrounding content
|
||||
* will not align correctly. This will be fixed soon.
|
||||
*
|
||||
* @param {string=} align-title Where to align the title.
|
||||
* @param {string=} align-title Where to align the title.
|
||||
* Available: 'left', 'right', or 'center'. Defaults to 'center'.
|
||||
* @param {boolean=} no-tap-scroll By default, the header bar will scroll the
|
||||
* content to the top when tapped. Set no-tap-scroll to true to disable this
|
||||
* behavior.
|
||||
* Avaialble: 'left', 'right', or 'center'. Defaults to 'center'.
|
||||
* Available: true or false. Defaults to false.
|
||||
*
|
||||
* @usage
|
||||
* ```html
|
||||
@@ -5046,7 +5150,7 @@ IonicModule
|
||||
* will not align correctly. This will be fixed soon.
|
||||
*
|
||||
* @param {string=} align-title Where to align the title.
|
||||
* Avaialble: 'left', 'right', or 'center'. Defaults to 'center'.
|
||||
* Available: 'left', 'right', or 'center'. Defaults to 'center'.
|
||||
*
|
||||
* @usage
|
||||
* ```html
|
||||
@@ -5368,7 +5472,7 @@ function($animate, $compile) {
|
||||
|
||||
|
||||
var ITEM_TPL_DELETE_BUTTON =
|
||||
'<div class="item-left-edit item-delete ng-hide">' +
|
||||
'<div class="item-left-edit item-delete enable-pointer-events">' +
|
||||
'</div>';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
@@ -5402,7 +5506,7 @@ IonicModule
|
||||
.directive('ionDeleteButton', ['$animate', function($animate) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['^ionItem', '^ionList'],
|
||||
require: ['^ionItem', '^?ionList'],
|
||||
//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,
|
||||
@@ -5417,8 +5521,8 @@ IonicModule
|
||||
container.append($element);
|
||||
itemCtrl.$element.append(container).addClass('item-left-editable');
|
||||
|
||||
if (listCtrl.showDelete()) {
|
||||
$animate.removeClass(container, 'ng-hide');
|
||||
if (listCtrl && listCtrl.showDelete()) {
|
||||
container.addClass('visible active');
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -5517,7 +5621,7 @@ IonicModule
|
||||
}]);
|
||||
|
||||
var ITEM_TPL_REORDER_BUTTON =
|
||||
'<div data-prevent-scroll="true" class="item-right-edit item-reorder ng-hide">' +
|
||||
'<div data-prevent-scroll="true" class="item-right-edit item-reorder enable-pointer-events">' +
|
||||
'</div>';
|
||||
|
||||
/**
|
||||
@@ -5532,17 +5636,18 @@ var ITEM_TPL_REORDER_BUTTON =
|
||||
*
|
||||
* 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).
|
||||
* Note: Reordering works best when used with `ng-repeat`. Be sure that all `ion-item` children of an `ion-list` are part of the same `ng-repeat` expression.
|
||||
*
|
||||
* See {@link ionic.directive:ionList} for a complete example.
|
||||
* When an item reorder is complete, the expression given in the `on-reorder` attribute is called. The `on-reorder` expression is given two locals that can be used: `$fromIndex` and `$toIndex`. See below for an example.
|
||||
*
|
||||
* Look at {@link ionic.directive:ionList} for more examples.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```html
|
||||
* <ion-list ng-controller="MyCtrl">
|
||||
* <ion-item ng-repeat="item in items">
|
||||
* Item {{$index}}
|
||||
* Item {{item}}
|
||||
* <ion-reorder-button class="ion-navicon"
|
||||
* on-reorder="moveItem(item, $fromIndex, $toIndex)">
|
||||
* </ion-reorder>
|
||||
@@ -5564,10 +5669,10 @@ var ITEM_TPL_REORDER_BUTTON =
|
||||
* Parameters given: $fromIndex, $toIndex.
|
||||
*/
|
||||
IonicModule
|
||||
.directive('ionReorderButton', ['$animate', function($animate) {
|
||||
.directive('ionReorderButton', ['$animate', '$parse', function($animate, $parse) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['^ionItem', '^ionList'],
|
||||
require: ['^ionItem', '^?ionList'],
|
||||
priority: Number.MAX_VALUE,
|
||||
compile: function($element, $attr) {
|
||||
$attr.$set('class', ($attr['class'] || '') + ' button icon button-icon', true);
|
||||
@@ -5575,8 +5680,10 @@ IonicModule
|
||||
return function($scope, $element, $attr, ctrls) {
|
||||
var itemCtrl = ctrls[0];
|
||||
var listCtrl = ctrls[1];
|
||||
var onReorderFn = $parse($attr.onReorder);
|
||||
|
||||
$scope.$onReorder = function(oldIndex, newIndex) {
|
||||
$scope.$eval($attr.onReorder, {
|
||||
onReorderFn($scope, {
|
||||
$fromIndex: oldIndex,
|
||||
$toIndex: newIndex
|
||||
});
|
||||
@@ -5586,8 +5693,8 @@ IonicModule
|
||||
container.append($element);
|
||||
itemCtrl.$element.append(container).addClass('item-right-editable');
|
||||
|
||||
if (listCtrl.showReorder()) {
|
||||
$animate.removeClass(container, 'ng-hide');
|
||||
if (listCtrl && listCtrl.showReorder()) {
|
||||
container.addClass('visible active');
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -5783,7 +5890,7 @@ function($animate, $timeout) {
|
||||
//Make sure onReorder is called in apply cycle,
|
||||
//but also make sure it has no conflicts by doing
|
||||
//$evalAsync
|
||||
itemScope.$evalAsync(function() {
|
||||
$timeout(function() {
|
||||
itemScope.$onReorder(oldIndex, newIndex);
|
||||
});
|
||||
}
|
||||
@@ -5793,18 +5900,17 @@ function($animate, $timeout) {
|
||||
}
|
||||
});
|
||||
|
||||
if (angular.isDefined($attr.canSwipe)) {
|
||||
if (isDefined($attr.canSwipe)) {
|
||||
$scope.$watch('!!(' + $attr.canSwipe + ')', function(value) {
|
||||
listCtrl.canSwipeItems(value);
|
||||
});
|
||||
}
|
||||
|
||||
if (angular.isDefined($attr.showDelete)) {
|
||||
if (isDefined($attr.showDelete)) {
|
||||
$scope.$watch('!!(' + $attr.showDelete + ')', function(value) {
|
||||
listCtrl.showDelete(value);
|
||||
});
|
||||
}
|
||||
if (angular.isDefined($attr.showReorder)) {
|
||||
if (isDefined($attr.showReorder)) {
|
||||
$scope.$watch('!!(' + $attr.showReorder + ')', function(value) {
|
||||
listCtrl.showReorder(value);
|
||||
});
|
||||
@@ -5820,9 +5926,12 @@ function($animate, $timeout) {
|
||||
listCtrl.canSwipeItems(!isShown);
|
||||
|
||||
$element.children().toggleClass('list-left-editing', isShown);
|
||||
toggleNgHide('.item-delete.item-left-edit', isShown);
|
||||
toggleTapDisabled('.item-content', isShown);
|
||||
$element.toggleClass('disable-pointer-events', isShown);
|
||||
|
||||
var deleteButton = jqLite($element[0].getElementsByClassName('item-delete'));
|
||||
setButtonShown(deleteButton, listCtrl.showDelete);
|
||||
});
|
||||
|
||||
$scope.$watch(function() {
|
||||
return listCtrl.showReorder();
|
||||
}, function(isShown, wasShown) {
|
||||
@@ -5833,27 +5942,18 @@ function($animate, $timeout) {
|
||||
listCtrl.canSwipeItems(!isShown);
|
||||
|
||||
$element.children().toggleClass('list-right-editing', isShown);
|
||||
toggleNgHide('.item-reorder.item-right-edit', isShown);
|
||||
toggleTapDisabled('.item-content', isShown);
|
||||
$element.toggleClass('disable-pointer-events', isShown);
|
||||
|
||||
var reorderButton = jqLite($element[0].getElementsByClassName('item-reorder'));
|
||||
setButtonShown(reorderButton, listCtrl.showReorder);
|
||||
});
|
||||
|
||||
function toggleNgHide(selector, shouldShow) {
|
||||
forEach($element[0].querySelectorAll(selector), function(node) {
|
||||
if (shouldShow) {
|
||||
$animate.removeClass(jqLite(node), 'ng-hide');
|
||||
} else {
|
||||
$animate.addClass(jqLite(node), 'ng-hide');
|
||||
}
|
||||
function setButtonShown(el, shown) {
|
||||
shown() && el.addClass('visible') || el.removeClass('active');
|
||||
ionic.requestAnimationFrame(function() {
|
||||
shown() && el.addClass('active') || el.removeClass('invisible');
|
||||
});
|
||||
}
|
||||
function toggleTapDisabled(selector, shouldDisable) {
|
||||
var el = jqLite($element[0].querySelectorAll(selector));
|
||||
if (shouldDisable) {
|
||||
el.attr('data-tap-disabled', 'true');
|
||||
} else {
|
||||
el.removeAttr('data-tap-disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -5942,12 +6042,23 @@ IonicModule
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
controller: [function(){}],
|
||||
template: '<div class="modal-backdrop">' +
|
||||
'<div class="modal-wrapper" ng-transclude></div>' +
|
||||
'</div>'
|
||||
};
|
||||
}]);
|
||||
|
||||
IonicModule
|
||||
.directive('ionModalView', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
compile: function(element, attr) {
|
||||
element.addClass('modal');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ionNavBackButton
|
||||
@@ -5979,7 +6090,7 @@ IonicModule
|
||||
* ```html
|
||||
* <ion-nav-bar ng-controller="MyCtrl">
|
||||
* <ion-nav-back-button class="button-clear"
|
||||
* ng-click="canGoBack && goBack()">
|
||||
* ng-click="doSomethingCool()">
|
||||
* <i class="ion-arrow-left-c"></i> Back
|
||||
* </ion-nav-back-button>
|
||||
* </ion-nav-bar>
|
||||
@@ -6083,8 +6194,9 @@ IonicModule.constant('$ionicNavBarConfig', {
|
||||
* 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')
|
||||
* Add an [animation class](/docs/components#animations) to the element via the
|
||||
* `animation` attribute to enable animated changing of titles
|
||||
* (recommended: 'nav-title-slide-ios7').
|
||||
*
|
||||
* Note that the ion-nav-bar element will only work correctly if your content has an
|
||||
* ionView around it.
|
||||
@@ -6094,7 +6206,7 @@ IonicModule.constant('$ionicNavBarConfig', {
|
||||
* ```html
|
||||
* <body ng-app="starter">
|
||||
* <!-- The nav bar that will be updated as we navigate -->
|
||||
* <ion-nav-bar class="bar-positive nav-title-slide-ios7">
|
||||
* <ion-nav-bar class="bar-positive" animation="nav-title-slide-ios7">
|
||||
* </ion-nav-bar>
|
||||
*
|
||||
* <!-- where the initial view template will be rendered -->
|
||||
@@ -6156,7 +6268,7 @@ function($ionicViewService, $rootScope, $animate, $compile, $ionicNavBarConfig)
|
||||
compile: function(tElement, tAttrs) {
|
||||
//We cannot transclude here because it breaks element.data() inheritance on compile
|
||||
tElement
|
||||
.addClass('bar bar-header nav-bar ' + $ionicNavBarConfig.transition)
|
||||
.addClass('bar bar-header nav-bar')
|
||||
.append(
|
||||
'<div class="buttons left-buttons"> ' +
|
||||
'</div>' +
|
||||
@@ -6165,6 +6277,12 @@ function($ionicViewService, $rootScope, $animate, $compile, $ionicNavBarConfig)
|
||||
'</div>'
|
||||
);
|
||||
|
||||
if (isDefined(tAttrs.animation)) {
|
||||
tElement.addClass(tAttrs.animation);
|
||||
} else {
|
||||
tElement.addClass($ionicNavBarConfig.transition);
|
||||
}
|
||||
|
||||
return { pre: prelink };
|
||||
function prelink($scope, $element, $attr, navBarCtrl) {
|
||||
navBarCtrl._headerBarView = new ionic.views.HeaderBar({
|
||||
@@ -6947,6 +7065,7 @@ IonicModule
|
||||
* @usage
|
||||
* ```html
|
||||
* <ion-side-menu-content
|
||||
* edge-drag-threshold="true"
|
||||
* drag-content="true">
|
||||
* </ion-side-menu-content>
|
||||
* ```
|
||||
@@ -6954,6 +7073,10 @@ IonicModule
|
||||
* {@link ionic.directive:ionSideMenus} documentation.
|
||||
*
|
||||
* @param {boolean=} drag-content Whether the content can be dragged. Default true.
|
||||
* @param {boolean|number=} edge-drag-threshold Whether the content drag can only start if it is below a certain threshold distance from the edge of the screen. Default false. Accepts three types of values:
|
||||
* - If a non-zero number is given, that many pixels is used as the maximum allowed distance from the edge that starts dragging the side menu.
|
||||
* - If true is given, the default number of pixels (25) is used as the maximum allowed distance.
|
||||
* - If false or 0 is given, the edge drag threshold is disabled, and dragging from anywhere on the content is allowed.
|
||||
*
|
||||
*/
|
||||
IonicModule
|
||||
@@ -6972,7 +7095,7 @@ function($timeout, $ionicGesture) {
|
||||
|
||||
$element.addClass('menu-content pane');
|
||||
|
||||
if (angular.isDefined(attr.dragContent)) {
|
||||
if (isDefined(attr.dragContent)) {
|
||||
$scope.$watch(attr.dragContent, function(value) {
|
||||
sideMenuCtrl.canDragContent(value);
|
||||
});
|
||||
@@ -6980,6 +7103,12 @@ function($timeout, $ionicGesture) {
|
||||
sideMenuCtrl.canDragContent(true);
|
||||
}
|
||||
|
||||
if (isDefined(attr.edgeDragThreshold)) {
|
||||
$scope.$watch(attr.edgeDragThreshold, function(value) {
|
||||
sideMenuCtrl.edgeDragThreshold(value);
|
||||
});
|
||||
}
|
||||
|
||||
var defaultPrevented = false;
|
||||
var isDragging = false;
|
||||
|
||||
@@ -7022,6 +7151,7 @@ function($timeout, $ionicGesture) {
|
||||
var releaseGesture = $ionicGesture.on('release', dragReleaseFn, $element);
|
||||
|
||||
sideMenuCtrl.setContent({
|
||||
element: element[0],
|
||||
onDrag: function(e) {},
|
||||
endDrag: function(e) {},
|
||||
getTranslateX: function() {
|
||||
@@ -7150,7 +7280,8 @@ IonicModule
|
||||
*
|
||||
* @param {string=} delegate-handle The handle used to identify this slideBox
|
||||
* with {@link ionic.service:$ionicSlideBoxDelegate}.
|
||||
* @param {boolean=} does-continue Whether the slide box should automatically slide.
|
||||
* @param {boolean=} does-continue Whether the slide box should loop.
|
||||
* @param {boolean=} auto-play Whether the slide box should automatically slide. Default true if does-continue is true.
|
||||
* @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.
|
||||
@@ -7168,6 +7299,7 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
autoPlay: '=',
|
||||
doesContinue: '@',
|
||||
slideInterval: '@',
|
||||
showPager: '@',
|
||||
@@ -7180,7 +7312,8 @@ function($timeout, $compile, $ionicSlideBoxDelegate) {
|
||||
var _this = this;
|
||||
|
||||
var continuous = $scope.$eval($scope.doesContinue) === true;
|
||||
var slideInterval = continuous ? $scope.$eval($scope.slideInterval) || 4000 : 0;
|
||||
var shouldAutoPlay = isDefined($attrs.autoPlay) ? !!$scope.autoPlay : false;
|
||||
var slideInterval = shouldAutoPlay ? $scope.$eval($scope.slideInterval) || 4000 : 0;
|
||||
|
||||
var slider = new ionic.views.Slider({
|
||||
el: $element[0],
|
||||
@@ -7375,6 +7508,7 @@ function($rootScope, $animate, $ionicBind, $compile) {
|
||||
attrStr('icon-off', attr.iconOff) +
|
||||
attrStr('badge', attr.badge) +
|
||||
attrStr('badge-style', attr.badgeStyle) +
|
||||
attrStr('hidden', attr.hidden) +
|
||||
attrStr('class', attr['class']) +
|
||||
'></ion-tab-nav>';
|
||||
|
||||
@@ -7453,7 +7587,7 @@ IonicModule
|
||||
replace: true,
|
||||
require: ['^ionTabs', '^ionTab'],
|
||||
template:
|
||||
'<a ng-class="{\'tab-item-active\': isTabActive(), \'has-badge\':badge}" ' +
|
||||
'<a ng-class="{\'tab-item-active\': isTabActive(), \'has-badge\':badge, \'tab-hidden\':isHidden()}" ' +
|
||||
' class="tab-item">' +
|
||||
'<span class="badge {{badgeStyle}}" ng-if="badge">{{badge}}</span>' +
|
||||
'<i class="icon {{getIconOn()}}" ng-if="getIconOn() && isTabActive()"></i>' +
|
||||
@@ -7466,6 +7600,7 @@ IonicModule
|
||||
iconOn: '@',
|
||||
iconOff: '@',
|
||||
badge: '=',
|
||||
hidden: '@',
|
||||
badgeStyle: '@',
|
||||
'class': '@'
|
||||
},
|
||||
@@ -7489,6 +7624,11 @@ IonicModule
|
||||
});
|
||||
}
|
||||
|
||||
$scope.isHidden = function() {
|
||||
if($attrs.hidden === 'true' || $attrs.hidden === true)return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.getIconOn = function() {
|
||||
return $scope.iconOn || $scope.icon;
|
||||
};
|
||||
@@ -7636,33 +7776,34 @@ function($ionicGesture, $timeout) {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
require: '?ngModel',
|
||||
scope: {
|
||||
ngModel: '=?',
|
||||
ngValue: '=?',
|
||||
ngChecked: '=?',
|
||||
ngChange: '&',
|
||||
ngDisabled: '=?'
|
||||
},
|
||||
transclude: true,
|
||||
template: '<div class="item item-toggle">' +
|
||||
'<div ng-transclude></div>' +
|
||||
'<label class="toggle">' +
|
||||
'<input type="checkbox" ng-model="ngModel" ng-value="ngValue" ng-change="ngChange()" ng-disabled="ngDisabled">' +
|
||||
'<div class="track">' +
|
||||
'<div class="handle"></div>' +
|
||||
'</div>' +
|
||||
'</label>' +
|
||||
'</div>',
|
||||
template:
|
||||
'<div class="item item-toggle">' +
|
||||
'<div ng-transclude></div>' +
|
||||
'<label class="toggle">' +
|
||||
'<input type="checkbox">' +
|
||||
'<div class="track">' +
|
||||
'<div class="handle"></div>' +
|
||||
'</div>' +
|
||||
'</label>' +
|
||||
'</div>',
|
||||
|
||||
compile: function(element, attr) {
|
||||
var input = element.find('input');
|
||||
if(attr.name) input.attr('name', attr.name);
|
||||
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);
|
||||
}
|
||||
forEach({
|
||||
'name': attr.name,
|
||||
'ng-value': attr.ngValue,
|
||||
'ng-model': attr.ngModel,
|
||||
'ng-checked': attr.ngChecked,
|
||||
'ng-disabled': attr.ngDisabled,
|
||||
'ng-true-value': attr.ngTrueValue,
|
||||
'ng-false-value': attr.ngFalseValue,
|
||||
'ng-change': attr.ngChange
|
||||
}, function(value, name) {
|
||||
if (isDefined(value)) {
|
||||
input.attr(name, value);
|
||||
}
|
||||
});
|
||||
|
||||
return function($scope, $element, $attr) {
|
||||
var el, checkbox, track, handle;
|
||||
@@ -7735,13 +7876,17 @@ IonicModule
|
||||
return {
|
||||
restrict: 'EA',
|
||||
priority: 1000,
|
||||
require: '^?ionNavBar',
|
||||
require: ['^?ionNavBar', '^?ionModal'],
|
||||
compile: function(tElement, tAttrs, transclude) {
|
||||
tElement.addClass('pane');
|
||||
tElement[0].removeAttribute('title');
|
||||
|
||||
return function link($scope, $element, $attr, navBarCtrl) {
|
||||
if (!navBarCtrl) {
|
||||
return function link($scope, $element, $attr, ctrls) {
|
||||
var navBarCtrl = ctrls[0];
|
||||
var modalCtrl = ctrls[1];
|
||||
|
||||
//Don't use the ionView if we're inside a modal or there's no navbar
|
||||
if (!navBarCtrl || modalCtrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user