npm-polymer-elements
Version:
Polymer Elements package for npm
217 lines (191 loc) • 7.9 kB
HTML
<!--
@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="../polymer/polymer.html">
<link rel="import" href="../marked-element/marked-element.html">
<link rel="import" href="iron-doc-property-styles.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">
<template>
<style include="iron-doc-property-styles"></style>
<div id="transitionMask">
<div id="signature">
<a id="[[anchorId]]" href$="#[[anchorId]]" class="name deeplink">{{descriptor.name}}</a><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 class="annotation">[[_getAnnotation(descriptor)]]</span>
</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>
<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',
},
/**
* Unique anchor ID for deep-linking.
*
*/
anchorId: {
type: String,
reflectToAttribute: true
}
},
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;
},
_getAnnotation: function(descriptor) {
var annotations = [];
if (descriptor['default'] !== undefined) {
annotations.push('Default: ' + descriptor['default']);
}
if (descriptor.readOnly) {
annotations.push('readOnly');
}
if (descriptor.notify) {
annotations.push('notifies');
}
return annotations.join(' – ');
}
});
})();
</script>
</dom-module>