| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Calls |readyTest| repeatedly until it returns true, then calls | |
| 7 * |readyCallback|. | |
| 8 * @param {function():boolean} readyTest | |
| 9 * @param {!Function} readyCallback | |
| 10 */ | |
| 11 function doWhenReady(readyTest, readyCallback) { | |
| 12 // TODO(dschuyler): Determine whether this hack can be removed. | |
| 13 // See also: https://github.com/Polymer/polymer/issues/3629 | |
| 14 var intervalId = setInterval(function() { | |
| 15 if (readyTest()) { | |
| 16 clearInterval(intervalId); | |
| 17 readyCallback(); | |
| 18 } | |
| 19 }, 10); | |
| 20 } | |
| 21 | |
| 22 /** | |
| 23 * Responds to route changes by expanding, collapsing, or scrolling to sections | 6 * Responds to route changes by expanding, collapsing, or scrolling to sections |
| 24 * on the page. Expanded sections take up the full height of the container. At | 7 * on the page. Expanded sections take up the full height of the container. At |
| 25 * most one section should be expanded at any given time. | 8 * most one section should be expanded at any given time. |
| 26 * @polymerBehavior MainPageBehavior | 9 * @polymerBehavior MainPageBehavior |
| 27 */ | 10 */ |
| 28 var MainPageBehaviorImpl = { | 11 var MainPageBehaviorImpl = { |
| 29 /** @type {?HTMLElement} The scrolling container. */ | 12 /** @type {?HTMLElement} The scrolling container. */ |
| 30 scroller: null, | 13 scroller: null, |
| 31 | 14 |
| 32 /** @override */ | 15 /** @override */ |
| 33 attached: function() { | 16 attached: function() { |
| 34 if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') | 17 if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') |
| 35 this.scroller = this.domHost.parentNode.scroller; | 18 this.scroller = this.domHost.parentNode.scroller; |
| 36 else | 19 else |
| 37 this.scroller = document.body; // Used in unit tests. | 20 this.scroller = document.body; // Used in unit tests. |
| 38 }, | 21 }, |
| 39 | 22 |
| 40 /** | 23 /** |
| 41 * @param {!settings.Route} newRoute | 24 * @param {!settings.Route} newRoute |
| 42 * @param {settings.Route} oldRoute | 25 * @param {settings.Route} oldRoute |
| 43 */ | 26 */ |
| 44 currentRouteChanged: function(newRoute, oldRoute) { | 27 currentRouteChanged: function(newRoute, oldRoute) { |
| 45 if (oldRoute || !newRoute.section) { | 28 // Allow the page to load before expanding the section. |
| 29 if (!oldRoute) |
| 30 setTimeout(this.tryTransitionToSection_.bind(this)); |
| 31 else |
| 46 this.tryTransitionToSection_(); | 32 this.tryTransitionToSection_(); |
| 47 return; | |
| 48 } | |
| 49 | |
| 50 // Wait for the page to really be ready before expanding or scrolling to the | |
| 51 // section. TODO(michaelpg): Remove this workaround with a global workaround | |
| 52 // for crbug.com/638074. | |
| 53 doWhenReady(function() { | |
| 54 if (newRoute != settings.getCurrentRoute()) | |
| 55 return; | |
| 56 var section = this.getSection(newRoute.section); | |
| 57 return section && (!newRoute.isSubpage() || section.canAnimateExpand()); | |
| 58 }.bind(this), this.tryTransitionToSection_.bind(this)); | |
| 59 }, | 33 }, |
| 60 | 34 |
| 61 /** | 35 /** |
| 62 * If possible, transitions to the current route's section (by expanding or | 36 * If possible, transitions to the current route's section (by expanding or |
| 63 * scrolling to it). If another transition is running, finishes or cancels | 37 * scrolling to it). If another transition is running, finishes or cancels |
| 64 * that one, then schedules this function again. This ensures the current | 38 * that one, then schedules this function again. This ensures the current |
| 65 * section is quickly shown, without getting the page into a broken state -- | 39 * section is quickly shown, without getting the page into a broken state -- |
| 66 * if currentRoute changes in between calls, just transition to the new route. | 40 * if currentRoute changes in between calls, just transition to the new route. |
| 67 * @private | 41 * @private |
| 68 */ | 42 */ |
| (...skipping 15 matching lines...) Expand all Loading... |
| 84 if (expandedSection) { | 58 if (expandedSection) { |
| 85 // If the section shouldn't be expanded, collapse it. | 59 // If the section shouldn't be expanded, collapse it. |
| 86 if (!currentRoute.isSubpage() || expandedSection != currentSection) { | 60 if (!currentRoute.isSubpage() || expandedSection != currentSection) { |
| 87 promise = this.collapseSection_(expandedSection); | 61 promise = this.collapseSection_(expandedSection); |
| 88 // Scroll to the collapsed section. | 62 // Scroll to the collapsed section. |
| 89 if (currentSection) | 63 if (currentSection) |
| 90 this.scrollToSection_(); | 64 this.scrollToSection_(); |
| 91 } | 65 } |
| 92 } else if (currentSection) { | 66 } else if (currentSection) { |
| 93 // Expand the section into a subpage or scroll to it on the main page. | 67 // Expand the section into a subpage or scroll to it on the main page. |
| 68 if (!currentSection.clientHeight) { |
| 69 setTimeout(this.tryTransitionToSection_.bind(this)); |
| 70 return; |
| 71 } |
| 94 if (currentRoute.isSubpage()) | 72 if (currentRoute.isSubpage()) |
| 95 promise = this.expandSection_(currentSection); | 73 promise = this.expandSection_(currentSection); |
| 96 else | 74 else |
| 97 this.scrollToSection_(); | 75 this.scrollToSection_(); |
| 98 } | 76 } |
| 99 | 77 |
| 100 // When this animation ends, another may be necessary. Call this function | 78 // When this animation ends, another may be necessary. Call this function |
| 101 // again after the promise resolves. | 79 // again after the promise resolves. |
| 102 if (promise) | 80 if (promise) |
| 103 promise.then(this.tryTransitionToSection_.bind(this)); | 81 promise.then(this.tryTransitionToSection_.bind(this)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 if (!canAnimateCollapse) { | 183 if (!canAnimateCollapse) { |
| 206 // Finish by restoring the section into the page. | 184 // Finish by restoring the section into the page. |
| 207 section.setFrozen(false); | 185 section.setFrozen(false); |
| 208 return Promise.resolve(); | 186 return Promise.resolve(); |
| 209 } | 187 } |
| 210 | 188 |
| 211 // Play the actual collapse animation. | 189 // Play the actual collapse animation. |
| 212 return new Promise(function(resolve, reject) { | 190 return new Promise(function(resolve, reject) { |
| 213 // Wait for the other sections to show up so we can scroll properly. | 191 // Wait for the other sections to show up so we can scroll properly. |
| 214 setTimeout(function() { | 192 setTimeout(function() { |
| 215 var newSection = settings.getCurrentRoute().section && | 193 var currentRoute = settings.getCurrentRoute(); |
| 216 this.getSection(settings.getCurrentRoute().section); | 194 var newSection = |
| 195 currentRoute.section && this.getSection(currentRoute.section); |
| 217 | 196 |
| 218 // Scroll to the section if indicated by the route. TODO(michaelpg): Is | 197 // Scroll to the new section if it's on this page. If the route has no |
| 219 // this the right behavior, or should we return to the previous scroll | 198 // section (e.g., a root page), return to the original position. |
| 220 // position? | |
| 221 if (newSection) | 199 if (newSection) |
| 222 newSection.scrollIntoView(); | 200 newSection.scrollIntoView(); |
| 223 else | 201 else if (!currentRoute.section) |
| 224 this.scroller.scrollTop = this.origScrollTop_; | 202 this.scroller.scrollTop = this.origScrollTop_; |
| 225 | 203 |
| 226 this.currentAnimation_ = section.animateCollapse( | 204 this.currentAnimation_ = section.animateCollapse( |
| 227 /** @type {!HTMLElement} */(this.scroller)); | 205 /** @type {!HTMLElement} */(this.scroller)); |
| 228 | 206 |
| 229 this.currentAnimation_.finished.catch(function() { | 207 this.currentAnimation_.finished.catch(function() { |
| 230 // The collapse was canceled, so the page is showing a subpage still. | 208 // The collapse was canceled, so the page is showing a subpage still. |
| 231 this.fire('subpage-expand'); | 209 this.fire('subpage-expand'); |
| 232 }.bind(this)).then(function() { | 210 }.bind(this)).then(function() { |
| 233 // Clean up after the animation succeeds or cancels. | 211 // Clean up after the animation succeeds or cancels. |
| 234 section.setFrozen(false); | 212 section.setFrozen(false); |
| 235 section.classList.remove('collapsing'); | 213 section.classList.remove('collapsing'); |
| 236 this.toggleScrolling_(true); | 214 this.toggleScrolling_(true); |
| 237 this.currentAnimation_ = null; | 215 this.currentAnimation_ = null; |
| 238 resolve(); | 216 resolve(); |
| 239 }.bind(this)); | 217 }.bind(this)); |
| 240 }.bind(this)); | 218 }.bind(this)); |
| 241 }.bind(this)); | 219 }.bind(this)); |
| 242 }, | 220 }, |
| 243 | 221 |
| 244 /** @private */ | 222 /** @private */ |
| 245 scrollToSection_: function() { | 223 scrollToSection_: function() { |
| 246 doWhenReady( | 224 assert(this.scrollHeight > 0); |
| 247 function() { | 225 var section = this.getSection(settings.getCurrentRoute().section); |
| 248 return this.scrollHeight > 0; | 226 assert(section); |
| 249 }.bind(this), | 227 section.scrollIntoView(); |
| 250 function() { | |
| 251 // If the current section changes while we are waiting for the page to | |
| 252 // be ready, scroll to the newest requested section. | |
| 253 var section = this.getSection(settings.getCurrentRoute().section); | |
| 254 if (section) | |
| 255 section.scrollIntoView(); | |
| 256 }.bind(this)); | |
| 257 }, | 228 }, |
| 258 | 229 |
| 259 /** | 230 /** |
| 260 /** | 231 /** |
| 261 * Hides or unhides the sections not being expanded. | 232 * Hides or unhides the sections not being expanded. |
| 262 * @param {string} sectionName The section to keep visible. | 233 * @param {string} sectionName The section to keep visible. |
| 263 * @param {boolean} hidden Whether the sections should be hidden. | 234 * @param {boolean} hidden Whether the sections should be hidden. |
| 264 * @private | 235 * @private |
| 265 */ | 236 */ |
| 266 toggleOtherSectionsHidden_: function(sectionName, hidden) { | 237 toggleOtherSectionsHidden_: function(sectionName, hidden) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; | 271 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; |
| 301 } | 272 } |
| 302 } | 273 } |
| 303 }; | 274 }; |
| 304 | 275 |
| 305 /** @polymerBehavior */ | 276 /** @polymerBehavior */ |
| 306 var MainPageBehavior = [ | 277 var MainPageBehavior = [ |
| 307 settings.RouteObserverBehavior, | 278 settings.RouteObserverBehavior, |
| 308 MainPageBehaviorImpl, | 279 MainPageBehaviorImpl, |
| 309 ]; | 280 ]; |
| OLD | NEW |