OLD | NEW |
---|---|
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. | |
6 var EASING_FUNCTION = 'cubic-bezier(0.4, 0, 0.2, 1)'; | |
7 var EXPAND_DURATION = 350; | |
8 | |
9 /** | 5 /** |
10 * Calls |readyTest| repeatedly until it returns true, then calls | 6 * Calls |readyTest| repeatedly until it returns true, then calls |
11 * |readyCallback|. | 7 * |readyCallback|. |
12 * @param {function():boolean} readyTest | 8 * @param {function():boolean} readyTest |
13 * @param {!Function} readyCallback | 9 * @param {!Function} readyCallback |
14 */ | 10 */ |
15 function doWhenReady(readyTest, readyCallback) { | 11 function doWhenReady(readyTest, readyCallback) { |
16 // TODO(dschuyler): Determine whether this hack can be removed. | 12 // TODO(dschuyler): Determine whether this hack can be removed. |
17 // See also: https://github.com/Polymer/polymer/issues/3629 | 13 // See also: https://github.com/Polymer/polymer/issues/3629 |
18 var intervalId = setInterval(function() { | 14 var intervalId = setInterval(function() { |
19 if (readyTest()) { | 15 if (readyTest()) { |
20 clearInterval(intervalId); | 16 clearInterval(intervalId); |
21 readyCallback(); | 17 readyCallback(); |
22 } | 18 } |
23 }, 10); | 19 }, 10); |
24 } | 20 } |
25 | 21 |
26 /** | 22 /** |
27 * Provides animations to expand and collapse individual sections in a page. | 23 * Responds to route changes by expanding, collapsing, and scrolling to |
28 * Expanded sections take up the full height of the container. At most one | 24 * sections. Expanded sections take up the full height of the container. At |
29 * section should be expanded at any given time. | 25 * most one section should be expanded at any given time. |
26 * TODO(michaelpg): Combine with RoutableBehaviorImpl. | |
30 * @polymerBehavior Polymer.MainPageBehavior | 27 * @polymerBehavior Polymer.MainPageBehavior |
31 */ | 28 */ |
32 var MainPageBehaviorImpl = { | 29 var MainPageBehaviorImpl = { |
33 /** @type {?Element} The scrolling container. */ | |
34 scroller: null, | |
35 | |
36 /** @override */ | 30 /** @override */ |
37 attached: function() { | 31 attached: function() { |
38 if (this.domHost && this.domHost.parentNode.tagName == 'PAPER-HEADER-PANEL') | 32 /** @type {!HTMLElement} */ |
Dan Beam
2016/08/05 00:18:05
indent off
| |
39 this.scroller = this.domHost.parentNode.$.mainContainer; | 33 this.scroller = (this.domHost && this.domHost.parentNode.tagName == |
Dan Beam
2016/08/05 00:18:05
what's the functional difference here? why are yo
| |
40 else | 34 'PAPER-HEADER-PANEL') ? |
41 this.scroller = document.body; // Used in unit tests. | 35 this.domHost.parentNode.$.mainContainer : |
Dan Beam
2016/08/05 00:18:05
yeppppppp this'll trigger that presubmit
| |
36 document.body; // Used in unit tests. | |
42 }, | 37 }, |
43 | 38 |
44 /** | 39 /** |
45 * Hides or unhides the sections not being expanded. | 40 * Hides or unhides the sections not being expanded. |
46 * @param {string} sectionName The section to keep visible. | 41 * @param {string} sectionName The section to keep visible. |
47 * @param {boolean} hidden Whether the sections should be hidden. | 42 * @param {boolean} hidden Whether the sections should be hidden. |
48 * @private | 43 * @private |
49 */ | 44 */ |
50 toggleOtherSectionsHidden_: function(sectionName, hidden) { | 45 toggleOtherSectionsHidden_: function(sectionName, hidden) { |
51 var sections = Polymer.dom(this.root).querySelectorAll( | 46 var sections = Polymer.dom(this.root).querySelectorAll( |
52 'settings-section'); | 47 'settings-section'); |
53 for (var section of sections) | 48 for (var section of sections) |
54 section.hidden = hidden && (section.section != sectionName); | 49 section.hidden = hidden && (section.section != sectionName); |
55 }, | 50 }, |
56 | 51 |
57 /** | 52 /** |
53 * Transistions to the current route if the |deferredTransition_| flag is set. | |
Dan Beam
2016/08/05 00:47:07
Transitions
| |
54 * @private | |
55 */ | |
56 runDeferredTransition_: function() { | |
Dan Beam
2016/08/05 00:47:06
this makes it seem as if "deferredTransition_" is
| |
57 // TODO(michaelpg): Manage transition lifetime better. crbug.com/624145 | |
58 if (!this.deferredTransition_) | |
59 return; | |
60 this.deferredTransition_ = false; | |
61 this.transitionToRoute_(); | |
62 }, | |
63 | |
64 /** | |
65 * Transitions to the current route based on the state of the current page | |
66 * (i.e., expands and collapses sections as necessary). Must only be called | |
67 * when no other transition is running or pending. | |
68 * @private | |
69 */ | |
70 transitionToRoute_: function() { | |
71 assert(!this.currentSectionTransition_); | |
72 | |
73 var expandedSection = /** @type {?SettingsSectionElement} */( | |
74 this.$$('settings-section.expanded')); | |
75 if (expandedSection) { | |
76 if (expandedSection.section == this.currentRoute.section && | |
77 this.currentRoute.subpage.length > 0) { | |
78 // settings-animated-pages controls visibility of subpages in sections. | |
Dan Beam
2016/08/05 00:47:06
can you describe this in a different, more high-le
| |
79 return; | |
80 } | |
81 | |
82 // Collapse this section (and check for a deferred transition when | |
83 // finished). | |
84 this.collapseSection(expandedSection).then( | |
85 this.runDeferredTransition_.bind(this)); | |
86 | |
87 // If the new route is a sub-page, we'll have to expand that next. | |
88 this.deferredTransition_ = this.currentRoute.subpage.length > 0; | |
89 return; | |
90 } | |
91 | |
92 if (this.currentRoute.section.length == 0) | |
Dan Beam
2016/08/05 00:47:06
nit: can you just use truthiness for section or ot
| |
93 return; | |
94 | |
95 var section = this.getSection_(this.currentRoute.section); | |
96 if (!section) | |
97 return; | |
98 | |
99 // Expand the section if the route is a subpage (and check for a deferred | |
100 // transition when finished). | |
101 if (this.currentRoute.subpage.length > 0) { | |
102 this.expandSection(section).then(this.runDeferredTransition_.bind(this)); | |
103 return; | |
104 } | |
105 | |
Dan Beam
2016/08/05 00:47:06
can you put a comment saying which cases actually
| |
106 this.scrollToSection_(); | |
107 }, | |
108 | |
109 /** | |
58 * Animates the card in |section|, expanding it to fill the page. | 110 * Animates the card in |section|, expanding it to fill the page. |
59 * @param {!SettingsSectionElement} section | 111 * @param {!SettingsSectionElement} section |
112 * @return {!Promise} Promise when the transition finishes or cancels. | |
60 */ | 113 */ |
61 expandSection: function(section) { | 114 expandSection: function(section) { |
62 // If another section's card is expanding, cancel that animation first. | 115 assert(!this.currentSectionTransition_); |
63 var expanding = this.$$('.expanding'); | |
64 if (expanding) { | |
65 if (expanding == section) | |
66 return; | |
67 | 116 |
68 if (this.animations['section']) { | 117 // The overscroll must not shrink during the transition. |
69 // Cancel the animation, then call startExpandSection_. | 118 this.fire('overscroll-suppress'); |
70 this.cancelAnimation('section', function() { | |
71 this.startExpandSection_(section); | |
72 }.bind(this)); | |
73 } else { | |
74 // The animation must have finished but its promise hasn't resolved yet. | |
75 // When it resolves, collapse that section's card before expanding | |
76 // this one. | |
77 setTimeout(function() { | |
78 this.collapseSection( | |
79 /** @type {!SettingsSectionElement} */(expanding)); | |
80 this.finishAnimation('section', function() { | |
81 this.startExpandSection_(section); | |
82 }.bind(this)); | |
83 }.bind(this)); | |
84 } | |
85 | 119 |
86 return; | 120 // Prevent additional scrolling and keep the expanding section clipped. |
87 } | 121 this.scroller.style.overflow = ''; |
122 var scrollerWidth = this.scroller.clientWidth; | |
123 this.mainScrollTop_ = this.scroller.scrollTop; | |
124 this.scroller.style.overflow = 'hidden'; | |
88 | 125 |
89 if (this.$$('.collapsing') && this.animations['section']) { | 126 // Set the width to account for the missing scrollbar. |
90 // Finish the collapse animation before expanding. | |
91 this.finishAnimation('section', function() { | |
92 this.startExpandSection_(section); | |
93 }.bind(this)); | |
94 return; | |
95 } | |
96 | |
97 this.startExpandSection_(section); | |
98 }, | |
99 | |
100 /** | |
101 * Helper function to set up and start the expand animation. | |
102 * @param {!SettingsSectionElement} section | |
103 */ | |
104 startExpandSection_: function(section) { | |
105 if (section.classList.contains('expanded')) | |
106 return; | |
107 | |
108 // Freeze the scroller and save its position. | |
109 this.listScrollTop_ = this.scroller.scrollTop; | |
110 | |
111 var scrollerWidth = this.scroller.clientWidth; | |
112 this.scroller.style.overflow = 'hidden'; | |
113 // Adjust width to compensate for scroller. | |
114 var scrollbarWidth = this.scroller.clientWidth - scrollerWidth; | 127 var scrollbarWidth = this.scroller.clientWidth - scrollerWidth; |
115 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; | 128 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; |
116 | 129 |
117 // Freezes the section's height so its card can be removed from the flow. | 130 this.currentSectionTransition_ = |
118 this.freezeSection_(section); | 131 new settings.OpenSectionTransition(section, this.scroller); |
119 | 132 |
120 // Expand the section's card to fill the parent. | 133 return this.currentSectionTransition_.play().then(function(success) { |
121 var animationPromise = this.playExpandSection_(section); | 134 this.currentSectionTransition_ = null; |
135 if (success) { | |
136 // Hide other sections and scroll to the top of the subpage. | |
137 this.classList.add('showing-subpage'); | |
138 this.toggleOtherSectionsHidden_(section.section, true); | |
139 this.scroller.scrollTop = 0; | |
140 // Notify that the page is fully expanded. | |
141 this.fire('subpage-expand'); | |
142 } else { | |
143 // The open transition cancelled, so scroll back to our old location. | |
144 this.scroller.scrollTop = this.mainScrollTop_; | |
145 } | |
122 | 146 |
123 animationPromise.then(function() { | 147 // Overscroll can now be recalculated. |
124 this.scroller.scrollTop = 0; | 148 this.fire('overscroll-recalc'); |
125 this.toggleOtherSectionsHidden_(section.section, true); | 149 |
126 }.bind(this), function() { | 150 // Restore the scrollbar. |
127 // Animation was canceled; restore the section. | 151 this.scroller.style.width = ''; |
128 this.unfreezeSection_(section); | |
129 }.bind(this)).then(function() { | |
130 this.scroller.style.overflow = ''; | 152 this.scroller.style.overflow = ''; |
131 this.scroller.style.width = ''; | |
132 }.bind(this)); | 153 }.bind(this)); |
133 }, | 154 }, |
134 | 155 |
135 /** | 156 /** |
136 * Animates the card in |section|, collapsing it back into its section. | 157 * Animates the card in |section|, collapsing it back into its section. |
137 * @param {!SettingsSectionElement} section | 158 * @param {!SettingsSectionElement} section |
159 * @return {!Promise} Promise when the transition finishes or cancels. | |
138 */ | 160 */ |
139 collapseSection: function(section) { | 161 collapseSection: function(section) { |
140 // If the section's card is still expanding, cancel the expand animation. | 162 assert(!this.currentSectionTransition_); |
141 if (section.classList.contains('expanding')) { | 163 assert(section.classList.contains('expanded')); |
142 if (this.animations['section']) { | |
143 this.cancelAnimation('section'); | |
144 } else { | |
145 // The animation must have finished but its promise hasn't finished | |
146 // resolving; try again asynchronously. | |
147 this.async(function() { | |
148 this.collapseSection(section); | |
149 }); | |
150 } | |
151 return; | |
152 } | |
153 | 164 |
154 if (!section.classList.contains('expanded')) | 165 // TODO(michaelpg): Minimize horizontal motion when scrollbar changes for |
155 return; | 166 // the common cases. |
167 this.scroller.style.overflow = 'hidden'; | |
168 | |
169 // Set up the close transition first, which takes the section out of the | |
170 // flow, before showing everything. | |
171 this.currentSectionTransition_ = | |
172 new settings.CloseSectionTransition(section, this.scroller); | |
173 this.currentSectionTransition_.setUp(); | |
156 | 174 |
157 this.toggleOtherSectionsHidden_(section.section, false); | 175 this.toggleOtherSectionsHidden_(section.section, false); |
176 this.classList.remove('showing-subpage'); | |
177 this.fire('overscroll-recalc'); | |
158 | 178 |
159 var scrollerWidth = this.scroller.clientWidth; | 179 return new Promise(function(resolve, reject) { |
160 this.scroller.style.overflow = 'hidden'; | 180 // Wait for the other sections to show up so we can scroll properly. |
161 // Adjust width to compensate for scroller. | 181 setTimeout(function() { |
162 var scrollbarWidth = this.scroller.clientWidth - scrollerWidth; | 182 // Allow overscroll adjustment so it changes now rather than after the |
163 this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)'; | 183 // transition has begun. |
164 | 184 |
165 this.playCollapseSection_(section).then(function() { | 185 var newSection = this.currentRoute.section && |
166 this.unfreezeSection_(section); | 186 this.getSection_(this.currentRoute.section); |
167 this.scroller.style.overflow = ''; | 187 |
168 this.scroller.style.width = ''; | 188 // Scroll to the section if indicated by the route. TODO(dschuyler): Is |
169 section.classList.remove('collapsing'); | 189 // this the right behavior, or should we return to the previous scroll |
190 // position? | |
191 if (newSection) | |
192 newSection.scrollIntoView(); | |
193 else | |
194 this.scroller.scrollTop = this.mainScrollTop_; | |
195 | |
196 this.currentSectionTransition_.play().then(function(success) { | |
197 this.currentSectionTransition_ = null; | |
198 if (!success) { | |
199 // The collapse was canceled, so ensure the page is still set up for | |
200 // a full-height section. | |
201 this.fire('subpage-expand'); | |
202 } | |
203 | |
204 // Restore the scrollbar. | |
205 this.scroller.style.overflow = ''; | |
206 this.scroller.style.width = ''; | |
Dan Beam
2016/08/05 00:47:06
marginally useful: make a lockScrolling_() and unl
| |
207 resolve(); | |
208 }.bind(this)); | |
209 }.bind(this)); | |
170 }.bind(this)); | 210 }.bind(this)); |
171 }, | 211 }, |
172 | |
173 /** | |
174 * Freezes a section's height so its card can be removed from the flow without | |
175 * affecting the layout of the surrounding sections. | |
176 * @param {!SettingsSectionElement} section | |
177 * @private | |
178 */ | |
179 freezeSection_: function(section) { | |
180 var card = section.$.card; | |
181 section.style.height = section.clientHeight + 'px'; | |
182 | |
183 var cardHeight = card.offsetHeight; | |
184 var cardWidth = card.offsetWidth; | |
185 // If the section is not displayed yet (e.g., navigated directly to a | |
186 // sub-page), cardHeight and cardWidth are 0, so do not set the height or | |
187 // width explicitly. | |
188 // TODO(michaelpg): Improve this logic when refactoring | |
189 // settings-animated-pages. | |
190 if (cardHeight && cardWidth) { | |
191 // TODO(michaelpg): Temporary hack to store the height the section should | |
192 // collapse to when it closes. | |
193 card.origHeight_ = cardHeight; | |
194 | |
195 card.style.height = cardHeight + 'px'; | |
196 card.style.width = cardWidth + 'px'; | |
197 } else { | |
198 // Set an invalid value so we don't try to use it later. | |
199 card.origHeight_ = NaN; | |
200 } | |
201 | |
202 // Place the section's card at its current position but removed from the | |
203 // flow. | |
204 card.style.top = card.getBoundingClientRect().top + 'px'; | |
205 section.classList.add('frozen'); | |
206 }, | |
207 | |
208 /** | |
209 * After freezeSection_, restores the section to its normal height. | |
210 * @param {!SettingsSectionElement} section | |
211 * @private | |
212 */ | |
213 unfreezeSection_: function(section) { | |
214 if (!section.classList.contains('frozen')) | |
215 return; | |
216 var card = section.$.card; | |
217 section.classList.remove('frozen'); | |
218 card.style.top = ''; | |
219 card.style.height = ''; | |
220 card.style.width = ''; | |
221 section.style.height = ''; | |
222 }, | |
223 | |
224 /** | |
225 * Expands the card in |section| to fill the page. | |
226 * @param {!SettingsSectionElement} section | |
227 * @return {!Promise} | |
228 * @private | |
229 */ | |
230 playExpandSection_: function(section) { | |
231 var card = section.$.card; | |
232 | |
233 // The card should start at the top of the page. | |
234 var targetTop = this.scroller.getBoundingClientRect().top; | |
235 | |
236 section.classList.add('expanding'); | |
237 | |
238 // Expand the card, using minHeight. (The card must span the container's | |
239 // client height, so it must be at least 100% in case the card is too short. | |
240 // If the card is already taller than the container's client height, we | |
241 // don't want to shrink the card to 100% or the content will overflow, so | |
242 // we can't use height, and animating height wouldn't look right anyway.) | |
243 var keyframes = [{ | |
244 top: card.style.top, | |
245 minHeight: card.style.height, | |
246 easing: EASING_FUNCTION, | |
247 }, { | |
248 top: targetTop + 'px', | |
249 minHeight: 'calc(100% - ' + targetTop + 'px)', | |
250 }]; | |
251 var options = /** @type {!KeyframeEffectOptions} */({ | |
252 duration: EXPAND_DURATION | |
253 }); | |
254 // TODO(michaelpg): Change elevation of sections. | |
255 var promise; | |
256 if (keyframes[0].top && keyframes[0].minHeight) | |
257 promise = this.animateElement('section', card, keyframes, options); | |
258 else | |
259 promise = Promise.resolve(); | |
260 | |
261 promise.then(function() { | |
262 section.classList.add('expanded'); | |
263 card.style.top = ''; | |
264 this.style.margin = 'auto'; | |
265 section.$.header.hidden = true; | |
266 section.style.height = ''; | |
267 }.bind(this), function() { | |
268 // The animation was canceled; catch the error and continue. | |
269 }).then(function() { | |
270 // Whether finished or canceled, clean up the animation. | |
271 section.classList.remove('expanding'); | |
272 card.style.height = ''; | |
273 card.style.width = ''; | |
274 }); | |
275 | |
276 return promise; | |
277 }, | |
278 | |
279 /** | |
280 * Collapses the card in |section| back to its normal position. | |
281 * @param {!SettingsSectionElement} section | |
282 * @return {!Promise} | |
283 * @private | |
284 */ | |
285 playCollapseSection_: function(section) { | |
286 var card = section.$.card; | |
287 | |
288 this.style.margin = ''; | |
289 section.$.header.hidden = false; | |
290 | |
291 var startingTop = this.scroller.getBoundingClientRect().top; | |
292 | |
293 var cardHeightStart = card.clientHeight; | |
294 var cardWidthStart = card.clientWidth; | |
295 | |
296 section.classList.add('collapsing'); | |
297 section.classList.remove('expanding', 'expanded'); | |
298 | |
299 // If we navigated here directly, we don't know the original height of the | |
300 // section, so we skip the animation. | |
301 // TODO(michaelpg): remove this condition once sliding is implemented. | |
302 if (isNaN(card.origHeight_)) | |
303 return Promise.resolve(); | |
304 | |
305 // Restore the section to its proper height to make room for the card. | |
306 section.style.height = section.clientHeight + card.origHeight_ + 'px'; | |
307 | |
308 // TODO(michaelpg): this should be in collapseSection(), but we need to wait | |
309 // until the full page height is available (setting the section height). | |
310 this.scroller.scrollTop = this.listScrollTop_; | |
311 | |
312 // The card is unpositioned, so use its position as the ending state, | |
313 // but account for scroll. | |
314 var targetTop = card.getBoundingClientRect().top - this.scroller.scrollTop; | |
315 | |
316 // Account for the section header. | |
317 var headerStyle = getComputedStyle(section.$.header); | |
318 targetTop += section.$.header.offsetHeight + | |
319 parseInt(headerStyle.marginBottom, 10) + | |
320 parseInt(headerStyle.marginTop, 10); | |
321 | |
322 var keyframes = [{ | |
323 top: startingTop + 'px', | |
324 minHeight: cardHeightStart + 'px', | |
325 easing: EASING_FUNCTION, | |
326 }, { | |
327 top: targetTop + 'px', | |
328 minHeight: card.origHeight_ + 'px', | |
329 }]; | |
330 var options = /** @type {!KeyframeEffectOptions} */({ | |
331 duration: EXPAND_DURATION | |
332 }); | |
333 | |
334 card.style.width = cardWidthStart + 'px'; | |
335 var promise = this.animateElement('section', card, keyframes, options); | |
336 promise.then(function() { | |
337 card.style.width = ''; | |
338 }); | |
339 return promise; | |
340 }, | |
341 }; | 212 }; |
342 | 213 |
343 | 214 |
344 /** @polymerBehavior */ | 215 /** @polymerBehavior */ |
345 var MainPageBehavior = [ | 216 var MainPageBehavior = [ |
346 TransitionBehavior, | |
347 MainPageBehaviorImpl | 217 MainPageBehaviorImpl |
348 ]; | 218 ]; |
349 | 219 |
350 | 220 |
351 /** | 221 /** |
352 * TODO(michaelpg): integrate slide animations. | 222 * TODO(michaelpg): integrate slide animations. |
353 * @polymerBehavior RoutableBehavior | 223 * @polymerBehavior RoutableBehavior |
354 */ | 224 */ |
355 var RoutableBehaviorImpl = { | 225 var RoutableBehaviorImpl = { |
356 properties: { | 226 properties: { |
357 /** Contains the current route. */ | 227 /** Contains the current route. */ |
358 currentRoute: { | 228 currentRoute: { |
359 type: Object, | 229 type: Object, |
360 notify: true, | 230 notify: true, |
361 observer: 'currentRouteChanged_', | 231 observer: 'currentRouteChanged_', |
362 }, | 232 }, |
363 }, | 233 }, |
364 | 234 |
365 /** @private */ | 235 /** @private */ |
366 scrollToSection_: function() { | 236 scrollToSection_: function() { |
367 doWhenReady( | 237 doWhenReady( |
368 function() { | 238 function() { |
369 return this.scrollHeight > 0; | 239 return this.scrollHeight > 0; |
370 }.bind(this), | 240 }.bind(this), |
371 function() { | 241 function() { |
372 // If the current section changes while we are waiting for the page to | 242 // If the current section changes while we are waiting for the page to |
373 // be ready, scroll to the newest requested section. | 243 // be ready, scroll to the newest requested section. |
374 this.getSection_(this.currentRoute.section).scrollIntoView(); | 244 var section = this.getSection_(this.currentRoute.section); |
245 if (section) | |
246 section.scrollIntoView(); | |
375 }.bind(this)); | 247 }.bind(this)); |
376 }, | 248 }, |
377 | 249 |
378 /** @private */ | 250 /** |
251 * @param {?settings.Route} newRoute | |
252 * @param {?settings.Route} oldRoute | |
253 * @private | |
254 */ | |
379 currentRouteChanged_: function(newRoute, oldRoute) { | 255 currentRouteChanged_: function(newRoute, oldRoute) { |
380 var newRouteIsSubpage = newRoute && newRoute.subpage.length; | 256 if (!oldRoute && newRoute && newRoute.subpage.length > 0) { |
381 var oldRouteIsSubpage = oldRoute && oldRoute.subpage.length; | |
382 | |
383 if (!oldRoute && newRouteIsSubpage) { | |
384 // Allow the page to load before expanding the section. TODO(michaelpg): | 257 // Allow the page to load before expanding the section. TODO(michaelpg): |
385 // Time this better when refactoring settings-animated-pages. | 258 // Time this better when refactoring settings-animated-pages. |
386 setTimeout(function() { | 259 this.deferredTransition_ = true; |
387 var section = this.getSection_(newRoute.section); | 260 setTimeout(this.runDeferredTransition_.bind(this)); |
388 if (section) | |
389 this.expandSection(section); | |
390 }.bind(this)); | |
391 return; | 261 return; |
392 } | 262 } |
393 | 263 |
394 if (newRouteIsSubpage) { | 264 if (this.currentSectionTransition_) { |
395 if (!oldRouteIsSubpage || newRoute.section != oldRoute.section) { | 265 // Transition to the current route when the current one finishes. |
396 var section = this.getSection_(newRoute.section); | 266 this.deferredTransition_ = true; |
397 if (section) | 267 |
398 this.expandSection(section); | 268 // If the current transition is opening a section we want to close, cancel |
269 // that transition immediately. | |
270 if (this.currentSectionTransition_ instanceof | |
271 settings.OpenSectionTransition && | |
272 (this.currentSectionTransition_.section != newRoute.section || | |
273 newRoute.subpage.length == 0)) { | |
Dan Beam
2016/08/05 00:47:07
can you use some temporary variables for this?
| |
274 this.currentSectionTransition_.cancel(); | |
399 } | 275 } |
400 } else { | 276 return; |
401 if (oldRouteIsSubpage) { | 277 } |
402 var section = this.getSection_(oldRoute.section); | |
403 if (section) | |
404 this.collapseSection(section); | |
405 } | |
406 | 278 |
407 // Scrolls to the section if this main page contains the route's section. | 279 this.transitionToRoute_(); |
408 if (newRoute && newRoute.section && this.getSection_(newRoute.section)) | |
409 this.scrollToSection_(); | |
410 } | |
411 }, | 280 }, |
412 | 281 |
413 /** | 282 /** |
414 * Helper function to get a section from the local DOM. | 283 * Helper function to get a section from the local DOM. |
415 * @param {string} section Section name of the element to get. | 284 * @param {string} section Section name of the element to get. |
416 * @return {?SettingsSectionElement} | 285 * @return {?SettingsSectionElement} |
417 * @private | 286 * @private |
418 */ | 287 */ |
419 getSection_: function(section) { | 288 getSection_: function(section) { |
420 return /** @type {?SettingsSectionElement} */( | 289 return /** @type {?SettingsSectionElement} */( |
421 this.$$('[section=' + section + ']')); | 290 this.$$('[section=' + section + ']')); |
422 }, | 291 }, |
423 }; | 292 }; |
424 | 293 |
425 | 294 |
426 /** @polymerBehavior */ | 295 /** @polymerBehavior */ |
427 var RoutableBehavior = [ | 296 var RoutableBehavior = [ |
428 MainPageBehavior, | 297 MainPageBehavior, |
429 RoutableBehaviorImpl | 298 RoutableBehaviorImpl |
430 ]; | 299 ]; |
OLD | NEW |