Index: masters/master.client.dart.fyi/templates/console.html |
=================================================================== |
--- masters/master.client.dart.fyi/templates/console.html (revision 0) |
+++ masters/master.client.dart.fyi/templates/console.html (revision 0) |
@@ -0,0 +1,473 @@ |
+{% extends "announce.html" %} |
+ |
+{% block head %} |
+{{ super() }} |
+<script type='text/javascript'> |
+// <![CDATA[ |
+// |
+ |
+// |
+// 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); |
+ } |
+} |
+ |
+// Creates a new cookie. |
+function createCookie(name, value, day) { |
+ var date = new Date(); |
+ date.setTime(date.getTime() + (day * 24 * 60 * 60 * 1000)); |
+ var expires = "; expires=" + date.toGMTString(); |
+ document.cookie = name + "=" + value+expires + "; path=/"; |
+} |
+ |
+// Returns the vaue of a cookie, or null if it does not exist. |
+function readCookie(name) { |
+ var begin = name + "="; |
+ var data = document.cookie.split(';'); |
+ for(var i = 0; i < data.length; i++) { |
+ var cookie = data[i]; |
+ while (cookie.charAt(0) == ' ') |
+ cookie = cookie.substring(1, cookie.length); |
+ if (cookie.indexOf(begin) == 0) |
+ return cookie.substring(begin.length, cookie.length); |
+ } |
+ |
+ return null; |
+} |
+ |
+// Deletes a cookie. |
+function eraseCookie(name) { |
+ createCookie(name, "", -1); |
+} |
+ |
+// Hides all "details" and "comments" section. |
+function collapse() { |
+ // Hide all Comments sections. |
+ var comments = document.querySelectorAll('.DevComment'); |
+ for(var i = 0; i < comments.length; i++) { |
+ comments[i].style.display = "none"; |
+ } |
+ |
+ // Hide all details sections. |
+ var details = document.querySelectorAll('.DevDetails'); |
+ for(var i = 0; i < details.length; i++) { |
+ details[i].style.display = "none"; |
+ } |
+ |
+ // Fix the rounding on the Revision box. (Lower right corner must be round) |
+ var revisions = document.querySelectorAll('.DevRev'); |
+ for(var i = 0; i < revisions.length; i++) { |
+ revisions[i].className = revisions[i].className + ' DevRevCollapse'; |
+ } |
+ |
+ // Fix the rounding on the last category box. (Lower left corner must be round) |
+ var status = document.querySelectorAll('.last'); |
+ for(var i = 0; i < status.length; i++) { |
+ status[i].className = status[i].className + ' DevStatusCollapse'; |
+ } |
+ |
+ // Create a cookie to remember that we want the view to be collapsed. |
+ createCookie('collapsed', 'true', 30) |
+ |
+ // Hide the collapse and the unmerge buttons. |
+ document.querySelectorAll('.collapse')[0].style.display = 'none' |
+ document.querySelectorAll('.unmerge')[0].style.display = 'none' |
+ |
+ // Activate the merge and expand buttons. |
+ document.querySelectorAll('.uncollapse')[0].style.display = 'inline' |
+ document.querySelectorAll('.merge')[0].style.display = 'inline' |
+} |
+ |
+// Expands the view. This is the opposite of "Collapse" |
+function uncollapse() { |
+ unmerge(); |
+ |
+ // Make the comments visible. |
+ var comments = document.querySelectorAll('.DevComment'); |
+ for(var i = 0; i < comments.length; i++) { |
+ comments[i].style.display = ""; |
+ } |
+ |
+ // Make the details visible. |
+ var details = document.querySelectorAll('.DevDetails'); |
+ for(var i = 0; i < details.length; i++) { |
+ details[i].style.display = ""; |
+ } |
+ |
+ // Remove the round corner (lower right) for the Revision box. |
+ var revisions = document.querySelectorAll('.DevRev'); |
+ for(var i = 0; i < revisions.length; i++) { |
+ revisions[i].className = revisions[i].className.replace('DevRevCollapse', ''); |
+ } |
+ |
+ // Remoe the round corner (lower left) for the last category box. |
+ var status = document.querySelectorAll('.DevStatus'); |
+ for(var i = 0; i < status.length; i++) { |
+ status[i].className = status[i].className.replace('DevStatusCollapse', ''); |
+ } |
+ |
+ // Delete the cookies that say that we want to be collapsed or merged. |
+ eraseCookie('collapsed') |
+ eraseCookie('merged') |
+ |
+ // Display the "collapse" and "merge" buttons. |
+ document.querySelectorAll('.collapse')[0].style.display = 'inline' |
+ document.querySelectorAll('.merge')[0].style.display = 'inline' |
+ |
+ // Remove the "uncollapse" and "unmerge" buttons. |
+ document.querySelectorAll('.uncollapse')[0].style.display = 'none' |
+ document.querySelectorAll('.unmerge')[0].style.display = 'none' |
+} |
+ |
+// Merge all the status boxes together. |
+function merge() { |
+ collapse(); |
+ |
+ // Hide all the spacing. |
+ var spacing = document.querySelectorAll('.DevStatusSpacing'); |
+ for(var i = 0; i < spacing.length; i++) { |
+ spacing[i].style.display = "none"; |
+ } |
+ |
+ // Each boxes have, in the className, a tag that uniquely represents the |
+ // build where this data comes from. |
+ // Since we want to merge all the boxes coming from the same build, we |
+ // parse the document to find all the builds, and then, for each build, we |
+ // concatenate the boxes. |
+ |
+ var allTags = []; |
+ all = document.getElementsByTagName('*') |
+ for(var i = 0; i < all.length; i++) { |
+ var element = all[i]; |
+ start = element.className.indexOf('Tag') |
+ if (start != -1) { |
+ var className = "" |
+ end = element.className.indexOf(' ', start) |
+ if (end != -1) { |
+ className = element.className.substring(start, end); |
+ } else { |
+ className = element.className.substring(start); |
+ } |
+ allTags[className] = 1; |
+ } |
+ } |
+ |
+ // Mergeall tags that we found |
+ for (i in allTags) { |
+ var current = document.querySelectorAll('.' + i); |
+ |
+ // We do the work only if there is more than 1 box with the same |
+ // build. |
+ if (current.length > 1) { |
+ // Add the noround class to all the boxes. |
+ for(var i = 0; i < current.length; i++) { |
+ current[i].className = current[i].className + ' noround'; |
+ } |
+ |
+ // Add the begin class to the first box. |
+ current[0].className = current[0].className + ' begin'; |
+ |
+ // Add the end class to the last box. |
+ last = current.length - 1; |
+ current[last].className = current[last].className + ' end'; |
+ } |
+ } |
+ |
+ // Display the "unmerge" button. |
+ document.querySelectorAll('.unmerge')[0].style.display = 'inline' |
+ document.querySelectorAll('.uncollapse')[0].style.display = 'inline' |
+ |
+ // Remove the "merge" button. |
+ document.querySelectorAll('.collapse')[0].style.display = 'none' |
+ document.querySelectorAll('.merge')[0].style.display = 'none' |
+ |
+ // Create a cookie to remember that we want to be merged. |
+ createCookie('merged', 'true', 30) |
+} |
+ |
+// Un-merge the view. This is the opposite of "merge". |
+function unmerge() { |
+ // We put back all the spacing. |
+ var spacing = document.querySelectorAll('.DevStatusSpacing'); |
+ for(var i = 0; i < spacing.length; i++) { |
+ spacing[i].style.display = ""; |
+ } |
+ |
+ // We remove the class added to all the boxes we modified. |
+ var noround = document.querySelectorAll('.noround'); |
+ for(var i = 0; i < noround.length; i++) { |
+ noround[i].className = noround[i].className.replace("begin", ''); |
+ noround[i].className = noround[i].className.replace("end", ''); |
+ noround[i].className = noround[i].className.replace("noround", ''); |
+ } |
+ |
+ // Delete the cookie, we don't want to be merged anymore. |
+ eraseCookie('merged') |
+ |
+ // Display the "merge" button. |
+ document.querySelectorAll('.merge')[0].style.display = 'inline' |
+ |
+ // Hide the "unmerge" button. |
+ document.querySelectorAll('.unmerge')[0].style.display = 'none' |
+} |
+ |
+function SetupView() { |
+ if (readCookie('merged')) { |
+ merge(); |
+ } else if (readCookie('collapsed')) { |
+ collapse(); |
+ } |
+} |
+ |
+document.addEventListener("DOMContentLoaded", SetupView, false); |
+ |
+// ]]> |
+</script> |
+{% endblock %} |
+ |
+{% block content %} |
+ |
+<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 %} |
+{% if branch != ANYBRANCH %} |
+ <br><b>Branch:</b> {{ branch|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 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> |
+ </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/> |
+ |
+{% set alt_class = cycler('', 'Alt') %} |
+ |
+<div align="center"> |
+<table width="96%"> |
+ |
+{% if categories|length > 1 %} |
+ <tr> |
+ <td width="1%"> |
+ </td> |
+ <td width="1%"> |
+ </td> |
+ {% for c in categories %} |
+ <td class='DevStatus Alt {{ "first" if loop.first else '' }} {{ "last" if loop.last else '' }}' width='{{ c.size }}%'> |
+ {{ c.name|numstrip }} |
+ </td> |
+ {% endfor %} |
+ </tr> |
+ <tr class='DevStatusSpacing'> |
+ </tr> |
+{% endif %} |
+ |
+{% if slaves %} |
+ <tr> |
+ <td width="1%"> |
+ </td> |
+ <td width="1%"> |
+ </td> |
+ {% for c in categories %} |
+ <td class='DevSlave Alt {{ "last" if loop.last else '' }}'> |
+ <table width="100%"> |
+ <tr> |
+ {% for s in slaves[c.name] %} |
+ <td class='DevSlaveBox'> |
+ <a href='{{ s.url }}' title='{{ s.pageTitle }}' class='DevSlaveBox {{ s.color }}' target="_blank"> |
+ </a> |
+ </td> |
+ {% endfor %} |
+ </tr> |
+ </table> |
+ </td> |
+ {% endfor %} |
+ </tr> |
+{% endif %} |
+ |
+{% for r in revisions %} |
+ {% set alt = alt_class.next() %} |
+ {% set last = "last" if loop.last else "" %} |
+ |
+ <tr> |
+ <td class='DevRev {{ alt }} DevRevCollapse' width="1%"> |
+ <a href="{{ r.link }}" target="_blank">{{ r.id|shortrev(r.repository) }}</a> |
+ </td> |
+ <td class='DevName {{ alt }}' width="1%"> |
+ {{ r.who|user }} |
+ </td> |
+ |
+ {% for c in categories %} |
+ <td class='DevStatus {{ alt }} {% if loop.last %}DevStatusCollapse{% endif %}'> |
+ <table width="100%"> |
+ <tr> |
+ {% for b in r.builds[c.name] %} |
+ <td class='DevStatusBox'> |
+ <a href='#' onclick='showBuildBox("{{ b.url }}", event); return false;' |
+ title='{{ b.pageTitle|e }}' class='DevStatusBox {{ b.color }} {{ b.tag }}' |
+ target="_blank"></a> |
+ </td> |
+ {% endfor %} |
+ </tr> |
+ </table> |
+ </td> |
+ {% endfor %} |
+ </tr> |
+ |
+ <tr> |
+ <td colspan="{{ r.span }}" class='DevComment {{ alt }}'> |
+ {{ r.comments|changecomment(r.project or None)|replace('\n', '<br/>')|replace(' ',' ') }} |
+ </td> |
+ </tr> |
+ |
+ {% if r.details %} |
+ <tr> |
+ <td colspan="{{ r.span }}" class='DevDetails {{ alt }}'> |
+ <ul style='margin: 0px; padding: 0 0 0 1.5em;'> |
+ {% for d in r.details %} |
+ <li>{{ d.buildername }}: {{ d.status }} - |
+ {%- for l in d.logs -%} |
+ <a href="{{ l.url }}"> {{ l.name }} </a>{% if not loop.last %} - {% endif %} |
+ {%- endfor -%} |
+ </li> |
+ {% endfor %} |
+ </ul> |
+ </td> |
+ </tr> |
+ {% endif %} |
+ |
+ <tr class='DevStatusSpacing'> |
+ <td> |
+ </td> |
+ </tr> |
+{% else %} |
+ <tr><td>No revisions available</td></tr> |
+{% endfor %} |
+ |
+</table> |
+</div> |
+ |
+ |
+<div id="divBox" onmouseout="if (checkMouseLeave(this, event)) this.style.display = 'None'" class="BuildWaterfall"> |
+</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 %} |
+<div class="footer" style="clear:both"> |
+ <hr/> |
+ [ <a class='collapse' href='#' OnClick='collapse(); return false;'>collapse</a> |
+ <a class='uncollapse' href='#' OnClick='uncollapse(); return false;'>un-collapse</a> |
+ <a class='merge' href="#" OnClick="merge(); return false;">merge</a> |
+ <a class='unmerge' style='display: none' href="#" OnClick="unmerge(); return false;">un-merge</a> ] |
+</div> |
+{% endblock %} |
Property changes on: masters/master.client.dart.fyi/templates/console.html |
___________________________________________________________________ |
Added: svn:mime-type |
+ text/html |
Added: svn:eol-style |
+ LF |