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

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

Issue 2054013002: [MD settings] advanced toggle; add scrollWhenReady (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review nits Created 4 years, 6 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 // Fast out, slow in. 5 // Fast out, slow in.
6 var EASING_FUNCTION = 'cubic-bezier(0.4, 0, 0.2, 1)'; 6 var EASING_FUNCTION = 'cubic-bezier(0.4, 0, 0.2, 1)';
7 var EXPAND_DURATION = 350; 7 var EXPAND_DURATION = 350;
8 8
9 /** 9 /**
10 * Workaround for scrolling an element into view when using Polymer.
11 * @param {function():Element} containerCallback Return parent of element.
12 * @param {function():Element} elementCallback Return element to scroll to.
13 */
14 function scrollWhenReady(containerCallback, elementCallback) {
15 // TODO(dschuyler): Determine whether this setTimeout can be removed.
16 // See also: https://github.com/Polymer/polymer/issues/3629
17 setTimeout(function pollForScrollHeight() {
18 var container = containerCallback();
19 if (!container || container.scrollHeight == 0) {
20 setTimeout(pollForScrollHeight.bind(this), 10);
21 return;
22 }
23
24 elementCallback().scrollIntoView();
25 }.bind(this));
26 }
27
28 /**
10 * Provides animations to expand and collapse individual sections in a page. 29 * Provides animations to expand and collapse individual sections in a page.
11 * Expanded sections take up the full height of the container. At most one 30 * Expanded sections take up the full height of the container. At most one
12 * section should be expanded at any given time. 31 * section should be expanded at any given time.
13 * @polymerBehavior Polymer.MainPageBehavior 32 * @polymerBehavior Polymer.MainPageBehavior
14 */ 33 */
15 var MainPageBehaviorImpl = { 34 var MainPageBehaviorImpl = {
16 /** 35 /**
17 * @type {string} Selector to get the sections. Derived elements 36 * @type {string} Selector to get the sections. Derived elements
18 * must override. 37 * must override.
19 */ 38 */
20 sectionSelector: '', 39 sectionSelector: '',
21 40
22 /** @type {?Element} The scrolling container. Elements must set this. */ 41 /** @type {?Element} The scrolling container. */
23 scroller: null, 42 scroller: null,
24 43
44 /** @override */
45 attached: function() {
46 this.scroller = this.domHost && this.domHost.parentNode.$.mainContainer;
47 },
48
25 /** 49 /**
26 * Hides or unhides the sections not being expanded. 50 * Hides or unhides the sections not being expanded.
27 * @param {string} sectionName The section to keep visible. 51 * @param {string} sectionName The section to keep visible.
28 * @param {boolean} hidden Whether the sections should be hidden. 52 * @param {boolean} hidden Whether the sections should be hidden.
29 * @private 53 * @private
30 */ 54 */
31 toggleOtherSectionsHidden_: function(sectionName, hidden) { 55 toggleOtherSectionsHidden_: function(sectionName, hidden) {
32 var sections = Polymer.dom(this.root).querySelectorAll( 56 var sections = Polymer.dom(this.root).querySelectorAll(
33 this.sectionSelector + ':not([section=' + sectionName + '])'); 57 this.sectionSelector + ':not([section=' + sectionName + '])');
34 for (var section of sections) 58 for (var section of sections)
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 /** 229 /**
206 * Expands the card in |section| to fill the page. 230 * Expands the card in |section| to fill the page.
207 * @param {!SettingsSectionElement} section 231 * @param {!SettingsSectionElement} section
208 * @return {!Promise} 232 * @return {!Promise}
209 * @private 233 * @private
210 */ 234 */
211 playExpandSection_: function(section) { 235 playExpandSection_: function(section) {
212 var card = section.$.card; 236 var card = section.$.card;
213 237
214 // The card should start at the top of the page. 238 // The card should start at the top of the page.
215 var targetTop = this.parentElement.getBoundingClientRect().top; 239 var targetTop = this.scroller.getBoundingClientRect().top;
216 240
217 section.classList.add('expanding'); 241 section.classList.add('expanding');
218 242
219 // Expand the card, using minHeight. (The card must span the container's 243 // Expand the card, using minHeight. (The card must span the container's
220 // client height, so it must be at least 100% in case the card is too short. 244 // client height, so it must be at least 100% in case the card is too short.
221 // If the card is already taller than the container's client height, we 245 // If the card is already taller than the container's client height, we
222 // don't want to shrink the card to 100% or the content will overflow, so 246 // don't want to shrink the card to 100% or the content will overflow, so
223 // we can't use height, and animating height wouldn't look right anyway.) 247 // we can't use height, and animating height wouldn't look right anyway.)
224 var keyframes = [{ 248 var keyframes = [{
225 top: card.style.top, 249 top: card.style.top,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 * @param {!SettingsSectionElement} section 286 * @param {!SettingsSectionElement} section
263 * @return {!Promise} 287 * @return {!Promise}
264 * @private 288 * @private
265 */ 289 */
266 playCollapseSection_: function(section) { 290 playCollapseSection_: function(section) {
267 var card = section.$.card; 291 var card = section.$.card;
268 292
269 this.style.margin = ''; 293 this.style.margin = '';
270 section.$.header.hidden = false; 294 section.$.header.hidden = false;
271 295
272 var startingTop = this.parentElement.getBoundingClientRect().top; 296 var startingTop = this.scroller.getBoundingClientRect().top;
273 297
274 var cardHeightStart = card.clientHeight; 298 var cardHeightStart = card.clientHeight;
275 var cardWidthStart = card.clientWidth; 299 var cardWidthStart = card.clientWidth;
276 300
277 section.classList.add('collapsing'); 301 section.classList.add('collapsing');
278 section.classList.remove('expanding', 'expanded'); 302 section.classList.remove('expanding', 'expanded');
279 303
280 // If we navigated here directly, we don't know the original height of the 304 // If we navigated here directly, we don't know the original height of the
281 // section, so we skip the animation. 305 // section, so we skip the animation.
282 // TODO(michaelpg): remove this condition once sliding is implemented. 306 // TODO(michaelpg): remove this condition once sliding is implemented.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 /** Contains the current route. */ 362 /** Contains the current route. */
339 currentRoute: { 363 currentRoute: {
340 type: Object, 364 type: Object,
341 notify: true, 365 notify: true,
342 observer: 'currentRouteChanged_', 366 observer: 'currentRouteChanged_',
343 }, 367 },
344 }, 368 },
345 369
346 /** @private */ 370 /** @private */
347 scrollToSection_: function() { 371 scrollToSection_: function() {
348 // TODO(dschuyler): Determine whether this setTimeout can be removed. 372 scrollWhenReady(
349 // See also: https://github.com/Polymer/polymer/issues/3629 373 function() {
350 setTimeout(function pollForScrollHeight() { 374 return this;
351 // If the current section changes while we are waiting for the page to be 375 }.bind(this),
352 // ready, scroll to the newest requested section. 376 function() {
353 var element = this.getSection_(this.currentRoute.section); 377 // If the current section changes while we are waiting for the page to
354 if (!element) 378 // be ready, scroll to the newest requested section.
355 return; 379 return this.getSection_(this.currentRoute.section);
356 380 }.bind(this));
357 var host = findAncestor(element, function(n) { return n.host; }).host;
358 if (host.scrollHeight == 0) {
359 setTimeout(pollForScrollHeight.bind(this), 100);
360 return;
361 }
362
363 // TODO(michaelpg): due to the workaround for crbug.com/617827 in
364 // settings_page_css.html, we have to use element.offsetTop instead of
365 // relying on element.scrollIntoView() so the margin is included.
366 host.scroller.scrollTop = element.offsetTop;
367 }.bind(this));
368 }, 381 },
369 382
370 /** @private */ 383 /** @private */
371 currentRouteChanged_: function(newRoute, oldRoute) { 384 currentRouteChanged_: function(newRoute, oldRoute) {
372 var newRouteIsSubpage = newRoute && newRoute.subpage.length; 385 var newRouteIsSubpage = newRoute && newRoute.subpage.length;
373 var oldRouteIsSubpage = oldRoute && oldRoute.subpage.length; 386 var oldRouteIsSubpage = oldRoute && oldRoute.subpage.length;
374 387
375 if (!oldRoute && newRouteIsSubpage) { 388 if (!oldRoute && newRouteIsSubpage) {
376 // Allow the page to load before expanding the section. TODO(michaelpg): 389 // Allow the page to load before expanding the section. TODO(michaelpg):
377 // Time this better when refactoring settings-animated-pages. 390 // Time this better when refactoring settings-animated-pages.
378 setTimeout(function() { 391 setTimeout(function() {
379 var section = this.getSection_(newRoute.section); 392 var section = this.getSection_(newRoute.section);
380 if (section) 393 if (section)
381 this.expandSection(section); 394 this.expandSection(section);
382 }.bind(this)); 395 }.bind(this));
383 return; 396 return;
384 } 397 }
385 398
386 if (!newRouteIsSubpage && oldRouteIsSubpage) { 399 if (!newRouteIsSubpage && oldRouteIsSubpage) {
387 var section = this.getSection_(oldRoute.section); 400 var section = this.getSection_(oldRoute.section);
388 if (section) 401 if (section)
389 this.collapseSection(section); 402 this.collapseSection(section);
390 } else if (newRouteIsSubpage && 403 } else if (newRouteIsSubpage &&
391 (!oldRouteIsSubpage || newRoute.section != oldRoute.section)) { 404 (!oldRouteIsSubpage || newRoute.section != oldRoute.section)) {
392 var section = this.getSection_(newRoute.section); 405 var section = this.getSection_(newRoute.section);
393 if (section) 406 if (section)
394 this.expandSection(section); 407 this.expandSection(section);
395 } else if (newRoute && newRoute.section) { 408 } else if (newRoute && newRoute.section &&
409 this.$$('[data-page=' + newRoute.page + ']')) {
396 this.scrollToSection_(); 410 this.scrollToSection_();
397 } 411 }
398 }, 412 },
399 413
400 /** 414 /**
401 * Helper function to get a section from the local DOM. 415 * Helper function to get a section from the local DOM.
402 * @param {string} section Section name of the element to get. 416 * @param {string} section Section name of the element to get.
403 * @return {?SettingsSectionElement} 417 * @return {?SettingsSectionElement}
404 * @private 418 * @private
405 */ 419 */
406 getSection_: function(section) { 420 getSection_: function(section) {
407 return /** @type {?SettingsSectionElement} */( 421 return /** @type {?SettingsSectionElement} */(
408 this.$$('[section=' + section + ']')); 422 this.$$('[section=' + section + ']'));
409 }, 423 },
410 }; 424 };
411 425
412 426
413 /** @polymerBehavior */ 427 /** @polymerBehavior */
414 var RoutableBehavior = [ 428 var RoutableBehavior = [
415 MainPageBehavior, 429 MainPageBehavior,
416 RoutableBehaviorImpl 430 RoutableBehaviorImpl
417 ]; 431 ];
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698