<link rel="import" href="../../bower_components/iron-selector/iron-selector.html"> <link rel="import" href="../../bower_components/iron-icons/iron-icons.html"> <link rel="import" href="../../bower_components/iron-icons/av-icons.html"> <link rel="import" href="../../bower_components/paper-drawer-panel/paper-drawer-panel.html"> <link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html"> <link rel="import" href="../../bower_components/paper-header-panel/paper-header-panel.html"> <link rel="import" href="../app-sidebar/app-sidebar.html"> <link rel="import" href="../app-logo/app-logo.html"> <link rel="import" href="../app-bar/app-bar.html"> <link rel="import" href="../cart-icon/cart-icon.html"> <link rel="import" href="../catalog-data/catalog-data.html"> <link rel="import" href="../catalog-package/catalog-package.html"> <link rel="import" href="../package-symbol/package-symbol.html"> <link rel="import" href="../tag-link/tag-link.html"> <link rel="import" href="../theme-color/theme-color.html"> <link rel="import" href="../element-action-menu/element-action-menu.html"> <link rel="import" href="../element-table/element-table.html"> <link rel="import" href="../element-table-cards/element-table-cards.html"> <link rel="import" href="../responsive-element/responsive-element.html"> <dom-module id="page-browse"> <link rel="import" type="css" href="page-browse.css"> <template> <catalog-data elements="{{elements}}" packages="{{packages}}"></catalog-data> <catalog-package name="[[package]]" data="{{packageInfo}}"></catalog-package> <paper-drawer-panel id="drawerPanel" responsive-width="900px" narrow="{{narrowMode}}" drawer-width="272px" disable-edge-swipe> <app-sidebar drawer> <paper-toolbar> <app-logo class="flex" tabindex="1"></app-logo> <app-bar class="horizontal layout center end-justified" no-search></app-bar> </paper-toolbar> <div id="search" class="layout horizontal center"> <iron-icon icon="search"></iron-icon> <input id="query" type="search" autocomplete="off" value="{{q::keyup}}" placeholder="Search Elements" class="flex" on-search="onSearch"> </div> <div class="content"> <div id="package-tag" hidden$="[[!tag]]"> <span>[[tag]]</span> <iron-icon icon="clear" on-tap="clearTag"></iron-icon> </div> <div id="package-list"> <nav> <a class="package" is="app-link" href="/browse?package=" active$="[[_isEqual(package,'')]]" tabindex="1"> <div class="layout horizontal center"> <div class="all-symbol" aria-hidden="true"><iron-icon icon="apps"></iron-icon></div> <span class="title flex">All Elements</span> </div> </a> <template is="dom-repeat" items="[[packages]]"> <a class="package" is="app-link" href$="[[_packageLink(item.name)]]" active$="[[_isEqual(package,item.name)]]" tabindex="1"> <div class="layout horizontal center"> <package-symbol aria-hidden="true" symbol="[[item.symbol]]" color="[[item.color]]"></package-symbol> <span class="title flex">[[item.title]]</span> </div> </a> </template> </nav> </div> <div hidden$="[[!tag]]" id="current-tag" class="horizontal layout center"> <b>Tag:</b> <span class="flex">[[tag]]</span> <iron-icon icon="clear" on-tap="clearTag"></iron-icon> </div> </div> </app-sidebar> <paper-header-panel id="container" mode="[[_getMode(narrowMode)]]" view$="[[_actualView(view)]]" main> <div class="paper-header"> <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button> <h2 class="flex">[[pageTitle]]</h2> <paper-icon-button class="toggleViewButton" icon="[[viewIcon]]" on-tap="toggleView" hidden$="[[_forceCards]]"></paper-icon-button> <cart-icon class="cartButton" id="cart-toggle" icon="stars" on-tap="cartOpen"></cart-icon> </div> <div id="content"> <div id="package-heading" hidden$="[[!packageInfo]]"> <div class="description">[[packageInfo.description]]</div> </div> <template is="dom-if" if="[[_stampCards(view)]]" restamp> <element-table-cards id="element-cards" elements="[[_filteredElements]]"></element-table-cards> </template> <template is="dom-if" if="[[_stampTable(view)]]" restamp> <element-table color="[[_getColor(packageInfo)]]" elements="[[_filteredElements]]" on-tag-selected="updateTag"></element-table> </template> </div> </paper-header-panel> </paper-drawer-panel> </template> </dom-module> <script> (function() { var _lastNavigated = null; Polymer({ is: 'page-browse', enableCustomStyleProperties: true, properties: { router: Object, pageTitle: {type: String}, // Query Parameters q: {type: String, notify: true, value: '', observer: '_qChanged'}, tag: {type: String, notify: true, value: ''}, package: {type: String, notify: true, value: ''}, view: {type: String, notify: true}, tagList: {type: Array, computed: 'arrayParam(tag)', value: function() { return []; }}, packageList: {type: Array, computed: 'arrayParam(package)', value: function() { return []; }}, viewIcon: {type: String, computed: 'computeViewIcon(view)', value: 'view-module'}, packages: Array, packageInfo: {type: Object, value: {}}, elements: Array, _filteredElements: Array, _elementCount: Number, _forceCards: {type: Boolean}, }, observers: [ 'updateURL(q,package, tag, view, elements)', 'updateMeta(package, packageInfo)', 'scrollToTop(package)' ], listeners: { 'update-params': '_handleParamsUpdate' }, ready: function() { this.view = this._forceCards ? 'cards' : 'table'; }, filter: function(element) { if (this.q && this.q.length && element.name.indexOf(this.q) < 0) { return false; } if (this.packageList.length && this.packageList.indexOf(element.package) < 0) { return false; } if (this.tagList.length) { var match = false; for (var i = 0; i < this.tagList.length; i++) { if (element.tags.join(' ').indexOf(this.tagList[i]) >= 0) match = true; } if (!match) return false; } return true; }, updateTag: function(e, detail) { e.stopPropagation(); e.preventDefault(); var newTag = detail.name; var t = this.tagList.slice(0); if (t.indexOf(newTag) < 0) t.push(newTag); this.tag = t.join(','); }, clearTag: function() { this.tag = null; }, updatePackage: function(e) { e.stopPropagation(); e.preventDefault(); var newPkg = e.currentTarget.name; var p = this.packageList.slice(0); if (p.indexOf(newPkg) < 0) p.push(newPkg); this.package = p.join(','); }, clearPackage: function() { this.package = null; }, togglePackages: function() { if (this.package) { this.prevPackage = this.package; this.clearPackage(); } else { this.package = this.prevPackage; } }, _parseQueryString: function() { var query = window.location.search.substring(1); var params = query.split('&'); var results = []; for (var i = 0; i < params.length; i++) { var pair = params[i].split('='); results[pair[0]] = pair[1]; } return results; }, _buildQueryString: function() { var out = []; if (this.q && this.q.length) out.push("q=" + this.q); if (this.tag && this.tag.length) out.push("tag=" + this.tag); if (this.package && this.package.length) out.push("package=" + this.package); if (this.view !== 'table') out.push("view=" + this.view); return out.join("&"); }, _handleParamsUpdate: function(_, params) { for (var key in params) { this[key] = params[key]; } }, _packageLink: function(name) { return "/browse?package=" + name; }, _qChanged: function(q) { if (q) { this.async(function() { this.$.query.focus(); // make sure to force the cursor to the end of the // input. Only an issue in Firefox. this.$.query.setSelectionRange(q.length, q.length); }); } }, updateURL: function(q, packageName, packageInfo, tag, view) { var qs = this._buildQueryString(); if (qs !== _lastNavigated && this.router) { _lastNavigated = qs; this.router.go('/browse' + (qs.length ? '?' + qs : ''), {replace: true}); } this.updateMeta(packageName, this.packageInfo); if (this.elements) { this._filteredElements = this.elements.filter(this.filter.bind(this)); this._elementCount = this._filteredElements.length; } this.scrollToTop(); }, updateMeta: function(packageName, packageInfo) { if (this.q && this.q.length) { var t = "'" + this.q + "' "; t += (packageInfo && packageInfo.title) ? packageInfo.title : "Elements"; this.pageTitle = t; } else if (packageInfo && packageInfo.title) { this.pageTitle = packageInfo.title; } else if (this.tagList.length) { this.pageTitle = "Elements Tagged '" + this.tagList.join("' or '") + "'"; } else { this.pageTitle = "All Elements"; } this.fire('page-meta', { title: this.pageTitle }); this.$.drawerPanel.closeDrawer(); }, toggleView: function() { if (this.view === 'table') { this.view = 'cards'; } else { this.view = 'table'; } }, computeViewIcon: function(view) { if (view === 'table') { return 'view-module'; } else { return 'view-list'; } }, arrayParam: function(param) { if (!param || !param.length) { return []; } return param.toString().split(','); }, cartOpen: function(e) { this.fire('cart-open'); }, onSearch: function(e) { // when a user clicks on the (x) button we need to be sure to // clear the query this.q = this.$.query.value; }, scrollToTop: function() { this.$.container.scroller.scrollTop = 0; }, _stampCards: function(view) { return view === 'cards'; }, _stampTable: function(view) { return view === 'table'; }, closeDrawer: function() { this.$.drawerPanel.closeDrawer(); }, _actualView: function(view, force) { return force ? 'cards' : view; }, _isEqual: function(a,b) { return a === b; }, _getColor: function() { return this.packageInfo && this.packageInfo.color ? this.packageInfo.color : ''; }, _getMode: function(narrow) { return narrow ? 'waterfall' : 'scroll'; } }); })(); </script>