Add an exponential backoff to rechecking the app list doodle.
[chromium-blink-merge.git] / third_party / polymer / components-chromium / core-scroll-header-panel / core-scroll-header-panel-extracted.js
blobdeaf4992db2732d8b857920b39d37a52876f5d85
2 (function() {
4   Polymer('core-scroll-header-panel',Polymer.mixin({
5     
6     /**
7      * Fired when the content has been scrolled.
8      *
9      * @event scroll
10      */
11      
12     /**
13      * Fired when the header is transformed.
14      *
15      * @event core-header-transform
16      */
17      
18     publish: {
19       /**
20        * If true, the header's height will condense to `_condensedHeaderHeight`
21        * as the user scrolls down from the top of the content area.
22        *
23        * @attribute condenses
24        * @type boolean
25        * @default false
26        */
27       condenses: false,
29       /**
30        * If true, no cross-fade transition from one background to another.
31        *
32        * @attribute noDissolve
33        * @type boolean
34        * @default false
35        */
36       noDissolve: false,
38       /**
39        * If true, the header doesn't slide back in when scrolling back up.
40        *
41        * @attribute noReveal
42        * @type boolean
43        * @default false
44        */
45       noReveal: false,
47       /**
48        * If true, the header is fixed to the top and never moves away.
49        *
50        * @attribute fixed
51        * @type boolean
52        * @default false
53        */
54       fixed: false,
55       
56       /**
57        * If true, the condensed header is always shown and does not move away.
58        *
59        * @attribute keepCondensedHeader
60        * @type boolean
61        * @default false
62        */
63       keepCondensedHeader: false,
65       /**
66        * The height of the header when it is at its full size.
67        *
68        * By default, the height will be measured when it is ready.  If the height
69        * changes later the user needs to either set this value to reflect the
70        * new height or invoke `measureHeaderHeight()`.
71        *
72        * @attribute headerHeight
73        * @type number
74        * @default 0
75        */
76       headerHeight: 0,
78       /**
79        * The height of the header when it is condensed.
80        *
81        * By default, `_condensedHeaderHeight` is 1/3 of `headerHeight` unless
82        * this is specified.
83        *
84        * @attribute condensedHeaderHeight
85        * @type number
86        * @default 0
87        */
88       condensedHeaderHeight: 0,
89       
90       /**
91        * By default, the top part of the header stays when the header is being
92        * condensed.  Set this to true if you want the top part of the header
93        * to be scrolled away.
94        *
95        * @attribute scrollAwayTopbar
96        * @type boolean
97        * @default false
98        */
99       scrollAwayTopbar: false
100     },
102     prevScrollTop: 0,
103     
104     headerMargin: 0,
105     
106     y: 0,
107     
108     observe: {
109       'headerMargin fixed': 'setup'
110     },
112     eventDelegates: {
113       'core-resize': 'measureHeaderHeight'
114     },
116     attached: function() {
117       this.resizableAttachedHandler();
118     },
120     ready: function() {
121       this._scrollHandler = this.scroll.bind(this);
122       this.scroller.addEventListener('scroll', this._scrollHandler);
123     },
124     
125     detached: function() {
126       this.scroller.removeEventListener('scroll', this._scrollHandler);
127       this.resizableDetachedHandler();
128     },
129     
130     domReady: function() {
131       this.async('measureHeaderHeight');
132     },
134     get header() {
135       return this.$.headerContent.getDistributedNodes()[0];
136     },
137     
138     /**
139      * Returns the scrollable element.
140      *
141      * @property scroller
142      * @type Object
143      */
144     get scroller() {
145       return this.$.mainContainer;
146     },
147     
148     /**
149      * Invoke this to tell `core-scroll-header-panel` to re-measure the header's
150      * height.
151      *
152      * @method measureHeaderHeight
153      */
154     measureHeaderHeight: function() {
155       var header = this.header;
156       if (header && header.offsetHeight) {
157         this.headerHeight = header.offsetHeight;
158       }
159     },
160     
161     headerHeightChanged: function() {
162       if (!this.condensedHeaderHeight) {
163         // assume _condensedHeaderHeight is 1/3 of the headerHeight
164         this._condensedHeaderHeight = this.headerHeight * 1 / 3;
165       }
166       this.condensedHeaderHeightChanged();
167     },
168     
169     condensedHeaderHeightChanged: function() {
170       if (this.condensedHeaderHeight) {
171         this._condensedHeaderHeight = this.condensedHeaderHeight;
172       }
173       if (this.headerHeight) {
174         this.headerMargin = this.headerHeight - this._condensedHeaderHeight;
175       }
176     },
177     
178     condensesChanged: function() {
179       if (this.condenses) {
180         this.scroll();
181       } else {
182         // reset transform/opacity set on the header
183         this.condenseHeader(null);
184       }
185     },
186     
187     setup: function() {
188       var s = this.scroller.style;
189       s.paddingTop = this.fixed ? '' : this.headerHeight + 'px';
190       s.top = this.fixed ? this.headerHeight + 'px' : '';
191       if (this.fixed) {
192         this.transformHeader(null);
193       } else {
194         this.scroll();
195       }
196     },
197     
198     transformHeader: function(y) {
199       var s = this.$.headerContainer.style;
200       this.translateY(s, -y);
201       
202       if (this.condenses) {
203         this.condenseHeader(y);
204       }
205       
206       this.fire('core-header-transform', {y: y, height: this.headerHeight, 
207           condensedHeight: this._condensedHeaderHeight});
208     },
209     
210     condenseHeader: function(y) {
211       var reset = y == null;
212       // adjust top bar in core-header so the top bar stays at the top
213       if (!this.scrollAwayTopbar && this.header.$ && this.header.$.topBar) {
214         this.translateY(this.header.$.topBar.style, 
215             reset ? null : Math.min(y, this.headerMargin));
216       }
217       // transition header bg
218       var hbg = this.$.headerBg.style;
219       if (!this.noDissolve) {
220         hbg.opacity = reset ? '' : (this.headerMargin - y) / this.headerMargin;
221       }
222       // adjust header bg so it stays at the center
223       this.translateY(hbg, reset ? null : y / 2);
224       // transition condensed header bg
225       var chbg = this.$.condensedHeaderBg.style;
226       if (!this.noDissolve) {
227         chbg = this.$.condensedHeaderBg.style;
228         chbg.opacity = reset ? '' : y / this.headerMargin;
229         // adjust condensed header bg so it stays at the center
230         this.translateY(chbg, reset ? null : y / 2);
231       }
232     },
233     
234     translateY: function(s, y) {
235       var t = y == null ? '' : 'translate3d(0, ' + y + 'px, 0)';
236       setTransform(s, t);
237     },
238     
239     scroll: function(event) {
240       if (!this.header) {
241         return;
242       }
243       
244       var sTop = this.scroller.scrollTop;
245       
246       var y = Math.min(this.keepCondensedHeader ? 
247           this.headerMargin : this.headerHeight, Math.max(0, 
248           (this.noReveal ? sTop : this.y + sTop - this.prevScrollTop)));
249       
250       if (this.condenses && this.prevScrollTop >= sTop && sTop > this.headerMargin) {
251         y = Math.max(y, this.headerMargin);
252       }
253       
254       if (!event || !this.fixed && y !== this.y) {
255         this.transformHeader(y);
256       }
257       
258       this.prevScrollTop = Math.max(sTop, 0);
259       this.y = y;
260       
261       if (event) {
262         this.fire('scroll', {target: this.scroller}, this, false);
263       }
264     }
266   }, Polymer.CoreResizable));
267   
268   //determine proper transform mechanizm
269   if (document.documentElement.style.transform !== undefined) {
270     var setTransform = function(style, string) {
271       style.transform = string;
272     }
273   } else {
274     var setTransform = function(style, string) {
275       style.webkitTransform = string;
276     }
277   }
279 })();