view.html revision 589bd3da3403e305af802d412d14213f64478b2d
1<!DOCTYPE html> 2 3<html ng-app="Loader" ng-controller="Loader.Controller"> 4 5<head> 6 <title ng-bind="windowTitle"></title> 7 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script> 8 <script src="loader.js"></script> 9 <script src="diff_viewer.js"></script> 10 <link rel="stylesheet" href="view.css"> 11</head> 12 13<body> 14 <h2> 15 Instructions, roadmap, etc. are at 16 <a href="http://tinyurl.com/SkiaRebaselineServer"> 17 http://tinyurl.com/SkiaRebaselineServer 18 </a> 19 </h2> 20 21 <em> 22 {{loadingMessage}} 23 </em> 24 25 <div ng-hide="!categories"><!-- everything: hide until data is loaded --> 26 27 <div class="warning-div" 28 ng-hide="!(header.isEditable && header.isExported)"> 29 WARNING! These results are editable and exported, so any user 30 who can connect to this server over the network can modify them. 31 </div> 32 33 <div ng-hide="!(header.timeUpdated)"> 34 Results current as of {{localTimeString(header.timeUpdated)}} 35 </div> 36 37 <div><!-- tabs --> 38 <div class="tab-spacer" ng-repeat="tab in tabs"> 39 <div class="tab-{{tab == viewingTab}}" 40 ng-click="setViewingTab(tab)"> 41 {{tab}} ({{numResultsPerTab[tab]}}) 42 </div> 43 <div class="tab-spacer"> 44 45 </div> 46 </div> 47 </div><!-- tabs --> 48 49 <div class="tab-main"><!-- main display area of selected tab --> 50 51 <br> 52 <!-- We only show the filters/settings table on the Unfiled tab. --> 53 <table ng-hide="viewingTab != defaultTab" border="1"> 54 <tr> 55 <th colspan="4"> 56 Filters 57 </th> 58 <th> 59 Settings 60 </th> 61 </tr> 62 <tr valign="top"> 63 <!-- TODO(epoger): make this an ng-repeat over resultType, config, etc? --> 64 <td> 65 resultType<br> 66 <label ng-repeat="(resultType, count) in categories['resultType'] track by $index"> 67 <input type="checkbox" 68 name="resultTypes" 69 value="{{resultType}}" 70 ng-checked="!isValueInSet(resultType, hiddenResultTypes)" 71 ng-click="toggleValueInSet(resultType, hiddenResultTypes); setUpdatesPending(true)"> 72 {{resultType}} ({{count}})<br> 73 </label> 74 <button ng-click="hiddenResultTypes = {}; updateResults()"> 75 all 76 </button> 77 <button ng-click="hiddenResultTypes = {}; toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()"> 78 none 79 </button> 80 <button ng-click="toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()"> 81 toggle 82 </button> 83 </td> 84 <td ng-repeat="category in ['builder', 'test']"> 85 {{category}} 86 <br> 87 <input type="text" 88 ng-model="categoryValueMatch[category]" 89 ng-change="setUpdatesPending(true)"/> 90 <br> 91 <button ng-click="setCategoryValueMatch(category, '')" 92 ng-disabled="('' == categoryValueMatch[category])"> 93 clear (show all) 94 </button> 95 </td> 96 <td> 97 config<br> 98 <label ng-repeat="(config, count) in categories['config'] track by $index"> 99 <input type="checkbox" 100 name="configs" 101 value="{{config}}" 102 ng-checked="!isValueInSet(config, hiddenConfigs)" 103 ng-click="toggleValueInSet(config, hiddenConfigs); setUpdatesPending(true)"> 104 {{config}} ({{count}})<br> 105 </label> 106 <button ng-click="hiddenConfigs = {}; updateResults()"> 107 all 108 </button> 109 <button ng-click="hiddenConfigs = {}; toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()"> 110 none 111 </button> 112 <button ng-click="toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()"> 113 toggle 114 </button> 115 </td> 116 <td><table> 117 <tr><td> 118 Image width 119 <input type="text" ng-model="imageSizePending" 120 ng-init="imageSizePending=100" 121 ng-change="areUpdatesPending = true" 122 maxlength="4"/> 123 </td></tr> 124 <tr><td> 125 Max records to display 126 <input type="text" ng-model="displayLimitPending" 127 ng-init="displayLimitPending=50" 128 ng-change="areUpdatesPending = true" 129 maxlength="4"/> 130 </td></tr> 131 <tr><td> 132 <button class="update-results-button" 133 ng-click="updateResults()" 134 ng-disabled="!areUpdatesPending"> 135 Update Results 136 </button> 137 </td></tr> 138 </tr></table></td> 139 </tr> 140 </table> 141 142 <p> 143 144 <!-- Submission UI that we only show in the Pending Approval tab. --> 145 <div ng-hide="'Pending Approval' != viewingTab"> 146 <div style="display:inline-block"> 147 <button style="font-size:20px" 148 ng-click="submitApprovals(filteredTestData)" 149 ng-disabled="submitPending || (filteredTestData.length == 0)"> 150 Update these {{filteredTestData.length}} expectations on the server 151 </button> 152 </div> 153 <div style="display:inline-block"> 154 <div style="font-size:20px" 155 ng-hide="!submitPending"> 156 Submitting, please wait... 157 </div> 158 </div> 159 <div> 160 Advanced settings... 161 <input type="checkbox" ng-model="showSubmitAdvancedSettings"> 162 show 163 <ul ng-hide="!showSubmitAdvancedSettings"> 164 <li ng-repeat="setting in ['reviewed-by-human', 'ignore-failure']"> 165 {{setting}} 166 <input type="checkbox" ng-model="submitAdvancedSettings[setting]"> 167 </li> 168 <li ng-repeat="setting in ['bug']"> 169 {{setting}} 170 <input type="text" ng-model="submitAdvancedSettings[setting]"> 171 </li> 172 </ul> 173 </div> 174 </div> 175 176 <p> 177 178 <table border="0"><tr><td> <!-- table holding results header + results table --> 179 <table border="0" width="100%"> <!-- results header --> 180 <tr> 181 <td> 182 Found {{filteredTestData.length}} matches; 183 <span ng-hide="filteredTestData.length <= limitedTestData.length"> 184 displaying the first {{limitedTestData.length}} 185 </span> 186 <span ng-hide="filteredTestData.length > limitedTestData.length"> 187 displaying them all 188 </span> 189 <br> 190 (click on the column header radio buttons to re-sort by that column) 191 </td> 192 <td align="right"> 193 <div> 194 all tests shown: 195 <button ng-click="selectAllItems()"> 196 select 197 </button> 198 <button ng-click="clearAllItems()"> 199 clear 200 </button> 201 <button ng-click="toggleAllItems()"> 202 toggle 203 </button> 204 </div> 205 <div ng-repeat="otherTab in tabs"> 206 <button ng-click="moveSelectedItemsToTab(otherTab)" 207 ng-disabled="selectedItems.length == 0" 208 ng-hide="otherTab == viewingTab"> 209 move {{selectedItems.length}} selected tests to {{otherTab}} tab 210 </button> 211 </div> 212 </td> 213 </tr> 214 </table> <!-- results header --> 215 </td></tr><tr><td> 216 <table border="1" ng-app="diff_viewer"> <!-- results --> 217 <tr> 218 <!-- Most column headers are displayed in a common fashion... --> 219 <th ng-repeat="categoryName in ['resultType', 'builder', 'test', 'config']"> 220 <input type="radio" 221 name="sortColumnRadio" 222 value="{{categoryName}}" 223 ng-checked="(sortColumn == categoryName)" 224 ng-click="sortResultsBy(categoryName)"> 225 {{categoryName}} 226 </th> 227 <!-- ... but there are a few columns where we display things differently. --> 228 <th> 229 <input type="radio" 230 name="sortColumnRadio" 231 value="bugs" 232 ng-checked="(sortColumn == 'bugs')" 233 ng-click="sortResultsBy('bugs')"> 234 bugs 235 </th> 236 <th width="{{imageSize}}"> 237 <input type="radio" 238 name="sortColumnRadio" 239 value="expectedHashDigest" 240 ng-checked="(sortColumn == 'expectedHashDigest')" 241 ng-click="sortResultsBy('expectedHashDigest')"> 242 expected image 243 </th> 244 <th width="{{imageSize}}"> 245 <input type="radio" 246 name="sortColumnRadio" 247 value="actualHashDigest" 248 ng-checked="(sortColumn == 'actualHashDigest')" 249 ng-click="sortResultsBy('actualHashDigest')"> 250 actual image 251 </th> 252 <th width="{{imageSize}}"> 253 <input type="radio" 254 name="sortColumnRadio" 255 value="percentDifferingPixels" 256 ng-checked="(sortColumn == 'percentDifferingPixels')" 257 ng-click="sortResultsBy('percentDifferingPixels')"> 258 differing pixels in white 259 </th> 260 <th width="{{imageSize}}"> 261 <input type="radio" 262 name="sortColumnRadio" 263 value="weightedDiffMeasure" 264 ng-checked="(sortColumn == 'weightedDiffMeasure')" 265 ng-click="sortResultsBy('weightedDiffMeasure')"> 266 difference per pixel 267 <br> 268 <input type="range" ng-model="pixelDiffBgColorBrightness" 269 ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" 270 ng-change="pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" 271 title="image background brightness" 272 min="0" max="255"/> 273 </th> 274 <th> 275 <!-- item-selection checkbox column --> 276 </th> 277 </tr> 278 279 <tr ng-repeat="result in limitedTestData" ng-controller="ImageController"> 280 <td> 281 {{result.resultType}} 282 <br> 283 <button class="show-only-button" 284 ng-hide="viewingTab != defaultTab" 285 ng-click="showOnlyResultType(result.resultType)" 286 title="show only results of type '{{result.resultType}}'"> 287 show only 288 </button> 289 <br> 290 <button class="show-all-button" 291 ng-hide="viewingTab != defaultTab" 292 ng-disabled="0 == setSize(hiddenResultTypes)" 293 ng-click="showAllResultTypes()" 294 title="show results of all types"> 295 show all 296 </button> 297 </td> 298 <td ng-repeat="categoryName in ['builder', 'test']"> 299 {{result[categoryName]}} 300 <br> 301 <button class="show-only-button" 302 ng-hide="viewingTab != defaultTab" 303 ng-disabled="result[categoryName] == categoryValueMatch[categoryName]" 304 ng-click="setCategoryValueMatch(categoryName, result[categoryName])" 305 title="show only results of {{categoryName}} '{{result[categoryName]}}'"> 306 show only 307 </button> 308 <br> 309 <button class="show-all-button" 310 ng-hide="viewingTab != defaultTab" 311 ng-disabled="'' == categoryValueMatch[categoryName]" 312 ng-click="setCategoryValueMatch(categoryName, '')" 313 title="show results of all {{categoryName}}s"> 314 show all 315 </button> 316 </td> 317 <td> 318 {{result.config}} 319 <br> 320 <button class="show-only-button" 321 ng-hide="viewingTab != defaultTab" 322 ng-click="showOnlyConfig(result.config)" 323 title="show only results of config '{{result.config}}'"> 324 show only 325 </button> 326 <br> 327 <button class="show-all-button" 328 ng-hide="viewingTab != defaultTab" 329 ng-disabled="0 == setSize(hiddenConfigs)" 330 ng-click="showAllConfigs()" 331 title="show results of all configs"> 332 show all 333 </button> 334 </td> 335 <td> 336 <a ng-repeat="bug in result['bugs']" 337 href="https://code.google.com/p/skia/issues/detail?id={{bug}}" 338 target="_blank"> 339 {{bug}} 340 </a> 341 </td> 342 343 <!-- expected image --> 344 <td valign="bottom" width="{{imageSize}}"> 345 <a href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png" target="_blank">View Image</a><br/> 346 <img-compare type="baseline" width="{{imageSize}}" 347 src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png" /> 348 349 </td> 350 351 <!-- actual image --> 352 <td valign="bottom" width="{{imageSize}}"> 353 <a href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png" target="_blank">View Image</a><br/> 354 <img-compare type="test" width="{{imageSize}}" 355 src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png" /> 356 357 </td> 358 359 <!-- whitediffs: every differing pixel shown in white --> 360 <td valign="bottom" width="{{imageSize}}"> 361 <div ng-hide="result.expectedHashDigest == result.actualHashDigest" 362 title="{{result.numDifferingPixels | number:0}} of {{(100 * result.numDifferingPixels / result.percentDifferingPixels) | number:0}} pixels ({{result.percentDifferingPixels.toFixed(4)}}%) differ from expectation."> 363 364 {{result.percentDifferingPixels.toFixed(4)}}% 365 ({{result.numDifferingPixels}}) 366 <br/> 367 <a href="/static/generated-images/whitediffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" target="_blank">View Image</a><br/> 368 <img-compare type="differingPixelsInWhite" width="{{imageSize}}" 369 src="/static/generated-images/whitediffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" /> 370 371 </div> 372 <div ng-hide="result.expectedHashDigest != result.actualHashDigest" 373 style="text-align:center"> 374 –none– 375 </div> 376 </td> 377 378 <!-- diffs: per-channel RGB deltas --> 379 <td valign="bottom" width="{{imageSize}}"> 380 <div ng-hide="result.expectedHashDigest == result.actualHashDigest" 381 title="Weighted difference measure is {{result.weightedDiffMeasure.toFixed(4)}}%. Maximum difference per channel: R={{result.maxDiffPerChannel[0]}}, G={{result.maxDiffPerChannel[1]}}, B={{result.maxDiffPerChannel[2]}}"> 382 383 {{result.weightedDiffMeasure.toFixed(4)}}% 384 {{result.maxDiffPerChannel}} 385 <br/> 386 <a href="/static/generated-images/diffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" target="_blank">View Image</a><br/> 387 <img-compare ng-style="{backgroundColor: pixelDiffBgColor}" 388 type="differencePerPixel" width="{{imageSize}}" 389 src="/static/generated-images/diffs/{{result.expectedHashDigest}}-vs-{{result.actualHashDigest}}.png" 390 ng-mousedown="MagnifyDraw($event, true)" 391 ng-mousemove="MagnifyDraw($event, false)" 392 ng-mouseup="MagnifyEnd($event)" 393 ng-mouseleave="MagnifyEnd($event)" /> 394 395 </div> 396 <div ng-hide="result.expectedHashDigest != result.actualHashDigest" 397 style="text-align:center"> 398 –none– 399 </div> 400 </td> 401 402 <td> 403 <input type="checkbox" 404 name="rowSelect" 405 value="{{result.index}}" 406 ng-checked="isValueInArray(result.index, selectedItems)" 407 ng-click="toggleValueInArray(result.index, selectedItems)"> 408 </tr> 409 </table> <!-- results --> 410 </td></tr></table> <!-- table holding results header + results table --> 411 412 </div><!-- main display area of selected tab --> 413 </div><!-- everything: hide until data is loaded --> 414 415 <!-- TODO(epoger): Can we get the base URLs (commondatastorage and 416 issues list) from 417 https://skia.googlesource.com/buildbot/+/master/site_config/global_variables.json ? 418 I tried importing the 419 http://skia.googlecode.com/svn/buildbot/skia_tools.js script and using 420 that to do so, but I got Access-Control-Allow-Origin errors. 421 --> 422 423</body> 424</html> 425