3 Polymer('core-collapse', {
5 * Fired when the target element has been resized as a result of the opened
21 * If true, the orientation is horizontal; otherwise is vertical.
23 * @attribute horizontal
30 * Set opened to true to show the collapse element and to false to hide it.
39 * Collapsing/expanding animation duration in second.
48 * If true, the size of the target element is fixed and is set
49 * on the element. Otherwise it will try to
50 * use auto to determine the natural size to use
51 * for collapsing/expanding.
53 * @attribute fixedSize
60 this.transitionEndListener = this.transitionEnd.bind(this);
64 this.target = this.target || this;
67 domReady: function() {
68 this.async(function() {
69 this.afterInitialUpdate = true;
73 detached: function() {
75 this.removeListeners(this.target);
79 targetChanged: function(old) {
81 this.removeListeners(old);
86 this.isTargetReady = !!this.target;
87 this.classList.toggle('core-collapse-closed', this.target !== this);
88 this.target.style.overflow = 'hidden';
89 this.horizontalChanged();
90 this.addListeners(this.target);
91 // set core-collapse-closed class initially to hide the target
92 this.toggleClosedClass(true);
96 addListeners: function(node) {
97 node.addEventListener('transitionend', this.transitionEndListener);
100 removeListeners: function(node) {
101 node.removeEventListener('transitionend', this.transitionEndListener);
104 horizontalChanged: function() {
105 this.dimension = this.horizontal ? 'width' : 'height';
108 openedChanged: function() {
113 * Toggle the opened state.
118 this.opened = !this.opened;
121 setTransitionDuration: function(duration) {
122 var s = this.target.style;
123 s.transition = duration ? (this.dimension + ' ' + duration + 's') : null;
124 if (duration === 0) {
125 this.async('transitionEnd');
129 transitionEnd: function() {
130 if (this.opened && !this.fixedSize) {
131 this.updateSize('auto', null);
133 this.setTransitionDuration(null);
134 this.toggleClosedClass(!this.opened);
135 this.asyncFire('core-resize', null, this.target);
138 toggleClosedClass: function(closed) {
139 this.hasClosedClass = closed;
140 this.target.classList.toggle('core-collapse-closed', closed);
143 updateSize: function(size, duration, forceEnd) {
144 this.setTransitionDuration(duration);
146 var s = this.target.style;
147 var nochange = s[this.dimension] === size;
148 s[this.dimension] = size;
149 // transitonEnd will not be called if the size has not changed
150 if (forceEnd && nochange) {
151 this.transitionEnd();
159 if (!this.isTargetReady) {
160 this.targetChanged();
162 this.horizontalChanged();
163 this[this.opened ? 'show' : 'hide']();
166 calcSize: function() {
167 return this.target.getBoundingClientRect()[this.dimension] + 'px';
170 getComputedSize: function() {
171 return getComputedStyle(this.target)[this.dimension];
175 this.toggleClosedClass(false);
176 // for initial update, skip the expanding animation to optimize
177 // performance e.g. skip calcSize
178 if (!this.afterInitialUpdate) {
179 this.transitionEnd();
182 if (!this.fixedSize) {
183 this.updateSize('auto', null);
184 var s = this.calcSize();
185 this.updateSize(0, null);
187 this.async(function() {
188 this.updateSize(this.size || s, this.duration, true);
193 // don't need to do anything if it's already hidden
194 if (this.hasClosedClass && !this.fixedSize) {
197 if (this.fixedSize) {
198 // save the size before hiding it
199 this.size = this.getComputedSize();
201 this.updateSize(this.calcSize(), null);
203 this.async(function() {
204 this.updateSize(0, this.duration);