nexus site path corrected
[portal.git] / ecomp-portal-FE / client / bower_components / angular-material / modules / js / bottomSheet / bottomSheet.js
1 /*!
2  * Angular Material Design
3  * https://github.com/angular/material
4  * @license MIT
5  * v0.9.8
6  */
7 (function( window, angular, undefined ){
8 "use strict";
9
10 /**
11  * @ngdoc module
12  * @name material.components.bottomSheet
13  * @description
14  * BottomSheet
15  */
16 angular.module('material.components.bottomSheet', [
17   'material.core',
18   'material.components.backdrop'
19 ])
20   .directive('mdBottomSheet', MdBottomSheetDirective)
21   .provider('$mdBottomSheet', MdBottomSheetProvider);
22
23 function MdBottomSheetDirective() {
24   return {
25     restrict: 'E'
26   };
27 }
28
29 /**
30  * @ngdoc service
31  * @name $mdBottomSheet
32  * @module material.components.bottomSheet
33  *
34  * @description
35  * `$mdBottomSheet` opens a bottom sheet over the app and provides a simple promise API.
36  *
37  * ## Restrictions
38  *
39  * - The bottom sheet's template must have an outer `<md-bottom-sheet>` element.
40  * - Add the `md-grid` class to the bottom sheet for a grid layout.
41  * - Add the `md-list` class to the bottom sheet for a list layout.
42  *
43  * @usage
44  * <hljs lang="html">
45  * <div ng-controller="MyController">
46  *   <md-button ng-click="openBottomSheet()">
47  *     Open a Bottom Sheet!
48  *   </md-button>
49  * </div>
50  * </hljs>
51  * <hljs lang="js">
52  * var app = angular.module('app', ['ngMaterial']);
53  * app.controller('MyController', function($scope, $mdBottomSheet) {
54  *   $scope.openBottomSheet = function() {
55  *     $mdBottomSheet.show({
56  *       template: '<md-bottom-sheet>Hello!</md-bottom-sheet>'
57  *     });
58  *   };
59  * });
60  * </hljs>
61  */
62
63  /**
64  * @ngdoc method
65  * @name $mdBottomSheet#show
66  *
67  * @description
68  * Show a bottom sheet with the specified options.
69  *
70  * @param {object} options An options object, with the following properties:
71  *
72  *   - `templateUrl` - `{string=}`: The url of an html template file that will
73  *   be used as the content of the bottom sheet. Restrictions: the template must
74  *   have an outer `md-bottom-sheet` element.
75  *   - `template` - `{string=}`: Same as templateUrl, except this is an actual
76  *   template string.
77  *   - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified, it will create a new child scope.
78  *     This scope will be destroyed when the bottom sheet is removed unless `preserveScope` is set to true.
79  *   - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
80  *   - `controller` - `{string=}`: The controller to associate with this bottom sheet.
81  *   - `locals` - `{string=}`: An object containing key/value pairs. The keys will
82  *   be used as names of values to inject into the controller. For example,
83  *   `locals: {three: 3}` would inject `three` into the controller with the value
84  *   of 3.
85  *   - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
86  *   the location of the click will be used as the starting point for the opening animation
87  *   of the the dialog.
88  *   - `resolve` - `{object=}`: Similar to locals, except it takes promises as values
89  *   and the bottom sheet will not open until the promises resolve.
90  *   - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
91  *   - `parent` - `{element=}`: The element to append the bottom sheet to. The `parent` may be a `function`, `string`,
92  *   `object`, or null. Defaults to appending to the body of the root element (or the root element) of the application.
93  *   e.g. angular.element(document.getElementById('content')) or "#content"
94  *   - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the bottom sheet is open.
95  *     Default true.
96  *
97  * @returns {promise} A promise that can be resolved with `$mdBottomSheet.hide()` or
98  * rejected with `$mdBottomSheet.cancel()`.
99  */
100
101 /**
102  * @ngdoc method
103  * @name $mdBottomSheet#hide
104  *
105  * @description
106  * Hide the existing bottom sheet and resolve the promise returned from
107  * `$mdBottomSheet.show()`. This call will close the most recently opened/current bottomsheet (if any).
108  *
109  * @param {*=} response An argument for the resolved promise.
110  *
111  */
112
113 /**
114  * @ngdoc method
115  * @name $mdBottomSheet#cancel
116  *
117  * @description
118  * Hide the existing bottom sheet and reject the promise returned from
119  * `$mdBottomSheet.show()`.
120  *
121  * @param {*=} response An argument for the rejected promise.
122  *
123  */
124
125 function MdBottomSheetProvider($$interimElementProvider) {
126   // how fast we need to flick down to close the sheet, pixels/ms
127   var CLOSING_VELOCITY = 0.5;
128   var PADDING = 80; // same as css
129
130   bottomSheetDefaults.$inject = ["$animate", "$mdConstant", "$mdUtil", "$timeout", "$compile", "$mdTheming", "$mdBottomSheet", "$rootElement", "$mdGesture"];
131   return $$interimElementProvider('$mdBottomSheet')
132     .setDefaults({
133       methods: ['disableParentScroll', 'escapeToClose', 'targetEvent'],
134       options: bottomSheetDefaults
135     });
136
137   /* ngInject */
138   function bottomSheetDefaults($animate, $mdConstant, $mdUtil, $timeout, $compile, $mdTheming, $mdBottomSheet, $rootElement, $mdGesture) {
139     var backdrop;
140
141     return {
142       themable: true,
143       targetEvent: null,
144       onShow: onShow,
145       onRemove: onRemove,
146       escapeToClose: true,
147       disableParentScroll: true
148     };
149
150
151     function onShow(scope, element, options) {
152
153       element = $mdUtil.extractElementByName(element, 'md-bottom-sheet');
154
155       // Add a backdrop that will close on click
156       backdrop = $compile('<md-backdrop class="md-opaque md-bottom-sheet-backdrop">')(scope);
157       backdrop.on('click', function() {
158         $timeout($mdBottomSheet.cancel);
159       });
160       $mdTheming.inherit(backdrop, options.parent);
161
162       $animate.enter(backdrop, options.parent, null);
163
164       var bottomSheet = new BottomSheet(element, options.parent);
165       options.bottomSheet = bottomSheet;
166
167       // Give up focus on calling item
168       options.targetEvent && angular.element(options.targetEvent.target).blur();
169       $mdTheming.inherit(bottomSheet.element, options.parent);
170
171       if (options.disableParentScroll) {
172         options.lastOverflow = options.parent.css('overflow');
173         options.parent.css('overflow', 'hidden');
174       }
175
176       return $animate.enter(bottomSheet.element, options.parent)
177         .then(function() {
178           var focusable = angular.element(
179             element[0].querySelector('button') ||
180             element[0].querySelector('a') ||
181             element[0].querySelector('[ng-click]')
182           );
183           focusable.focus();
184
185           if (options.escapeToClose) {
186             options.rootElementKeyupCallback = function(e) {
187               if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
188                 $timeout($mdBottomSheet.cancel);
189               }
190             };
191             $rootElement.on('keyup', options.rootElementKeyupCallback);
192           }
193         });
194
195     }
196
197     function onRemove(scope, element, options) {
198
199       var bottomSheet = options.bottomSheet;
200
201       $animate.leave(backdrop);
202       return $animate.leave(bottomSheet.element).then(function() {
203         if (options.disableParentScroll) {
204           options.parent.css('overflow', options.lastOverflow);
205           delete options.lastOverflow;
206         }
207
208         bottomSheet.cleanup();
209
210         // Restore focus
211         options.targetEvent && angular.element(options.targetEvent.target).focus();
212       });
213     }
214
215     /**
216      * BottomSheet class to apply bottom-sheet behavior to an element
217      */
218     function BottomSheet(element, parent) {
219       var deregister = $mdGesture.register(parent, 'drag', { horizontal: false });
220       parent.on('$md.dragstart', onDragStart)
221         .on('$md.drag', onDrag)
222         .on('$md.dragend', onDragEnd);
223
224       return {
225         element: element,
226         cleanup: function cleanup() {
227           deregister();
228           parent.off('$md.dragstart', onDragStart)
229             .off('$md.drag', onDrag)
230             .off('$md.dragend', onDragEnd);
231         }
232       };
233
234       function onDragStart(ev) {
235         // Disable transitions on transform so that it feels fast
236         element.css($mdConstant.CSS.TRANSITION_DURATION, '0ms');
237       }
238
239       function onDrag(ev) {
240         var transform = ev.pointer.distanceY;
241         if (transform < 5) {
242           // Slow down drag when trying to drag up, and stop after PADDING
243           transform = Math.max(-PADDING, transform / 2);
244         }
245         element.css($mdConstant.CSS.TRANSFORM, 'translate3d(0,' + (PADDING + transform) + 'px,0)');
246       }
247
248       function onDragEnd(ev) {
249         if (ev.pointer.distanceY > 0 &&
250             (ev.pointer.distanceY > 20 || Math.abs(ev.pointer.velocityY) > CLOSING_VELOCITY)) {
251           var distanceRemaining = element.prop('offsetHeight') - ev.pointer.distanceY;
252           var transitionDuration = Math.min(distanceRemaining / ev.pointer.velocityY * 0.75, 500);
253           element.css($mdConstant.CSS.TRANSITION_DURATION, transitionDuration + 'ms');
254           $timeout($mdBottomSheet.cancel);
255         } else {
256           element.css($mdConstant.CSS.TRANSITION_DURATION, '');
257           element.css($mdConstant.CSS.TRANSFORM, '');
258         }
259       }
260     }
261
262   }
263
264 }
265 MdBottomSheetProvider.$inject = ["$$interimElementProvider"];
266
267 })(window, window.angular);