Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: master/templates/console.html

Issue 648353002: Remove Skia's forked buildbot code (Closed) Base URL: https://skia.googlesource.com/buildbot.git@master
Patch Set: Address comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « master/templates/change_macros.html ('k') | master/templates/horizontal_one_box_per_build.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 {% extends "layout.html" %}
2
3 {% block head %}
4 {{ super() }}
5 <script type='text/javascript'>
6 // <![CDATA[
7 //
8
9 // Data loaded from the master's JSON interface.
10 var builders = {};
11 var revisions = [];
12
13 // Number of events to load from the master.
14 var console_limit = {{ default_console_limit }};
15 var default_console_limit = {{ default_console_limit }};
16 var max_console_limit = {{ max_console_limit }};
17
18 // Minimum number of revisions to display on the console.
19 var min_display_revisions = 25;
20
21 //
22 // Make the commit message display more or less.
23 //
24 function toggleMore(id, visible) {
25 if (visible) {
26 document.getElementById(id + "_long_desc").style.display = "inline";
27 document.getElementById(id + "_morelink").style.display = "none";
28 document.getElementById(id + "_lesslink").style.display = "inline";
29 } else {
30 document.getElementById(id + "_long_desc").style.display = "none";
31 document.getElementById(id + "_morelink").style.display = "inline";
32 document.getElementById(id + "_lesslink").style.display = "none";
33 }
34 }
35
36 //
37 // Functions used to display the build status bubble on box click.
38 //
39
40 // show the build status box. This is called when the user clicks on a block.
41 function showBuildBox(url, event) {
42 // Find the current curson position.
43 var cursorPosTop = (window.event ? window.event.clientY : event.pageY)
44 var cursorPosLeft = (window.event ? window.event.clientX : event.pageX)
45
46 // Offset the position by 5, to make the window appears under the cursor.
47 cursorPosTop = cursorPosTop + document.body.scrollTop -5 ;
48 cursorPosLeft = cursorPosLeft + document.body.scrollLeft - 5;
49
50 // Move the div (hidden) under the cursor.
51 var divBox = document.getElementById('divBox');
52 divBox.style.top = parseInt(cursorPosTop) + 'px';
53 divBox.style.left = parseInt(cursorPosLeft) + 'px';
54
55 // Reload the hidden frame with the build page we want to show.
56 // The onload even on this frame will update the div and make it visible.
57 document.getElementById("frameBox").src = url
58
59 // We don't want to reload the page.
60 return false;
61 }
62
63 // OnLoad handler for the iframe containing the build to show.
64 function updateDiv(event) {
65 // Get the frame innerHTML.
66 var iframeContent = document.getElementById("frameBox").contentWindow.docume nt.body.innerHTML;
67
68 // If there is any content, update the div, and make it visible.
69 if (iframeContent) {
70 var divBox = document.getElementById('divBox');
71 divBox.innerHTML = iframeContent ;
72 divBox.style.display = "block";
73 }
74 }
75
76 // Util functions to know if an element is contained inside another element.
77 // We use this to know when we mouse out our build status div.
78 function containsDOM (container, containee) {
79 var isParent = false;
80 do {
81 if ((isParent = container == containee))
82 break;
83 containee = containee.parentNode;
84 } while (containee != null);
85
86 return isParent;
87 }
88
89 // OnMouseOut handler. Returns true if the mouse moved out of the element.
90 // It is false if the mouse is still in the element, but in a blank part of it,
91 // like in an empty table cell.
92 function checkMouseLeave(element, event) {
93 if (element.contains && event.toElement) {
94 return !element.contains(event.toElement);
95 }
96 else if (event.relatedTarget) {
97 return !containsDOM(element, event.relatedTarget);
98 }
99 }
100
101 // Obtain the current date and time in a nicely formatted string.
102 function getDateString() {
103 var date = new Date();
104 return date.toDateString() + " at " + date.toTimeString();
105 }
106
107 // Set the "loading" message.
108 function setLoadingMessage(msg) {
109 var loading = document.getElementById("loading_div");
110 if (loading) {
111 loading.innerHTML = msg;
112 }
113 }
114
115 // Load the console page data.
116 function loadConsoleData() {
117 // Note: We don't include "&revs=" here because that would artificially limit
118 // the number of revisions we get back and therefore prevent us from being
119 // able to scale back console_limit when it no longer needs to be very big.
120 loadJSONP('/console_json?limit=' + console_limit, fixConsoleData);
121 setLoadingMessage("Loading...");
122 }
123
124 // Sort the categories, subcategories, and builders for display.
125 function fixConsoleData(data) {
126 if (data["revisions"].length < min_display_revisions &&
127 console_limit < max_console_limit) {
128 console_limit = Math.min(console_limit * 2, max_console_limit);
129 loadConsoleData();
130 return;
131 }
132 if (data["revisions"].length > min_display_revisions * 2) {
133 console_limit = Math.max(console_limit / 1.5, default_console_limit);
134 }
135 var new_builders = {};
136 var categories = Object.keys(data["builders"]);
137 categories.sort();
138 for (var category_index in categories) {
139 var category = categories[category_index];
140 new_builders[category] = {};
141 var subcategories = Object.keys(data["builders"][category]);
142 subcategories.sort()
143 for (var subcategory_index in subcategories) {
144 var subcategory = subcategories[subcategory_index];
145 new_builders[category][subcategory] = data["builders"][category][subcatego ry];
146 for (var cat_full in new_builders[category][subcategory]) {
147 new_builders[category][subcategory][cat_full].sort();
148 }
149 }
150 }
151 builders = new_builders;
152 revisions = data["revisions"];
153 setLoadingMessage("Last loaded at " + getDateString());
154 buildConsoleTable();
155 }
156
157 // Create a new row with two spacer cells.
158 function newRowWithSpacers(table) {
159 var row = table.insertRow(-1);
160 var spacer = row.insertCell(-1)
161 spacer.style.width = "1%";
162 var spacer = row.insertCell(-1)
163 spacer.style.width = "1%";
164 return row;
165 }
166
167 function newHyperlink(href, text, open_in_new_tab) {
168 var link = document.createElement("a");
169 link.href = href;
170 if (text) {
171 link.innerHTML = text;
172 }
173 if (open_in_new_tab == true) {
174 link.target = "_blank";
175 }
176 return link;
177 }
178
179 // Build the main console view table.
180 function buildConsoleTable() {
181 // The main console table.
182 var table = document.getElementById("console_table");
183
184 // Clear the table.
185 while (table.hasChildNodes()) {
186 table.removeChild(table.lastChild);
187 }
188
189 // Count the number of columns, starting with 2 for the spacer TDs, so that
190 // we can get the colspans right.
191 var total_cols = 2;
192
193 // Top row: Categories.
194 var top_row = newRowWithSpacers(table);
195
196 // Second row: Subcategories.
197 var second_row = newRowWithSpacers(table);
198
199 // Third row: Individual builder statuses.
200 var builder_row = newRowWithSpacers(table);
201
202 // Keep track of the first and last visible categories.
203 var first_category = null;
204 var last_category = null;
205
206 // This loop creates the content for the top three rows.
207 for (var category in builders) {
208 // Create the category headers with links to the waterfall for each.
209 var category_td = top_row.insertCell(-1);
210 category_td.id = "category_header_" + category;
211 var td_class = "DevStatus Alt category_" + category;
212 category_td.className = td_class;
213 var category_link = newHyperlink("/waterfall?");
214 var h3 = document.createElement("h3");
215 h3.innerHTML = category;
216 // Hyperlink to the waterfall page which displays all builders within this
217 // category. Each full category name is appended in the subsequent loops.
218 category_link.appendChild(h3);
219 category_td.appendChild(category_link);
220
221 if (!allCategories[category]) {
222 // Hide the column header for this category if the associated checkbox
223 // isn't checked.
224 category_td.style.display = "none";
225 } else {
226 // If the category is visible, mark it as a possible first or last visible
227 // category.
228 if (!first_category) {
229 first_category = category;
230 }
231 last_category = category;
232 }
233
234 // Keep track of the colspan (number of builders) for this category as we
235 // loop over the subcategories.
236 var category_colspan = 0;
237
238 // Loop over the subcategories.
239 for (var subcategory in builders[category]) {
240 // Create the subcategory headers with links to the waterfall for each.
241 var subcategory_td = second_row.insertCell(-1);
242 subcategory_td.className = "DevStatus category_" + category + "_subcategor y_" + subcategory;
243 subcategory_td.colSpan = builders[category][subcategory].length;
244 // Hyperlink to the waterfall page which displays all builders within this
245 // subcategory. Each full category name is appended in the subsequent
246 // loops.
247 var subcategory_link = newHyperlink("/waterfall?", subcategory)
248 subcategory_td.appendChild(subcategory_link);
249
250 // Hide the column header for this subcategory if the associated checkbox
251 // isn't checked.
252 if (!(allCategories[category] && allSubcategories[subcategory])) {
253 subcategory_td.style.display = "none";
254 }
255
256 // Loop over the full category names (eg. "Build|Ubuntu12|GateKeeper")
257 // within each subcategory.
258 for (var cat_full in builders[category][subcategory]) {
259 // Create a wrapper cell to hold the builder statuses for this category.
260 var builder_wrapper_td = builder_row.insertCell(-1);
261 builder_wrapper_td.className = "DevSlave Alt category_" + category + "_s ubcategory_" + subcategory;
262 // Create a sub-table within the builder wrapper cell.
263 var builder_wrapper_table = document.createElement("table");
264 builder_wrapper_table.width = "100%";
265 builder_wrapper_td.appendChild(builder_wrapper_table);
266 var builder_wrapper_table_tr = builder_wrapper_table.insertRow(-1);
267 // Hide the builder wrapper cell if the current category and subcategory
268 // aren't both displaying.
269 if (!(allCategories[category] && allSubcategories[subcategory])) {
270 builder_wrapper_td.style.display = "none";
271 }
272
273 // Append the full category name to the category and subcategory
274 // waterfall links.
275 if (category_link.href.indexOf("?", category_link.href.length - 1) == -1 ) {
276 category_link.href += "&";
277 }
278 category_link.href += "category=" + cat_full;
279 if (subcategory_link.href.indexOf("?", subcategory_link.href.length - 1) == -1) {
280 subcategory_link.href += "&";
281 }
282 subcategory_link.href += "category=" + cat_full;
283
284 // Loop over the builders within this fully-qualified category.
285 for (var builder_index in builders[category][subcategory][cat_full]) {
286 // Create a colored cell with a link to this builder's status page.
287 var builder = builders[category][subcategory][cat_full][builder_index] ;
288 var builder_name = builder.builderName;
289 var builder_td = builder_wrapper_table_tr.insertCell(-1);
290 builder_td.className = "DevSlaveBox";
291 builder_td.builder_name = builder_name;
292 builder_link = newHyperlink(builder.url, "", true);
293 builder_link.id = "commentIndicator_" + builder_name;
294 builder_link.className = "DevSlaveBox " + builder.color;
295 if (builder_statuses[builder_name]) {
296 builder_link.classList.add("BuilderHasComment");
297 }
298 builder_td.appendChild(builder_link);
299
300 // Create the status tooltip for this builder.
301 var tooltip_div = document.createElement("div");
302 tooltip_div.className = "BuilderTooltip RoundedRect";
303 buildComment(builder_name, tooltip_div);
304 builder_td.appendChild(tooltip_div);
305 }
306 // Only count the columns which are being displayed toward the total
307 // colspan.
308 if (allCategories[category] && allSubcategories[subcategory]) {
309 total_cols++;
310 }
311 }
312 // Only cound the subcategories which are being displayed toward the
313 // categories' colspans.
314 if (allCategories[category] && allSubcategories[subcategory]) {
315 category_colspan += subcategory_td.colSpan;
316 }
317 }
318 category_td.colSpan = category_colspan;
319 }
320
321 // Round the corners of the first and last visible category headers.
322 if (first_category) {
323 document.getElementById("category_header_" + first_category).classList.add(" first");
324 }
325 if (last_category) {
326 document.getElementById("category_header_" + last_category).classList.add("l ast")
327 }
328
329 // Build rows for each revision.
330 for (var rev_index in revisions) {
331 // Information about this revision.
332 var revision = revisions[rev_index];
333
334 // String which alternates between "" and " Alt"; used for creating
335 // alternating shades of gray.
336 var alt = "";
337 if (rev_index % 2) {
338 alt = " Alt";
339 }
340
341 // Row containing the commit hash, committer, and statuses for each builder
342 // at this revision.
343 var rev_status_tr = table.insertRow(-1);
344 // Cell containing the commit hash with a link to the commit in the
345 // repository.
346 var revision_td = rev_status_tr.insertCell(-1);
347 revision_td.className = "DevRev" + alt;
348 var revision_link = newHyperlink(revision.repository + "/+/" + revision.id,
349 revision.id.substring(0, 11),
350 true);
351 revision_td.appendChild(revision_link);
352 // Cell containing the committer's username.
353 var dev_name_td = rev_status_tr.insertCell(-1);
354 dev_name_td.className = "DevName" + alt;
355 dev_name_td.width = "1%";
356 dev_name_td.innerHTML = revision.who;
357
358 // Loop over the builders, obtaining the status and creating a build status
359 // popup link for each.
360 for (var category in builders) {
361 for (var subcategory in builders[category]) {
362 for (var cat_full in builders[category][subcategory]) {
363 // Wrapper cell containing statuses for builders in this fully-
364 // qualified category.
365 var build_status_td = rev_status_tr.insertCell(-1);
366 // Hide the build status cell if we're not displaying both the
367 // builder's category and subcategory.
368 if (!allCategories[category] || !allSubcategories[subcategory]) {
369 build_status_td.style.display = "none";
370 }
371 build_status_td.className = "DevStatus category_" + category + "_subca tegory_" + subcategory + alt;
372 // Table which will hold the individual builder statuses.
373 var build_status_wrapper = document.createElement("table");
374 build_status_wrapper.width = "100%";
375 build_status_td.appendChild(build_status_wrapper);
376 var builder_wrapper_tr = build_status_wrapper.insertRow(-1);
377 // Loop over the builders in this fully-qualified category.
378 for (var builder_index in builders[category][subcategory][cat_full]) {
379 var builder = builders[category][subcategory][cat_full][builder_inde x];
380 // Loop over the list of builds at this revision for this builder.
381 // This is almost always a single build.
382 for (var build_index in revision.builds[builder.builderName]) {
383 var build = revision.builds[builder.builderName][build_index];
384 // Create a colored cell representing the result of this build,
385 // with a link to open a popup with more detailed build step
386 // statuses.
387 var build_td = builder_wrapper_tr.insertCell(-1);
388 build_td.className = "DevStatusBox";
389 var build_link = newHyperlink("#", "", true);
390 build_link.popup_url = build.url;
391 build_link.onclick = function(event) { showBuildBox(this.popup_url , event); return false; };
392 build_link.title = build.pageTitle;
393 build_link.className = "DevStatusBox " + build.color + " " + build .tag;
394 build_td.appendChild(build_link);
395 }
396 }
397 }
398 }
399 }
400
401 // Row containing the change description for this revision.
402 var rev_comment_tr = table.insertRow(-1);
403 var rev_comment_td = rev_comment_tr.insertCell(-1);
404 rev_comment_td.className = "DevComment" + alt;
405 rev_comment_td.colSpan = total_cols;
406 // Split the comment text into: first line (short) and remainder (long).
407 var comment_short_text_span = document.createElement("span");
408 rev_comment_td.appendChild(comment_short_text_span);
409 var comment_long_text_span = document.createElement("span");
410 comment_long_text_span.id = revision.id + "_long_desc";
411 comment_long_text_span.style.display = "none";
412 // Create "more" and "less" links.
413 var more_link = document.createElement("a");
414 more_link.href = "javascript:toggleMore('" + revision.id + "', true)";
415 more_link.id = revision.id + "_morelink";
416 more_link.innerHTML = "more";
417 rev_comment_td.appendChild(more_link);
418 var less_link = document.createElement("a");
419 less_link.href = "javascript:toggleMore('" + revision.id + "', false)";
420 less_link.id = revision.id + "_lesslink";
421 less_link.style.display = "none";
422 less_link.innerHTML = "less";
423 rev_comment_td.appendChild(less_link);
424 rev_comment_td.appendChild(comment_long_text_span);
425 var comment_text_lines = revision.comments.split("\n");
426 // Only include the "more" link if the comment has more than one line.
427 if (comment_text_lines.length > 1) {
428 comment_short_text_span.innerHTML = comment_text_lines[0] + " ... ";
429 var comment_long_text_para = document.createElement("p");
430 comment_long_text_span.appendChild(comment_long_text_para);
431 for (var comment_line = 1; comment_line < comment_text_lines.length; ++com ment_line) {
432 comment_long_text_span.innerHTML += comment_text_lines[comment_line] + " <br/>";
433 }
434 comment_long_text_span.innerHTML = addLinks(comment_long_text_span.innerHT ML);
435 } else {
436 comment_short_text_span.innerHTML = revision.comments;
437 more_link.style.display = "none";
438 }
439
440 // Optional row containing more information about the revision, for example
441 // test failures.
442 if (revision["details"] && revision["details"].length > 0) {
443 var details_tr = table.insertRow(-1);
444 var details_td = details_tr.insertCell(-1);
445 details_td.colSpan = total_cols;
446 details_td.className = "DevDetails bottom" + alt;
447 var details_list = document.createElement("ul");
448 for (var detail_index in revision["details"]) {
449 var detail = revision["details"][detail_index];
450 var detail_item = document.createElement("li");
451 var detail_text = document.createElement("span");
452 detail_text.innerHTML = detail["buildername"] + ": " + detail["status"] + " - &nbsp;";
453 detail_item.appendChild(detail_text);
454 for (var log_index in detail["logs"]) {
455 var log = detail["logs"][log_index];
456 var log_link = document.createElement("a");
457 log_link.href = log["url"];
458 log_link.innerHTML = log["name"];
459 detail_item.appendChild(log_link);
460 }
461 details_list.appendChild(detail_item);
462 }
463 details_td.appendChild(details_list);
464 } else {
465 rev_comment_td.className += " bottom";
466 }
467
468 // Spacing row just containing whitespace.
469 var rev_spacing_tr = table.insertRow(-1);
470 rev_spacing_tr.className = "DevStatusSpacing";
471 var rev_spacing_td = rev_spacing_tr.insertCell(-1);
472 }
473 }
474
475 // ]]>
476 </script>
477 {% endblock %}
478
479 {% block content %}
480
481 <h1>Console View</h1>
482
483 <div id="loading_div"></div>
484
485 <div align="center">
486 <table width="95%" class="Grid" border="0" cellspacing="0">
487 <tr>
488 <td width="33%" align="left" class="left_align">
489 {% if repository %}
490 <br><b>Repository:</b> {{ repository|e }}
491 {% endif %}
492 </td>
493 <td width="33%" align="center" class="center_align">
494 <div align="center">
495 <table class="info">
496 <tr>
497 <td>Legend:&nbsp;&nbsp;</td>
498 <td class='legend success' title='All tests passed'>Passed</td>
499 <td class='legend failure' title='There is a new failure. Take a l ook!'>Failed</td>
500 <td class='legend warnings' title='It was failing before, and it i s still failing. Make sure you did not introduce new regressions'>Failed&nbsp;Ag ain</td>
501 <td class='legend running' title='The tests are still running'>Run ning</td>
502 <td class='legend running_failure' title='The tests are still runn ing, but at least one step has failed.'>Running&nbsp;w/&nbsp;failures</td>
503 <td class='legend exception' title='Something went wrong with the test, there is no result'>Exception</td>
504 <td class='legend offline' title='The builder is offline, as there are no slaves connected to it'>Offline</td>
505 <td class='legend notstarted' title='No result yet.'>No&nbsp;data< /td>
506 <td class='legend BuilderHasComment' title='This builder has a com ment.'>Builder comment</td>
507 </tr>
508 </table>
509 </div>
510 </td>
511 <td width="33%" align="right" class="right_align">
512 <script type="text/javascript">
513 // <![CDATA[
514 function reload_page() {
515 name_value = document.getElementById('namebox').value
516 if (document.location.href.lastIndexOf('?') == -1)
517 document.location.href = document.location.href+ '?name=' + name_v alue;
518 else
519 document.location.href = document.location.href+ '&name=' + name_v alue;
520 }
521 // ]]>
522 </script>
523 <input id='namebox' name='name' type='text' style='color:#999;'
524 onblur='this.value = this.value || this.defaultValue; this.style.col or = "#999";'
525 onfocus='this.value=""; this.style.color = "#000";'
526 value='Personalized for...'/>
527 <input type='submit' value='Go' onclick='reload_page()'/>
528 </td>
529 </tr>
530 </table>
531 </div>
532
533 <br/>
534 <div align="center">
535 <table id="console_table" width="96%"></table>
536 </div>
537
538
539 <div id="divBox" onmouseout="if (checkMouseLeave(this, event)) this.style.displa y = 'none'" class="BuildWaterfall" style="display: none;">
540 </div>
541
542
543 <iframe id="frameBox" style="display: none;"></iframe>
544
545 <script type="text/javascript">
546 // replace 'onload="updateDiv(event);" with this, as iframe doesn't have onload event in xhtml
547 window.onload = function() {
548 document.getElementById('frameBox').onload = function(event) {
549 updateDiv(event);
550 };
551 };
552 </script>
553
554 {% endblock %}
555
556
557 {% block footer %}
558
559 {{ super() }}
560 {# <p>Debug info: {{ debuginfo }}</p> #}
561 {% endblock %}
OLDNEW
« no previous file with comments | « master/templates/change_macros.html ('k') | master/templates/horizontal_one_box_per_build.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698