| 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 | 6 * Calls |readyTest| repeatedly until it returns true, then calls |
| 7 * |readyCallback|. | 7 * |readyCallback|. |
| 8 * @param {function():boolean} readyTest | 8 * @param {function():boolean} readyTest |
| 9 * @param {!Function} readyCallback | 9 * @param {!Function} readyCallback |
| 10 */ | 10 */ |
| 11 function doWhenReady(readyTest, readyCallback) { | 11 function doWhenReady(readyTest, readyCallback) { |
| 12 // TODO(dschuyler): Determine whether this hack can be removed. | 12 if (readyTest()) { |
| 13 readyCallback(); |
| 14 return; |
| 15 } |
| 16 |
| 17 // TODO(michaelpg): Remove this hack. |
| 13 // See also: https://github.com/Polymer/polymer/issues/3629 | 18 // See also: https://github.com/Polymer/polymer/issues/3629 |
| 14 var intervalId = setInterval(function() { | 19 var intervalId = setInterval(function() { |
| 15 if (readyTest()) { | 20 if (readyTest()) { |
| 16 clearInterval(intervalId); | 21 clearInterval(intervalId); |
| 17 readyCallback(); | 22 readyCallback(); |
| 18 } | 23 } |
| 19 }, 10); | 24 }, 10); |
| 20 } | 25 } |
| 21 | 26 |
| 22 /** | 27 /** |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 return; | 80 return; |
| 76 } | 81 } |
| 77 | 82 |
| 78 var promise; | 83 var promise; |
| 79 var expandedSection = /** @type {?SettingsSectionElement} */( | 84 var expandedSection = /** @type {?SettingsSectionElement} */( |
| 80 this.$$('settings-section.expanded')); | 85 this.$$('settings-section.expanded')); |
| 81 if (expandedSection) { | 86 if (expandedSection) { |
| 82 // If the section shouldn't be expanded, collapse it. | 87 // If the section shouldn't be expanded, collapse it. |
| 83 if (!currentRoute.isSubpage() || expandedSection != currentSection) { | 88 if (!currentRoute.isSubpage() || expandedSection != currentSection) { |
| 84 promise = this.collapseSection_(expandedSection); | 89 promise = this.collapseSection_(expandedSection); |
| 85 // Scroll to the collapsed section. TODO(michaelpg): This can look weird | 90 // Scroll to the collapsed section. |
| 86 // because the collapse we just scheduled calculated its end target | |
| 87 // based on the current scroll position. This bug existed before, and is | |
| 88 // fixed in the next patch by making the card position: absolute. | |
| 89 if (currentSection) | 91 if (currentSection) |
| 90 currentSection.scrollIntoView(); | 92 currentSection.scrollIntoView(); |
| 91 } | 93 } |
| 92 } else if (currentSection) { | 94 } else if (currentSection) { |
| 93 // Expand the section into a subpage or scroll to it on the main page. | 95 // Expand the section into a subpage or scroll to it on the main page. |
| 94 if (currentRoute.isSubpage()) | 96 if (currentRoute.isSubpage()) |
| 95 promise = this.expandSection_(currentSection); | 97 promise = this.expandSection_(currentSection); |
| 96 else | 98 else |
| 97 currentSection.scrollIntoView(); | 99 currentSection.scrollIntoView(); |
| 98 } | 100 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 }, | 144 }, |
| 143 | 145 |
| 144 /** | 146 /** |
| 145 * Animates the card in |section|, expanding it to fill the page. | 147 * Animates the card in |section|, expanding it to fill the page. |
| 146 * @param {!SettingsSectionElement} section | 148 * @param {!SettingsSectionElement} section |
| 147 * @return {!Promise} Resolved when the transition is finished or canceled. | 149 * @return {!Promise} Resolved when the transition is finished or canceled. |
| 148 * @private | 150 * @private |
| 149 */ | 151 */ |
| 150 expandSection_: function(section) { | 152 expandSection_: function(section) { |
| 151 assert(this.scroller); | 153 assert(this.scroller); |
| 152 assert(section.canAnimateExpand()); | 154 |
| 155 if (!section.canAnimateExpand()) { |
| 156 // Try to wait for the section to be created. |
| 157 return new Promise(function(resolve, reject) { |
| 158 setTimeout(resolve); |
| 159 }); |
| 160 } |
| 153 | 161 |
| 154 // Save the scroller position before freezing it. | 162 // Save the scroller position before freezing it. |
| 155 this.origScrollTop_ = this.scroller.scrollTop; | 163 this.origScrollTop_ = this.scroller.scrollTop; |
| 156 this.toggleScrolling_(false); | 164 this.toggleScrolling_(false); |
| 157 | 165 |
| 158 // Freeze the section's height so its card can be removed from the flow. | 166 // Freeze the section's height so its card can be removed from the flow. |
| 159 section.setFrozen(true); | 167 section.setFrozen(true); |
| 160 | 168 |
| 161 this.currentAnimation_ = section.animateExpand(this.scroller); | 169 this.currentAnimation_ = section.animateExpand(this.scroller); |
| 162 var promise = this.currentAnimation_ ? | |
| 163 this.currentAnimation_.finished : Promise.resolve(); | |
| 164 | 170 |
| 165 var finished; | 171 var finished; |
| 166 return promise.then(function() { | 172 return this.currentAnimation_.finished.then(function() { |
| 173 // Hide other sections and scroll to the top of the subpage. |
| 174 this.classList.add('showing-subpage'); |
| 175 this.toggleOtherSectionsHidden_(section.section, true); |
| 167 this.scroller.scrollTop = 0; | 176 this.scroller.scrollTop = 0; |
| 168 this.toggleOtherSectionsHidden_(section.section, true); | 177 section.setFrozen(false); |
| 178 |
| 179 // Notify that the page is fully expanded. |
| 180 this.fire('subpage-expand'); |
| 181 |
| 169 finished = true; | 182 finished = true; |
| 170 }.bind(this), function() { | 183 }.bind(this), function() { |
| 171 // The animation was canceled; restore the section. | 184 // The animation was canceled; restore the section and scroll position. |
| 172 section.setFrozen(false); | 185 section.setFrozen(false); |
| 186 this.scroller.scrollTop = this.origScrollTop_; |
| 187 |
| 173 finished = false; | 188 finished = false; |
| 174 }).then(function() { | 189 }.bind(this)).then(function() { |
| 175 section.cleanUpAnimateExpand(finished); | |
| 176 this.toggleScrolling_(true); | 190 this.toggleScrolling_(true); |
| 177 this.currentAnimation_ = null; | 191 this.currentAnimation_ = null; |
| 178 }.bind(this)); | 192 }.bind(this)); |
| 179 }, | 193 }, |
| 180 | 194 |
| 181 /** | 195 /** |
| 182 * Animates the card in |section|, collapsing it back into its section. | 196 * Animates the card in |section|, collapsing it back into its section. |
| 183 * @param {!SettingsSectionElement} section | 197 * @param {!SettingsSectionElement} section |
| 184 * @return {!Promise} Resolved when the transition is finished or canceled. | 198 * @return {!Promise} Resolved when the transition is finished or canceled. |
| 185 * @private | |
| 186 */ | 199 */ |
| 187 collapseSection_: function(section) { | 200 collapseSection_: function(section) { |
| 188 assert(this.scroller); | 201 assert(this.scroller); |
| 189 assert(section.canAnimateCollapse()); | 202 assert(section.classList.contains('expanded')); |
| 190 | 203 |
| 204 var canAnimateCollapse = section.canAnimateCollapse(); |
| 205 if (canAnimateCollapse) { |
| 206 this.toggleScrolling_(false); |
| 207 // Do the initial collapse setup, which takes the section out of the flow, |
| 208 // before showing everything. |
| 209 section.setUpAnimateCollapse(this.scroller); |
| 210 } else { |
| 211 section.classList.remove('expanded'); |
| 212 } |
| 213 |
| 214 // Show everything. |
| 191 this.toggleOtherSectionsHidden_(section.section, false); | 215 this.toggleOtherSectionsHidden_(section.section, false); |
| 192 this.toggleScrolling_(false); | 216 this.classList.remove('showing-subpage'); |
| 193 | 217 |
| 194 this.currentAnimation_ = | 218 if (!canAnimateCollapse) { |
| 195 section.animateCollapse(this.scroller, this.origScrollTop_); | 219 // Finish by restoring the section into the page. |
| 196 var promise = this.currentAnimation_ ? | 220 section.setFrozen(false); |
| 197 this.currentAnimation_.finished : Promise.resolve(); | 221 return Promise.resolve(); |
| 222 } |
| 198 | 223 |
| 199 return promise.then(function() { | 224 // Play the actual collapse animation. |
| 200 section.cleanUpAnimateCollapse(true); | 225 return new Promise(function(resolve, reject) { |
| 201 }, function() { | 226 // Wait for the other sections to show up so we can scroll properly. |
| 202 section.cleanUpAnimateCollapse(false); | 227 setTimeout(function() { |
| 203 }).then(function() { | 228 var newSection = settings.getCurrentRoute().section && |
| 204 section.setFrozen(false); | 229 this.getSection(settings.getCurrentRoute().section); |
| 205 section.classList.remove('collapsing'); | 230 |
| 206 this.toggleScrolling_(true); | 231 // Scroll to the section if indicated by the route. TODO(michaelpg): Is |
| 207 this.currentAnimation_ = null; | 232 // this the right behavior, or should we return to the previous scroll |
| 233 // position? |
| 234 if (newSection) |
| 235 newSection.scrollIntoView(); |
| 236 else |
| 237 this.scroller.scrollTop = this.origScrollTop_; |
| 238 |
| 239 this.currentAnimation_ = section.animateCollapse( |
| 240 /** @type {!HTMLElement} */(this.scroller)); |
| 241 |
| 242 this.currentAnimation_.finished.catch(function() { |
| 243 // The collapse was canceled, so the page is showing a subpage still. |
| 244 this.fire('subpage-expand'); |
| 245 }.bind(this)).then(function() { |
| 246 // Clean up after the animation succeeds or cancels. |
| 247 section.setFrozen(false); |
| 248 section.classList.remove('collapsing'); |
| 249 this.toggleScrolling_(true); |
| 250 this.currentAnimation_ = null; |
| 251 resolve(); |
| 252 }.bind(this)); |
| 253 }.bind(this)); |
| 208 }.bind(this)); | 254 }.bind(this)); |
| 209 }, | 255 }, |
| 210 | 256 |
| 211 /** | 257 /** |
| 258 /** |
| 212 * Hides or unhides the sections not being expanded. | 259 * Hides or unhides the sections not being expanded. |
| 213 * @param {string} sectionName The section to keep visible. | 260 * @param {string} sectionName The section to keep visible. |
| 214 * @param {boolean} hidden Whether the sections should be hidden. | 261 * @param {boolean} hidden Whether the sections should be hidden. |
| 215 * @private | 262 * @private |
| 216 */ | 263 */ |
| 217 toggleOtherSectionsHidden_: function(sectionName, hidden) { | 264 toggleOtherSectionsHidden_: function(sectionName, hidden) { |
| 218 var sections = Polymer.dom(this.root).querySelectorAll( | 265 var sections = Polymer.dom(this.root).querySelectorAll( |
| 219 'settings-section'); | 266 'settings-section'); |
| 220 for (var section of sections) | 267 for (var section of sections) |
| 221 section.hidden = hidden && (section.section != sectionName); | 268 section.hidden = hidden && (section.section != sectionName); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 251 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; | 298 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; |
| 252 } | 299 } |
| 253 } | 300 } |
| 254 }; | 301 }; |
| 255 | 302 |
| 256 /** @polymerBehavior */ | 303 /** @polymerBehavior */ |
| 257 var MainPageBehavior = [ | 304 var MainPageBehavior = [ |
| 258 settings.RouteObserverBehavior, | 305 settings.RouteObserverBehavior, |
| 259 MainPageBehaviorImpl, | 306 MainPageBehaviorImpl, |
| 260 ]; | 307 ]; |
| OLD | NEW |