blob: d73499fa627fea61666e998e25896c447be6b144 [file] [log] [blame]
<!-- The <commands-sk> custom element declaration.
Displays the list of commands in an SKP in an ordered list.
Attributes:
cmd - The data to display. Looks like:
{
"version": 1,
"commands":[
{
"details": {"command":"BeginDrawPicture"},
"_depth":0,
"_prefix":[]
},
{
"details":{"command":"Save"},
"_depth":1,
"_prefix":[{"icon":"image:image","color":"#A6CEE3"}]
},
...
]
}
item - The index of the command that is selected.
grouping - The number of op-sks to group together under each
op-expando-sk.
Events:
op-selected - This event contains the index of the op selected in
e.details.index.
op-toggled - This event is sent when a paper-checkbox is toggled.
The checked status and index of the op are returned in e.detail.
{
checked: false,
index: 102,
}
This event bubbles up from the op-sk child elements.
Methods:
scrollToTop(index) - Scroll the op at the given index to the top of the
selection.
-->
<style type="text/css" media="screen">
#selector details-sk.selected {
background: #eee;
}
</style>
<link rel=import href="op.html">
<link rel=import href="op-expando.html">
<dom-module id="commands-sk">
<style>
:host {
position: relative;
}
#selector {
overflow-y: scroll;
height: 80vh;
display: block;
}
</style>
<template>
<div id=selector>
<template is="dom-repeat" items="{{_initial(cmd, grouping)}}" as="command">
<op-sk op="{{command}}" prefix="{{command._prefix}}" index="{{command._index}}"></op-sk>
</template>
<template is="dom-repeat" items="{{_groupings(cmd, grouping)}}" as="g" initial-count="{{grouping}}">
<op-expando-sk cmd="{{cmd}}" begin="{{g.begin}}" end="{{g.end}}"></op-expando-sk>
</template>
<template is="dom-repeat" items="{{_remainder(cmd, grouping)}}" as="command">
<op-sk op="{{command}}" prefix="{{command._prefix}}" index="{{command._index}}"></op-sk>
</template>
</div>
</template>
</dom-module>
<script>
Polymer({
is: "commands-sk",
properties: {
cmd: {
type: Object,
value: function() { return { commands: [] }; },
reflectToAttribute: false,
},
item: {
type: Number,
value: 0,
reflectToAttribute: true,
observer: "_itemChange",
},
grouping: {
type: Number,
value: 10,
reflectToAttribute: true,
},
},
ready: function() {
this.$.selector.addEventListener('click', function(e) {
// Find the op-sk that was selected and return its index, not
// the item's location in the list.
var ele = sk.findParent(e.target, "PAPER-CHECKBOX");
if (ele != null) {
return;
}
ele = sk.findParent(e.target, "PAPER-ICON-BUTTON");
if (ele != null) {
return;
}
ele = sk.findParent(e.target, "OP-SK");
if (ele == null) {
return;
}
this.item = this._findItemFromIndex(ele.index);
}.bind(this));
},
// Scrolls the op-sk with index=index to the top. Waits for the
// element to exist and not be hidden, both of which might
// occur if the op-sk is inside an op-expando-sk.
scrollToTop: function(index) {
var ele = $$$("op-sk[index='" + index + "']", this.$.selector);
if (ele && ele.style.display != "none") {
this.$.selector.scrollTop = ele.offsetTop - 150;
} else {
window.setTimeout(this.scrollToTop.bind(this, index), 10);
}
},
_findItemFromIndex: function(index) {
var item = 0;
for (var i = 0; i < this.cmd.commands.length ; i++) {
if (this.cmd.commands[i]._index == index) {
item = i;
break;
}
}
return item;
},
_itemChange: function(newItem, oldItem) {
if (this.cmd.commands.length == 0) {
return;
}
var index = this.cmd.commands[this.item]._index;
if (newItem != oldItem) {
var detail = {
index: index,
}
this.dispatchEvent(new CustomEvent('op-selected', { detail: detail, bubbles: true }));
}
// Unselect the previously selected ele.
$$("op-sk[selected]", this.$.selector).forEach(function(ele) {
ele.removeAttribute('selected');
});
// Expand the op-expando that contains our new selected ele, if any.
var begin = Math.floor(this.item/this.grouping)*this.grouping;
var ele = $$$("op-sk[index='" + index + "']", this.$.selector);
var expando = $$$("op-expando-sk[begin='" + begin + "']", this.$.selector);
if (expando && expando.expanded == false) {
expando.expanded = true;
}
// Set the new op-sk as selected.
this._setSelected(index);
},
// Sets the 'selected' attribute of the op-sk with index=index.
//
// Will wait for the element to come into existence, which is needed
// if the op-sk is inside an op-expando-sk.
_setSelected: function(index) {
var ele = $$$("op-sk[index='" + index + "']", this.$.selector);
if (ele) {
ele.setAttribute('selected', true);
} else {
window.setTimeout(this._setSelected.bind(this, index), 10);
}
},
_initial: function(cmd, grouping) {
return cmd.commands.slice(0, grouping);
},
_remainder: function(cmd, grouping) {
var n = cmd.commands.length;
if (n <= grouping) {
return [];
}
var remainder = n % grouping;
return cmd.commands.slice(-remainder);
},
_groupings: function(cmd, grouping) {
var ret = [];
var n = cmd.commands.length;
if (n <= grouping) {
return ret;
}
var num_groups = Math.floor(n / grouping) - 1;
if (num_groups < 1) {
return ret;
}
for (var i = 0; i < num_groups; i++) {
ret.push({
begin: (i+1)*grouping,
end: (i+2)*grouping,
});
}
return ret;
},
});
</script>