a545815cc44400130e26ff8c4136968cbd704dfb
[vnfsdk/refrepo.git] /
1 /*!
2  * Angular Material Design
3  * https://github.com/angular/material
4  * @license MIT
5  * v1.1.3
6  */
7 (function( window, angular, undefined ){
8 "use strict";
9
10 (function() {
11   'use strict';
12
13   /**
14    * @ngdoc module
15    * @name material.components.fabToolbar
16    */
17   angular
18     // Declare our module
19     .module('material.components.fabToolbar', [
20       'material.core',
21       'material.components.fabShared',
22       'material.components.fabActions'
23     ])
24
25     // Register our directive
26     .directive('mdFabToolbar', MdFabToolbarDirective)
27
28     // Register our custom animations
29     .animation('.md-fab-toolbar', MdFabToolbarAnimation)
30
31     // Register a service for the animation so that we can easily inject it into unit tests
32     .service('mdFabToolbarAnimation', MdFabToolbarAnimation);
33
34   /**
35    * @ngdoc directive
36    * @name mdFabToolbar
37    * @module material.components.fabToolbar
38    *
39    * @restrict E
40    *
41    * @description
42    *
43    * The `<md-fab-toolbar>` directive is used to present a toolbar of elements (usually `<md-button>`s)
44    * for quick access to common actions when a floating action button is activated (via click or
45    * keyboard navigation).
46    *
47    * You may also easily position the trigger by applying one one of the following classes to the
48    * `<md-fab-toolbar>` element:
49    *  - `md-fab-top-left`
50    *  - `md-fab-top-right`
51    *  - `md-fab-bottom-left`
52    *  - `md-fab-bottom-right`
53    *
54    * These CSS classes use `position: absolute`, so you need to ensure that the container element
55    * also uses `position: absolute` or `position: relative` in order for them to work.
56    *
57    * @usage
58    *
59    * <hljs lang="html">
60    * <md-fab-toolbar md-direction='left'>
61    *   <md-fab-trigger>
62    *     <md-button aria-label="Add..."><md-icon md-svg-src="/img/icons/plus.svg"></md-icon></md-button>
63    *   </md-fab-trigger>
64    *
65    *   <md-toolbar>
66    *    <md-fab-actions>
67    *      <md-button aria-label="Add User">
68    *        <md-icon md-svg-src="/img/icons/user.svg"></md-icon>
69    *      </md-button>
70    *
71    *      <md-button aria-label="Add Group">
72    *        <md-icon md-svg-src="/img/icons/group.svg"></md-icon>
73    *      </md-button>
74    *    </md-fab-actions>
75    *   </md-toolbar>
76    * </md-fab-toolbar>
77    * </hljs>
78    *
79    * @param {string} md-direction From which direction you would like the toolbar items to appear
80    * relative to the trigger element. Supports `left` and `right` directions.
81    * @param {expression=} md-open Programmatically control whether or not the toolbar is visible.
82    */
83   function MdFabToolbarDirective() {
84     return {
85       restrict: 'E',
86       transclude: true,
87       template: '<div class="md-fab-toolbar-wrapper">' +
88       '  <div class="md-fab-toolbar-content" ng-transclude></div>' +
89       '</div>',
90
91       scope: {
92         direction: '@?mdDirection',
93         isOpen: '=?mdOpen'
94       },
95
96       bindToController: true,
97       controller: 'MdFabController',
98       controllerAs: 'vm',
99
100       link: link
101     };
102
103     function link(scope, element, attributes) {
104       // Add the base class for animations
105       element.addClass('md-fab-toolbar');
106
107       // Prepend the background element to the trigger's button
108       element.find('md-fab-trigger').find('button')
109         .prepend('<div class="md-fab-toolbar-background"></div>');
110     }
111   }
112
113   function MdFabToolbarAnimation() {
114
115     function runAnimation(element, className, done) {
116       // If no className was specified, don't do anything
117       if (!className) {
118         return;
119       }
120
121       var el = element[0];
122       var ctrl = element.controller('mdFabToolbar');
123
124       // Grab the relevant child elements
125       var backgroundElement = el.querySelector('.md-fab-toolbar-background');
126       var triggerElement = el.querySelector('md-fab-trigger button');
127       var toolbarElement = el.querySelector('md-toolbar');
128       var iconElement = el.querySelector('md-fab-trigger button md-icon');
129       var actions = element.find('md-fab-actions').children();
130
131       // If we have both elements, use them to position the new background
132       if (triggerElement && backgroundElement) {
133         // Get our variables
134         var color = window.getComputedStyle(triggerElement).getPropertyValue('background-color');
135         var width = el.offsetWidth;
136         var height = el.offsetHeight;
137
138         // Make it twice as big as it should be since we scale from the center
139         var scale = 2 * (width / triggerElement.offsetWidth);
140
141         // Set some basic styles no matter what animation we're doing
142         backgroundElement.style.backgroundColor = color;
143         backgroundElement.style.borderRadius = width + 'px';
144
145         // If we're open
146         if (ctrl.isOpen) {
147           // Turn on toolbar pointer events when closed
148           toolbarElement.style.pointerEvents = 'inherit';
149
150           backgroundElement.style.width = triggerElement.offsetWidth + 'px';
151           backgroundElement.style.height = triggerElement.offsetHeight + 'px';
152           backgroundElement.style.transform = 'scale(' + scale + ')';
153
154           // Set the next close animation to have the proper delays
155           backgroundElement.style.transitionDelay = '0ms';
156           iconElement && (iconElement.style.transitionDelay = '.3s');
157
158           // Apply a transition delay to actions
159           angular.forEach(actions, function(action, index) {
160             action.style.transitionDelay = (actions.length - index) * 25 + 'ms';
161           });
162         } else {
163           // Turn off toolbar pointer events when closed
164           toolbarElement.style.pointerEvents = 'none';
165
166           // Scale it back down to the trigger's size
167           backgroundElement.style.transform = 'scale(1)';
168
169           // Reset the position
170           backgroundElement.style.top = '0';
171
172           if (element.hasClass('md-right')) {
173             backgroundElement.style.left = '0';
174             backgroundElement.style.right = null;
175           }
176
177           if (element.hasClass('md-left')) {
178             backgroundElement.style.right = '0';
179             backgroundElement.style.left = null;
180           }
181
182           // Set the next open animation to have the proper delays
183           backgroundElement.style.transitionDelay = '200ms';
184           iconElement && (iconElement.style.transitionDelay = '0ms');
185
186           // Apply a transition delay to actions
187           angular.forEach(actions, function(action, index) {
188             action.style.transitionDelay = 200 + (index * 25) + 'ms';
189           });
190         }
191       }
192     }
193
194     return {
195       addClass: function(element, className, done) {
196         runAnimation(element, className, done);
197         done();
198       },
199
200       removeClass: function(element, className, done) {
201         runAnimation(element, className, done);
202         done();
203       }
204     };
205   }
206 })();
207
208 })(window, window.angular);