Add an exponential backoff to rechecking the app list doodle.
[chromium-blink-merge.git] / third_party / polymer / components-chromium / core-header-panel / core-header-panel-extracted.js
blob149f7be53541f66e3caeecb4f0cf9da12dd2af27
3   Polymer('core-header-panel',{
5     /**
6      * Fired when the content has been scrolled.  `event.detail.target` returns
7      * the scrollable element which you can use to access scroll info such as
8      * `scrollTop`.
9      *
10      *     <core-header-panel on-scroll="{{scrollHandler}}">
11      *       ...
12      *     </core-header-panel>
13      *
14      *
15      *     scrollHandler: function(event) {
16      *       var scroller = event.detail.target;
17      *       console.log(scroller.scrollTop);
18      *     }
19      *
20      * @event scroll
21      */
23     publish: {
24       /**
25        * Controls header and scrolling behavior. Options are
26        * `standard`, `seamed`, `waterfall`, `waterfall-tall`, `scroll` and 
27        * `cover`. Default is `standard`.
28        *
29        * `standard`: The header is a step above the panel. The header will consume the
30        * panel at the point of entry, preventing it from passing through to the
31        * opposite side.
32        *
33        * `seamed`: The header is presented as seamed with the panel.
34        *
35        * `waterfall`: Similar to standard mode, but header is initially presented as
36        * seamed with panel, but then separates to form the step.
37        *
38        * `waterfall-tall`: The header is initially taller (`tall` class is added to
39        * the header).  As the user scrolls, the header separates (forming an edge)
40        * while condensing (`tall` class is removed from the header).
41        *
42        * `scroll`: The header keeps its seam with the panel, and is pushed off screen.
43        *
44        * `cover`: The panel covers the whole `core-header-panel` including the
45        * header. This allows user to style the panel in such a way that the panel is
46        * partially covering the header.
47        *
48        *     <style>
49        *       core-header-panel[mode=cover]::shadow #mainContainer {
50        *         left: 80px;
51        *       }
52        *       .content {
53        *         margin: 60px 60px 60px 0;
54        *       }
55        *     </style>
56        *
57        *     <core-header-panel mode="cover">
58        *       <core-toolbar class="tall">
59        *         <core-icon-button icon="menu"></core-icon-button>
60        *       </core-toolbar>
61        *       <div class="content"></div>
62        *     </core-header-panel>
63        *
64        * @attribute mode
65        * @type string
66        * @default ''
67        */
68       mode: {value: '', reflect: true},
70       /**
71        * The class used in waterfall-tall mode.  Change this if the header
72        * accepts a different class for toggling height, e.g. "medium-tall"
73        *
74        * @attribute tallClass
75        * @type string
76        * @default 'tall'
77        */
78       tallClass: 'tall',
80       /**
81        * If true, the drop-shadow is always shown no matter what mode is set to.
82        *
83        * @attribute shadow
84        * @type boolean
85        * @default false
86        */
87       shadow: false
88     },
90     animateDuration: 200,
92     modeConfigs: {
93       shadowMode: {'waterfall': 1, 'waterfall-tall': 1},
94       noShadow: {'seamed': 1, 'cover': 1, 'scroll': 1},
95       tallMode: {'waterfall-tall': 1},
96       outerScroll: {'scroll': 1}
97     },
98     
99     ready: function() {
100       this.scrollHandler = this.scroll.bind(this);
101       this.addListener();
102     },
103     
104     detached: function() {
105       this.removeListener(this.mode);
106     },
107     
108     addListener: function() {
109       this.scroller.addEventListener('scroll', this.scrollHandler);
110     },
111     
112     removeListener: function(mode) {
113       var s = this.getScrollerForMode(mode);
114       s.removeEventListener('scroll', this.scrollHandler);
115     },
117     domReady: function() {
118       this.async('scroll');
119     },
121     modeChanged: function(old) {
122       var configs = this.modeConfigs;
123       var header = this.header;
124       if (header) {
125         // in tallMode it may add tallClass to the header; so do the cleanup
126         // when mode is changed from tallMode to not tallMode
127         if (configs.tallMode[old] && !configs.tallMode[this.mode]) {
128           header.classList.remove(this.tallClass);
129           this.async(function() {
130             header.classList.remove('animate');
131           }, null, this.animateDuration);
132         } else {
133           header.classList.toggle('animate', configs.tallMode[this.mode]);
134         }
135       }
136       if (configs && (configs.outerScroll[this.mode] || configs.outerScroll[old])) {
137         this.removeListener(old);
138         this.addListener();
139       }
140       this.scroll();
141     },
143     get header() {
144       return this.$.headerContent.getDistributedNodes()[0];
145     },
146     
147     getScrollerForMode: function(mode) {
148       return this.modeConfigs.outerScroll[mode] ?
149           this.$.outerContainer : this.$.mainContainer;
150     },
152     /**
153      * Returns the scrollable element.
154      *
155      * @property scroller
156      * @type Object
157      */
158     get scroller() {
159       return this.getScrollerForMode(this.mode);
160     },
162     scroll: function() {
163       var configs = this.modeConfigs;
164       var main = this.$.mainContainer;
165       var header = this.header;
167       var sTop = main.scrollTop;
168       var atTop = sTop === 0;
170       this.$.dropShadow.classList.toggle('hidden', !this.shadow &&
171           (atTop && configs.shadowMode[this.mode] || configs.noShadow[this.mode]));
173       if (header && configs.tallMode[this.mode]) {
174         header.classList.toggle(this.tallClass, atTop ||
175             header.classList.contains(this.tallClass) &&
176             main.scrollHeight < this.$.outerContainer.offsetHeight);
177       }
179       this.fire('scroll', {target: this.scroller}, this, false);
180     }
182   });