2013-09-27 15:02:44 +00:00
<!DOCTYPE html>
2013-10-15 20:10:33 +00:00
< html ng-app = "Loader" ng-controller = "Loader.Controller" >
2013-09-27 15:02:44 +00:00
< head >
2013-10-15 20:10:33 +00:00
< title ng-bind = "windowTitle" > < / title >
2013-09-27 15:02:44 +00:00
< script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js" > < / script >
< script src = "loader.js" > < / script >
2014-02-04 22:45:40 +00:00
< script src = "diff_viewer.js" > < / script >
2013-10-23 15:07:26 +00:00
< link rel = "stylesheet" href = "view.css" >
2013-09-27 15:02:44 +00:00
< / head >
< body >
2013-10-29 17:39:09 +00:00
< h2 >
Instructions, roadmap, etc. are at
< a href = "http://tinyurl.com/SkiaRebaselineServer" >
http://tinyurl.com/SkiaRebaselineServer
< / a >
< / h2 >
2013-10-11 18:45:33 +00:00
< em >
{{loadingMessage}}
2013-10-02 18:57:48 +00:00
< / em >
2013-09-30 15:06:25 +00:00
2013-10-23 15:07:26 +00:00
< div ng-hide = "!categories" > <!-- everything: hide until data is loaded -->
2013-10-24 15:38:27 +00:00
< div class = "warning-div"
ng-hide="!(header.isEditable & & header.isExported)">
2013-10-09 18:05:58 +00:00
WARNING! These results are editable and exported, so any user
who can connect to this server over the network can modify them.
< / div >
2013-10-23 15:07:26 +00:00
2013-10-15 20:10:33 +00:00
< div ng-hide = "!(header.timeUpdated)" >
Results current as of {{localTimeString(header.timeUpdated)}}
< / div >
2013-10-23 15:07:26 +00:00
2013-10-24 15:38:27 +00:00
< div > <!-- tabs -->
< div class = "tab-spacer" ng-repeat = "tab in tabs" >
2013-10-23 15:07:26 +00:00
< div class = "tab-{{tab == viewingTab}}"
ng-click="setViewingTab(tab)">
{{tab}} ({{numResultsPerTab[tab]}})
< / div >
2013-10-24 15:38:27 +00:00
< div class = "tab-spacer" >
2013-10-23 15:07:26 +00:00
< / div >
< / div >
< / div > <!-- tabs -->
2013-10-24 15:38:27 +00:00
< div class = "tab-main" > <!-- main display area of selected tab -->
2013-10-23 15:07:26 +00:00
< br >
2013-10-24 15:38:27 +00:00
<!-- We only show the filters/settings table on the Unfiled tab. -->
2013-10-23 15:07:26 +00:00
< table ng-hide = "viewingTab != defaultTab" border = "1" >
2013-10-02 18:57:48 +00:00
< tr >
2013-10-29 15:49:40 +00:00
< th colspan = "4" >
2013-10-02 18:57:48 +00:00
Filters
< / th >
< th >
Settings
< / th >
< / tr >
< tr valign = "top" >
2013-10-26 14:31:11 +00:00
<!-- TODO(epoger): make this an ng - repeat over resultType, config, etc? -->
2013-10-02 18:57:48 +00:00
< td >
resultType< br >
2013-10-26 15:01:08 +00:00
< label ng-repeat = "(resultType, count) in categories['resultType'] track by $index" >
2013-10-02 18:57:48 +00:00
< input type = "checkbox"
name="resultTypes"
value="{{resultType}}"
2013-10-24 15:38:27 +00:00
ng-checked="!isValueInSet(resultType, hiddenResultTypes)"
ng-click="toggleValueInSet(resultType, hiddenResultTypes); setUpdatesPending(true)">
2013-10-02 18:57:48 +00:00
{{resultType}} ({{count}})< br >
< / label >
2013-10-29 15:49:40 +00:00
< button ng-click = "hiddenResultTypes = {}; updateResults()" >
all
< / button >
< button ng-click = "hiddenResultTypes = {}; toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()" >
none
< / button >
< button ng-click = "toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()" >
toggle
< / button >
< / td >
< td ng-repeat = "category in ['builder', 'test']" >
{{category}}
< br >
< input type = "text"
ng-model="categoryValueMatch[category]"
ng-change="setUpdatesPending(true)"/>
< br >
< button ng-click = "setCategoryValueMatch(category, '')"
ng-disabled="('' == categoryValueMatch[category])">
clear (show all)
< / button >
2013-10-02 18:57:48 +00:00
< / td >
< td >
config< br >
2013-10-26 15:01:08 +00:00
< label ng-repeat = "(config, count) in categories['config'] track by $index" >
2013-10-02 18:57:48 +00:00
< input type = "checkbox"
name="configs"
value="{{config}}"
2013-10-24 15:38:27 +00:00
ng-checked="!isValueInSet(config, hiddenConfigs)"
ng-click="toggleValueInSet(config, hiddenConfigs); setUpdatesPending(true)">
2013-10-02 18:57:48 +00:00
{{config}} ({{count}})< br >
< / label >
2013-10-29 15:49:40 +00:00
< button ng-click = "hiddenConfigs = {}; updateResults()" >
all
< / button >
< button ng-click = "hiddenConfigs = {}; toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()" >
none
< / button >
< button ng-click = "toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()" >
toggle
< / button >
2013-10-02 18:57:48 +00:00
< / td >
< td > < table >
< tr > < td >
2014-02-06 15:17:28 +00:00
Image width
2013-10-02 18:57:48 +00:00
< input type = "text" ng-model = "imageSizePending"
ng-init="imageSizePending=100"
ng-change="areUpdatesPending = true"
maxlength="4"/>
< / td > < / tr >
< tr > < td >
Max records to display
< input type = "text" ng-model = "displayLimitPending"
ng-init="displayLimitPending=50"
ng-change="areUpdatesPending = true"
maxlength="4"/>
< / td > < / tr >
< tr > < td >
2013-10-24 15:38:27 +00:00
< button class = "update-results-button"
2013-10-02 18:57:48 +00:00
ng-click="updateResults()"
ng-disabled="!areUpdatesPending">
Update Results
< / button >
< / td > < / tr >
< / tr > < / table > < / td >
< / tr >
< / table >
2013-09-27 15:02:44 +00:00
2013-10-23 15:07:26 +00:00
< p >
2013-10-24 15:38:27 +00:00
<!-- Submission UI that we only show in the Pending Approval tab. -->
2013-10-23 15:07:26 +00:00
< div ng-hide = "'Pending Approval' != viewingTab" >
< div style = "display:inline-block" >
< button style = "font-size:20px"
ng-click="submitApprovals(filteredTestData)"
ng-disabled="submitPending || (filteredTestData.length == 0)">
Update these {{filteredTestData.length}} expectations on the server
< / button >
< / div >
< div style = "display:inline-block" >
< div style = "font-size:20px"
ng-hide="!submitPending">
Submitting, please wait...
2013-10-18 18:36:25 +00:00
< / div >
2013-10-23 15:07:26 +00:00
< / div >
2013-10-26 14:31:11 +00:00
< div >
Advanced settings...
< input type = "checkbox" ng-model = "showSubmitAdvancedSettings" >
show
< ul ng-hide = "!showSubmitAdvancedSettings" >
2013-11-05 21:00:24 +00:00
< li ng-repeat = "setting in ['reviewed-by-human', 'ignore-failure']" >
2013-10-26 14:31:11 +00:00
{{setting}}
< input type = "checkbox" ng-model = "submitAdvancedSettings[setting]" >
< / li >
< li ng-repeat = "setting in ['bug']" >
{{setting}}
< input type = "text" ng-model = "submitAdvancedSettings[setting]" >
< / li >
< / ul >
< / div >
2013-10-23 15:07:26 +00:00
< / div >
2013-10-02 18:57:48 +00:00
< p >
2013-10-23 15:07:26 +00:00
2013-11-01 14:29:03 +00:00
< table border = "0" > < tr > < td > <!-- table holding results header + results table -->
< table border = "0" width = "100%" > <!-- results header -->
< tr >
< td >
Found {{filteredTestData.length}} matches;
< span ng-hide = "filteredTestData.length <= limitedTestData.length" >
displaying the first {{limitedTestData.length}}
< / span >
< span ng-hide = "filteredTestData.length > limitedTestData.length" >
displaying them all
< / span >
< br >
(click on the column header radio buttons to re-sort by that column)
< / td >
< td align = "right" >
< div >
all tests shown:
< button ng-click = "selectAllItems()" >
select
< / button >
< button ng-click = "clearAllItems()" >
clear
< / button >
< button ng-click = "toggleAllItems()" >
toggle
< / button >
< / div >
< div ng-repeat = "otherTab in tabs" >
< button ng-click = "moveSelectedItemsToTab(otherTab)"
ng-disabled="selectedItems.length == 0"
ng-hide="otherTab == viewingTab">
move {{selectedItems.length}} selected tests to {{otherTab}} tab
< / button >
< / div >
< / td >
< / tr >
< / table > <!-- results header -->
< / td > < / tr > < tr > < td >
2014-02-04 22:45:40 +00:00
< table border = "1" ng-app = "diff_viewer" > <!-- results -->
2013-09-27 15:02:44 +00:00
< tr >
2013-10-24 15:38:27 +00:00
<!-- Most column headers are displayed in a common fashion... -->
2013-10-02 18:57:48 +00:00
< th ng-repeat = "categoryName in ['resultType', 'builder', 'test', 'config']" >
< input type = "radio"
name="sortColumnRadio"
value="{{categoryName}}"
ng-checked="(sortColumn == categoryName)"
ng-click="sortResultsBy(categoryName)">
{{categoryName}}
< / th >
2013-10-24 15:38:27 +00:00
<!-- ... but there are a few columns where we display things differently. -->
2013-10-26 14:31:11 +00:00
< th >
< input type = "radio"
name="sortColumnRadio"
value="bugs"
ng-checked="(sortColumn == 'bugs')"
ng-click="sortResultsBy('bugs')">
bugs
< / th >
2013-11-22 19:26:18 +00:00
< th width = "{{imageSize}}" >
2013-10-02 18:57:48 +00:00
< input type = "radio"
name="sortColumnRadio"
value="expectedHashDigest"
ng-checked="(sortColumn == 'expectedHashDigest')"
ng-click="sortResultsBy('expectedHashDigest')">
expected image
< / th >
2013-11-22 19:26:18 +00:00
< th width = "{{imageSize}}" >
2013-10-02 18:57:48 +00:00
< input type = "radio"
name="sortColumnRadio"
value="actualHashDigest"
ng-checked="(sortColumn == 'actualHashDigest')"
ng-click="sortResultsBy('actualHashDigest')">
actual image
< / th >
2013-11-22 19:26:18 +00:00
< th width = "{{imageSize}}" >
2013-11-08 16:25:25 +00:00
< input type = "radio"
name="sortColumnRadio"
value="percentDifferingPixels"
ng-checked="(sortColumn == 'percentDifferingPixels')"
ng-click="sortResultsBy('percentDifferingPixels')">
2013-11-22 19:26:18 +00:00
differing pixels in white
2013-11-08 16:25:25 +00:00
< / th >
2013-11-22 19:26:18 +00:00
< th width = "{{imageSize}}" >
2013-11-08 16:25:25 +00:00
< input type = "radio"
name="sortColumnRadio"
value="weightedDiffMeasure"
ng-checked="(sortColumn == 'weightedDiffMeasure')"
ng-click="sortResultsBy('weightedDiffMeasure')">
2014-02-11 18:21:26 +00:00
perceptual difference
2014-02-05 19:49:17 +00:00
< br >
< input type = "range" ng-model = "pixelDiffBgColorBrightness"
ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)"
ng-change="pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)"
title="image background brightness"
min="0" max="255"/>
2013-11-08 16:25:25 +00:00
< / th >
2013-10-23 15:07:26 +00:00
< th >
2013-10-09 18:05:58 +00:00
<!-- item - selection checkbox column -->
< / th >
2013-09-27 15:02:44 +00:00
< / tr >
2013-10-29 15:49:40 +00:00
2014-02-04 22:45:40 +00:00
< tr ng-repeat = "result in limitedTestData" ng-controller = "ImageController" >
2014-02-06 20:22:25 +00:00
< td >
2013-10-29 15:49:40 +00:00
{{result.resultType}}
2014-02-06 20:22:25 +00:00
< br >
< button class = "show-only-button"
ng-hide="viewingTab != defaultTab"
ng-click="showOnlyResultType(result.resultType)"
title="show only results of type '{{result.resultType}}'">
show only
< / button >
< br >
< button class = "show-all-button"
ng-hide="viewingTab != defaultTab"
ng-disabled="0 == setSize(hiddenResultTypes)"
ng-click="showAllResultTypes()"
title="show results of all types">
show all
< / button >
2013-10-29 15:49:40 +00:00
< / td >
2014-02-06 20:22:25 +00:00
< td ng-repeat = "categoryName in ['builder', 'test']" >
2013-10-26 14:31:11 +00:00
{{result[categoryName]}}
2014-02-06 20:22:25 +00:00
< br >
< button class = "show-only-button"
ng-hide="viewingTab != defaultTab"
ng-disabled="result[categoryName] == categoryValueMatch[categoryName]"
ng-click="setCategoryValueMatch(categoryName, result[categoryName])"
title="show only results of {{categoryName}} '{{result[categoryName]}}'">
show only
< / button >
< br >
< button class = "show-all-button"
ng-hide="viewingTab != defaultTab"
ng-disabled="'' == categoryValueMatch[categoryName]"
ng-click="setCategoryValueMatch(categoryName, '')"
title="show results of all {{categoryName}}s">
show all
< / button >
2013-10-26 14:31:11 +00:00
< / td >
2014-02-06 20:22:25 +00:00
< td >
2013-10-29 15:49:40 +00:00
{{result.config}}
2014-02-06 20:22:25 +00:00
< br >
< button class = "show-only-button"
ng-hide="viewingTab != defaultTab"
ng-click="showOnlyConfig(result.config)"
title="show only results of config '{{result.config}}'">
show only
< / button >
< br >
< button class = "show-all-button"
ng-hide="viewingTab != defaultTab"
ng-disabled="0 == setSize(hiddenConfigs)"
ng-click="showAllConfigs()"
title="show results of all configs">
show all
< / button >
2013-10-29 15:49:40 +00:00
< / td >
2013-10-26 14:31:11 +00:00
< td >
< a ng-repeat = "bug in result['bugs']"
href="https://code.google.com/p/skia/issues/detail?id={{bug}}"
target="_blank">
{{bug}}
< / a >
< / td >
2013-11-08 16:25:25 +00:00
<!-- expected image -->
2014-02-06 15:17:28 +00:00
< td valign = "bottom" width = "{{imageSize}}" >
2014-02-04 22:45:40 +00:00
< a href = "http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png" target = "_blank" > View Image< / a > < br / >
2014-02-06 15:17:28 +00:00
< img-compare type = "baseline" width = "{{imageSize}}"
2014-02-04 22:45:40 +00:00
src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png" />
2013-09-27 15:02:44 +00:00
< / td >
2013-11-08 16:25:25 +00:00
<!-- actual image -->
2014-02-06 15:17:28 +00:00
< td valign = "bottom" width = "{{imageSize}}" >
2014-02-04 22:45:40 +00:00
< a href = "http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png" target = "_blank" > View Image< / a > < br / >
2014-02-06 15:17:28 +00:00
< img-compare type = "test" width = "{{imageSize}}"
2014-02-04 22:45:40 +00:00
src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png" />
2013-09-27 15:02:44 +00:00
< / td >
2013-11-08 16:25:25 +00:00
<!-- whitediffs: every differing pixel shown in white -->
2014-02-06 15:17:28 +00:00
< td valign = "bottom" width = "{{imageSize}}" >
2013-11-22 19:26:18 +00:00
< div ng-hide = "result.expectedHashDigest == result.actualHashDigest"
title="{{result.numDifferingPixels | number:0}} of {{(100 * result.numDifferingPixels / result.percentDifferingPixels) | number:0}} pixels ({{result.percentDifferingPixels.toFixed(4)}}%) differ from expectation.">
2014-02-04 22:45:40 +00:00
2013-11-08 16:25:25 +00:00
{{result.percentDifferingPixels.toFixed(4)}}%
2013-11-22 19:26:18 +00:00
({{result.numDifferingPixels}})
2014-02-04 22:45:40 +00:00
< br / >
< a href = "/static/generated-images/whitediffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" target = "_blank" > View Image< / a > < br / >
2014-02-06 15:17:28 +00:00
< img-compare type = "differingPixelsInWhite" width = "{{imageSize}}"
2014-02-04 22:45:40 +00:00
src="/static/generated-images/whitediffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" />
2013-11-08 16:25:25 +00:00
< / div >
< div ng-hide = "result.expectedHashDigest != result.actualHashDigest"
style="text-align:center">
– none–
< / div >
< / td >
<!-- diffs: per - channel RGB deltas -->
2014-02-06 15:17:28 +00:00
< td valign = "bottom" width = "{{imageSize}}" >
2013-11-22 19:26:18 +00:00
< div ng-hide = "result.expectedHashDigest == result.actualHashDigest"
2014-02-11 18:21:26 +00:00
title="Perceptual difference measure is {{result.perceptualDifference.toFixed(4)}}%. Maximum difference per channel: R={{result.maxDiffPerChannel[0]}}, G={{result.maxDiffPerChannel[1]}}, B={{result.maxDiffPerChannel[2]}}">
2014-02-04 22:45:40 +00:00
2014-02-11 18:21:26 +00:00
{{result.perceptualDifference.toFixed(4)}}%
2013-11-22 19:26:18 +00:00
{{result.maxDiffPerChannel}}
2014-02-04 22:45:40 +00:00
< br / >
< a href = "/static/generated-images/diffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" target = "_blank" > View Image< / a > < br / >
2014-02-05 19:49:17 +00:00
< img-compare ng-style = "{backgroundColor: pixelDiffBgColor}"
2014-02-06 15:17:28 +00:00
type="differencePerPixel" width="{{imageSize}}"
2014-02-04 22:45:40 +00:00
src="/static/generated-images/diffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png"
ng-mousedown="MagnifyDraw($event, true)"
ng-mousemove="MagnifyDraw($event, false)"
ng-mouseup="MagnifyEnd($event)"
ng-mouseleave="MagnifyEnd($event)" />
2013-11-08 16:25:25 +00:00
< / div >
< div ng-hide = "result.expectedHashDigest != result.actualHashDigest"
style="text-align:center">
– none–
< / div >
< / td >
2013-10-23 15:07:26 +00:00
< td >
2013-10-09 18:05:58 +00:00
< input type = "checkbox"
name="rowSelect"
value="{{result.index}}"
2013-10-24 15:38:27 +00:00
ng-checked="isValueInArray(result.index, selectedItems)"
ng-click="toggleValueInArray(result.index, selectedItems)">
2013-09-27 15:02:44 +00:00
< / tr >
2013-11-01 14:29:03 +00:00
< / table > <!-- results -->
< / td > < / tr > < / table > <!-- table holding results header + results table -->
2013-10-24 15:38:27 +00:00
< / div > <!-- main display area of selected tab -->
2013-10-23 15:07:26 +00:00
< / div > <!-- everything: hide until data is loaded -->
2013-09-27 15:02:44 +00:00
<!-- TODO(epoger): Can we get the base URLs (commondatastorage and
issues list) from
2014-01-09 21:41:39 +00:00
https://skia.googlesource.com/buildbot/+/master/site_config/global_variables.json ?
I tried importing the
2013-09-27 15:02:44 +00:00
http://skia.googlecode.com/svn/buildbot/skia_tools.js script and using
that to do so, but I got Access-Control-Allow-Origin errors.
-->
< / body >
< / html >