11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Polymer('core-collapse', {
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Fired when the target element has been resized as a result of the opened
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * state changing.
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @event core-resize
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    */
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * The target element.
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @attribute target
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @type object
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @default null
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    target: null,
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * If true, the orientation is horizontal; otherwise is vertical.
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @attribute horizontal
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @type boolean
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @default false
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    horizontal: false,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Set opened to true to show the collapse element and to false to hide it.
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @attribute opened
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @type boolean
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @default false
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    opened: false,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Collapsing/expanding animation duration in second.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @attribute duration
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @type number
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @default 0.33
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    duration: 0.33,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * If true, the size of the target element is fixed and is set
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * on the element.  Otherwise it will try to
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * use auto to determine the natural size to use
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * for collapsing/expanding.
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @attribute fixedSize
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @type boolean
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @default false
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fixedSize: false,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    created: function() {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.transitionEndListener = this.transitionEnd.bind(this);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ready: function() {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.target = this.target || this;
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    domReady: function() {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.async(function() {
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.afterInitialUpdate = true;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      });
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    detached: function() {
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (this.target) {
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.removeListeners(this.target);
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    targetChanged: function(old) {
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (old) {
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.removeListeners(old);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!this.target) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.isTargetReady = !!this.target;
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.classList.toggle('core-collapse-closed', this.target !== this);
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.target.style.overflow = 'hidden';
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.horizontalChanged();
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.addListeners(this.target);
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // set core-collapse-closed class initially to hide the target
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.toggleClosedClass(true);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.update();
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    addListeners: function(node) {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      node.addEventListener('transitionend', this.transitionEndListener);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    removeListeners: function(node) {
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      node.removeEventListener('transitionend', this.transitionEndListener);
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    horizontalChanged: function() {
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.dimension = this.horizontal ? 'width' : 'height';
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    openedChanged: function() {
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.update();
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Toggle the opened state.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @method toggle
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    toggle: function() {
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.opened = !this.opened;
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    setTransitionDuration: function(duration) {
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      var s = this.target.style;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      s.transition = duration ? (this.dimension + ' ' + duration + 's') : null;
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (duration === 0) {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.async('transitionEnd');
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    transitionEnd: function() {
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (this.opened && !this.fixedSize) {
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize('auto', null);
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.setTransitionDuration(null);
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.toggleClosedClass(!this.opened);
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.asyncFire('core-resize', null, this.target);
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    toggleClosedClass: function(closed) {
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.hasClosedClass = closed;
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.target.classList.toggle('core-collapse-closed', closed);
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    updateSize: function(size, duration, forceEnd) {
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.setTransitionDuration(duration);
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.calcSize();
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      var s = this.target.style;
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      var nochange = s[this.dimension] === size;
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      s[this.dimension] = size;
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // transitonEnd will not be called if the size has not changed
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (forceEnd && nochange) {
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.transitionEnd();
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    update: function() {
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!this.target) {
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!this.isTargetReady) {
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.targetChanged();
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.horizontalChanged();
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this[this.opened ? 'show' : 'hide']();
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    calcSize: function() {
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return this.target.getBoundingClientRect()[this.dimension] + 'px';
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    getComputedSize: function() {
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return getComputedStyle(this.target)[this.dimension];
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    show: function() {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.toggleClosedClass(false);
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // for initial update, skip the expanding animation to optimize
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // performance e.g. skip calcSize
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!this.afterInitialUpdate) {
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.transitionEnd();
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return;
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!this.fixedSize) {
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize('auto', null);
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        var s = this.calcSize();
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize(0, null);
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.async(function() {
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize(this.size || s, this.duration, true);
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      });
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    },
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    hide: function() {
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // don't need to do anything if it's already hidden
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (this.hasClosedClass && !this.fixedSize) {
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return;
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (this.fixedSize) {
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // save the size before hiding it
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.size = this.getComputedSize();
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else {
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize(this.calcSize(), null);
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this.async(function() {
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.updateSize(0, this.duration);
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      });
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  });
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
210