@@ -56,19 +56,22 @@ angular.module('material.components.toolbar', [
56
56
* at one fourth the rate at which the user scrolls down. Default 0.5.
57
57
*/
58
58
59
- function mdToolbarDirective ( $$rAF , $mdConstant , $mdUtil , $mdTheming , $animate ) {
60
- var translateY = angular . bind ( null , $mdUtil . supplant , 'translate3d(0,{0}px,0)' ) ;
59
+ function mdToolbarDirective ( $$rAF , $mdConstant , $mdUtil , $mdTheming , $animate ) {
60
+ var translateY = angular . bind ( null , $mdUtil . supplant , 'translate3d(0,{0}px,0)' ) ;
61
61
62
62
return {
63
63
restrict : 'E' ,
64
+ template : '<div ng-transclude></div>' ,
65
+ transclude : true ,
64
66
controller : angular . noop ,
67
+ scope : {
68
+ scrollShrink : '=?mdScrollShrink'
69
+ } ,
65
70
link : function ( scope , element , attr ) {
66
71
67
72
$mdTheming ( element ) ;
68
73
69
- if ( angular . isDefined ( attr . mdScrollShrink ) ) {
70
- setupScrollShrink ( ) ;
71
- }
74
+ setupScrollShrink ( ) ;
72
75
73
76
function setupScrollShrink ( ) {
74
77
// Current "y" position of scroll
@@ -84,24 +87,68 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate )
84
87
var debouncedContentScroll = $$rAF . throttle ( onContentScroll ) ;
85
88
var debouncedUpdateHeight = $mdUtil . debounce ( updateToolbarHeight , 5 * 1000 ) ;
86
89
90
+ var disableScrollShrink ;
91
+
87
92
// Wait for $mdContentLoaded event from mdContent directive.
88
93
// If the mdContent element is a sibling of our toolbar, hook it up
89
94
// to scroll events.
90
95
scope . $on ( '$mdContentLoaded' , onMdContentLoad ) ;
91
96
97
+ // If the toolbar is used inside an ng-if statement, we may miss the
98
+ // $mdContentLoaded event, so we attempt to fake it if we have a
99
+ // md-content close enough.
100
+ scope . $watch ( 'scrollShrink' , onChangeScrollShrink ) ;
101
+
102
+ // If the scope is destroyed (which could happen with ng-if), make sure
103
+ // to disable scroll shrinking again
104
+ scope . $on ( '$destroy' , function ( ) {
105
+ disableScrollShrink ( ) ;
106
+ } ) ;
107
+
108
+ function onChangeScrollShrink ( scrollShrink ) {
109
+ var closestContent = element . parent ( ) . find ( 'md-content' ) ;
110
+
111
+ // If we have a content element, fake the call; this might still fail
112
+ // if the content element isn't a sibling of the toolbar
113
+ if ( ! contentElement && closestContent . length ) {
114
+ onMdContentLoad ( null , closestContent ) ;
115
+ }
116
+
117
+ if ( contentElement ) {
118
+ // Disable only if the attribute's expression evaluates to false
119
+ if ( scrollShrink === false ) {
120
+ disableScrollShrink ( ) ;
121
+ } else {
122
+ enableScrollShrink ( ) ;
123
+ }
124
+ }
125
+ }
126
+
127
+ function enableScrollShrink ( ) {
128
+ contentElement . on ( 'scroll' , debouncedContentScroll ) ;
129
+ contentElement . attr ( 'scroll-shrink' , 'true' ) ;
130
+
131
+ $$rAF ( updateToolbarHeight ) ;
132
+
133
+ return function disableScrollShrink ( ) {
134
+ contentElement . off ( 'scroll' , debouncedContentScroll ) ;
135
+ contentElement . attr ( 'scroll-shrink' , 'false' ) ;
136
+
137
+ $$rAF ( updateToolbarHeight ) ;
138
+ }
139
+ }
140
+
141
+
92
142
function onMdContentLoad ( $event , newContentEl ) {
93
143
// Toolbar and content must be siblings
94
- if ( element . parent ( ) [ 0 ] === newContentEl . parent ( ) [ 0 ] ) {
144
+ if ( newContentEl && element . parent ( ) [ 0 ] === newContentEl . parent ( ) [ 0 ] ) {
95
145
// unhook old content event listener if exists
96
146
if ( contentElement ) {
97
147
contentElement . off ( 'scroll' , debouncedContentScroll ) ;
98
148
}
99
149
100
- newContentEl . on ( 'scroll' , debouncedContentScroll ) ;
101
- newContentEl . attr ( 'scroll-shrink' , 'true' ) ;
102
-
103
150
contentElement = newContentEl ;
104
- $$rAF ( updateToolbarHeight ) ;
151
+ disableScrollShrink = enableScrollShrink ( ) ;
105
152
}
106
153
}
107
154
@@ -113,9 +160,12 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate )
113
160
//
114
161
// As the user scrolls down, the content will be transformed up slowly
115
162
// to put the content underneath where the toolbar was.
116
- var margin = ( - toolbarHeight * shrinkSpeedFactor ) + 'px' ;
117
- contentElement . css ( 'margin-top' , margin ) ;
118
- contentElement . css ( 'margin-bottom' , margin ) ;
163
+ var margin = ( - toolbarHeight * shrinkSpeedFactor ) + 'px' ;
164
+
165
+ contentElement . css ( {
166
+ "margin-top" : margin ,
167
+ "margin-bottom" : margin
168
+ } ) ;
119
169
120
170
onContentScroll ( ) ;
121
171
}
@@ -130,17 +180,17 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming, $animate )
130
180
Math . max ( 0 , y + scrollTop - prevScrollTop )
131
181
) ;
132
182
133
- element . css ( $mdConstant . CSS . TRANSFORM , translateY ( [ - y * shrinkSpeedFactor ] ) ) ;
134
- contentElement . css ( $mdConstant . CSS . TRANSFORM , translateY ( [ ( toolbarHeight - y ) * shrinkSpeedFactor ] ) ) ;
183
+ element . css ( $mdConstant . CSS . TRANSFORM , translateY ( [ - y * shrinkSpeedFactor ] ) ) ;
184
+ contentElement . css ( $mdConstant . CSS . TRANSFORM , translateY ( [ ( toolbarHeight - y ) * shrinkSpeedFactor ] ) ) ;
135
185
136
186
prevScrollTop = scrollTop ;
137
187
138
- $mdUtil . nextTick ( function ( ) {
188
+ $mdUtil . nextTick ( function ( ) {
139
189
var hasWhiteFrame = element . hasClass ( 'md-whiteframe-z1' ) ;
140
190
141
- if ( hasWhiteFrame && ! y ) {
191
+ if ( hasWhiteFrame && ! y ) {
142
192
$animate . removeClass ( element , 'md-whiteframe-z1' ) ;
143
- } else if ( ! hasWhiteFrame && y ) {
193
+ } else if ( ! hasWhiteFrame && y ) {
144
194
$animate . addClass ( element , 'md-whiteframe-z1' ) ;
145
195
}
146
196
} ) ;
0 commit comments