epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 1 | <!DOCTYPE html> |
| 2 | |
| 3 | <html ng-app="Loader" ng-controller="Loader.Controller"> |
| 4 | |
| 5 | <head> |
| 6 | <title ng-bind="windowTitle"></title> |
humper | 27ff227 | 2014-08-06 12:39:59 -0700 | [diff] [blame] | 7 | <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 8 | <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js"></script> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 9 | <script src="constants.js"></script> |
| 10 | <script src="live-loader.js"></script> |
humper | 27ff227 | 2014-08-06 12:39:59 -0700 | [diff] [blame] | 11 | <script src="utils.js"></script> |
| 12 | |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 13 | <link rel="stylesheet" href="view.css"> |
| 14 | </head> |
| 15 | |
| 16 | <body> |
| 17 | <h2> |
| 18 | Instructions, roadmap, etc. are at |
| 19 | <a href="http://tinyurl.com/SkiaRebaselineServer"> |
| 20 | http://tinyurl.com/SkiaRebaselineServer |
| 21 | </a> |
| 22 | </h2> |
| 23 | |
| 24 | <em ng-show="!readyToDisplay"> |
| 25 | Loading results of query: |
| 26 | <ul> |
epoger | e73cd5a | 2014-08-07 12:13:12 -0700 | [diff] [blame] | 27 | <li>setA: "{{setASection}}" within {{setADir}}</li> |
| 28 | <li>setB: "{{setBSection}}" within {{setBDir}}</li> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 29 | </ul> |
| 30 | <br> |
| 31 | {{loadingMessage}} |
| 32 | </em> |
| 33 | |
| 34 | <div ng-show="readyToDisplay"> |
| 35 | |
| 36 | <div class="warning-div" |
| 37 | ng-show="urlSchemaVersionLoaded != constants.URL_VALUE__SCHEMA_VERSION__CURRENT"> |
| 38 | WARNING! The URL you loaded used schema version {{urlSchemaVersionLoaded}}, rather than |
| 39 | the most recent version {{constants.URL_VALUE__SCHEMA_VERSION__CURRENT}}. It has been |
| 40 | converted to the most recent version on a best-effort basis; you may wish to double-check |
| 41 | which records are displayed. |
| 42 | </div> |
| 43 | |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 44 | <div ng-show="header[constants.KEY__HEADER__TIME_UPDATED]"> |
epoger | 5c4b137 | 2014-08-14 07:12:46 -0700 | [diff] [blame] | 45 | setA: "{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}" |
| 46 | within {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}} |
| 47 | <span ng-show="header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]">at <a href="https://skia.googlesource.com/skia/+/{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}">rev {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}</a></span> |
| 48 | <br> |
| 49 | setB: "{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}" |
| 50 | within {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}} |
| 51 | <span ng-show="header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]">at <a href="https://skia.googlesource.com/skia/+/{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}">rev {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}</a></span> |
| 52 | <br> |
epoger | 30e26cd | 2014-08-13 19:29:49 -0700 | [diff] [blame] | 53 | <a href="{{liveQueryUrl}}">latest raw JSON diffs between these two sets</a><br> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 54 | These results current as of |
| 55 | {{localTimeString(header[constants.KEY__HEADER__TIME_UPDATED])}} |
| 56 | </div> |
| 57 | |
| 58 | <div class="tab-wrapper"><!-- tabs --> |
| 59 | <div class="tab-spacer" ng-repeat="tab in tabs"> |
| 60 | <div class="tab tab-{{tab == viewingTab}}" |
| 61 | ng-click="setViewingTab(tab)"> |
| 62 | {{tab}} ({{numResultsPerTab[tab]}}) |
| 63 | </div> |
| 64 | <div class="tab-spacer"> |
| 65 | |
| 66 | </div> |
| 67 | </div> |
| 68 | </div><!-- tabs --> |
| 69 | |
| 70 | <div class="tab-main"><!-- main display area of selected tab --> |
| 71 | |
| 72 | <br> |
| 73 | <!-- We only show the filters/settings table on the Unfiled tab. --> |
| 74 | <table ng-show="viewingTab == defaultTab" border="1"> |
| 75 | <tr> |
| 76 | <th colspan="4"> |
| 77 | Filters |
| 78 | </th> |
| 79 | <th> |
| 80 | Settings |
| 81 | </th> |
| 82 | </tr> |
| 83 | <tr valign="top"> |
| 84 | |
| 85 | <!-- filters --> |
| 86 | <td ng-repeat="columnName in orderedColumnNames"> |
| 87 | |
| 88 | <!-- Only display filterable columns here... --> |
| 89 | <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]"> |
| 90 | {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}<br> |
| 91 | |
| 92 | <!-- If we filter this column using free-form text match... --> |
| 93 | <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]"> |
| 94 | <input type="text" |
| 95 | ng-model="columnStringMatch[columnName]" |
| 96 | ng-change="setUpdatesPending(true)"/> |
| 97 | <br> |
| 98 | <button ng-click="setColumnStringMatch(columnName, '')" |
| 99 | ng-disabled="('' == columnStringMatch[columnName])"> |
| 100 | clear (show all) |
| 101 | </button> |
| 102 | </div> |
| 103 | |
| 104 | <!-- If we filter this column using checkboxes... --> |
| 105 | <div ng-if="!extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]"> |
| 106 | <label ng-repeat="valueAndCount in extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]"> |
| 107 | <input type="checkbox" |
| 108 | name="resultTypes" |
| 109 | value="{{valueAndCount[0]}}" |
| 110 | ng-checked="isValueInSet(valueAndCount[0], showingColumnValues[columnName])" |
| 111 | ng-click="toggleValueInSet(valueAndCount[0], showingColumnValues[columnName]); setUpdatesPending(true)"> |
| 112 | {{valueAndCount[0]}} ({{valueAndCount[1]}})<br> |
| 113 | </label> |
| 114 | <button ng-click="showingColumnValues[columnName] = {}; toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()" |
| 115 | ng-disabled="!readyToDisplay || allColumnValues[columnName].length == setSize(showingColumnValues[columnName])"> |
| 116 | all |
| 117 | </button> |
| 118 | <button ng-click="showingColumnValues[columnName] = {}; updateResults()" |
| 119 | ng-disabled="!readyToDisplay || 0 == setSize(showingColumnValues[columnName])"> |
| 120 | none |
| 121 | </button> |
| 122 | <button ng-click="toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()"> |
| 123 | toggle |
| 124 | </button> |
| 125 | </div> |
| 126 | |
| 127 | </div> |
| 128 | </td> |
| 129 | |
| 130 | <!-- settings --> |
| 131 | <td><table> |
| 132 | <tr><td> |
| 133 | <input type="checkbox" ng-model="showThumbnailsPending" |
| 134 | ng-init="showThumbnailsPending = true" |
| 135 | ng-change="areUpdatesPending = true"/> |
| 136 | Show thumbnails |
| 137 | </td></tr> |
| 138 | <tr><td> |
| 139 | <input type="checkbox" ng-model="mergeIdenticalRowsPending" |
| 140 | ng-init="mergeIdenticalRowsPending = true" |
| 141 | ng-change="areUpdatesPending = true"/> |
| 142 | Merge identical rows |
| 143 | </td></tr> |
| 144 | <tr><td> |
| 145 | Image width |
| 146 | <input type="text" ng-model="imageSizePending" |
| 147 | ng-init="imageSizePending=100" |
| 148 | ng-change="areUpdatesPending = true" |
| 149 | maxlength="4"/> |
| 150 | </td></tr> |
| 151 | <tr><td> |
| 152 | Max records to display |
| 153 | <input type="text" ng-model="displayLimitPending" |
| 154 | ng-init="displayLimitPending=50" |
| 155 | ng-change="areUpdatesPending = true" |
| 156 | maxlength="4"/> |
| 157 | </td></tr> |
| 158 | <tr><td> |
| 159 | <button class="update-results-button" |
| 160 | ng-click="updateResults()" |
| 161 | ng-disabled="!areUpdatesPending"> |
| 162 | Update Results |
| 163 | </button> |
| 164 | </td></tr> |
| 165 | </tr></table></td> |
| 166 | </tr> |
| 167 | </table> |
| 168 | |
| 169 | <p> |
| 170 | |
| 171 | <!-- Submission UI that we only show in the Pending Approval tab. --> |
| 172 | <div ng-show="'Pending Approval' == viewingTab"> |
epoger | 9f1ae46 | 2014-08-14 09:55:36 -0700 | [diff] [blame] | 173 | <div style="font-size:20px"> |
| 174 | TODO(epoger): We don't yet support submitting new SKP expectations. |
| 175 | </div> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 176 | <div style="display:inline-block"> |
| 177 | <button style="font-size:20px" |
| 178 | ng-click="submitApprovals(filteredImagePairs)" |
epoger | 9f1ae46 | 2014-08-14 09:55:36 -0700 | [diff] [blame] | 179 | ng-disabled="true || submitPending || (filteredImagePairs.length == 0)"> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 180 | Update these {{filteredImagePairs.length}} expectations on the server |
| 181 | </button> |
| 182 | </div> |
| 183 | <div style="display:inline-block"> |
| 184 | <div style="font-size:20px" |
| 185 | ng-show="submitPending"> |
| 186 | Submitting, please wait... |
| 187 | </div> |
| 188 | </div> |
| 189 | <div> |
| 190 | Advanced settings... |
| 191 | <input type="checkbox" ng-model="showSubmitAdvancedSettings"> |
| 192 | show |
| 193 | <ul ng-show="showSubmitAdvancedSettings"> |
| 194 | <li ng-repeat="setting in [constants.KEY__EXPECTATIONS__REVIEWED, constants.KEY__EXPECTATIONS__IGNOREFAILURE]"> |
| 195 | {{setting}} |
| 196 | <input type="checkbox" ng-model="submitAdvancedSettings[setting]"> |
| 197 | </li> |
| 198 | <li ng-repeat="setting in ['bug']"> |
| 199 | {{setting}} |
| 200 | <input type="text" ng-model="submitAdvancedSettings[setting]"> |
| 201 | </li> |
| 202 | </ul> |
| 203 | </div> |
| 204 | </div> |
| 205 | |
| 206 | <p> |
| 207 | |
| 208 | <table border="0"><tr><td> <!-- table holding results header + results table --> |
| 209 | <table border="0" width="100%"> <!-- results header --> |
| 210 | <tr> |
| 211 | <td> |
| 212 | Found {{filteredImagePairs.length}} matches; |
| 213 | <span ng-show="filteredImagePairs.length > limitedImagePairs.length"> |
| 214 | displaying the first {{limitedImagePairs.length}}. |
| 215 | </span> |
| 216 | <span ng-show="filteredImagePairs.length <= limitedImagePairs.length"> |
| 217 | displaying them all. |
| 218 | </span> |
| 219 | <span ng-show="renderEndTime > renderStartTime"> |
| 220 | Rendered in {{(renderEndTime - renderStartTime).toFixed(0)}} ms. |
| 221 | </span> |
| 222 | <br> |
| 223 | (click on the column header radio buttons to re-sort by that column) |
| 224 | </td> |
| 225 | <td align="right"> |
| 226 | <div> |
| 227 | all tests shown: |
| 228 | <button ng-click="selectAllImagePairs()"> |
| 229 | select |
| 230 | </button> |
| 231 | <button ng-click="clearAllImagePairs()"> |
| 232 | clear |
| 233 | </button> |
| 234 | <button ng-click="toggleAllImagePairs()"> |
| 235 | toggle |
| 236 | </button> |
| 237 | </div> |
| 238 | <div ng-repeat="otherTab in tabs"> |
| 239 | <button ng-click="moveSelectedImagePairsToTab(otherTab)" |
| 240 | ng-disabled="selectedImagePairs.length == 0" |
| 241 | ng-show="otherTab != viewingTab"> |
| 242 | move {{selectedImagePairs.length}} selected tests to {{otherTab}} tab |
| 243 | </button> |
| 244 | </div> |
| 245 | </td> |
| 246 | </tr> |
| 247 | </table> <!-- results header --> |
| 248 | </td></tr><tr><td> |
| 249 | <table border="1" ng-app="diff_viewer"> <!-- results --> |
| 250 | <tr> |
| 251 | <!-- Most column headers are displayed in a common fashion... --> |
| 252 | <th ng-repeat="columnName in orderedColumnNames"> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 253 | <a ng-class="'sort-' + sortedByColumnsCls(columnName)" |
| 254 | ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)" |
| 255 | href="" |
| 256 | class="sortable-header"> |
| 257 | {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} |
| 258 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 259 | </th> |
| 260 | <!-- ... but there are a few columns where we display things differently. --> |
| 261 | <th> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 262 | <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__EXPECTATIONS__BUGS)" |
| 263 | ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)" |
| 264 | href="" |
| 265 | class="sortable-header"> |
| 266 | bugs |
| 267 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 268 | </th> |
| 269 | <th width="{{imageSize}}"> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 270 | <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" |
| 271 | ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" |
| 272 | href="" |
epoger | 5c4b137 | 2014-08-14 07:12:46 -0700 | [diff] [blame] | 273 | title="setA: '{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}' within {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}" |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 274 | class="sortable-header"> |
| 275 | {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} |
| 276 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 277 | </th> |
| 278 | <th width="{{imageSize}}"> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 279 | <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" |
| 280 | ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" |
| 281 | href="" |
epoger | 5c4b137 | 2014-08-14 07:12:46 -0700 | [diff] [blame] | 282 | title="setB: '{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}' within {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}" |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 283 | class="sortable-header"> |
| 284 | {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} |
| 285 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 286 | </th> |
| 287 | <th width="{{imageSize}}"> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 288 | <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" |
| 289 | ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" |
| 290 | href="" |
| 291 | class="sortable-header"> |
| 292 | differing pixels in white |
| 293 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 294 | </th> |
| 295 | <th width="{{imageSize}}"> |
stephana | d9bf7db | 2014-08-08 07:21:00 -0700 | [diff] [blame] | 296 | <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" |
| 297 | ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" |
| 298 | href="" |
| 299 | class="sortable-header"> |
| 300 | perceptual difference |
| 301 | </a> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 302 | <br> |
| 303 | <input type="range" ng-model="pixelDiffBgColorBrightness" |
| 304 | ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" |
| 305 | ng-change="pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" |
| 306 | title="image background brightness" |
| 307 | min="0" max="255"/> |
| 308 | </th> |
| 309 | <th> |
| 310 | <!-- imagepair-selection checkbox column --> |
| 311 | </th> |
| 312 | </tr> |
| 313 | |
| 314 | <tr ng-repeat="imagePair in limitedImagePairs" valign="top" |
| 315 | ng-class-odd="'results-odd'" ng-class-even="'results-even'" |
| 316 | results-updated-callback-directive> |
| 317 | |
| 318 | <td ng-repeat="columnName in orderedColumnNames"> |
| 319 | {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}} |
| 320 | <br> |
| 321 | <button class="show-only-button" |
| 322 | ng-show="viewingTab == defaultTab" |
| 323 | ng-disabled="1 == setSize(showingColumnValues[columnName])" |
| 324 | ng-click="showOnlyColumnValue(columnName, imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName])" |
| 325 | title="show only results of {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}}"> |
| 326 | show only |
| 327 | </button> |
| 328 | <br> |
| 329 | <button class="show-all-button" |
| 330 | ng-show="viewingTab == defaultTab" |
| 331 | ng-disabled="allColumnValues[columnName].length == setSize(showingColumnValues[columnName])" |
| 332 | ng-click="showAllColumnValues(columnName)" |
| 333 | title="show results of all {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}s"> |
| 334 | show all |
| 335 | </button> |
| 336 | </td> |
| 337 | |
| 338 | <!-- bugs --> |
| 339 | <td> |
| 340 | <a ng-repeat="bug in imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS][constants.KEY__EXPECTATIONS__BUGS]" |
| 341 | href="https://code.google.com/p/skia/issues/detail?id={{bug}}" |
| 342 | target="_blank"> |
| 343 | {{bug}} |
| 344 | </a> |
| 345 | </td> |
| 346 | |
| 347 | <!-- image A --> |
| 348 | <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}"> |
| 349 | <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] != null"> |
| 350 | <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" target="_blank">View Image</a><br/> |
| 351 | <img ng-if="showThumbnails" |
| 352 | width="{{imageSize}}" |
| 353 | ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" /> |
| 354 | </div> |
| 355 | <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] == null" |
| 356 | style="text-align:center"> |
| 357 | –none– |
| 358 | </div> |
| 359 | </td> |
| 360 | |
| 361 | <!-- image B --> |
| 362 | <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}"> |
| 363 | <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] != null"> |
| 364 | <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" target="_blank">View Image</a><br/> |
| 365 | <img ng-if="showThumbnails" |
| 366 | width="{{imageSize}}" |
| 367 | ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" /> |
| 368 | </div> |
| 369 | <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] == null" |
| 370 | style="text-align:center"> |
| 371 | –none– |
| 372 | </div> |
| 373 | </td> |
| 374 | |
| 375 | <!-- whitediffs: every differing pixel shown in white --> |
| 376 | <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}"> |
| 377 | <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]" |
| 378 | title="{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] | number:0}} of {{(100 * imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] / imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS]) | number:0}} pixels ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%) differ from expectation."> |
| 379 | |
stephana | a1aa5c2 | 2014-08-15 06:53:23 -0700 | [diff] [blame^] | 380 | <a href="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" target="_blank">View Image</a><br/> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 381 | <img ng-if="showThumbnails" |
| 382 | width="{{imageSize}}" |
stephana | a1aa5c2 | 2014-08-15 06:53:23 -0700 | [diff] [blame^] | 383 | ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" /> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 384 | <br/> |
| 385 | {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}% |
| 386 | ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS]}}) |
| 387 | </div> |
| 388 | <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]" |
| 389 | style="text-align:center"> |
| 390 | –none– |
| 391 | </div> |
| 392 | </td> |
| 393 | |
| 394 | <!-- diffs: per-channel RGB deltas --> |
| 395 | <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}"> |
| 396 | <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]" |
| 397 | title="Perceptual difference measure is {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%. Maximum difference per channel: R={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][0]}}, G={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][1]}}, B={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][2]}}"> |
| 398 | |
stephana | a1aa5c2 | 2014-08-15 06:53:23 -0700 | [diff] [blame^] | 399 | <a href="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" target="_blank">View Image</a><br/> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 400 | <img ng-if="showThumbnails" |
| 401 | ng-style="{backgroundColor: pixelDiffBgColor}" |
| 402 | width="{{imageSize}}" |
stephana | a1aa5c2 | 2014-08-15 06:53:23 -0700 | [diff] [blame^] | 403 | ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" /> |
epoger | 0b71276 | 2014-08-05 10:07:22 -0700 | [diff] [blame] | 404 | <br/> |
| 405 | {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}% |
| 406 | {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL]}} |
| 407 | </div> |
| 408 | <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]" |
| 409 | style="text-align:center"> |
| 410 | –none– |
| 411 | </div> |
| 412 | </td> |
| 413 | |
| 414 | <td ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}"> |
| 415 | <br/> |
| 416 | <input type="checkbox" |
| 417 | name="rowSelect" |
| 418 | value="{{imagePair.index}}" |
| 419 | ng-checked="isValueInArray(imagePair.index, selectedImagePairs)" |
| 420 | ng-click="toggleSomeImagePairs($index, imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN])"> |
| 421 | </tr> |
| 422 | </table> <!-- imagePairs --> |
| 423 | </td></tr></table> <!-- table holding results header + imagePairs table --> |
| 424 | |
| 425 | </div><!-- main display area of selected tab --> |
| 426 | </div><!-- everything: hide until readyToDisplay --> |
| 427 | |
| 428 | </body> |
| 429 | </html> |