| <!-- The <test-summary-sk> custom element declaration. |
| |
| Displays a summary for the given test. |
| |
| Attributes: |
| summary - A object that gives a summary of a test. Should look like: |
| |
| { |
| "name": "01-original", |
| "diameter": 123242, |
| "untriaged": 2, |
| "num": 2, |
| "untHashes": ["ababab...", "2b2b2b2...", ...], |
| } |
| |
| query - paramset in URL query string format. |
| include - boolean, include ignores. |
| head - boolean, only use digests at head. |
| details - boolean, if true display the details about the untriaged digests. |
| limit - The maximum number of traces and digests to show when displaying details. |
| triage - If true display the image, its closest match, and the triage controls. |
| |
| Events: |
| Methods: |
| |
| focusNext() - Move the focus to the next digest. Returns true if focus actually moved. |
| |
| focusPrev() - Move the focus to the previous digest. Returns true if focus actually moved. |
| |
| markFocus(status) - Set the triage status of the digest with focus to 'status'. |
| --> |
| <polymer-element name="test-summary-sk"> |
| <template> |
| <style type="text/css" media="screen"> |
| span { |
| width: 25em; |
| display: inline-block; |
| overflow-wrap: break-word; |
| margin-left: 1em; |
| } |
| span.short { |
| width: 5em; |
| } |
| .detail { |
| margin-left: 3em; |
| padding: 0.5em; |
| } |
| test-summary-details-sk { |
| box-shadow: 3px 3px 6px 1px rgba(133,133,133,1); |
| margin-top: 1em; |
| margin-bottom: 1em; |
| margin-left: 3em; |
| padding: 1em; |
| } |
| test-summary-details-sk[data-focus] { |
| box-shadow: 3px 3px 6px 5px #FF7F00; |
| } |
| test-summary-details-sk[triage] { |
| display: none; |
| } |
| test-summary-details-sk[triage][data-diff] { |
| display: block; |
| } |
| .only { |
| margin-left: 3em; |
| font-weight: bold; |
| padding: 1em; |
| } |
| paper-spinner { |
| margin-left: 1em; |
| } |
| |
| .blameColumn { |
| width: 20em; |
| } |
| |
| </style> |
| <div vertical layout> |
| <div horizontal layout> |
| <span> |
| <b> |
| <a href="?query={{query | filterNames}}%26name%3D{{summary.name}}&include={{include}}&head={{head}}&untonly=false&details=true&limit=500&triage=true"> |
| {{summary.name}} |
| </a> |
| </b> |
| </span> |
| <!-- <span class=short>{{summary.diameter}}</span> --> |
| <span class=short> |
| <a href="cmp/{{summary.name}}?topQuery={{query}}&topIncludeIgnores={{include}}&leftQuery={{query}}&leftIncludeIgnores={{include}}&head={{head}}"> |
| <core-icon icon=apps></core-icon> |
| </a> |
| </span> |
| <span class=short>{{summary.pos}}</span> |
| <span class=short>{{summary.neg}}</span> |
| <span class=short>{{summary.untriaged}}</span> |
| <span class=short>{{summary.num}}</span> |
| <div class="blameColumn" vertical layout> |
| <template repeat="{{b in summary.blame}}"> |
| <div>{{b.prob | formatPercent }}% - {{b.author}}</div> |
| </template> |
| </div> |
| <span class=short> |
| <template if="{{!triage}}"> |
| <a href="/legacy/#/triage/{{summary.name}}?head={{head}}">Legacy Triage</a> |
| </template> |
| </span> |
| </div> |
| <div vertical layout id=details> |
| <div horizontal layout center> |
| <counter-sk id="counter"></counter-sk> |
| <paper-spinner id="spinner"></paper-spinner> |
| </div> |
| <template if="{{details}}"> |
| <template repeat="{{d, i in summary.untHashes}}"> |
| <template if="{{i<limit}}"> |
| <test-summary-details-sk test="{{summary.name}}" images="{{!triage || loaded}}" digest="{{d}}" limit="{{limit}}" triage="{{triage}}"></test-summary-details-sk> |
| </template> |
| </template> |
| <template if="{{summary.untHashes.length>limit}}"> |
| <div class=only>Only the first {{limit}} hashes are shown.</only> |
| </template> |
| </template> |
| </div> |
| </div> |
| </template> |
| <script> |
| Polymer({ |
| publish: { |
| summary: { |
| value: {}, |
| reflect: true, |
| }, |
| query: { |
| value: "", |
| reflect: true, |
| }, |
| include: { |
| value: false, |
| reflect: true, |
| }, |
| head: { |
| value: true, |
| reflect: true, |
| }, |
| limit: { |
| value: 0, |
| reflect: true, |
| }, |
| details: { |
| value: false, |
| reflect: true, |
| }, |
| triage: { |
| value: false, |
| reflect: true, |
| }, |
| }, |
| |
| created: function() { |
| this.summary = {}; |
| }, |
| |
| ready: function() { |
| this.loadedCount = 0; |
| this.loaded = false; |
| var that = this; |
| // Listen for each test-summary-details-sk to complete loading. |
| this.$.details.addEventListener('details-loaded', function(e) { |
| // Move the newly loaded element to the right location in the list. |
| var node = e.detail; |
| var last = null; |
| var diffValue = +node.dataset.diff; |
| // Find the sibling element we should appear before, which is the |
| // first element with a smaller diff value. |
| $$('test-summary-details-sk', that.$.details).forEach(function(ele) { |
| var d = ele.dataset.diff; |
| if (d) { |
| if (last == undefined && +d < diffValue) { |
| last = ele; |
| } |
| } |
| }); |
| // Insert the node, in the list, or as the first child if last=null. |
| that.$.details.insertBefore(node, last); |
| |
| // Keep the spinner spinning until all details elements have been loaded. |
| that.loadedCount++; |
| that.$.counter.current = that.loadedCount; |
| if (that.loadedCount == that.summary.untHashes.length) { |
| that.$.spinner.active = false; |
| that.$.counter.active = false; |
| that.loaded = true; |
| } |
| }); |
| }, |
| |
| // findFocus returns the current details element with the keyboard focus. |
| findFocus: function() { |
| return $$$('test-summary-details-sk[data-focus]', this.shadowRoot) |
| }, |
| |
| // moveFocus does the actual work of changing the focus from lastEle |
| // to nextEle. |
| // |
| // Returns true if focus actually moved. |
| moveFocus: function(lastEle, nextEle) { |
| // Don't wrap around past the bottom of the list. |
| if (lastEle != null && nextEle == null) { |
| return false; |
| } |
| if (lastEle != null) { |
| lastEle.removeAttribute('data-focus'); |
| } |
| // If nothing is selected, then focus on the first details element. |
| if (nextEle == null) { |
| nextEle = $$$('test-summary-details-sk', this.shadowRoot); |
| } |
| nextEle.setAttribute('data-focus', 'true'); |
| nextEle.scrollIntoView(false); |
| return true; |
| }, |
| |
| // Move the focus to the next digest. |
| focusNext: function() { |
| var nextEle = null; |
| var lastEle = this.findFocus(); |
| if (lastEle != null) { |
| nextEle = lastEle.nextElementSibling; |
| } |
| return this.moveFocus(lastEle, nextEle); |
| }, |
| |
| // Move the focus to the previous digest. |
| focusPrev: function() { |
| var nextEle = null; |
| var lastEle = this.findFocus(); |
| if (lastEle != null) { |
| nextEle = lastEle.previousElementSibling; |
| if (nextEle.nodeName == "TEMPLATE") { |
| nextEle = null; |
| } |
| } |
| return this.moveFocus(lastEle, nextEle); |
| }, |
| |
| // Set the triage status of the digest with focus to 'status'. |
| markFocus: function(status) { |
| if (!this.triage) { |
| return |
| } |
| var focus = this.findFocus(); |
| if (focus != null) { |
| focus.triggerTriage(status); |
| } |
| }, |
| |
| summaryChanged: function() { |
| this.dataset.name = this.summary.name; |
| this.dataset.diameter = this.summary.diameter; |
| this.dataset.pos = this.summary.pos; |
| this.dataset.neg = this.summary.neg; |
| this.dataset.untriaged = this.summary.untriaged; |
| this.dataset.num = this.summary.num; |
| this.loadedCount = 0; |
| if (this.triage && this.details) { |
| this.$.spinner.active = true; |
| this.$.counter.current = 0; |
| this.$.counter.max = this.summary.untHashes.length; |
| this.$.counter.active = true; |
| } |
| }, |
| |
| // filterNames removes all parameters with a key of 'name' from a param set query string. |
| filterNames: function(s) { |
| var o = sk.query.toParamSet(window.decodeURIComponent(s)); |
| delete o["name"]; |
| return window.encodeURIComponent(sk.query.fromParamSet(o)); |
| }, |
| |
| formatPercent: function(prob) { |
| return (prob*100).toFixed(1); |
| } |
| }); |
| </script> |
| </polymer-element> |