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 |