UNPKG

npm-polymer-elements

Version:

Polymer Elements package for npm

270 lines (229 loc) 10.2 kB
<!-- @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="../paper-button/paper-button.html"> <link rel="import" href="../paper-styles/color.html"> <link rel="import" href="../paper-styles/shadow.html"> <link rel="import" href="../paper-styles/typography.html"> <link rel="import" href="../prism-element/prism-highlighter.html"> <link rel="import" href="iron-doc-property.html"> <link rel="import" href="iron-doc-viewer-styles.html"> <!-- Renders documentation describing an element's API. `iron-doc-viewer` renders element and behavior descriptions as extracted by [Hydrolysis](https://github.com/PolymerLabs/hydrolysis). You can provide them either via binding... <iron-doc-viewer descriptor="{{elementDescriptor}}"></iron-doc-viewer> ...or by placing the element descriptor in JSON as the text content of an `iron-doc-viewer`: <iron-doc-viewer> { "is": "awesome-sauce", "properties": [ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"}, ] } </iron-doc-viewer> However, be aware that due to current limitations in Polymer 0.8, _changes_ to the text content will not be respected, only the initial value will be loaded. If you wish to update the documented element, please set it via the `descriptor` property. @demo demo/index.html Basic Demo --> <dom-module id="iron-doc-viewer"> <template> <style include="iron-doc-viewer-styles"></style> <prism-highlighter></prism-highlighter> <section id="summary" class="card" hidden$="[[!descriptor.desc]]"> <marked-element markdown="{{descriptor.desc}}"> <div class="markdown-html"></div> </marked-element> </section> <nav id="api"> <header>API Reference</header> <paper-button id="togglePrivate" on-tap="_togglePrivate">{{_privateToggleLabel}}</paper-button> </nav> <section id="[[_formatAnchor(prefix,'properties')]]" class="card" hidden$="{{_noneToShow(_showPrivate,_properties)}}"> <header><a href="#[[_formatAnchor(prefix,'properties')]]" class="deeplink">Properties</a></header> <template is="dom-repeat" items="{{_properties}}" hidden$="{{!_properties.length}}"> <iron-doc-property anchor-id="[[_formatAnchor(prefix,'property',item.name)]]" descriptor="{{item}}"></iron-doc-property> </template> </section> <section id="[[_formatAnchor(prefix,'methods')]]" class="card" hidden$="{{_noneToShow(_showPrivate,_methods)}}"> <header><a href="#[[_formatAnchor(prefix,'methods')]]" class="deeplink">Methods</a></header> <template is="dom-repeat" items="{{_methods}}"> <iron-doc-property anchor-id="[[_formatAnchor(prefix,'method',item.name)]]" descriptor="{{item}}"></iron-doc-property> </template> </section> <section id="[[_formatAnchor(prefix,'events')]]" class="card" hidden$="{{_noneToShow(_showPrivate,_events)}}"> <header><a href="#[[_formatAnchor(prefix,'events')]" class="deeplink">Events</a></header> <template is="dom-repeat" items="{{_events}}"> <iron-doc-property anchor-id="[[_formatAnchor(prefix,'event',item.name)]]" descriptor="{{item}}"></iron-doc-property> </template> </section> <section id="[[_formatAnchor(prefix,'behaviors')]]" class="card" hidden$="{{_hideBehaviors(_behaviors)}}"> <header><a href="#[[_formatAnchor(prefix,'behaviors')]]" class="deeplink">Behaviors</a></header> <template is="dom-repeat" items="{{_behaviors}}"> <p on-click="_broadcastBehavior">{{item}}</p> </template> </section> </template> <script> (function() { Polymer({ is: 'iron-doc-viewer', 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.ElementDescriptor} */ descriptor: { type: Object, observer: '_descriptorChanged', }, /** * Prefix for fragment identifiers used in anchors. * For static routing `iron-component-page` can * set this to a string identifying the current component. */ prefix: { type: String, value: '' }, /** Whether private properties should be hidden or shown. */ _showPrivate: { type: Boolean, value: false, observer: '_showPrivateChanged', }, /** The label to show for the Private API toggle. */ _privateToggleLabel: String, /** * Broadcast when another component is clicked on * @param {String} detail name of the component * iron-doc-viewer container should load component if possible * @event iron-doc-viewer-component-selected */ }, ready: function() { var jsonDescriptor = this._loadJson(); // Note that this is only an error during element creation. You are free // to stomp over the descriptor after it is ready. if (jsonDescriptor && this.descriptor) { console.error( this, 'received both a bound descriptor:', this.descriptor, 'and JSON descriptor:', this._jsonDescriptor, 'Please provide only one'); throw new Error( '<iron-doc-viewer> accepts either a bound or JSON descriptor; not both'); } if (jsonDescriptor) { this.descriptor = jsonDescriptor; } }, /** * Loads a hydrolysis element descriptor (as JSON) from the text content of * this element, if present. * * @return {hydrolysis.ElementDescriptor} The parsed descriptor, or `null`. */ _loadJson: function() { var textContent = ''; Array.prototype.forEach.call(Polymer.dom(this).childNodes, function(node) { textContent = textContent + node.textContent; }); textContent = textContent.trim(); if (textContent === '') return null; try { return JSON.parse(textContent); } catch(error) { console.error('Failure when parsing JSON:', textContent, error); throw error; } }, /** Converts `descriptor` into our template-friendly `_model`. */ _descriptorChanged: function() { if (!this.descriptor) return; // Split the documented properties between functions and other types. var properties = []; var methods = []; for (var i = 0, property; property = this.descriptor.properties[i]; i++) { (property.type === 'Function' ? methods : properties).push(property); } this._properties = properties; this._methods = methods; this._events = this.descriptor.events || []; this._behaviors = this.descriptor.behaviors || []; this.toggleAttribute('abstract', this.descriptor.abstract); }, /** * Scrolls to the currently selected anchor, as identified * by the URL hash. Whichever element or script is in charge * of routing should call this method on initial page load and * on hashchange events. */ scrollToAnchor: function(hash) { // ToDo: handle linking to private members if (hash && hash.length > 1) { // ensure all dom-repeats have rendered. Polymer.dom.flush(); var anchorId = window.location.hash.slice(1); var elementToFocus = this.$$('[anchor-id="' + anchorId + '"]'); if (elementToFocus) { elementToFocus.scrollIntoView(); } } }, _collapsedChanged: function() { this._collapseToggleLabel = this._collapsed ? 'expand' : 'collapse'; // Bound values aren't exposed to dom-repeat's scope. var properties = this.querySelectorAll('iron-doc-property'); for (var i = 0, property; property = properties[i]; i++) { property.collapsed = this._collapsed; } }, _toggleCollapsed: function() { this._collapsed = !this._collapsed; }, _showPrivateChanged: function() { this._privateToggleLabel = (this._showPrivate ? 'hide' : 'show') + ' private API'; this.toggleClass('show-private', this._showPrivate); }, _togglePrivate: function() { this._showPrivate = !this._showPrivate; }, _noneToShow: function(showPrivate, items) { for (var i = 0; i < items.length; i++) { if (showPrivate || !items[i].private) return false; } return true; }, _formatAnchor: function(prefix, type, membername) { var suffix = membername ? '-' + membername : ''; return prefix + type + suffix; }, _hideBehaviors: function(behaviors) { return behaviors === null || behaviors.length === 0; }, _broadcastBehavior: function(ev) { this.fire('iron-doc-viewer-component-selected', ev.target._templateInstance.item); } }); })(); </script> </dom-module>