<!-- @license Copyright (c) 2015 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 --> <link rel="import" href="../marked-element/marked-element.html"> <link rel="import" href="../paper-styles/typography.html"> <link rel="import" href="../polymer/polymer.html"> <!-- Renders documentation describing a specific property of an element. Give it a hydrolysis `PropertyDescriptor` (via `descriptor`), and watch it go! --> <dom-module id="iron-doc-property"> <link rel="import" type="css" href="iron-doc-property.css"> <template> <div id="transitionMask"> <div id="signature"> <span class="name">{{descriptor.name}}</span><span class="params">(<span>{{_paramText}}</span>)</span> <span class="return" hidden$="{{!descriptor.return}}">➙ <span class="type">{{descriptor.return.type}}</span></span> </div> <div id="details"> <div id="meta" hidden$="{{_computeHideMeta(descriptor)}}"> <span id="type" class="type">{{descriptor.type}}</span> <span id="default" hidden$="{{_computeHideDefault(descriptor.default)}}">default: <span class="value">{{_computeDefaultDisplay(descriptor.default)}}</span></span> <template is="dom-if" if="{{descriptor.readOnly}}"><span> readOnly</span></template> <template is="dom-if" if="{{descriptor.notify}}"><span> notify</span></template> </div> <ol id="params" hidden$="{{_computeHideParams(descriptor,return)}}"> <template is="dom-repeat" items="{{descriptor.params}}"> <li hidden$="{{!item.type}}"> <span class="name">{{item.name}}</span> <span class="type">{{item.type}}</span> <marked-element markdown="{{item.desc}}"> <div class="markdown-html"></div> </marked-element> </li> </template> <li class="return" hidden$="{{!descriptor.return}}">Returns <span class="type">{{descriptor.return.type}}</span> <marked-element markdown="{{descriptor.return.desc}}"> <div class="markdown-html"></div> </marked-element> </li> </ol> <marked-element id="desc" markdown="{{descriptor.desc}}" hidden$="{{!descriptor.desc}}"> <div class="markdown-html"></div> </marked-element> </div> </div> </template> </dom-module> <script> (function() { Polymer({ is: 'iron-doc-property', properties: { /** * The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated * element descriptor to display details for. * * Alternatively, the element descriptor can be provided as JSON via the text content * of this element. * * @type {hydrolysis.PropertyDescriptor} */ descriptor: { type: Object, observer: '_descriptorChanged', }, /** * Whether the property should show a one-liner, or full summary. * * Note that this property _is_ reflected as an attribute, but we perform * the reflection manually. In order to support the CSS transitions, we * must calculate the element height before setting the attribute. */ collapsed: { type: Boolean, value: false, observer: '_collapsedChanged', }, }, listeners: { 'transitionEnd': '_onTransitionEnd', 'webkitTransitionEnd': '_onTransitionEnd', }, ready: function() { this._isReady = true; }, /** * Resets any state that was set up for transitions. * * We are careful to reset our explicit heights after a transition * completes, so that the property doesn't clip values if the user resizes * their viewport. */ _onTransitionEnd: function(event) { if (event.path[0] !== this.$.transitionMask) return; this.$.transitionMask.style.height = ''; }, _descriptorChanged: function() { this.toggleAttribute('private', this.descriptor.private); this.toggleAttribute('configuration', this.descriptor.configuration); this.toggleAttribute('function', this.descriptor.function); this._paramText = (this.descriptor.params || []).map(function(param) { return param.name; }).join(', '); }, /** * Reflects `collapsed` as the `_collapsed` attribute. * * "Why not use `reflectToAttribute: true`?", you ask? A fine question! * * We avoid simple reflection purely because there is no purely declarative * way of transitioning to/from `height: auto`. This callback manages * setting explicit heights for the property so that CSS can interpolate it. * * @see #_onTransitionEnd */ _collapsedChanged: function() { if (!this._isReady) { this.toggleAttribute('_collapsed', this.collapsed); return; } var container = this.$.transitionMask; var collapsed = this.collapsed; // Measure `height: auto`, which we will need regardless of transition // direction. We assume that the collapsed state has an explicit height // set via CSS rules; so we do not bother measuring that. container.style.height = 'auto'; var fullHeight = container.offsetHeight; // Then, we reset to the start state. Changing directions mid-transition // is _not_ supported! if (this.collapsed) { container.style.height = fullHeight + 'px'; // Height 'auto'. } else { container.style.height = ''; // Height specified by CSS rule. } // We must wait a frame so that the transition engine has a chance to know // that something actually changed. requestAnimationFrame(function() { this.toggleAttribute('_collapsed', collapsed); if (this.collapsed) { container.style.height = ''; // Height specified by CSS rule. } else { container.style.height = fullHeight + 'px'; // Height 'auto'. } }.bind(this)); }, // hidden if no type and no defaults _computeHideMeta: function(descriptor) { return descriptor.type === undefined && descriptor.default === undefined; }, // hidden if no params, and no return value _computeHideParams: function(descriptor,ret) { return (!descriptor.params || descriptor.params.length === 0) && !ret; }, _computeHideDefault: function(def) { return def === undefined; }, _computeDefaultDisplay: function(def) { if (def === '') return "''"; return def; } }); })(); </script>