| OLD | NEW |
| (Empty) |
| 1 {%- block doctype -%} | |
| 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
| 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
| 4 {% endblock %} | |
| 5 <!-- Copied and modified from: | |
| 6 http://src.chromium.org/viewvc/chrome/trunk/tools/build/third_party/buildbot_8_4
p1/buildbot/status/web/templates/layout.html?revision=89637&content-type=text/pl
ain | |
| 7 --> | |
| 8 <html xmlns="http://www.w3.org/1999/xhtml"> | |
| 9 <head> | |
| 10 {% block head %} | |
| 11 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
| 12 {% if metatags %} | |
| 13 {{ metatags }} | |
| 14 {% endif %} | |
| 15 <title>{{ pageTitle|e }}</title> | |
| 16 <link rel="stylesheet" href="{{ stylesheet }}" type="text/css" /> | |
| 17 <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_t
o_root }}rss"> | |
| 18 <script type="text/javascript"> | |
| 19 "use strict"; | |
| 20 | |
| 21 // Revision of the buildbot code on the build master. | |
| 22 var javascript_revision = "{{ master_revision }}"; | |
| 23 | |
| 24 // Ports used to access the buildbot webstatus pages. | |
| 25 var internalPort = "{{ internal_port }}"; | |
| 26 var externalPort = "{{ external_port }}"; | |
| 27 | |
| 28 // JSON data URL. | |
| 29 var tree_status_appspot_url = "{{ tree_status_baseurl }}"; | |
| 30 | |
| 31 // Per-builder status messages. | |
| 32 var builder_statuses = {}; | |
| 33 | |
| 34 // How often, in milliseconds, to refresh the page. | |
| 35 var refreshInterval = {{ refresh or default_refresh }} * 1000; | |
| 36 var refreshTimer = null; | |
| 37 | |
| 38 // Number of times a page reload has been cancelled due to activity on the p
age. | |
| 39 var cancelledReloads = 0; | |
| 40 | |
| 41 // Maximum number of cancelled reloads before forcing a reload. | |
| 42 var maxCancelledReloads = 10; | |
| 43 | |
| 44 // Variables passed in the URL. | |
| 45 var urlVars = {}; | |
| 46 | |
| 47 // Categories of builders, and whether each category should be displayed. | |
| 48 var allCategories = { | |
| 49 {% for r in all_categories %} | |
| 50 "{{ r }}": true, | |
| 51 {% endfor %} | |
| 52 }; | |
| 53 | |
| 54 // Subcategories of builders, and whether each category should be displayed. | |
| 55 var allSubcategories = { | |
| 56 {% for subcategory in all_subcategories %} | |
| 57 "{{ subcategory }}": true, | |
| 58 {% endfor %} | |
| 59 }; | |
| 60 | |
| 61 // Subcategories listed by which category they fall under. | |
| 62 var subcategoriesByCategory = { | |
| 63 {% for category in subcategories_by_category %} | |
| 64 "{{ category }}": [ | |
| 65 {% for subcategory in subcategories_by_category[category] %} | |
| 66 "{{ subcategory }}", | |
| 67 {% endfor %} | |
| 68 ], | |
| 69 {% endfor %} | |
| 70 } | |
| 71 | |
| 72 function addLinks(text) { | |
| 73 // Linkify arbitrary URLs. | |
| 74 var new_text = ""; | |
| 75 if (text && text.indexOf("<a href=") == -1) { | |
| 76 new_text = text.replace( | |
| 77 /(https?:\/\/.+?)(\s|\t|<|\n|\r|$)/g, '<a href="$1" target="_blank">
$1</a>$2'); | |
| 78 } | |
| 79 | |
| 80 // Linkify instances of "skia:123". | |
| 81 var re = new RegExp("skia:[0-9]+"); | |
| 82 var found_bugs = new_text.match(/skia:[0-9]+/g); | |
| 83 if (found_bugs) { | |
| 84 for (var i = 0; i < found_bugs.length; ++i) { | |
| 85 var found_bug = found_bugs[i]; | |
| 86 var bug_number = found_bug.split(":")[1]; | |
| 87 var bug_link = '<a href="https://code.google.com/p/skia/issues/detail?
id=' + bug_number + '" target="_blank">' + found_bug + '</a>'; | |
| 88 new_text = new_text.replace(found_bug, bug_link); | |
| 89 } | |
| 90 } | |
| 91 return new_text; | |
| 92 } | |
| 93 | |
| 94 // Switch to a new host/port. | |
| 95 function setHostAndPort(host, port) { | |
| 96 var current_host = window.location.host.split(":"); | |
| 97 if (!host) { | |
| 98 host = current_host[0]; | |
| 99 } | |
| 100 if (!port) { | |
| 101 port = current_host[1]; | |
| 102 } | |
| 103 window.location.host = host + ":" + port; | |
| 104 } | |
| 105 | |
| 106 // Parse the variables in the URL and return a key/value dictionary. | |
| 107 function parseArgs() | |
| 108 { | |
| 109 var args = {}; | |
| 110 var dict = window.location.search.slice(1).split('&'); | |
| 111 for(var i = 0; i < dict.length; i++) { | |
| 112 var split = dict[i].split('='); | |
| 113 var key = split[0]; | |
| 114 var value = split[1]; | |
| 115 if (args[key]) { | |
| 116 if (Object.prototype.toString.call(args[key]) == "[object Array]") { | |
| 117 args[key].push(value); | |
| 118 } else { | |
| 119 args[key] = [args[key], value]; | |
| 120 } | |
| 121 } else if (key != "") { | |
| 122 args[key] = value; | |
| 123 } | |
| 124 } | |
| 125 return args; | |
| 126 } | |
| 127 | |
| 128 // If the currently running revision of this page differs from that of the | |
| 129 // build master, reload the whole page instead of just the JSON data. | |
| 130 function doReload() { | |
| 131 // Get the master's code revision. | |
| 132 loadJSONP("/json/master_revision", | |
| 133 gotMasterRevision, | |
| 134 null); | |
| 135 } | |
| 136 | |
| 137 // Callback function for doReload. | |
| 138 function gotMasterRevision(data) { | |
| 139 if (data["master_checkedout_revision"] != javascript_revision) { | |
| 140 // Force a reload of the page if the master has a new revision. | |
| 141 location.reload(true); | |
| 142 } else { | |
| 143 loadAllData(); | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 // Reload the page, if the user isn't actively interacting with it. | |
| 148 function reloadPage() { | |
| 149 var reloadIsAllowed = true; | |
| 150 | |
| 151 // Don't allow reload if a build box is open. | |
| 152 var buildBox = document.getElementById("divBox"); | |
| 153 if (buildBox && buildBox.style.display != "none") { | |
| 154 console.log("divBox is displaying (" + buildBox.style.display + ")."); | |
| 155 reloadIsAllowed = false; | |
| 156 } | |
| 157 | |
| 158 if (reloadIsAllowed) { | |
| 159 doReload(); | |
| 160 } else if (cancelledReloads >= maxCancelledReloads) { | |
| 161 console.log("Forcing a reload because the number of " + | |
| 162 "previously-cancelled reloads exceeded " + | |
| 163 maxCancelledReloads + "."); | |
| 164 doReload(); | |
| 165 } else { | |
| 166 console.log("Not reloading page because the user is interacting with it.
"); | |
| 167 cancelledReloads++; | |
| 168 refreshTimer = setTimeout(reloadPage, refreshInterval); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 // Return the name of a non-anonymous function. | |
| 173 function getFunctionName(func) { | |
| 174 var name = func.toString(); | |
| 175 name = name.substr("function ".length); | |
| 176 name = name.substr(0, name.indexOf("(")); | |
| 177 return name; | |
| 178 } | |
| 179 | |
| 180 // Use JSONP to retrieve data from the given URL. There are a few possible | |
| 181 // outcomes: | |
| 182 // 1. The server returns valid JSONP. In this case, the provided callback | |
| 183 // will be called with the data as the parameter. | |
| 184 // 2. The server returns an error code (eg. if the requested URL isn't | |
| 185 // valid). In this case, the provided errback will be called. | |
| 186 // 3. The server returns a success code but the response does not contain | |
| 187 // valid JSONP. In this case, the callback cannot be called, since that | |
| 188 // call is part of the JSONP response. Additionally, the errback will | |
| 189 // not fire, since there is no way to dynamically insert a try/catch | |
| 190 // around the response content, and the script tag's onError handler | |
| 191 // only fires if the script could not be obtained from the server. | |
| 192 // | |
| 193 // Note: callback must NOT be an anonymous function. | |
| 194 // | |
| 195 function loadJSONP(url, callback, errback) { | |
| 196 var script = document.createElement("script"); | |
| 197 var src = appendParamToURL(url, "callback", getFunctionName(callback)); | |
| 198 script.setAttribute("src", src); | |
| 199 script.onError = errback | |
| 200 document.getElementsByTagName("head")[0].appendChild(script); | |
| 201 } | |
| 202 | |
| 203 // Use an XmlHttpRequest to retrieve data from the given URL. | |
| 204 function loadXML(url, callback) { | |
| 205 var req = new XMLHttpRequest(); | |
| 206 req.open("GET", url, true); | |
| 207 req.onreadystatechange = function() { | |
| 208 if (req.readyState == 4) { callback(req.responseText); } | |
| 209 }; | |
| 210 req.send(); | |
| 211 } | |
| 212 | |
| 213 // Set the tree status. | |
| 214 function setTreeStatus(data) { | |
| 215 var tree_status_div = document.getElementById("tree_status_div"); | |
| 216 if (tree_status_div) { | |
| 217 tree_status_div.className = "status-message " + data["general_state"]; | |
| 218 } | |
| 219 var tree_status_message = document.getElementById("tree_status_message"); | |
| 220 if (tree_status_message) { | |
| 221 tree_status_message.innerHTML = data["message"]; | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 // Set the current sheriff. | |
| 226 function setSheriff(data) { | |
| 227 var sheriff_div = document.getElementById("sheriff_div"); | |
| 228 if (sheriff_div) { | |
| 229 sheriff_div.innerHTML = "Sheriff: " + data["username"]; | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 // Set builder statuses. | |
| 234 function setBuilderStatuses(data) { | |
| 235 // Set the global builder status variable. | |
| 236 builder_statuses = data; | |
| 237 | |
| 238 // Mark builders who have comments. | |
| 239 for (var builder_name in data) { | |
| 240 // Builder column headers. | |
| 241 var comment_indicator = document.getElementById("commentIndicator_" + bu
ilder_name); | |
| 242 if (comment_indicator) { | |
| 243 comment_indicator.className += " BuilderHasComment"; | |
| 244 } | |
| 245 | |
| 246 // Summary boxes for all masters. | |
| 247 var summary_box = document.getElementById("summaryBox_" + builder_name); | |
| 248 if (summary_box) { | |
| 249 summary_box.className += " BuilderHasComment"; | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 // Optionally display the builder status message on the page. | |
| 254 var display_comment_elems = document.getElementsByClassName("DisplayBuilde
rComment"); | |
| 255 for (var i = 0; i < display_comment_elems.length; ++i) { | |
| 256 var display_comment = display_comment_elems[i]; | |
| 257 display_comment.innerHTML = ""; | |
| 258 var builder_name = display_comment.id.slice("displayBuilderComment_".len
gth); | |
| 259 buildComment(builder_name, display_comment); | |
| 260 if (builder_statuses[builder_name]) { | |
| 261 display_comment.className += " BuilderHasComment"; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 // Rebuild the console table, if applicable. | |
| 266 if (typeof buildConsoleTable == "function") { | |
| 267 buildConsoleTable(); | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 // Function to call on page load. Reloads the page with appropriate options | |
| 272 // if they are not already set. | |
| 273 function init() { | |
| 274 var host = window.location.host; | |
| 275 var checkedRadio; | |
| 276 if (host.indexOf(internalPort, host.length - internalPort.length) !== -1)
{ | |
| 277 checkedRadio = document.getElementById("radio_internal"); | |
| 278 } else if (host.indexOf(externalPort, host.length - externalPort.length) !
== -1) { | |
| 279 checkedRadio = document.getElementById("radio_external"); | |
| 280 } | |
| 281 if (checkedRadio) { | |
| 282 checkedRadio.checked = true; | |
| 283 } | |
| 284 | |
| 285 urlVars = parseArgs(); | |
| 286 if (urlVars["hideCategories"]) { | |
| 287 var categoryList = urlVars["hideCategories"].split(","); | |
| 288 for (var i = 0; i < categoryList.length; ++i) { | |
| 289 var name = categoryList[i]; | |
| 290 allCategories[name] = false; | |
| 291 var chkbox = document.getElementById("chkbox_category_" + name); | |
| 292 if (chkbox) { | |
| 293 chkbox.checked = false; | |
| 294 } | |
| 295 } | |
| 296 } | |
| 297 if (urlVars["hideSubcategories"]) { | |
| 298 var subcategoryList = urlVars["hideSubcategories"].split(","); | |
| 299 for (var i = 0; i < subcategoryList.length; ++i) { | |
| 300 var name = subcategoryList[i]; | |
| 301 allSubcategories[name] = false; | |
| 302 var chkbox = document.getElementById("chkbox_subcategory_" + name); | |
| 303 if (chkbox) { | |
| 304 chkbox.checked = false; | |
| 305 } | |
| 306 } | |
| 307 } | |
| 308 loadAllData(); | |
| 309 } | |
| 310 | |
| 311 // Display the most recent build for each builder on the given master. | |
| 312 function setLatestBuildsForMaster(master, master_builder_url, builders) { | |
| 313 var master_data_row = document.getElementById("results_summary_" + master)
; | |
| 314 if (!master_data_row) { | |
| 315 return; | |
| 316 } | |
| 317 // Clear any old results, up to the first cell which is the label. | |
| 318 while (master_data_row.cells.length > 1) { | |
| 319 master_data_row.deleteCell(-1); | |
| 320 } | |
| 321 // Add the new results. | |
| 322 for (var builder_index = 0; builder_index < builders.length; ++builder_ind
ex) { | |
| 323 var cell = master_data_row.insertCell(-1); | |
| 324 cell.className = "mini-box"; | |
| 325 cell.style.padding = "0px"; | |
| 326 cell.style.verticalAlign = "bottom"; | |
| 327 var builder_name = builders[builder_index].name; | |
| 328 cell.id = "summaryBox_" + builder_name | |
| 329 var outcome = builders[builder_index].outcome; | |
| 330 if (!outcome) { | |
| 331 outcome = "offline"; | |
| 332 } | |
| 333 var link = document.createElement("a"); | |
| 334 link.href = master_builder_url + builder_name; | |
| 335 link.title = builder_name; | |
| 336 link.target = "_blank"; | |
| 337 link.innerHTML = " "; | |
| 338 cell.style.width = "10px"; | |
| 339 link.style.width = "100%"; | |
| 340 link.style.height = "100%"; | |
| 341 link.className = outcome; | |
| 342 link.style.margin = "0px"; | |
| 343 link.style.padding = "0px"; | |
| 344 | |
| 345 // Decorate the result summary box if there's a comment for the builder. | |
| 346 if (builder_statuses[builder_name]) { | |
| 347 cell.className += " BuilderHasComment"; | |
| 348 } | |
| 349 | |
| 350 cell.appendChild(link); | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 // Callback functions for individual masters. | |
| 355 {% for master in masters %} | |
| 356 {% if not (not is_internal_view and master['name'] == 'PrivateSkia') %} | |
| 357 function setLatestBuildsFor{{ master['name'] }}(data) { | |
| 358 setLatestBuildsForMaster("{{ master['name'] }}", | |
| 359 "http://{{ master['host'] }}:{{ master['internal_
port'] if is_internal_view else master['external_port'] }}/waterfall?show=", | |
| 360 data['builders']); | |
| 361 } | |
| 362 {% endif %} | |
| 363 {% endfor %} | |
| 364 | |
| 365 // Callback function for AutoRoll bot status. | |
| 366 function gotARBStatus(data) { | |
| 367 var arb_status_div = document.getElementById("arb_status_div"); | |
| 368 if (arb_status_div) { | |
| 369 arb_status_div.innerHTML = "AutoRoll Status: " + addLinks(data); | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 // Load JSON data from various places. | |
| 374 function loadAllData() { | |
| 375 // Tree status. | |
| 376 loadJSONP(tree_status_appspot_url + "/banner-status?format=json", | |
| 377 setTreeStatus, | |
| 378 function() { | |
| 379 setTreeStatus({ | |
| 380 "general_state": "", | |
| 381 "message": "Failed to load tree status.", | |
| 382 }); | |
| 383 }); | |
| 384 | |
| 385 // Current sheriff. | |
| 386 loadJSONP(tree_status_appspot_url + "/current-sheriff", | |
| 387 setSheriff, | |
| 388 function() { setSheriff({"username": "unknown"}); }); | |
| 389 | |
| 390 // Builder statuses. | |
| 391 loadJSONP(tree_status_appspot_url + "/builder-status/get_builder_statuses"
, | |
| 392 setBuilderStatuses); | |
| 393 | |
| 394 // Last build result for each builder on each master. | |
| 395 var master_json_url = ""; | |
| 396 {% for master in masters %} | |
| 397 {% if not (not is_internal_view and master['name'] == 'PrivateSkia') %} | |
| 398 master_json_url = "http://{{ master['host'] }}:{{ master['internal_port']
if is_internal_view else master['external_port'] }}/json/builder_statuses"; | |
| 399 loadJSONP(master_json_url, setLatestBuildsFor{{ master['name'] }}); | |
| 400 {% endif %} | |
| 401 {% endfor %} | |
| 402 | |
| 403 // AutoRoll bot status. | |
| 404 loadXML("http://chromium-skia-gm.storage.googleapis.com/arb_status.html",
gotARBStatus); | |
| 405 | |
| 406 // Set the reload timer. | |
| 407 refreshTimer = setTimeout(reloadPage, refreshInterval); | |
| 408 | |
| 409 // Load the console data, if applicable. | |
| 410 if (typeof loadConsoleData == "function") { | |
| 411 loadConsoleData(); | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 // Get the comment text for a given builder. | |
| 416 function buildComment(builder_name, container) { | |
| 417 var file_bug_link = document.createElement("a"); | |
| 418 file_bug_link.href = "http://code.google.com/p/skia/issues/entry?labels=Br
eakingTheBuildbots,Type-Defect,Priority-Medium&summary=" + builder_name; | |
| 419 file_bug_link.target = "_blank"; | |
| 420 file_bug_link.appendChild(document.createTextNode("file bug")); | |
| 421 | |
| 422 var edit_status_url = tree_status_appspot_url + "/builder-status/?selected
_builder_name=" + builder_name; | |
| 423 var edit_status_link = document.createElement("a"); | |
| 424 edit_status_link.href = edit_status_url; | |
| 425 edit_status_link.target = "_blank"; | |
| 426 | |
| 427 var builder_para = document.createElement("p"); | |
| 428 builder_para.style.fontWeight = "bold"; | |
| 429 builder_para.style.lineHeight = "105%"; | |
| 430 builder_para.appendChild(document.createTextNode(builder_name)); | |
| 431 container.appendChild(builder_para); | |
| 432 | |
| 433 var comment_para = document.createElement("p"); | |
| 434 | |
| 435 var comment = null; | |
| 436 if (builder_statuses[builder_name]) { | |
| 437 comment = builder_statuses[builder_name]["message"]; | |
| 438 } | |
| 439 if (comment) { | |
| 440 comment_para.appendChild(document.createTextNode(comment)); | |
| 441 comment_para.innerHTML = addLinks(comment_para.innerHTML); | |
| 442 edit_status_link.appendChild(document.createTextNode("edit")); | |
| 443 } else { | |
| 444 edit_status_link.appendChild(document.createTextNode("add comment")); | |
| 445 } | |
| 446 container.appendChild(comment_para); | |
| 447 | |
| 448 var links_para = document.createElement("p"); | |
| 449 links_para.appendChild(document.createTextNode("(")); | |
| 450 links_para.appendChild(edit_status_link); | |
| 451 links_para.appendChild(document.createTextNode(" or ")); | |
| 452 links_para.appendChild(file_bug_link); | |
| 453 links_para.appendChild(document.createTextNode(")")); | |
| 454 container.appendChild(links_para); | |
| 455 } | |
| 456 | |
| 457 // Display a builder tooltip. | |
| 458 function showBuilderTooltip(builder_name, event) { | |
| 459 var tooltipbox = document.getElementById('builderTooltip'); | |
| 460 if (tooltipbox) { | |
| 461 var cursorPosTop = (window.event ? window.event.clientY : event.pageY) | |
| 462 var cursorPosLeft = (window.event ? window.event.clientX : event.pageX) | |
| 463 | |
| 464 cursorPosTop = cursorPosTop + document.body.scrollTop + 5; | |
| 465 cursorPosLeft = cursorPosLeft + document.body.scrollLeft; | |
| 466 | |
| 467 tooltipbox.innerHTML = ""; | |
| 468 buildComment(builder_name, tooltipbox); | |
| 469 tooltipbox.style.top = parseInt(cursorPosTop) + 'px'; | |
| 470 tooltipbox.style.left = parseInt(cursorPosLeft) + 'px'; | |
| 471 tooltipbox.style.display = "block"; | |
| 472 } | |
| 473 } | |
| 474 | |
| 475 // Hide the builder tooltip. | |
| 476 function hideBuilderTooltip(event) { | |
| 477 var tooltipbox = document.getElementById('builderTooltip'); | |
| 478 if (tooltipbox) { | |
| 479 // Only hide the tooltip if the mouse is outside the tooltip area. | |
| 480 var cursorPosTop = (window.event ? window.event.clientY : event.pageY) | |
| 481 var cursorPosLeft = (window.event ? window.event.clientX : event.pageX) | |
| 482 cursorPosTop = cursorPosTop + document.body.scrollTop; | |
| 483 cursorPosLeft = cursorPosLeft + document.body.scrollLeft; | |
| 484 | |
| 485 var top = parseInt(tooltipbox.style.top.replace("px", "")); | |
| 486 var left = parseInt(tooltipbox.style.left.replace("px", "")); | |
| 487 var bottom = top + parseInt(tooltipbox.offsetHeight); | |
| 488 var right = left + parseInt(tooltipbox.offsetWidth); | |
| 489 | |
| 490 if (cursorPosTop < top - 5 || cursorPosTop > bottom || | |
| 491 cursorPosLeft < left || cursorPosLeft > right) { | |
| 492 tooltipbox.style.display = "none"; | |
| 493 } | |
| 494 } | |
| 495 } | |
| 496 | |
| 497 // Helper function used by refreshCategories which loops through an array of | |
| 498 // elements and shows or hides them as indicated. | |
| 499 function showOrHideElements(elems, shouldDisplay) { | |
| 500 for (var i = 0; i < elems.length; ++i) { | |
| 501 elems[i].style.display = shouldDisplay ? "table-cell" : "none"; | |
| 502 } | |
| 503 } | |
| 504 | |
| 505 // Update the display based on the selected set of categories and | |
| 506 // subcategories. | |
| 507 function refreshCategories() { | |
| 508 for (var category in allCategories) { | |
| 509 // Show or hide each subcategory. | |
| 510 var colSpan = 0; | |
| 511 for (var i = 0; i < subcategoriesByCategory[category].length; ++i) { | |
| 512 var subcategory = subcategoriesByCategory[category][i]; | |
| 513 var className = "category_" + category + "_subcategory_" + subcategory
; | |
| 514 var elemsToChange = document.getElementsByClassName(className); | |
| 515 // Only display a subcategory if its category is also displaying. | |
| 516 var shouldDisplay = allCategories[category] && allSubcategories[subcat
egory] | |
| 517 showOrHideElements(elemsToChange, shouldDisplay); | |
| 518 if (shouldDisplay) { | |
| 519 colSpan++; | |
| 520 } | |
| 521 } | |
| 522 | |
| 523 // Show or hide the category label. | |
| 524 var elemsToChange = document.getElementsByClassName("category_" + catego
ry); | |
| 525 var shouldDisplay = allCategories[category] && colSpan > 0; | |
| 526 showOrHideElements(elemsToChange, shouldDisplay); | |
| 527 | |
| 528 // Fix the colSpan of the category header. | |
| 529 var header = document.getElementById("category_header_" + category); | |
| 530 if (header) { | |
| 531 header.colSpan = colSpan; | |
| 532 } | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 // Adds the key/value parameter pair to the given URL. | |
| 537 function appendParamToURL(url, key, value) { | |
| 538 if (url.indexOf("?") == "-1") { | |
| 539 url += "?"; | |
| 540 } else { | |
| 541 url += "&"; | |
| 542 } | |
| 543 url += key + "=" + value; | |
| 544 return url; | |
| 545 } | |
| 546 | |
| 547 // Build a URL using the previous URL parameters and the category and | |
| 548 // subcategory lists. | |
| 549 function buildURL() { | |
| 550 var newLocation = location.protocol + "//" + location.host + location.path
name; | |
| 551 var firstVar = true; | |
| 552 for (var urlVar in urlVars) { | |
| 553 if (urlVar != "hideCategories" && urlVar != "hideSubcategories") { | |
| 554 if (Object.prototype.toString.call(urlVars[urlVar]) == "[object Array]
") { | |
| 555 for (var i = 0; i < urlVars[urlVar].length; ++i) { | |
| 556 newLocation = appendParamToURL(newLocation, urlVar, urlVars[urlVar
][i]); | |
| 557 } | |
| 558 } else { | |
| 559 newLocation = appendParamToURL(newLocation, urlVar, urlVars[urlVar])
; | |
| 560 } | |
| 561 } | |
| 562 } | |
| 563 | |
| 564 // Add hidden categories to the URL. | |
| 565 var hiddenCategories = "" | |
| 566 for (var category in allCategories) { | |
| 567 if (!allCategories[category]) { | |
| 568 if (hiddenCategories == "") { | |
| 569 hiddenCategories = category; | |
| 570 } else { | |
| 571 hiddenCategories += "," + category; | |
| 572 } | |
| 573 } | |
| 574 } | |
| 575 if (hiddenCategories != "") { | |
| 576 newLocation = appendParamToURL(newLocation, "hideCategories", hiddenCate
gories); | |
| 577 } | |
| 578 | |
| 579 // Add hidden subcategories to the URL. | |
| 580 var hiddenSubcategories = "" | |
| 581 for (var subcategory in allSubcategories) { | |
| 582 if (!allSubcategories[subcategory]) { | |
| 583 if (hiddenSubcategories == "") { | |
| 584 hiddenSubcategories = subcategory; | |
| 585 } else { | |
| 586 hiddenSubcategories += "," + subcategory; | |
| 587 } | |
| 588 } | |
| 589 } | |
| 590 if (hiddenSubcategories != "") { | |
| 591 newLocation = appendParamToURL(newLocation, "hideSubcategories", hiddenS
ubcategories); | |
| 592 } | |
| 593 | |
| 594 return newLocation; | |
| 595 } | |
| 596 | |
| 597 // Callback function for when a category or subcategory checkbox is clicked. | |
| 598 function checkboxClicked(id) { | |
| 599 var chkbox = document.getElementById(id); | |
| 600 var toChange = id.substring("chkbox_".length).split("_"); | |
| 601 if (toChange[0] == "category") { | |
| 602 allCategories[toChange[1]] = chkbox.checked; | |
| 603 } else if (toChange[0] == "subcategory") { | |
| 604 allSubcategories[toChange[1]] = chkbox.checked; | |
| 605 } | |
| 606 window.history.replaceState("", "Checked box", buildURL()); | |
| 607 | |
| 608 // Rebuild the console table, if applicable, or fall back on attempting to | |
| 609 // hide the correct categories and subcategories. | |
| 610 if (typeof buildConsoleTable == "function") { | |
| 611 buildConsoleTable(); | |
| 612 } else { | |
| 613 refreshCategories(); | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 // Callback function to adjust the reload time. | |
| 618 function setReload(textBox) { | |
| 619 var regex = /^\d+$/; | |
| 620 if (regex.test(textBox.value)) { | |
| 621 refreshInterval = textBox.value * 1000; | |
| 622 urlVars["reload"] = textBox.value; | |
| 623 window.history.replaceState("", "Changed refresh", buildURL()); | |
| 624 clearTimeout(refreshTimer); | |
| 625 refreshTimer = setTimeout(reloadPage, refreshInterval); | |
| 626 } | |
| 627 } | |
| 628 </script> | |
| 629 {% endblock %} | |
| 630 </head> | |
| 631 <body class="interface"> | |
| 632 {% block header -%} | |
| 633 <div id="skia_header" style="top:5px;"> | |
| 634 <a href="{{ tree_status_baseurl }}" target="_blank" style="text-decoration
:inherit;"> | |
| 635 <div id="tree_status_div" width="100%" height="50" class="status-message
"> | |
| 636 <span id="tree_status_message"></span> | |
| 637 <div id="sheriff_div" class="sheriff-message"></div> | |
| 638 <div id="arb_status_div" class="arb-status"></div> | |
| 639 </div> | |
| 640 </a> | |
| 641 <div id="container" style="float: left; width: 100%;"> | |
| 642 <div style="float:left; width:25%;"> | |
| 643 <form name="unused" action="javascript:void(0);"> | |
| 644 <input type="radio" name="internal_external" value="external" id="radi
o_external" onClick="setHostAndPort(null, '{{ external_port }}');">External View
<br> | |
| 645 <input type="radio" name="internal_external" value="internal" id="radi
o_internal" onClick="setHostAndPort(null, '{{ internal_port }}');">Internal View | |
| 646 <br/><nobr>Refresh (seconds): <input type="text" name="reload_time" va
lue="{{ refresh or default_refresh }}" onChange="setReload(this)" style="width:
50px;" maxlength="4" /></nobr> | |
| 647 <div> | |
| 648 {% if master_launch_datetime %} | |
| 649 <br/> | |
| 650 master launched at {{ master_launch_datetime.strftime('%Y-%m-%d %H:%
M:%S UTC') }} | |
| 651 | |
| 652 <br/> | |
| 653 <span title="master_running_revision: git hash of code at which the
buildbot master was launched"> | |
| 654 <u>master_running_revision</u> | |
| 655 </span> is | |
| 656 <a href="https://skia.googlesource.com/buildbot.git/+/{{ master_runn
ing_revision }}"> | |
| 657 {{ master_running_revision|truncate(8, True, "") }} | |
| 658 </a> | |
| 659 | |
| 660 <br/> | |
| 661 <span title="master_revision: git hash of code currently checked out
on master"> | |
| 662 <u>master_revision</u> | |
| 663 </span> is | |
| 664 <a href="https://skia.googlesource.com/buildbot.git/+/{{ master_revi
sion }}"> | |
| 665 {{ master_revision|truncate(8, True, "") }} | |
| 666 </a> | |
| 667 {% endif %} | |
| 668 </div> | |
| 669 </form> | |
| 670 </div> | |
| 671 | |
| 672 <div id="links" style="float:right; width:25%;"> | |
| 673 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://sites.google.com/site/skiadocs/developer
-documentation/the-skia-buildbots/1-overview" target="_blank">Full Skia document
ation</a><br/></li></ul></div> | |
| 674 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="{{ tree_status_baseurl }}" target="_blank">Skia
Tree Status Manager</a><br/></li></ul></div> | |
| 675 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://code.google.com/p/skia/issues/list?can=2
&q=label%3ABreakingTheBuildbots" target="_blank">Current build-breaking bugs</a>
<br/></li></ul></div> | |
| 676 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="http://skiaperf.com" target="_blank">Perf Dashbo
ard</a><br/></li></ul></div> | |
| 677 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="bug_graphs.html" target="_blank">Open Bugs Graph
</a><br/></li></ul></div> | |
| 678 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://storage.cloud.google.com/chromium-skia-g
m/static_analyzers/clang_static_analyzer/index.html" target="_blank">Clang Stati
c Analyzer</a><br/></li></ul></div> | |
| 679 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="buildbots_self_analysis.html" target="_blank">Bu
ildbot Self-Dashboard</a><br/></li></ul></div> | |
| 680 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="buildslave_idle.html" target="_blank">Buildslave
Idle Time Analysis</a><br/></li></ul></div> | |
| 681 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://skia-tree-status.appspot.com/sheriff" ta
rget="_blank">Sheriff Schedule</a><br/></li></ul></div> | |
| 682 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://skia-tree-status.appspot.com/skia-teleme
try/lua_script" target="_blank">Run Lua Scripts on SKP Repo</a><br/></li></ul></
div> | |
| 683 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://skia-tree-status.appspot.com/skia-teleme
try/skia_try" target="_blank">Run Patches on SKP Repo</a><br/></li></ul></div> | |
| 684 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="http://skia-tree-status.appspot.com/redirect/reb
aseline-server/static/view.html#/view.html?resultsToLoad=/results/failures" targ
et="_blank">Recent GM Failures</a><br/></li></ul></div> | |
| 685 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="http://chromium-skia-gm.commondatastorage.google
apis.com/depsroll.html" target="_blank">Current DEPS roll attempt</a><br/></li><
/ul></div> | |
| 686 <div style="float:right; width: 195px;"><ul style="margin: 0px 0px 0px
25px; padding:0;"><li><a href="https://codereview.chromium.org/search?closed=3&
project=skia&private=1&commit=2&limit=30" target="_blank">Commit Queue</a><br/><
/li></ul></div> | |
| 687 </div> | |
| 688 | |
| 689 <div style="text-align:center; width: 50%; margin-left: 25%; margin-righ
t: 25%"> | |
| 690 <div id="heading" style="font-size:3.5em; text-align:center;">Skia Bui
ldbots ({{ active_master_name }})</div> | |
| 691 <div> | |
| 692 <p> | |
| 693 Skia Build Masters: | |
| 694 <table> | |
| 695 <tr id="results_summary_client_skia"> | |
| 696 <td style="text-align: right"><a href="http://build.chromium.org/p
/client.skia/console">client.skia</a></td> | |
| 697 <td colspan="1000"><iframe width="100%" height="20" frameborder="0
" scrolling="no" src="http://build.chromium.org/p/client.skia/horizontal_one_box
_per_builder"></iframe></td> | |
| 698 </tr> | |
| 699 {% for master in masters %} | |
| 700 {% if not (not is_internal_view and master['name'] == 'PrivateSkia')
%} | |
| 701 <tr id="results_summary_{{ master['name'] }}"> | |
| 702 <td style="text-align: right"><a href="http://{{ master['host']
}}:{{ master['internal_port'] if is_internal_view else master['external_port'] }
}/console">{{ master['name'] }}</a></td> | |
| 703 </tr> | |
| 704 {% endif %} | |
| 705 {% endfor %} | |
| 706 </table> | |
| 707 </div> | |
| 708 </p> | |
| 709 </div> | |
| 710 </div> | |
| 711 | |
| 712 <div class="header"> | |
| 713 <a href="{{ path_to_root or '.' }}">Home</a> - | |
| 714 <a href="{{ path_to_root }}waterfall">Waterfall</a> | |
| 715 <a href="{{ path_to_root }}console">Console</a> | |
| 716 <a href="{{ path_to_root }}builders">Builders</a> | |
| 717 <a href="{{ path_to_root }}buildslaves">Buildslaves</a> - | |
| 718 <a href="{{ path_to_root }}failures">Currently Failing</a> - | |
| 719 <a href="{{ path_to_root }}trybots">Trybot Waterfall</a> - | |
| 720 <a href="{{ path_to_root }}json/help">JSON API</a> - | |
| 721 <a href="{{ path_to_root }}about">About</a> | |
| 722 </div> | |
| 723 </div> | |
| 724 {% endblock %} | |
| 725 | |
| 726 {%- block barecontent -%} | |
| 727 | |
| 728 <div class="content"> | |
| 729 {%- block content -%} | |
| 730 {%- endblock -%} | |
| 731 </div> | |
| 732 {%- endblock -%} | |
| 733 | |
| 734 {%- block footer -%} | |
| 735 <div class="footer" style="clear:both"> | |
| 736 <hr/> | |
| 737 <a href="http://buildbot.net/">BuildBot</a> ({{version}}) | |
| 738 {% if title -%} | |
| 739 working for the | |
| 740 {%- if title_url -%} | |
| 741 <a href="{{ title_url }}">{{ title }}</a> | |
| 742 {%- else -%} | |
| 743 {{ title }} | |
| 744 {%- endif -%} | |
| 745 project. | |
| 746 {%- endif -%} | |
| 747 <br/> | |
| 748 Page built: <b>{{ time }}</b> ({{ tz }}) | |
| 749 </div> | |
| 750 {% endblock -%} | |
| 751 <div id="builderTooltip" class="BuilderTooltip RoundedRect" style="display:
none;" onmouseout="hideBuilderTooltip(event)"></div> | |
| 752 <script language="JavaScript"> | |
| 753 init(); | |
| 754 </script> | |
| 755 </body> | |
| 756 </html> | |
| OLD | NEW |