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

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

Issue 2211303004: MD Settings: Refactor RoutableBehavior into MainPageBehavior (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « chrome/browser/resources/settings/settings_page/compiled_resources2.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(dschuyler): Determine whether this hack can be removed.
13 // See also: https://github.com/Polymer/polymer/issues/3629 13 // See also: https://github.com/Polymer/polymer/issues/3629
14 var intervalId = setInterval(function() { 14 var intervalId = setInterval(function() {
15 if (readyTest()) { 15 if (readyTest()) {
16 clearInterval(intervalId); 16 clearInterval(intervalId);
17 readyCallback(); 17 readyCallback();
18 } 18 }
19 }, 10); 19 }, 10);
20 } 20 }
21 21
22 /** 22 /**
23 * Provides animations to expand and collapse individual sections in a page. 23 * Responds to route changes by expanding, collapsing, or scrolling to sections
24 * Expanded sections take up the full height of the container. At most one 24 * on the page. Expanded sections take up the full height of the container. At
25 * section should be expanded at any given time. 25 * most one section should be expanded at any given time.
26 * @polymerBehavior Polymer.MainPageBehavior 26 * @polymerBehavior MainPageBehavior
27 */ 27 */
28 var MainPageBehaviorImpl = { 28 var MainPageBehaviorImpl = {
29 /** @type {?HTMLElement} The scrolling container. */ 29 /** @type {?HTMLElement} The scrolling container. */
30 scroller: null, 30 scroller: null,
31 31
32 /** @override */ 32 /** @override */
33 attached: function() { 33 attached: function() {
34 if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') 34 if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL')
35 this.scroller = this.domHost.parentNode.scroller; 35 this.scroller = this.domHost.parentNode.scroller;
36 else 36 else
37 this.scroller = document.body; // Used in unit tests. 37 this.scroller = document.body; // Used in unit tests.
38 }, 38 },
39 39
40 /** 40 /**
41 * Hides or unhides the sections not being expanded. 41 * @param {!settings.Route} newRoute
42 * @param {string} sectionName The section to keep visible. 42 * @param {!settings.Route} oldRoute
43 * @param {boolean} hidden Whether the sections should be hidden.
44 * @private
45 */ 43 */
46 toggleOtherSectionsHidden_: function(sectionName, hidden) { 44 currentRouteChanged: function(newRoute, oldRoute) {
michaelpg 2016/08/06 03:20:37 Same code, just moved up to the other public funct
47 var sections = Polymer.dom(this.root).querySelectorAll( 45 var newRouteIsSubpage = newRoute && newRoute.subpage.length;
48 'settings-section'); 46 var oldRouteIsSubpage = oldRoute && oldRoute.subpage.length;
49 for (var section of sections) 47
50 section.hidden = hidden && (section.section != sectionName); 48 if (!oldRoute && newRouteIsSubpage) {
49 // Allow the page to load before expanding the section. TODO(michaelpg):
50 // Time this better when refactoring settings-animated-pages.
51 setTimeout(function() {
52 var section = this.getSection_(newRoute.section);
53 if (section)
54 this.expandSection_(section);
55 }.bind(this));
56 return;
57 }
58
59 if (newRouteIsSubpage) {
60 if (!oldRouteIsSubpage || newRoute.section != oldRoute.section) {
61 var section = this.getSection_(newRoute.section);
62 if (section)
63 this.expandSection_(section);
64 }
65 } else {
66 if (oldRouteIsSubpage) {
67 var section = this.getSection_(oldRoute.section);
68 if (section)
69 this.collapseSection_(section);
70 }
71
72 // Scrolls to the section if this main page contains the route's section.
73 if (newRoute && newRoute.section && this.getSection_(newRoute.section))
74 this.scrollToSection_();
75 }
51 }, 76 },
52 77
53 /** 78 /**
54 * Animates the card in |section|, expanding it to fill the page. 79 * Animates the card in |section|, expanding it to fill the page.
55 * @param {!SettingsSectionElement} section 80 * @param {!SettingsSectionElement} section
81 * @private
56 */ 82 */
57 expandSection: function(section) { 83 expandSection_: function(section) {
58 // If another section's card is expanding, cancel that animation first. 84 // If another section's card is expanding, cancel that animation first.
59 var expanding = this.$$('.expanding'); 85 var expanding = this.$$('.expanding');
60 if (expanding) { 86 if (expanding) {
61 if (expanding == section) 87 if (expanding == section)
62 return; 88 return;
63 89
64 if (this.animations['section']) { 90 if (this.animations['section']) {
65 // Cancel the animation, then call startExpandSection_. 91 // Cancel the animation, then call startExpandSection_.
66 this.cancelAnimation('section', function() { 92 this.cancelAnimation('section', function() {
67 this.startExpandSection_(section); 93 this.startExpandSection_(section);
68 }.bind(this)); 94 }.bind(this));
69 } else { 95 } else {
70 // The animation must have finished but its promise hasn't resolved yet. 96 // The animation must have finished but its promise hasn't resolved yet.
71 // When it resolves, collapse that section's card before expanding 97 // When it resolves, collapse that section's card before expanding
72 // this one. 98 // this one.
73 setTimeout(function() { 99 setTimeout(function() {
74 this.collapseSection( 100 this.collapseSection_(
75 /** @type {!SettingsSectionElement} */(expanding)); 101 /** @type {!SettingsSectionElement} */(expanding));
76 this.finishAnimation('section', function() { 102 this.finishAnimation('section', function() {
77 this.startExpandSection_(section); 103 this.startExpandSection_(section);
78 }.bind(this)); 104 }.bind(this));
79 }.bind(this)); 105 }.bind(this));
80 } 106 }
81 107
82 return; 108 return;
83 } 109 }
84 110
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 }.bind(this), function() { 148 }.bind(this), function() {
123 // Animation was canceled; restore the section. 149 // Animation was canceled; restore the section.
124 section.setFrozen(false); 150 section.setFrozen(false);
125 }.bind(this)).then(function() { 151 }.bind(this)).then(function() {
126 this.scroller.style.overflow = ''; 152 this.scroller.style.overflow = '';
127 this.scroller.style.width = ''; 153 this.scroller.style.width = '';
128 }.bind(this)); 154 }.bind(this));
129 }, 155 },
130 156
131 /** 157 /**
158 * Expands the card in |section| to fill the page.
159 * @param {!SettingsSectionElement} section
160 * @return {!Promise}
161 * @private
162 */
163 playExpandSection_: function(section) {
michaelpg 2016/08/06 03:20:37 Exact same code, just moved up one.
164 // We must be attached.
165 assert(this.scroller);
166
167 var promise;
168 var animationConfig = section.animateExpand(this.scroller);
169 if (animationConfig) {
170 promise = this.animateElement('section', animationConfig.card,
171 animationConfig.keyframes, animationConfig.options);
172 } else {
173 promise = Promise.resolve();
174 }
175
176 var finished;
177 promise.then(function() {
178 finished = true;
179 this.style.margin = 'auto';
180 }.bind(this), function() {
181 // The animation was canceled; catch the error and continue.
182 finished = false;
183 }).then(function() {
184 section.cleanUpAnimateExpand(finished);
185 });
186
187 return promise;
188 },
189
190 /**
132 * Animates the card in |section|, collapsing it back into its section. 191 * Animates the card in |section|, collapsing it back into its section.
133 * @param {!SettingsSectionElement} section 192 * @param {!SettingsSectionElement} section
193 * @private
134 */ 194 */
135 collapseSection: function(section) { 195 collapseSection_: function(section) {
136 // If the section's card is still expanding, cancel the expand animation. 196 // If the section's card is still expanding, cancel the expand animation.
137 if (section.classList.contains('expanding')) { 197 if (section.classList.contains('expanding')) {
138 if (this.animations['section']) { 198 if (this.animations['section']) {
139 this.cancelAnimation('section'); 199 this.cancelAnimation('section');
140 } else { 200 } else {
141 // The animation must have finished but its promise hasn't finished 201 // The animation must have finished but its promise hasn't finished
142 // resolving; try again asynchronously. 202 // resolving; try again asynchronously.
143 this.async(function() { 203 this.async(function() {
144 this.collapseSection(section); 204 this.collapseSection_(section);
145 }); 205 });
146 } 206 }
147 return; 207 return;
148 } 208 }
149 209
150 if (!section.canAnimateCollapse()) 210 if (!section.canAnimateCollapse())
151 return; 211 return;
152 212
153 this.toggleOtherSectionsHidden_(section.section, false); 213 this.toggleOtherSectionsHidden_(section.section, false);
154 214
155 var scrollerWidth = this.scroller.clientWidth; 215 var scrollerWidth = this.scroller.clientWidth;
156 this.scroller.style.overflow = 'hidden'; 216 this.scroller.style.overflow = 'hidden';
157 // Adjust width to compensate for scroller. 217 // Adjust width to compensate for scroller.
158 var scrollbarWidth = this.scroller.clientWidth - scrollerWidth; 218 var scrollbarWidth = this.scroller.clientWidth - scrollerWidth;
159 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; 219 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)';
160 220
161 this.playCollapseSection_(section).then(function() { 221 this.playCollapseSection_(section).then(function() {
162 section.setFrozen(false); 222 section.setFrozen(false);
163 this.scroller.style.overflow = ''; 223 this.scroller.style.overflow = '';
164 this.scroller.style.width = ''; 224 this.scroller.style.width = '';
165 section.classList.remove('collapsing'); 225 section.classList.remove('collapsing');
166 }.bind(this)); 226 }.bind(this));
167 }, 227 },
168 228
169 /** 229 /**
170 * Expands the card in |section| to fill the page.
171 * @param {!SettingsSectionElement} section
172 * @return {!Promise}
173 * @private
174 */
175 playExpandSection_: function(section) {
176 // We must be attached.
177 assert(this.scroller);
178
179 var promise;
180 var animationConfig = section.animateExpand(this.scroller);
181 if (animationConfig) {
182 promise = this.animateElement('section', animationConfig.card,
183 animationConfig.keyframes, animationConfig.options);
184 } else {
185 promise = Promise.resolve();
186 }
187
188 var finished;
189 promise.then(function() {
190 finished = true;
191 this.style.margin = 'auto';
192 }.bind(this), function() {
193 // The animation was canceled; catch the error and continue.
194 finished = false;
195 }).then(function() {
196 section.cleanUpAnimateExpand(finished);
197 });
198
199 return promise;
200 },
201
202 /**
203 * Collapses the card in |section| back to its normal position. 230 * Collapses the card in |section| back to its normal position.
204 * @param {!SettingsSectionElement} section 231 * @param {!SettingsSectionElement} section
205 * @return {!Promise} 232 * @return {!Promise}
206 * @private 233 * @private
207 */ 234 */
208 playCollapseSection_: function(section) { 235 playCollapseSection_: function(section) {
209 // We must be attached. 236 // We must be attached.
210 assert(this.scroller); 237 assert(this.scroller);
211 238
212 this.style.margin = ''; 239 this.style.margin = '';
213 240
214 var promise; 241 var promise;
215 var animationConfig = 242 var animationConfig =
216 section.animateCollapse(this.scroller, this.listScrollTop_); 243 section.animateCollapse(this.scroller, this.listScrollTop_);
217 if (animationConfig) { 244 if (animationConfig) {
218 promise = this.animateElement('section', animationConfig.card, 245 promise = this.animateElement('section', animationConfig.card,
219 animationConfig.keyframes, animationConfig.options); 246 animationConfig.keyframes, animationConfig.options);
220 } else { 247 } else {
221 promise = Promise.resolve(); 248 promise = Promise.resolve();
222 } 249 }
223 250
224 promise.then(function() { 251 promise.then(function() {
225 section.cleanUpAnimateCollapse(true); 252 section.cleanUpAnimateCollapse(true);
226 }, function() { 253 }, function() {
227 section.cleanUpAnimateCollapse(false); 254 section.cleanUpAnimateCollapse(false);
228 }); 255 });
229 return promise; 256 return promise;
230 }, 257 },
231 };
232 258
233
234 /** @polymerBehavior */
235 var MainPageBehavior = [
236 TransitionBehavior,
237 MainPageBehaviorImpl
238 ];
239
240
241 /**
242 * TODO(michaelpg): integrate slide animations.
243 * @polymerBehavior RoutableBehavior
244 */
245 var RoutableBehaviorImpl = {
246 /** @private */ 259 /** @private */
247 scrollToSection_: function() { 260 scrollToSection_: function() {
248 doWhenReady( 261 doWhenReady(
249 function() { 262 function() {
250 return this.scrollHeight > 0; 263 return this.scrollHeight > 0;
251 }.bind(this), 264 }.bind(this),
252 function() { 265 function() {
253 // If the current section changes while we are waiting for the page to 266 // If the current section changes while we are waiting for the page to
254 // be ready, scroll to the newest requested section. 267 // be ready, scroll to the newest requested section.
255 this.getSection_(settings.getCurrentRoute().section).scrollIntoView(); 268 this.getSection_(settings.getCurrentRoute().section).scrollIntoView();
256 }.bind(this)); 269 }.bind(this));
257 }, 270 },
258 271
259 /** @private */ 272 /**
260 currentRouteChanged: function(newRoute, oldRoute) { 273 * Hides or unhides the sections not being expanded.
261 var newRouteIsSubpage = newRoute && newRoute.subpage.length; 274 * @param {string} sectionName The section to keep visible.
262 var oldRouteIsSubpage = oldRoute && oldRoute.subpage.length; 275 * @param {boolean} hidden Whether the sections should be hidden.
263 276 * @private
264 if (!oldRoute && newRouteIsSubpage) { 277 */
265 // Allow the page to load before expanding the section. TODO(michaelpg): 278 toggleOtherSectionsHidden_: function(sectionName, hidden) {
michaelpg 2016/08/06 03:20:37 Again, exact same code from the top, just put down
266 // Time this better when refactoring settings-animated-pages. 279 var sections = Polymer.dom(this.root).querySelectorAll(
267 setTimeout(function() { 280 'settings-section');
268 var section = this.getSection_(newRoute.section); 281 for (var section of sections)
269 if (section) 282 section.hidden = hidden && (section.section != sectionName);
270 this.expandSection(section);
271 }.bind(this));
272 return;
273 }
274
275 if (newRouteIsSubpage) {
276 if (!oldRouteIsSubpage || newRoute.section != oldRoute.section) {
277 var section = this.getSection_(newRoute.section);
278 if (section)
279 this.expandSection(section);
280 }
281 } else {
282 if (oldRouteIsSubpage) {
283 var section = this.getSection_(oldRoute.section);
284 if (section)
285 this.collapseSection(section);
286 }
287
288 // Scrolls to the section if this main page contains the route's section.
289 if (newRoute && newRoute.section && this.getSection_(newRoute.section))
290 this.scrollToSection_();
291 }
292 }, 283 },
293 284
294 /** 285 /**
295 * Helper function to get a section from the local DOM. 286 * Helper function to get a section from the local DOM.
296 * @param {string} section Section name of the element to get. 287 * @param {string} section Section name of the element to get.
297 * @return {?SettingsSectionElement} 288 * @return {?SettingsSectionElement}
298 * @private 289 * @private
299 */ 290 */
300 getSection_: function(section) { 291 getSection_: function(section) {
301 return /** @type {?SettingsSectionElement} */( 292 return /** @type {?SettingsSectionElement} */(
302 this.$$('[section=' + section + ']')); 293 this.$$('[section=' + section + ']'));
303 }, 294 },
304 }; 295 };
305 296
306
307 /** @polymerBehavior */ 297 /** @polymerBehavior */
308 var RoutableBehavior = [ 298 var MainPageBehavior = [
309 MainPageBehavior,
310 settings.RouteObserverBehavior, 299 settings.RouteObserverBehavior,
311 RoutableBehaviorImpl 300 TransitionBehavior,
301 MainPageBehaviorImpl,
312 ]; 302 ];
OLDNEW
« no previous file with comments | « chrome/browser/resources/settings/settings_page/compiled_resources2.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698