Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: chrome/browser/resources/settings/settings_page/main_page_behavior.js

Issue 2230123002: MD Settings: fix collapse animation once and for all (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Overscroll2
Patch Set: rebase, rebase fix (doWhenReady) Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 ];
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698