commonroutesApp/www/lib/angular-material/modules/closure/toolbar/toolbar.js
www/lib/angular-material/modules/closure/toolbar/toolbar.jsRaw
1/*!
2 * Angular Material Design
3 * https://github.com/angular/material
4 * @license MIT
5 * v1.1.1
6 */
7goog.provide('ngmaterial.components.toolbar');
8goog.require('ngmaterial.components.content');
9goog.require('ngmaterial.core');
10/**
11 * @ngdoc module
12 * @name material.components.toolbar
13 */
14mdToolbarDirective.$inject = ["$$rAF", "$mdConstant", "$mdUtil", "$mdTheming", "$animate"];
15angular.module('material.components.toolbar', [
16 'material.core',
17 'material.components.content'
18])
19 .directive('mdToolbar', mdToolbarDirective);
20
21/**
22 * @ngdoc directive
23 * @name mdToolbar
24 * @module material.components.toolbar
25 * @restrict E
26 * @description
27 * `md-toolbar` is used to place a toolbar in your app.
28 *
29 * Toolbars are usually used above a content area to display the title of the
30 * current page, and show relevant action buttons for that page.
31 *
32 * You can change the height of the toolbar by adding either the
33 * `md-medium-tall` or `md-tall` class to the toolbar.
34 *
35 * @usage
36 * <hljs lang="html">
37 * <div layout="column" layout-fill>
38 * <md-toolbar>
39 *
40 * <div class="md-toolbar-tools">
41 * <span>My App's Title</span>
42 *
43 * <!-- fill up the space between left and right area -->
44 * <span flex></span>
45 *
46 * <md-button>
47 * Right Bar Button
48 * </md-button>
49 * </div>
50 *
51 * </md-toolbar>
52 * <md-content>
53 * Hello!
54 * </md-content>
55 * </div>
56 * </hljs>
57 *
58 * @param {boolean=} md-scroll-shrink Whether the header should shrink away as
59 * the user scrolls down, and reveal itself as the user scrolls up.
60 *
61 * _**Note (1):** for scrollShrink to work, the toolbar must be a sibling of a
62 * `md-content` element, placed before it. See the scroll shrink demo._
63 *
64 * _**Note (2):** The `md-scroll-shrink` attribute is only parsed on component
65 * initialization, it does not watch for scope changes._
66 *
67 *
68 * @param {number=} md-shrink-speed-factor How much to change the speed of the toolbar's
69 * shrinking by. For example, if 0.25 is given then the toolbar will shrink
70 * at one fourth the rate at which the user scrolls down. Default 0.5.
71 */
72
73function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate) {
74 var translateY = angular.bind(null, $mdUtil.supplant, 'translate3d(0,{0}px,0)');
75
76 return {
77 template: '',
78 restrict: 'E',
79
80 link: function(scope, element, attr) {
81
82 element.addClass('_md'); // private md component indicator for styling
83 $mdTheming(element);
84
85 $mdUtil.nextTick(function () {
86 element.addClass('_md-toolbar-transitions'); // adding toolbar transitions after digest
87 }, false);
88
89 if (angular.isDefined(attr.mdScrollShrink)) {
90 setupScrollShrink();
91 }
92
93 function setupScrollShrink() {
94
95 var toolbarHeight;
96 var contentElement;
97 var disableScrollShrink = angular.noop;
98
99 // Current "y" position of scroll
100 // Store the last scroll top position
101 var y = 0;
102 var prevScrollTop = 0;
103 var shrinkSpeedFactor = attr.mdShrinkSpeedFactor || 0.5;
104
105 var debouncedContentScroll = $$rAF.throttle(onContentScroll);
106 var debouncedUpdateHeight = $mdUtil.debounce(updateToolbarHeight, 5 * 1000);
107
108 // Wait for $mdContentLoaded event from mdContent directive.
109 // If the mdContent element is a sibling of our toolbar, hook it up
110 // to scroll events.
111
112 scope.$on('$mdContentLoaded', onMdContentLoad);
113
114 // If the toolbar is used inside an ng-if statement, we may miss the
115 // $mdContentLoaded event, so we attempt to fake it if we have a
116 // md-content close enough.
117
118 attr.$observe('mdScrollShrink', onChangeScrollShrink);
119
120 // If the toolbar has ngShow or ngHide we need to update height immediately as it changed
121 // and not wait for $mdUtil.debounce to happen
122
123 if (attr.ngShow) { scope.$watch(attr.ngShow, updateToolbarHeight); }
124 if (attr.ngHide) { scope.$watch(attr.ngHide, updateToolbarHeight); }
125
126 // If the scope is destroyed (which could happen with ng-if), make sure
127 // to disable scroll shrinking again
128
129 scope.$on('$destroy', disableScrollShrink);
130
131 /**
132 *
133 */
134 function onChangeScrollShrink(shrinkWithScroll) {
135 var closestContent = element.parent().find('md-content');
136
137 // If we have a content element, fake the call; this might still fail
138 // if the content element isn't a sibling of the toolbar
139
140 if (!contentElement && closestContent.length) {
141 onMdContentLoad(null, closestContent);
142 }
143
144 // Evaluate the expression
145 shrinkWithScroll = scope.$eval(shrinkWithScroll);
146
147 // Disable only if the attribute's expression evaluates to false
148 if (shrinkWithScroll === false) {
149 disableScrollShrink();
150 } else {
151 disableScrollShrink = enableScrollShrink();
152 }
153 }
154
155 /**
156 *
157 */
158 function onMdContentLoad($event, newContentEl) {
159 // Toolbar and content must be siblings
160 if (newContentEl && element.parent()[0] === newContentEl.parent()[0]) {
161 // unhook old content event listener if exists
162 if (contentElement) {
163 contentElement.off('scroll', debouncedContentScroll);
164 }
165
166 contentElement = newContentEl;
167 disableScrollShrink = enableScrollShrink();
168 }
169 }
170
171 /**
172 *
173 */
174 function onContentScroll(e) {
175 var scrollTop = e ? e.target.scrollTop : prevScrollTop;
176
177 debouncedUpdateHeight();
178
179 y = Math.min(
180 toolbarHeight / shrinkSpeedFactor,
181 Math.max(0, y + scrollTop - prevScrollTop)
182 );
183
184 element.css($mdConstant.CSS.TRANSFORM, translateY([-y * shrinkSpeedFactor]));
185 contentElement.css($mdConstant.CSS.TRANSFORM, translateY([(toolbarHeight - y) * shrinkSpeedFactor]));
186
187 prevScrollTop = scrollTop;
188
189 $mdUtil.nextTick(function() {
190 var hasWhiteFrame = element.hasClass('md-whiteframe-z1');
191
192 if (hasWhiteFrame && !y) {
193 $animate.removeClass(element, 'md-whiteframe-z1');
194 } else if (!hasWhiteFrame && y) {
195 $animate.addClass(element, 'md-whiteframe-z1');
196 }
197 });
198
199 }
200
201 /**
202 *
203 */
204 function enableScrollShrink() {
205 if (!contentElement) return angular.noop; // no md-content
206
207 contentElement.on('scroll', debouncedContentScroll);
208 contentElement.attr('scroll-shrink', 'true');
209
210 $mdUtil.nextTick(updateToolbarHeight, false);
211
212 return function disableScrollShrink() {
213 contentElement.off('scroll', debouncedContentScroll);
214 contentElement.attr('scroll-shrink', 'false');
215
216 updateToolbarHeight();
217 };
218 }
219
220 /**
221 *
222 */
223 function updateToolbarHeight() {
224 toolbarHeight = element.prop('offsetHeight');
225 // Add a negative margin-top the size of the toolbar to the content el.
226 // The content will start transformed down the toolbarHeight amount,
227 // so everything looks normal.
228 //
229 // As the user scrolls down, the content will be transformed up slowly
230 // to put the content underneath where the toolbar was.
231 var margin = (-toolbarHeight * shrinkSpeedFactor) + 'px';
232
233 contentElement.css({
234 "margin-top": margin,
235 "margin-bottom": margin
236 });
237
238 onContentScroll();
239 }
240
241 }
242
243 }
244 };
245
246}
247
248ngmaterial.components.toolbar = angular.module("material.components.toolbar");