Index: master/templates/console.html |
diff --git a/master/templates/console.html b/master/templates/console.html |
deleted file mode 100644 |
index e3196db44f71f783413e6fb43e40bcd8dbe3e78c..0000000000000000000000000000000000000000 |
--- a/master/templates/console.html |
+++ /dev/null |
@@ -1,561 +0,0 @@ |
-{% extends "layout.html" %} |
- |
-{% block head %} |
-{{ super() }} |
-<script type='text/javascript'> |
-// <![CDATA[ |
-// |
- |
-// Data loaded from the master's JSON interface. |
-var builders = {}; |
-var revisions = []; |
- |
-// Number of events to load from the master. |
-var console_limit = {{ default_console_limit }}; |
-var default_console_limit = {{ default_console_limit }}; |
-var max_console_limit = {{ max_console_limit }}; |
- |
-// Minimum number of revisions to display on the console. |
-var min_display_revisions = 25; |
- |
-// |
-// Make the commit message display more or less. |
-// |
-function toggleMore(id, visible) { |
- if (visible) { |
- document.getElementById(id + "_long_desc").style.display = "inline"; |
- document.getElementById(id + "_morelink").style.display = "none"; |
- document.getElementById(id + "_lesslink").style.display = "inline"; |
- } else { |
- document.getElementById(id + "_long_desc").style.display = "none"; |
- document.getElementById(id + "_morelink").style.display = "inline"; |
- document.getElementById(id + "_lesslink").style.display = "none"; |
- } |
-} |
- |
-// |
-// Functions used to display the build status bubble on box click. |
-// |
- |
-// show the build status box. This is called when the user clicks on a block. |
-function showBuildBox(url, event) { |
- // Find the current curson position. |
- var cursorPosTop = (window.event ? window.event.clientY : event.pageY) |
- var cursorPosLeft = (window.event ? window.event.clientX : event.pageX) |
- |
- // Offset the position by 5, to make the window appears under the cursor. |
- cursorPosTop = cursorPosTop + document.body.scrollTop -5 ; |
- cursorPosLeft = cursorPosLeft + document.body.scrollLeft - 5; |
- |
- // Move the div (hidden) under the cursor. |
- var divBox = document.getElementById('divBox'); |
- divBox.style.top = parseInt(cursorPosTop) + 'px'; |
- divBox.style.left = parseInt(cursorPosLeft) + 'px'; |
- |
- // Reload the hidden frame with the build page we want to show. |
- // The onload even on this frame will update the div and make it visible. |
- document.getElementById("frameBox").src = url |
- |
- // We don't want to reload the page. |
- return false; |
-} |
- |
-// OnLoad handler for the iframe containing the build to show. |
-function updateDiv(event) { |
- // Get the frame innerHTML. |
- var iframeContent = document.getElementById("frameBox").contentWindow.document.body.innerHTML; |
- |
- // If there is any content, update the div, and make it visible. |
- if (iframeContent) { |
- var divBox = document.getElementById('divBox'); |
- divBox.innerHTML = iframeContent ; |
- divBox.style.display = "block"; |
- } |
-} |
- |
-// Util functions to know if an element is contained inside another element. |
-// We use this to know when we mouse out our build status div. |
-function containsDOM (container, containee) { |
- var isParent = false; |
- do { |
- if ((isParent = container == containee)) |
- break; |
- containee = containee.parentNode; |
- } while (containee != null); |
- |
- return isParent; |
-} |
- |
-// OnMouseOut handler. Returns true if the mouse moved out of the element. |
-// It is false if the mouse is still in the element, but in a blank part of it, |
-// like in an empty table cell. |
-function checkMouseLeave(element, event) { |
- if (element.contains && event.toElement) { |
- return !element.contains(event.toElement); |
- } |
- else if (event.relatedTarget) { |
- return !containsDOM(element, event.relatedTarget); |
- } |
-} |
- |
-// Obtain the current date and time in a nicely formatted string. |
-function getDateString() { |
- var date = new Date(); |
- return date.toDateString() + " at " + date.toTimeString(); |
-} |
- |
-// Set the "loading" message. |
-function setLoadingMessage(msg) { |
- var loading = document.getElementById("loading_div"); |
- if (loading) { |
- loading.innerHTML = msg; |
- } |
-} |
- |
-// Load the console page data. |
-function loadConsoleData() { |
- // Note: We don't include "&revs=" here because that would artificially limit |
- // the number of revisions we get back and therefore prevent us from being |
- // able to scale back console_limit when it no longer needs to be very big. |
- loadJSONP('/console_json?limit=' + console_limit, fixConsoleData); |
- setLoadingMessage("Loading..."); |
-} |
- |
-// Sort the categories, subcategories, and builders for display. |
-function fixConsoleData(data) { |
- if (data["revisions"].length < min_display_revisions && |
- console_limit < max_console_limit) { |
- console_limit = Math.min(console_limit * 2, max_console_limit); |
- loadConsoleData(); |
- return; |
- } |
- if (data["revisions"].length > min_display_revisions * 2) { |
- console_limit = Math.max(console_limit / 1.5, default_console_limit); |
- } |
- var new_builders = {}; |
- var categories = Object.keys(data["builders"]); |
- categories.sort(); |
- for (var category_index in categories) { |
- var category = categories[category_index]; |
- new_builders[category] = {}; |
- var subcategories = Object.keys(data["builders"][category]); |
- subcategories.sort() |
- for (var subcategory_index in subcategories) { |
- var subcategory = subcategories[subcategory_index]; |
- new_builders[category][subcategory] = data["builders"][category][subcategory]; |
- for (var cat_full in new_builders[category][subcategory]) { |
- new_builders[category][subcategory][cat_full].sort(); |
- } |
- } |
- } |
- builders = new_builders; |
- revisions = data["revisions"]; |
- setLoadingMessage("Last loaded at " + getDateString()); |
- buildConsoleTable(); |
-} |
- |
-// Create a new row with two spacer cells. |
-function newRowWithSpacers(table) { |
- var row = table.insertRow(-1); |
- var spacer = row.insertCell(-1) |
- spacer.style.width = "1%"; |
- var spacer = row.insertCell(-1) |
- spacer.style.width = "1%"; |
- return row; |
-} |
- |
-function newHyperlink(href, text, open_in_new_tab) { |
- var link = document.createElement("a"); |
- link.href = href; |
- if (text) { |
- link.innerHTML = text; |
- } |
- if (open_in_new_tab == true) { |
- link.target = "_blank"; |
- } |
- return link; |
-} |
- |
-// Build the main console view table. |
-function buildConsoleTable() { |
- // The main console table. |
- var table = document.getElementById("console_table"); |
- |
- // Clear the table. |
- while (table.hasChildNodes()) { |
- table.removeChild(table.lastChild); |
- } |
- |
- // Count the number of columns, starting with 2 for the spacer TDs, so that |
- // we can get the colspans right. |
- var total_cols = 2; |
- |
- // Top row: Categories. |
- var top_row = newRowWithSpacers(table); |
- |
- // Second row: Subcategories. |
- var second_row = newRowWithSpacers(table); |
- |
- // Third row: Individual builder statuses. |
- var builder_row = newRowWithSpacers(table); |
- |
- // Keep track of the first and last visible categories. |
- var first_category = null; |
- var last_category = null; |
- |
- // This loop creates the content for the top three rows. |
- for (var category in builders) { |
- // Create the category headers with links to the waterfall for each. |
- var category_td = top_row.insertCell(-1); |
- category_td.id = "category_header_" + category; |
- var td_class = "DevStatus Alt category_" + category; |
- category_td.className = td_class; |
- var category_link = newHyperlink("/waterfall?"); |
- var h3 = document.createElement("h3"); |
- h3.innerHTML = category; |
- // Hyperlink to the waterfall page which displays all builders within this |
- // category. Each full category name is appended in the subsequent loops. |
- category_link.appendChild(h3); |
- category_td.appendChild(category_link); |
- |
- if (!allCategories[category]) { |
- // Hide the column header for this category if the associated checkbox |
- // isn't checked. |
- category_td.style.display = "none"; |
- } else { |
- // If the category is visible, mark it as a possible first or last visible |
- // category. |
- if (!first_category) { |
- first_category = category; |
- } |
- last_category = category; |
- } |
- |
- // Keep track of the colspan (number of builders) for this category as we |
- // loop over the subcategories. |
- var category_colspan = 0; |
- |
- // Loop over the subcategories. |
- for (var subcategory in builders[category]) { |
- // Create the subcategory headers with links to the waterfall for each. |
- var subcategory_td = second_row.insertCell(-1); |
- subcategory_td.className = "DevStatus category_" + category + "_subcategory_" + subcategory; |
- subcategory_td.colSpan = builders[category][subcategory].length; |
- // Hyperlink to the waterfall page which displays all builders within this |
- // subcategory. Each full category name is appended in the subsequent |
- // loops. |
- var subcategory_link = newHyperlink("/waterfall?", subcategory) |
- subcategory_td.appendChild(subcategory_link); |
- |
- // Hide the column header for this subcategory if the associated checkbox |
- // isn't checked. |
- if (!(allCategories[category] && allSubcategories[subcategory])) { |
- subcategory_td.style.display = "none"; |
- } |
- |
- // Loop over the full category names (eg. "Build|Ubuntu12|GateKeeper") |
- // within each subcategory. |
- for (var cat_full in builders[category][subcategory]) { |
- // Create a wrapper cell to hold the builder statuses for this category. |
- var builder_wrapper_td = builder_row.insertCell(-1); |
- builder_wrapper_td.className = "DevSlave Alt category_" + category + "_subcategory_" + subcategory; |
- // Create a sub-table within the builder wrapper cell. |
- var builder_wrapper_table = document.createElement("table"); |
- builder_wrapper_table.width = "100%"; |
- builder_wrapper_td.appendChild(builder_wrapper_table); |
- var builder_wrapper_table_tr = builder_wrapper_table.insertRow(-1); |
- // Hide the builder wrapper cell if the current category and subcategory |
- // aren't both displaying. |
- if (!(allCategories[category] && allSubcategories[subcategory])) { |
- builder_wrapper_td.style.display = "none"; |
- } |
- |
- // Append the full category name to the category and subcategory |
- // waterfall links. |
- if (category_link.href.indexOf("?", category_link.href.length - 1) == -1) { |
- category_link.href += "&"; |
- } |
- category_link.href += "category=" + cat_full; |
- if (subcategory_link.href.indexOf("?", subcategory_link.href.length - 1) == -1) { |
- subcategory_link.href += "&"; |
- } |
- subcategory_link.href += "category=" + cat_full; |
- |
- // Loop over the builders within this fully-qualified category. |
- for (var builder_index in builders[category][subcategory][cat_full]) { |
- // Create a colored cell with a link to this builder's status page. |
- var builder = builders[category][subcategory][cat_full][builder_index]; |
- var builder_name = builder.builderName; |
- var builder_td = builder_wrapper_table_tr.insertCell(-1); |
- builder_td.className = "DevSlaveBox"; |
- builder_td.builder_name = builder_name; |
- builder_link = newHyperlink(builder.url, "", true); |
- builder_link.id = "commentIndicator_" + builder_name; |
- builder_link.className = "DevSlaveBox " + builder.color; |
- if (builder_statuses[builder_name]) { |
- builder_link.classList.add("BuilderHasComment"); |
- } |
- builder_td.appendChild(builder_link); |
- |
- // Create the status tooltip for this builder. |
- var tooltip_div = document.createElement("div"); |
- tooltip_div.className = "BuilderTooltip RoundedRect"; |
- buildComment(builder_name, tooltip_div); |
- builder_td.appendChild(tooltip_div); |
- } |
- // Only count the columns which are being displayed toward the total |
- // colspan. |
- if (allCategories[category] && allSubcategories[subcategory]) { |
- total_cols++; |
- } |
- } |
- // Only cound the subcategories which are being displayed toward the |
- // categories' colspans. |
- if (allCategories[category] && allSubcategories[subcategory]) { |
- category_colspan += subcategory_td.colSpan; |
- } |
- } |
- category_td.colSpan = category_colspan; |
- } |
- |
- // Round the corners of the first and last visible category headers. |
- if (first_category) { |
- document.getElementById("category_header_" + first_category).classList.add("first"); |
- } |
- if (last_category) { |
- document.getElementById("category_header_" + last_category).classList.add("last") |
- } |
- |
- // Build rows for each revision. |
- for (var rev_index in revisions) { |
- // Information about this revision. |
- var revision = revisions[rev_index]; |
- |
- // String which alternates between "" and " Alt"; used for creating |
- // alternating shades of gray. |
- var alt = ""; |
- if (rev_index % 2) { |
- alt = " Alt"; |
- } |
- |
- // Row containing the commit hash, committer, and statuses for each builder |
- // at this revision. |
- var rev_status_tr = table.insertRow(-1); |
- // Cell containing the commit hash with a link to the commit in the |
- // repository. |
- var revision_td = rev_status_tr.insertCell(-1); |
- revision_td.className = "DevRev" + alt; |
- var revision_link = newHyperlink(revision.repository + "/+/" + revision.id, |
- revision.id.substring(0, 11), |
- true); |
- revision_td.appendChild(revision_link); |
- // Cell containing the committer's username. |
- var dev_name_td = rev_status_tr.insertCell(-1); |
- dev_name_td.className = "DevName" + alt; |
- dev_name_td.width = "1%"; |
- dev_name_td.innerHTML = revision.who; |
- |
- // Loop over the builders, obtaining the status and creating a build status |
- // popup link for each. |
- for (var category in builders) { |
- for (var subcategory in builders[category]) { |
- for (var cat_full in builders[category][subcategory]) { |
- // Wrapper cell containing statuses for builders in this fully- |
- // qualified category. |
- var build_status_td = rev_status_tr.insertCell(-1); |
- // Hide the build status cell if we're not displaying both the |
- // builder's category and subcategory. |
- if (!allCategories[category] || !allSubcategories[subcategory]) { |
- build_status_td.style.display = "none"; |
- } |
- build_status_td.className = "DevStatus category_" + category + "_subcategory_" + subcategory + alt; |
- // Table which will hold the individual builder statuses. |
- var build_status_wrapper = document.createElement("table"); |
- build_status_wrapper.width = "100%"; |
- build_status_td.appendChild(build_status_wrapper); |
- var builder_wrapper_tr = build_status_wrapper.insertRow(-1); |
- // Loop over the builders in this fully-qualified category. |
- for (var builder_index in builders[category][subcategory][cat_full]) { |
- var builder = builders[category][subcategory][cat_full][builder_index]; |
- // Loop over the list of builds at this revision for this builder. |
- // This is almost always a single build. |
- for (var build_index in revision.builds[builder.builderName]) { |
- var build = revision.builds[builder.builderName][build_index]; |
- // Create a colored cell representing the result of this build, |
- // with a link to open a popup with more detailed build step |
- // statuses. |
- var build_td = builder_wrapper_tr.insertCell(-1); |
- build_td.className = "DevStatusBox"; |
- var build_link = newHyperlink("#", "", true); |
- build_link.popup_url = build.url; |
- build_link.onclick = function(event) { showBuildBox(this.popup_url, event); return false; }; |
- build_link.title = build.pageTitle; |
- build_link.className = "DevStatusBox " + build.color + " " + build.tag; |
- build_td.appendChild(build_link); |
- } |
- } |
- } |
- } |
- } |
- |
- // Row containing the change description for this revision. |
- var rev_comment_tr = table.insertRow(-1); |
- var rev_comment_td = rev_comment_tr.insertCell(-1); |
- rev_comment_td.className = "DevComment" + alt; |
- rev_comment_td.colSpan = total_cols; |
- // Split the comment text into: first line (short) and remainder (long). |
- var comment_short_text_span = document.createElement("span"); |
- rev_comment_td.appendChild(comment_short_text_span); |
- var comment_long_text_span = document.createElement("span"); |
- comment_long_text_span.id = revision.id + "_long_desc"; |
- comment_long_text_span.style.display = "none"; |
- // Create "more" and "less" links. |
- var more_link = document.createElement("a"); |
- more_link.href = "javascript:toggleMore('" + revision.id + "', true)"; |
- more_link.id = revision.id + "_morelink"; |
- more_link.innerHTML = "more"; |
- rev_comment_td.appendChild(more_link); |
- var less_link = document.createElement("a"); |
- less_link.href = "javascript:toggleMore('" + revision.id + "', false)"; |
- less_link.id = revision.id + "_lesslink"; |
- less_link.style.display = "none"; |
- less_link.innerHTML = "less"; |
- rev_comment_td.appendChild(less_link); |
- rev_comment_td.appendChild(comment_long_text_span); |
- var comment_text_lines = revision.comments.split("\n"); |
- // Only include the "more" link if the comment has more than one line. |
- if (comment_text_lines.length > 1) { |
- comment_short_text_span.innerHTML = comment_text_lines[0] + " ... "; |
- var comment_long_text_para = document.createElement("p"); |
- comment_long_text_span.appendChild(comment_long_text_para); |
- for (var comment_line = 1; comment_line < comment_text_lines.length; ++comment_line) { |
- comment_long_text_span.innerHTML += comment_text_lines[comment_line] + "<br/>"; |
- } |
- comment_long_text_span.innerHTML = addLinks(comment_long_text_span.innerHTML); |
- } else { |
- comment_short_text_span.innerHTML = revision.comments; |
- more_link.style.display = "none"; |
- } |
- |
- // Optional row containing more information about the revision, for example |
- // test failures. |
- if (revision["details"] && revision["details"].length > 0) { |
- var details_tr = table.insertRow(-1); |
- var details_td = details_tr.insertCell(-1); |
- details_td.colSpan = total_cols; |
- details_td.className = "DevDetails bottom" + alt; |
- var details_list = document.createElement("ul"); |
- for (var detail_index in revision["details"]) { |
- var detail = revision["details"][detail_index]; |
- var detail_item = document.createElement("li"); |
- var detail_text = document.createElement("span"); |
- detail_text.innerHTML = detail["buildername"] + ": " + detail["status"] + " - "; |
- detail_item.appendChild(detail_text); |
- for (var log_index in detail["logs"]) { |
- var log = detail["logs"][log_index]; |
- var log_link = document.createElement("a"); |
- log_link.href = log["url"]; |
- log_link.innerHTML = log["name"]; |
- detail_item.appendChild(log_link); |
- } |
- details_list.appendChild(detail_item); |
- } |
- details_td.appendChild(details_list); |
- } else { |
- rev_comment_td.className += " bottom"; |
- } |
- |
- // Spacing row just containing whitespace. |
- var rev_spacing_tr = table.insertRow(-1); |
- rev_spacing_tr.className = "DevStatusSpacing"; |
- var rev_spacing_td = rev_spacing_tr.insertCell(-1); |
- } |
-} |
- |
-// ]]> |
-</script> |
-{% endblock %} |
- |
-{% block content %} |
- |
-<h1>Console View</h1> |
- |
-<div id="loading_div"></div> |
- |
-<div align="center"> |
- <table width="95%" class="Grid" border="0" cellspacing="0"> |
- <tr> |
- <td width="33%" align="left" class="left_align"> |
-{% if repository %} |
- <br><b>Repository:</b> {{ repository|e }} |
-{% endif %} |
- </td> |
- <td width="33%" align="center" class="center_align"> |
- <div align="center"> |
- <table class="info"> |
- <tr> |
- <td>Legend: </td> |
- <td class='legend success' title='All tests passed'>Passed</td> |
- <td class='legend failure' title='There is a new failure. Take a look!'>Failed</td> |
- <td class='legend warnings' title='It was failing before, and it is still failing. Make sure you did not introduce new regressions'>Failed Again</td> |
- <td class='legend running' title='The tests are still running'>Running</td> |
- <td class='legend running_failure' title='The tests are still running, but at least one step has failed.'>Running w/ failures</td> |
- <td class='legend exception' title='Something went wrong with the test, there is no result'>Exception</td> |
- <td class='legend offline' title='The builder is offline, as there are no slaves connected to it'>Offline</td> |
- <td class='legend notstarted' title='No result yet.'>No data</td> |
- <td class='legend BuilderHasComment' title='This builder has a comment.'>Builder comment</td> |
- </tr> |
- </table> |
- </div> |
- </td> |
- <td width="33%" align="right" class="right_align"> |
- <script type="text/javascript"> |
-// <![CDATA[ |
- function reload_page() { |
- name_value = document.getElementById('namebox').value |
- if (document.location.href.lastIndexOf('?') == -1) |
- document.location.href = document.location.href+ '?name=' + name_value; |
- else |
- document.location.href = document.location.href+ '&name=' + name_value; |
- } |
-// ]]> |
- </script> |
- <input id='namebox' name='name' type='text' style='color:#999;' |
- onblur='this.value = this.value || this.defaultValue; this.style.color = "#999";' |
- onfocus='this.value=""; this.style.color = "#000";' |
- value='Personalized for...'/> |
- <input type='submit' value='Go' onclick='reload_page()'/> |
- </td> |
- </tr> |
- </table> |
-</div> |
- |
-<br/> |
-<div align="center"> |
-<table id="console_table" width="96%"></table> |
-</div> |
- |
- |
-<div id="divBox" onmouseout="if (checkMouseLeave(this, event)) this.style.display = 'none'" class="BuildWaterfall" style="display: none;"> |
-</div> |
- |
- |
-<iframe id="frameBox" style="display: none;"></iframe> |
- |
-<script type="text/javascript"> |
-// replace 'onload="updateDiv(event);" with this, as iframe doesn't have onload event in xhtml |
-window.onload = function() { |
- document.getElementById('frameBox').onload = function(event) { |
- updateDiv(event); |
- }; |
-}; |
-</script> |
- |
-{% endblock %} |
- |
- |
-{% block footer %} |
- |
-{{ super() }} |
-{# <p>Debug info: {{ debuginfo }}</p> #} |
-{% endblock %} |