| Index: third_party/polymer/components/core-collapse/core-collapse.html
|
| diff --git a/third_party/polymer/components/core-collapse/core-collapse.html b/third_party/polymer/components/core-collapse/core-collapse.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..494f764c120e77f64ca9929b0f7f4107d4921d2a
|
| --- /dev/null
|
| +++ b/third_party/polymer/components/core-collapse/core-collapse.html
|
| @@ -0,0 +1,250 @@
|
| +<!--
|
| +Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
| +Code distributed by Google as part of the polymer project is also
|
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
| +-->
|
| +
|
| +<!--
|
| +`core-collapse` creates a collapsible block of content. By default, the content
|
| +will be collapsed. Use `opened` to show/hide the content.
|
| +
|
| + <button on-click="{{toggle}}">toggle collapse</button>
|
| +
|
| + <core-collapse id="collapse">
|
| + ...
|
| + </core-collapse>
|
| +
|
| + ...
|
| +
|
| + toggle: function() {
|
| + this.$.collapse.toggle();
|
| + }
|
| +
|
| +@group Polymer Core Elements
|
| +@element core-collapse
|
| +-->
|
| +
|
| +<link rel="import" href="../polymer/polymer.html">
|
| +
|
| +<link rel="stylesheet" href="core-collapse.css" shim-shadowdom>
|
| +
|
| +<polymer-element name="core-collapse" attributes="target horizontal opened duration fixedSize">
|
| +<template>
|
| +
|
| + <content></content>
|
| +
|
| +</template>
|
| +<script>
|
| +
|
| + Polymer('core-collapse', {
|
| + /**
|
| + * Fired when the target element has been resized as a result of the opened
|
| + * state changing.
|
| + *
|
| + * @event core-resize
|
| + */
|
| +
|
| + /**
|
| + * The target element.
|
| + *
|
| + * @attribute target
|
| + * @type object
|
| + * @default null
|
| + */
|
| + target: null,
|
| +
|
| + /**
|
| + * If true, the orientation is horizontal; otherwise is vertical.
|
| + *
|
| + * @attribute horizontal
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + horizontal: false,
|
| +
|
| + /**
|
| + * Set opened to true to show the collapse element and to false to hide it.
|
| + *
|
| + * @attribute opened
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + opened: false,
|
| +
|
| + /**
|
| + * Collapsing/expanding animation duration in second.
|
| + *
|
| + * @attribute duration
|
| + * @type number
|
| + * @default 0.33
|
| + */
|
| + duration: 0.33,
|
| +
|
| + /**
|
| + * If true, the size of the target element is fixed and is set
|
| + * on the element. Otherwise it will try to
|
| + * use auto to determine the natural size to use
|
| + * for collapsing/expanding.
|
| + *
|
| + * @attribute fixedSize
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + fixedSize: false,
|
| +
|
| + created: function() {
|
| + this.transitionEndListener = this.transitionEnd.bind(this);
|
| + },
|
| +
|
| + ready: function() {
|
| + this.target = this.target || this;
|
| + },
|
| +
|
| + domReady: function() {
|
| + this.async(function() {
|
| + this.afterInitialUpdate = true;
|
| + });
|
| + },
|
| +
|
| + detached: function() {
|
| + if (this.target) {
|
| + this.removeListeners(this.target);
|
| + }
|
| + },
|
| +
|
| + targetChanged: function(old) {
|
| + if (old) {
|
| + this.removeListeners(old);
|
| + }
|
| + if (!this.target) {
|
| + return;
|
| + }
|
| + this.isTargetReady = !!this.target;
|
| + this.classList.toggle('core-collapse-closed', this.target !== this);
|
| + this.target.style.overflow = 'hidden';
|
| + this.horizontalChanged();
|
| + this.addListeners(this.target);
|
| + // set core-collapse-closed class initially to hide the target
|
| + this.toggleClosedClass(true);
|
| + this.update();
|
| + },
|
| +
|
| + addListeners: function(node) {
|
| + node.addEventListener('transitionend', this.transitionEndListener);
|
| + },
|
| +
|
| + removeListeners: function(node) {
|
| + node.removeEventListener('transitionend', this.transitionEndListener);
|
| + },
|
| +
|
| + horizontalChanged: function() {
|
| + this.dimension = this.horizontal ? 'width' : 'height';
|
| + },
|
| +
|
| + openedChanged: function() {
|
| + this.update();
|
| + },
|
| +
|
| + /**
|
| + * Toggle the opened state.
|
| + *
|
| + * @method toggle
|
| + */
|
| + toggle: function() {
|
| + this.opened = !this.opened;
|
| + },
|
| +
|
| + setTransitionDuration: function(duration) {
|
| + var s = this.target.style;
|
| + s.transition = duration ? (this.dimension + ' ' + duration + 's') : null;
|
| + if (duration === 0) {
|
| + this.async('transitionEnd');
|
| + }
|
| + },
|
| +
|
| + transitionEnd: function() {
|
| + if (this.opened && !this.fixedSize) {
|
| + this.updateSize('auto', null);
|
| + }
|
| + this.setTransitionDuration(null);
|
| + this.toggleClosedClass(!this.opened);
|
| + this.asyncFire('core-resize', null, this.target);
|
| + },
|
| +
|
| + toggleClosedClass: function(closed) {
|
| + this.hasClosedClass = closed;
|
| + this.target.classList.toggle('core-collapse-closed', closed);
|
| + },
|
| +
|
| + updateSize: function(size, duration, forceEnd) {
|
| + this.setTransitionDuration(duration);
|
| + this.calcSize();
|
| + var s = this.target.style;
|
| + var nochange = s[this.dimension] === size;
|
| + s[this.dimension] = size;
|
| + // transitonEnd will not be called if the size has not changed
|
| + if (forceEnd && nochange) {
|
| + this.transitionEnd();
|
| + }
|
| + },
|
| +
|
| + update: function() {
|
| + if (!this.target) {
|
| + return;
|
| + }
|
| + if (!this.isTargetReady) {
|
| + this.targetChanged();
|
| + }
|
| + this.horizontalChanged();
|
| + this[this.opened ? 'show' : 'hide']();
|
| + },
|
| +
|
| + calcSize: function() {
|
| + return this.target.getBoundingClientRect()[this.dimension] + 'px';
|
| + },
|
| +
|
| + getComputedSize: function() {
|
| + return getComputedStyle(this.target)[this.dimension];
|
| + },
|
| +
|
| + show: function() {
|
| + this.toggleClosedClass(false);
|
| + // for initial update, skip the expanding animation to optimize
|
| + // performance e.g. skip calcSize
|
| + if (!this.afterInitialUpdate) {
|
| + this.transitionEnd();
|
| + return;
|
| + }
|
| + if (!this.fixedSize) {
|
| + this.updateSize('auto', null);
|
| + var s = this.calcSize();
|
| + this.updateSize(0, null);
|
| + }
|
| + this.async(function() {
|
| + this.updateSize(this.size || s, this.duration, true);
|
| + });
|
| + },
|
| +
|
| + hide: function() {
|
| + // don't need to do anything if it's already hidden
|
| + if (this.hasClosedClass && !this.fixedSize) {
|
| + return;
|
| + }
|
| + if (this.fixedSize) {
|
| + // save the size before hiding it
|
| + this.size = this.getComputedSize();
|
| + } else {
|
| + this.updateSize(this.calcSize(), null);
|
| + }
|
| + this.async(function() {
|
| + this.updateSize(0, this.duration);
|
| + });
|
| + }
|
| +
|
| + });
|
| +
|
| +</script>
|
| +</polymer-element>
|
|
|