Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 * @fileoverview | 6 * @fileoverview |
| 7 * 'cr-settings-section' shows a paper material themed section with a header | 7 * 'cr-settings-section' shows a paper material themed section with a header |
| 8 * which shows its page title. | 8 * which shows its page title. |
| 9 * | 9 * |
| 10 * Example: | 10 * Example: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 /** | 43 /** |
| 44 * Title for the page header and navigation menu. | 44 * Title for the page header and navigation menu. |
| 45 */ | 45 */ |
| 46 pageTitle: String, | 46 pageTitle: String, |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * Container that determines the sizing of expanded sections. | 49 * Container that determines the sizing of expanded sections. |
| 50 */ | 50 */ |
| 51 expandContainer: { | 51 expandContainer: { |
| 52 type: Object, | 52 type: Object, |
| 53 notify: true, | |
| 54 }, | 53 }, |
| 55 | 54 |
| 56 animationConfig: { | 55 animationConfig: { |
| 57 value: function() { | 56 value: function() { |
| 58 return { | 57 return { |
| 59 collapse: { | 58 collapse: { |
| 60 name: 'collapse-card-animation', | 59 name: 'collapse-card-animation', |
| 61 node: this, | 60 node: this, |
| 62 }, | 61 }, |
| 63 expand: { | 62 expand: { |
| 64 name: 'expand-card-animation', | 63 name: 'expand-card-animation', |
| 65 node: this, | 64 node: this, |
| 66 }, | 65 }, |
| 67 }; | 66 }; |
| 68 }, | 67 }, |
| 69 }, | 68 }, |
| 70 }, | 69 }, |
| 71 | 70 |
| 71 listeners: { | |
| 72 'expand-animation-complete': 'onExpandAnimationComplete_', | |
| 73 }, | |
| 74 | |
| 72 /** @private */ | 75 /** @private */ |
| 73 expanded_: false, | 76 expanded_: false, |
| 74 | 77 |
| 75 /** @private */ | 78 /** @private */ |
| 76 currentRouteChanged_: function() { | 79 currentRouteChanged_: function() { |
| 77 var expanded = this.currentRoute.section == this.section; | 80 var expanded = this.currentRoute.section == this.section; |
| 78 | 81 |
| 79 if (expanded != this.expanded_) { | 82 if (expanded != this.expanded_) { |
| 80 this.expanded_ = expanded; | 83 this.expanded_ = expanded; |
| 81 this.playAnimation(expanded ? 'expand' : 'collapse'); | 84 this.playAnimation(expanded ? 'expand' : 'collapse'); |
| 82 } | 85 } |
| 83 | 86 |
| 84 var visible = expanded || this.currentRoute.section == ''; | 87 var visible = expanded || this.currentRoute.section == ''; |
| 85 this.$.section.elevation = visible ? 1 : 0; | 88 this.$.card.elevation = visible ? 1 : 0; |
| 89 | |
| 90 // Remove 'hidden' class immediately, but defer adding it if we are invisble | |
| 91 // until the animation is complete. | |
| 92 if (visible) | |
| 93 this.hidden = false; | |
| 86 }, | 94 }, |
| 95 | |
| 96 /** @private */ | |
| 97 onExpandAnimationComplete_: function() { | |
| 98 this.hidden = this.currentRoute.section != '' && | |
| 99 this.currentRoute.section != this.section; | |
| 100 } | |
| 87 }); | 101 }); |
| 88 | 102 |
| 89 Polymer({ | 103 Polymer({ |
| 90 is: 'expand-card-animation', | 104 is: 'expand-card-animation', |
| 91 | 105 |
| 92 behaviors: [ | 106 behaviors: [ |
| 93 Polymer.NeonAnimationBehavior | 107 Polymer.NeonAnimationBehavior |
| 94 ], | 108 ], |
| 95 | 109 |
| 96 configure: function(config) { | 110 configure: function(config) { |
| 97 var node = config.node; | 111 var section = config.node; |
| 98 var containerRect = node.expandContainer.getBoundingClientRect(); | 112 var card = section.$.card; |
| 99 var nodeRect = node.getBoundingClientRect(); | 113 var containerRect = section.expandContainer.getBoundingClientRect(); |
| 114 var cardRect = card.getBoundingClientRect(); | |
| 100 | 115 |
| 101 // Save section's original height. | 116 // Set placeholder height so the page does not reflow during animation. |
| 102 node.unexpandedHeight = nodeRect.height; | 117 // TODO(tommycli): For URLs that directly load subpages, this does not work. |
| 118 var placeholder = section.$.placeholder; | |
| 119 placeholder.style.top = card.offsetTop + 'px'; | |
| 120 placeholder.style.height = card.offsetHeight + 'px'; | |
| 103 | 121 |
| 104 var headerHeight = node.$.header.getBoundingClientRect().height; | 122 section.classList.add('neon-animating'); |
| 105 var newTop = containerRect.top - headerHeight; | |
| 106 var newHeight = containerRect.height + headerHeight; | |
| 107 | 123 |
| 108 node.style.position = 'fixed'; | 124 this._effect = new KeyframeEffect(card, [ |
| 109 node.style.zIndex = '1'; | 125 {'top': cardRect.top + 'px', 'height': cardRect.height + 'px'}, |
| 110 | 126 {'top': containerRect.top + 'px', 'height': containerRect.height + 'px'}, |
| 111 this._effect = new KeyframeEffect(node, [ | |
| 112 {'top': nodeRect.top + 'px', 'height': nodeRect.height + 'px'}, | |
| 113 {'top': newTop + 'px', 'height': newHeight + 'px'}, | |
| 114 ], this.timingFromConfig(config)); | 127 ], this.timingFromConfig(config)); |
| 115 return this._effect; | 128 return this._effect; |
| 116 }, | 129 }, |
| 117 | 130 |
| 118 complete: function(config) { | 131 complete: function(config) { |
| 119 config.node.style.position = 'absolute'; | 132 var section = config.node; |
| 120 config.node.style.top = | 133 section.classList.remove('neon-animating'); |
| 121 -config.node.$.header.getBoundingClientRect().height + 'px'; | 134 section.classList.add('expanded'); |
| 122 config.node.style.bottom = 0; | 135 section.expandContainer.classList.add('expanded'); |
| 136 | |
| 137 // This event fires on itself as well, but that is benign. | |
| 138 var sections = section.parentNode.querySelectorAll('cr-settings-section'); | |
| 139 for (var i = 0; i < sections.length; ++i) { | |
|
Dan Beam
2015/09/26 00:22:07
assert(sections[i].parent == section.parent);
Dan Beam
2015/09/26 00:22:29
parentNode* (or parentElement?)
tommycli
2015/09/26 00:32:16
It would be benign to fire these on deeper descend
| |
| 140 sections[i].fire('expand-animation-complete'); | |
| 141 } | |
| 142 | |
| 143 section.expandContainer.scrollTop = 0; | |
| 123 } | 144 } |
| 124 }); | 145 }); |
| 125 | 146 |
| 126 Polymer({ | 147 Polymer({ |
| 127 is: 'collapse-card-animation', | 148 is: 'collapse-card-animation', |
| 128 | 149 |
| 129 behaviors: [ | 150 behaviors: [ |
| 130 Polymer.NeonAnimationBehavior | 151 Polymer.NeonAnimationBehavior |
| 131 ], | 152 ], |
| 132 | 153 |
| 133 configure: function(config) { | 154 configure: function(config) { |
| 134 var node = config.node; | 155 var section = config.node; |
| 156 var oldRect = section.expandContainer.getBoundingClientRect(); | |
| 135 | 157 |
| 136 var oldRect = node.getBoundingClientRect(); | 158 section.classList.remove('expanded'); |
| 159 section.expandContainer.classList.remove('expanded'); | |
| 137 | 160 |
| 138 // Temporarily set position to static to determine new height. | 161 // Get the placeholder coordinates before reflowing. |
| 139 node.style.position = ''; | 162 var newRect = section.$.placeholder.getBoundingClientRect(); |
| 140 var newTop = node.getBoundingClientRect().top; | |
| 141 | 163 |
| 142 // TODO(tommycli): This value is undefined when the user navigates to a | 164 section.classList.add('neon-animating'); |
| 143 // subpage directly by URL instead of from the settings root. Find a better | |
| 144 // method than using 200 as a dummy height. | |
| 145 var newHeight = node.unexpandedHeight || 200; | |
| 146 | 165 |
| 147 node.style.position = 'fixed'; | 166 this._effect = new KeyframeEffect(section.$.card, [ |
| 148 | |
| 149 this._effect = new KeyframeEffect(node, [ | |
| 150 {'top': oldRect.top + 'px', 'height': oldRect.height + 'px'}, | 167 {'top': oldRect.top + 'px', 'height': oldRect.height + 'px'}, |
| 151 {'top': newTop + 'px', 'height': newHeight + 'px'}, | 168 {'top': newRect.top + 'px', 'height': newRect.height + 'px'}, |
| 152 ], this.timingFromConfig(config)); | 169 ], this.timingFromConfig(config)); |
| 153 return this._effect; | 170 return this._effect; |
| 154 }, | 171 }, |
| 155 | 172 |
| 156 complete: function(config) { | 173 complete: function(config) { |
| 157 config.node.style.position = ''; | 174 config.node.classList.remove('neon-animating'); |
| 158 config.node.style.zIndex = '0'; | |
| 159 } | 175 } |
| 160 }); | 176 }); |
| OLD | NEW |