OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 cr.define('settings', function() { |
| 6 /** |
| 7 * Freezes the section's height so its card can be removed from the flow |
| 8 * without affecting the layout of the surrounding sections. |
| 9 * @param {!HTMLElement} section |
| 10 */ |
| 11 function freezeSection(section) { |
| 12 var card = section.$['card']; |
| 13 section.style.height = section.clientHeight + 'px'; |
| 14 |
| 15 var cardHeight = card.offsetHeight; |
| 16 var cardWidth = card.offsetWidth; |
| 17 |
| 18 // If the section is not displayed yet (e.g., navigated directly to a |
| 19 // sub-page), cardHeight and cardWidth are 0, so do not set the height or |
| 20 // width explicitly. |
| 21 // TODO(michaelpg): Improve this logic when refactoring |
| 22 // settings-animated-pages. |
| 23 if (cardHeight && cardWidth) { |
| 24 // TODO(michaelpg): Temporary hack to store the height the section should |
| 25 // collapse to when it closes. |
| 26 card.origHeight_ = cardHeight; |
| 27 |
| 28 card.style.height = cardHeight + 'px'; |
| 29 card.style.width = cardWidth + 'px'; |
| 30 } else { |
| 31 // Set an invalid value so we don't try to use it later. |
| 32 card.origHeight_ = NaN; |
| 33 } |
| 34 |
| 35 // Place the section's card at its current position but removed from the |
| 36 // flow. |
| 37 card.style.top = card.getBoundingClientRect().top + 'px'; |
| 38 section.classList.add('frozen'); |
| 39 } |
| 40 |
| 41 /** |
| 42 * After freezeSection, restores the section to its normal height. |
| 43 * @param {!HTMLElement} section |
| 44 */ |
| 45 function unfreezeSection(section) { |
| 46 if (!section.classList.contains('frozen')) |
| 47 return; |
| 48 var card = section.$['card']; |
| 49 section.classList.remove('frozen'); |
| 50 card.style.top = ''; |
| 51 card.style.height = ''; |
| 52 card.style.width = ''; |
| 53 section.style.height = ''; |
| 54 } |
| 55 |
| 56 /** |
| 57 * Opens a section by hiding other sections and expanding the section's card |
| 58 * to fill the screen vertically. |
| 59 * @constructor |
| 60 * @implements {settings.animation.AnimationGroup} |
| 61 * @param {!SettingsSectionElement} section |
| 62 * @param {!HTMLElement} container Scrolling container of sections. |
| 63 */ |
| 64 function OpenSectionTransition(section, container) { |
| 65 this.section = section; |
| 66 this.container = container; |
| 67 |
| 68 this.expandCardTransition_ = |
| 69 new settings.ExpandCardTransition(section.$['card'], container); |
| 70 } |
| 71 |
| 72 OpenSectionTransition.prototype = { |
| 73 __proto__: settings.animation.AnimationGroup.prototype, |
| 74 |
| 75 /** @override */ |
| 76 play: function() { |
| 77 // TODO(michaelpg): Change elevation of sections. |
| 78 freezeSection(this.section); |
| 79 this.section.classList.add('expanding'); |
| 80 |
| 81 this.expandCardTransition_.play(); |
| 82 |
| 83 this.finished = this.expandCardTransition_.finished |
| 84 .then(function() { |
| 85 this.cleanUp_(true); |
| 86 }.bind(this)) |
| 87 .catch(function(e) { |
| 88 this.cleanUp_(false); |
| 89 throw e; |
| 90 }.bind(this)); |
| 91 return this.finished; |
| 92 }, |
| 93 |
| 94 /** @override */ |
| 95 finish: function() { |
| 96 if (this.expandCardTransition_) |
| 97 this.expandCardTransition_.finish(); |
| 98 }, |
| 99 |
| 100 /** @override */ |
| 101 cancel: function() { |
| 102 if (this.expandCardTransition_) |
| 103 this.expandCardTransition_.cancel(); |
| 104 }, |
| 105 |
| 106 /** @override */ |
| 107 finished: null, |
| 108 |
| 109 /** |
| 110 * @param {boolean} finished Whether the animation finished. |
| 111 * @private |
| 112 */ |
| 113 cleanUp_: function(finished) { |
| 114 this.expandCardTransition_ = null; |
| 115 if (finished) { |
| 116 this.section.classList.add('expanded'); |
| 117 } else { |
| 118 // Animation was canceled; restore the section. |
| 119 unfreezeSection(this.section); |
| 120 } |
| 121 |
| 122 var card = this.section.$['card']; |
| 123 this.section.classList.remove('expanding'); |
| 124 this.section.style.height = ''; |
| 125 card.style.top = ''; |
| 126 card.style.height = ''; |
| 127 card.style.width = ''; |
| 128 }, |
| 129 }; |
| 130 |
| 131 /** |
| 132 * Closes a section by showing the other sections and collapsing the section's |
| 133 * card back into place. |
| 134 * @constructor |
| 135 * @implements {settings.animation.AnimationGroup} |
| 136 * @param {!SettingsSectionElement} section |
| 137 * @param {!HTMLElement} container Scrolling container of sections. |
| 138 */ |
| 139 function CloseSectionTransition(section, container) { |
| 140 this.section = section; |
| 141 this.container = container; |
| 142 |
| 143 assert(!section.classList.contains('expanding')); |
| 144 assert(!section.classList.contains('collapsing')); |
| 145 assert(section.classList.contains('expanded')); |
| 146 |
| 147 this.collapseCardTransition_ = new settings.CollapseCardTransition( |
| 148 section.$['card'], section.$['header'], container); |
| 149 } |
| 150 |
| 151 CloseSectionTransition.prototype = { |
| 152 __proto__: settings.animation.AnimationGroup.prototype, |
| 153 |
| 154 /** |
| 155 * Prepares the section for the transition by making it position: fixed. |
| 156 * This is useful as a separate step so the page can unhide everything |
| 157 * before starting the transition without this section affecting the flow. |
| 158 */ |
| 159 setUp: function() { |
| 160 this.collapseCardTransition_.setUp(); |
| 161 this.section.classList.add('collapsing'); |
| 162 this.section.classList.remove('expanding', 'expanded'); |
| 163 var card = this.section.$['card']; |
| 164 if (!isNaN(card.origHeight_)) { |
| 165 this.section.style.height = |
| 166 this.section.clientHeight + card.origHeight_ + 'px'; |
| 167 } |
| 168 }, |
| 169 |
| 170 /** @override */ |
| 171 play: function() { |
| 172 var card = this.section.$['card']; |
| 173 if (!isNaN(card.origHeight_)) |
| 174 this.finished = this.collapseCardTransition_.play(); |
| 175 |
| 176 // If we navigated here directly, we don't know the original height of the |
| 177 // section, so we skip the animation. |
| 178 // TODO(michaelpg): remove this condition once sliding is implemented as a |
| 179 // transition. |
| 180 if (isNaN(card.origHeight_)) |
| 181 this.finished = Promise.resolve(); |
| 182 |
| 183 this.finished.then( |
| 184 function() { |
| 185 unfreezeSection(this.section); |
| 186 }.bind(this), |
| 187 function() { |
| 188 this.section.classList.add('expanded'); |
| 189 }.bind(this)); |
| 190 |
| 191 // Whether the animation finishes or cancels, clean up. |
| 192 this.finished.catch(function() {}).then(function() { |
| 193 this.section.classList.remove('collapsing'); |
| 194 this.collapseCardTransition_ = null; |
| 195 }.bind(this)); |
| 196 |
| 197 return this.finished; |
| 198 }, |
| 199 |
| 200 /** @override */ |
| 201 finish: function() { |
| 202 if (this.collapseCardTransition_) |
| 203 this.collapseCardTransition_.finish(); |
| 204 }, |
| 205 |
| 206 /** @override */ |
| 207 cancel: function() { |
| 208 if (this.collapseCardTransition_) |
| 209 this.collapseCardTransition_.cancel(); |
| 210 }, |
| 211 |
| 212 /** @override */ |
| 213 finished: null, |
| 214 }; |
| 215 |
| 216 return { |
| 217 CloseSectionTransition: CloseSectionTransition, |
| 218 OpenSectionTransition: OpenSectionTransition, |
| 219 }; |
| 220 }); |
OLD | NEW |