| Index: chrome/browser/resources/settings/settings_page/open_section_transition.js | 
| diff --git a/chrome/browser/resources/settings/settings_page/open_section_transition.js b/chrome/browser/resources/settings/settings_page/open_section_transition.js | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..4f1415fe0a348cc78a51f3c8aea7a3c14862a6a2 | 
| --- /dev/null | 
| +++ b/chrome/browser/resources/settings/settings_page/open_section_transition.js | 
| @@ -0,0 +1,137 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +cr.define('settings', function() { | 
| +  'use strict'; | 
| + | 
| +  /** | 
| +   * Opens a section by hiding other sections and expanding the section's card | 
| +   * to fill the screen vertically. | 
| +   * @constructor | 
| +   * @implements {settings.animation.AnimationGroup} | 
| +   * @param {!SettingsSectionElement} section | 
| +   * @param {!HTMLElement} container Scrolling container of sections. | 
| +   */ | 
| +  function OpenSectionTransition(section, container) { | 
| +    this.section = section; | 
| +    /** @private */ this.container_ = container; | 
| +  } | 
| + | 
| +  OpenSectionTransition.prototype = { | 
| +    __proto__: settings.animation.AnimationGroup.prototype, | 
| + | 
| +    /** @override */ | 
| +    play: function() { | 
| +      var finished; | 
| +      // If we're running this transition before anything else, or coming from | 
| +      // a different page, don't animate. | 
| +      if (!this.section.canAnimateExpand()) { | 
| +        finished = Promise.resolve(true); | 
| +      } else { | 
| +        this.animation_ = this.section.animateExpand(this.container_); | 
| +        finished = this.animation_.finished; | 
| +      } | 
| + | 
| +      return this.finished = finished.then(function() { | 
| +        this.cleanUp_(true); | 
| +        return true; | 
| +      }.bind(this), function() { | 
| +        this.cleanUp_(false); | 
| +        return false; | 
| +      }.bind(this)); | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    finish: function() { | 
| +      if (this.animation_) | 
| +        this.animation_.finish(); | 
| +      this.animation_ = null; | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    cancel: function() { | 
| +      if (this.animation_) | 
| +        this.animation_.cancel(); | 
| +      this.animation_ = null; | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    finished: null, | 
| + | 
| +    /** | 
| +     * @param {boolean} finished Whether the animation finished. | 
| +     * @private | 
| +     */ | 
| +    cleanUp_: function(finished) { | 
| +      this.animation_ = null; | 
| +      this.section.classList.toggle('expanded', finished); | 
| +    }, | 
| +  }; | 
| + | 
| +  /** | 
| +   * Closes a section by collapsing it back into place and restoring the card. | 
| +   * @constructor | 
| +   * @implements {settings.animation.AnimationGroup} | 
| +   * @param {!SettingsSectionElement} section | 
| +   * @param {!HTMLElement} container Scrolling container of sections. | 
| +   */ | 
| +  function CloseSectionTransition(section, container) { | 
| +    this.section = section; | 
| +    /** @private */ this.container_ = container; | 
| +  } | 
| + | 
| +  CloseSectionTransition.prototype = { | 
| +    __proto__: settings.animation.AnimationGroup.prototype, | 
| + | 
| +    /** Prepares the transitions. */ | 
| +    setUp: function() { | 
| +      // If we navigated here directly, we don't know the original height of the | 
| +      // section, so we skip the animation. | 
| +      /** @private */ this.canCollapse_ = this.section.canAnimateCollapse(); | 
| +      if (this.canCollapse_) | 
| +        this.section.setUpAnimateCollapse(this.container_); | 
| +      this.section.classList.remove('expanded'); | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    play: function() { | 
| +      if (!this.canCollapse_) { | 
| +        this.finished = Promise.resolve(true); | 
| +      } else { | 
| +        this.animation_ = this.section.animateCollapse(this.container_); | 
| +        this.finished = this.animation_.finished; | 
| +      } | 
| + | 
| +      this.finished = this.finished.then(function() { | 
| +        return true; | 
| +      }, function() { | 
| +        this.section.classList.add('expanded'); | 
| +        return false; | 
| +      }.bind(this)); | 
| +      return this.finished; | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    finish: function() { | 
| +      if (this.animation_) | 
| +        this.animation_.finish(); | 
| +      this.animation_ = null; | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    cancel: function() { | 
| +      if (this.animation_) | 
| +        this.animation_.cancel(); | 
| +      this.animation_ = null; | 
| +    }, | 
| + | 
| +    /** @override */ | 
| +    finished: null, | 
| +  }; | 
| + | 
| +  return { | 
| +    CloseSectionTransition: CloseSectionTransition, | 
| +    OpenSectionTransition: OpenSectionTransition, | 
| +  }; | 
| +}); | 
|  |