| <!-- |
| The common.js file must be included before this file. |
| |
| This in an HTML Import-able file that contains the definition |
| of the following elements: |
| |
| <query-sk> |
| |
| To use this file import it: |
| |
| <link href="/res/imp/query.html" rel="import" /> |
| |
| Usage: |
| |
| <query-sk></query-sk> |
| |
| Properties: |
| currentquery - The current URL query formatted selections. |
| |
| whitelist - A list of keys for params that should always be shown. |
| |
| blacklist - A list of keys for params that should never be shown. |
| |
| matches - A URL for reporting the number of items that match |
| the currentquery. If not the empty string then a request |
| will be made to: |
| |
| matches + '?' + currentquery |
| |
| The response must have the form of: |
| |
| { |
| "matches": NNNN, |
| } |
| |
| noclear - Don't display the clear selections button. |
| |
| feedback - If set shows the current selections as string values. |
| |
| Methods: |
| setParamSet(set) - Set the params to be displayed. |
| |
| clearSelections() - Clear all selections. |
| |
| setSelections(sel) - Set the current selections. Must be called after |
| setParamSet. |
| |
| Events: |
| 'query-change' |
| The 'sk-query' element will produce 'query-change' events when the query |
| parameters chosen have changed. The event contains the current |
| selections formatted as a URL query, found in e.detail. |
| --> |
| <link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html"> |
| <link rel="import" href="/res/common/imp/toggle.html"> |
| <link rel="stylesheet" href="/res/common/css/md.css" type="text/css" media="all" /> |
| <link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html"> |
| |
| <style type="text/css" media="screen"> |
| #moreContainer.hide { |
| display: none; |
| } |
| </style> |
| |
| <dom-module id="query-sk"> |
| <style include="iron-flex iron-flex-alignment"> |
| |
| #moreContainer.hide { |
| display: none; |
| } |
| |
| select { |
| border: solid 1px lightgray; |
| padding: 0.2em; |
| } |
| |
| option { |
| padding: 0.2em; |
| } |
| |
| .node { |
| margin: 0.5em; |
| } |
| |
| .topControls { |
| min-width: 40em; |
| } |
| |
| .currSelection { |
| padding-left: 2em; |
| min-width: 40em; |
| } |
| |
| </style> |
| <template> |
| <div class="horizontal layout"> |
| <div class="vertical layout topControls"> |
| <div> |
| <button id="clear">Clear selections</button> |
| <span id="count"></span> |
| </div> |
| <div> |
| <paper-input id="fast" label="Filter"></paper-input> |
| </div> |
| </div> |
| <div hidden$="{{!feedback}}" class="currSelection"> |
| <pre>{{_splitAmp(currentquery)}}</pre> |
| </div> |
| </div> |
| <div id=inputsContainer class="horizontal layout wrap"> |
| <template is="dom-repeat" items="[[_primary]]" as="sel"> |
| <div class="node"> |
| <h4>[[sel.name]]</h4> |
| <select size=9 data-name$="[[sel.name]]" multiple=true initial-count=1000> |
| <template is="dom-repeat" items="[[sel.values]]" as="o"> |
| <option label$="[[o]]">[[o]]</option> |
| </template> |
| </select> |
| </div> |
| </template> |
| </div> |
| <toggle-display-sk id=toggle classname=hide>More...</toggle-display-sk> |
| <div id=moreContainer class="horizontal layout wrap hide"> |
| <template is="dom-repeat" items="[[_secondary]]" as="sel"> |
| <div class="node"> |
| <h4>[[sel.name]]</h4> |
| <select size=9 data-name$="[[sel.name]]" multiple=true> |
| <template is="dom-repeat" items="[[sel.values]]" as="o" initial-count=1000> |
| <option label$="[[o]]">[[o]]</option> |
| </template> |
| </select> |
| </div> |
| </template> |
| </div> |
| </template> |
| </dom-module> |
| <script> |
| (function () { |
| Polymer({ |
| is: 'query-sk', |
| |
| properties: { |
| currentquery: { |
| type: String, |
| value: "", |
| }, |
| matches: { |
| type: String, |
| value: '/query/0/-1/', |
| reflectToAttribute: true |
| }, |
| noclear: { |
| type: Boolean, |
| value: false, |
| reflectToAttribute: true |
| }, |
| whitelist: { |
| type: Array, |
| value: function() { |
| return [ |
| 'name', |
| 'bench_type', |
| 'os', |
| 'source_type', |
| 'scale', |
| 'extra_config', |
| 'config', |
| 'arch', |
| 'sub_result' |
| ]; |
| }, |
| reflectToAttribute: true |
| }, |
| blacklist: { |
| type: Array, |
| value: function() { return []; } |
| }, |
| feedback: { |
| type: Boolean, |
| value: false, |
| notify: true |
| } |
| }, |
| |
| ready: function() { |
| // Both _primary and _secondary are arrays of objects that look like: |
| // |
| // { |
| // name: "config", |
| // values: ["565", "8888", "gpu"] |
| // } |
| // |
| // Where _primary contains selections that are in the whitelist, and |
| // _secondary contains all the other selections. |
| this._primary = []; |
| this._secondary = []; |
| |
| this.$.inputsContainer.addEventListener('change', this._fireChange.bind(this)); |
| this.$.moreContainer.addEventListener('change', this._fireChange.bind(this)); |
| this.$.clear.addEventListener('click', this.clearSelections.bind(this)); |
| if (this.noclear) { |
| this.$.clear.style.display = 'none'; |
| } |
| this.$.fast.addEventListener('input', function (e) { |
| this.$.toggle.open(); |
| this._fastFilter(); |
| }.bind(this)); |
| }, |
| |
| _splitAmp: sk.query.splitAmp, |
| |
| _fastFilter: function() { |
| var filters = this.$.fast.value.trim().toLowerCase().split(/\s+/); |
| // Create a closure that returns true if the given label |
| // matches the filter. |
| var matches = function(s) { |
| s = s.toLowerCase(); |
| for (var i = 0; i < filters.length; i++) { |
| if (s.indexOf(filters[i]) >= 0) { |
| return true; |
| } |
| } |
| return false; |
| }; |
| $$('option', this).forEach(function (ele) { |
| ele.hidden = !matches(ele.getAttribute('label')); |
| }); |
| }, |
| |
| _fireChange: function() { |
| var q = this._selectionsAsQuery(); |
| |
| // Only fire if we see a real change in the state. |
| if (q != this.currentquery) { |
| this.currentquery = q; |
| this.dispatchEvent(new CustomEvent('query-change', { detail: q, bubbles: true })); |
| var countEle = this.$.count; |
| if (this.matches) { |
| sk.get(this.matches + "?" + q).then(JSON.parse).then(function (json) { |
| countEle.innerHTML = json['matches'] + ' lines selected<br />'; |
| }); |
| } |
| } |
| }, |
| |
| // _selectionsAsQuery bundles up the current set of selections as a URL query |
| // suitable for passing to the /query/ endpoint. |
| // |
| _selectionsAsQuery: function () { |
| var sel = []; |
| $$('option', this).forEach(function (option) { |
| if (!option.selected) { |
| return; |
| } |
| var key = option.parentElement.dataset.name; |
| sel.push(encodeURIComponent(key) + '=' + encodeURIComponent(option.value)); |
| }); |
| return sel.join('&'); |
| }, |
| |
| clearSelections: function() { |
| $$('option', this).forEach(function (elem) { |
| elem.selected = false; |
| }); |
| this.$.fast.value = ''; |
| this._fastFilter(); |
| this._fireChange(); |
| this.$.count.textContent = ''; |
| }, |
| |
| // Selects all the values in paramset. |
| // |
| // The argument is a URL query encoded paramset. |
| setSelections: function (paramset) { |
| paramset = sk.query.toParamSet(paramset); |
| this.clearSelections(); |
| $$('option', this).forEach(function (sel) { |
| var params = paramset[sel.parentElement.dataset.name]; |
| if (params) { |
| sel.selected = params.indexOf(sel.value) !== -1; |
| } |
| }); |
| this._fireChange(); |
| }, |
| |
| // When paramset is changed we rebuild _primary and _secondary. |
| // |
| // The paramset is an object that maps selection names |
| // to a list of selection values, not necessarily in alphabetical |
| // order. |
| setParamSet: function (paramset) { |
| var keylist = Object.keys(paramset).sort(); |
| this.splice('_primary', 0, this._primary.length); |
| this.splice('_secondary', 0, this._secondary.length); |
| for (var i = 0; i < keylist.length; i++) { |
| var key = keylist[i]; |
| if ((this.blacklist.length > 0) && (this.blacklist.indexOf(key) != -1)) { |
| continue; |
| } |
| |
| var sel = { |
| name: key, |
| values: paramset[key].sort() |
| }; |
| if (this.whitelist.length == 0 || this.whitelist.indexOf(key) != -1) { |
| this.push('_primary', sel); |
| } else { |
| this.push('_secondary', sel); |
| } |
| } |
| this.$.toggle.hidden = (this._secondary.length == 0); |
| } |
| }); |
| })(); |
| </script> |