blob: 35a39824379cbd8becd99cdd0b5eef5b13889471 [file]
<!--
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.
hideCount: If false, then query back to the server for the count
of matching traces.
noClear: Don't display the clear selections button.
fast: Display a edit box for fast trimming of options.
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:
'change'
The 'sk-query' element will produce 'change' events when the query
parameters chosen have changed. The event contains the current
selections formatted as a URL query, found in e.detail.
-->
<polymer-element name="query-sk" attributes="whiteList currentQuery hideCount noClear">
<template>
<style type="text/css" media="screen">
#more.display {
display: none;
}
toggle-display-sk {
display: none;
}
toggle-display-sk.display {
display: block;
}
select {
overflow: auto;
margin: 0.3em;
}
.node {
margin: 0 0.5em;
}
.more {
width: 100%
}
.option {
padding: 0.2em;
}
.option.core-selected {
background: #ddd;
}
.choices {
height: 15em;
overflow-y: auto;
border: solid lightgray 1px;
}
.hide {
display: none;
}
</style>
<div>
<paper-button raised id="clear">Clear selections</paper-button>
<span id="count"></span>
</div>
<template if="{{fast}}">
<div>
<paper-input id=fast label="Filter"></paper-input>
</div>
</template>
<div id="inputs" horizontal layout wrap>
<template repeat="{{sel in primary}}">
<div class="node">
<h4>{{sel.name}}</h4>
<div class="choices">
<core-selector valueattr="label" data-name="{{sel.name}}" multi>
<template repeat="{{o in sel.values}}">
<div class="option" label="{{o}}">{{o}}</div>
</template>
</core-selector>
</div>
</div>
</template>
</div>
<toggle-display-sk>More...</toggle-display-sk>
<div id="more" horizontal layout wrap class="display">
<template repeat="{{sel in secondary}}">
<div class="node">
<h4>{{sel.name}}</h4>
<div class="choices">
<core-selector valueattr="label" data-name="{{sel.name}}" multi>
<template repeat="{{o in sel.values}}">
<div class="option" label="{{o}}">{{o}}</div>
</template>
</core-selector>
</div>
</div>
</template>
</div>
</template>
<script>
(function(){
Polymer({
publish: {
hideCount: {
value: false,
reflect: true
},
noClear: {
value: false,
reflect: true
},
fast: {
value: false,
reflect: true,
},
},
created: 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.whiteList = ['name', 'bench_type', 'os', 'source_type', 'scale', 'extra_config', 'config', 'arch', 'sub_result'];
this.primary = [];
this.secondary = [];
},
ready: function() {
var that = this;
this.currentQuery = '';
this.$.inputs.addEventListener('core-select', this.fireChange.bind(this));
this.$.more.addEventListener('core-select', this.fireChange.bind(this));
this.$.clear.addEventListener('click', this.clearSelections.bind(this));
if (this.noClear) {
this.$.clear.style.display = 'none';
}
if (this.$.fast) {
this.$.fast.addEventListener('input', function(e) {
$$$('toggle-display-sk', that.shadowRoot).open();
that.fastFilter();
});
}
},
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;
};
$$('div[label]', this.$.inputs).forEach(function(ele) {
ele.classList.toggle('hide', !matches(ele.getAttribute('label')));
});
$$('div[label]', this.$.more).forEach(function(ele) {
ele.classList.toggle('hide', !matches(ele.getAttribute('label')));
});
},
clearSelections: function() {
$$('core-selector', this.$.inputs).forEach(function(elem) {
elem.selected = [];
});
$$('core-selector', this.$.more).forEach(function(elem) {
elem.selected = [];
});
this.$.count.textContent = '';
},
fireChange: function() {
var q = this.selectionsAsQuery();
// Only fire if we see a real change in the state.
// See https://github.com/Polymer/core-selector/issues/6
if (q != this.currentQuery) {
this.currentQuery = q;
this.dispatchEvent(new CustomEvent('change', {detail: q}));
var countEle = this.$.count;
if (!this.hideCount) {
sk.get('/query/0/-1/?' + 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 = [];
$$('core-selector', this.$.inputs).forEach(function(select) {
var key = select.dataset.name;
if (select.selected) {
select.selected.forEach(function(value) {
console.log(key, value);
sel.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
});
}
});
$$('core-selector', this.$.more).forEach(function(select) {
var key = select.dataset.name;
if (select.selected) {
select.selected.forEach(function(value) {
console.log(key, value);
sel.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
});
}
});
return sel.join('&');
},
// Selects all the values in paramset.
//
// The argument is a URL query encoded paramset.
setSelections: function(paramset) {
paramset = sk.query.toParamSet(paramset);
this.clearSelections();
$$('core-selector', this.$.inputs).forEach(function(sel) {
sel.selected = paramset[sel.dataset.name] || null;
});
$$('core-selector', this.$.more).forEach(function(sel) {
sel.selected = paramset[sel.dataset.name] || null;
});
},
// 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.primary = [];
this.secondary = [];
for (var i = 0; i < keylist.length; i++) {
var key = keylist[i];
var sel = {
name: key,
values: paramset[key].sort()
}
if (this.whiteList.length == 0 || this.whiteList.indexOf(key) != -1) {
this.primary.push(sel);
} else {
this.secondary.push(sel);
}
}
if (this.secondary.length == 0) {
$$$('toggle-display-sk', this.shadowRoot).classList.remove('display');
} else {
$$$('toggle-display-sk', this.shadowRoot).classList.add('display');
}
}
});
})();
</script>
</polymer-element>