OLD | NEW |
---|---|
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | 1 <!DOCTYPE html> |
agable
2013/04/15 19:33:30
Don't want to clobber the old base.html. Maybe put
Ryan Tseng
2013/04/17 22:53:48
Oops, I'll move it to viewer_base.html
| |
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | 2 <html lang="en"> |
3 <html xmlns="http://www.w3.org/1999/xhtml"> | 3 <head> |
4 <head> | 4 <meta charset="utf-8"> |
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | 5 <title>{% block title %}Build Log{% endblock %}</title> |
6 {% if reloadarg %} | 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
7 <meta http-equiv="refresh" content="{{ reloadarg }}" /> | 7 <meta name="description" content=""> |
8 {% endif %} | 8 <meta name="author" content=""> |
9 <title>{{ title }}</title> | |
10 <link rel="stylesheet" href="default.css" type="text/css" /> | |
11 | 9 |
12 <script type="text/javascript"> | 10 <!-- Le styles --> |
13 // <![CDATA[ | 11 <script src="http://code.jquery.com/jquery.js"></script> |
14 // | 12 <script src="/static/js/bootstrap.min.js"></script> |
13 <script src="/static/js/prettify.js"></script> | |
14 <style type="text/css"> | |
15 body { | |
16 padding-top: 60px; | |
17 padding-bottom: 40px; | |
18 } | |
19 .sidebar-nav { | |
20 padding: 9px 0; | |
21 } | |
15 | 22 |
16 // | 23 @media (max-width: 980px) { |
17 // Functions used to display the build status bubble on box click. | 24 /* Enable use of floated navbar text */ |
18 // | 25 .navbar-text.pull-right { |
19 | 26 float: none; |
20 // show the build status box. This is called when the user clicks on a block. | 27 padding-left: 5px; |
21 function showBuildBox(url, event) { | 28 padding-right: 5px; |
22 // Find the current curson position. | |
23 var cursorPosTop = (window.event ? window.event.clientY : event.pageY) | |
24 var cursorPosLeft = (window.event ? window.event.clientX : event.pageX) | |
25 | |
26 // Offset the position by 5, to make the window appears under the cursor. | |
27 cursorPosTop = cursorPosTop + document.body.scrollTop -5 ; | |
28 cursorPosLeft = cursorPosLeft + document.body.scrollLeft - 5; | |
29 | |
30 // Move the div (hidden) under the cursor. | |
31 var divBox = document.getElementById('divBox'); | |
32 divBox.style.top = parseInt(cursorPosTop) + 'px'; | |
33 divBox.style.left = parseInt(cursorPosLeft) + 'px'; | |
34 | |
35 // Reload the hidden frame with the build page we want to show. | |
36 // The onload even on this frame will update the div and make it visible. | |
37 document.getElementById("frameBox").src = url | |
38 | |
39 // We don't want to reload the page. | |
40 return false; | |
41 } | |
42 | |
43 // OnLoad handler for the iframe containing the build to show. | |
44 function updateDiv(event) { | |
45 // Get the frame innerHTML. | |
46 var iframeContent = document.getElementById("frameBox").contentWindow.docume nt.body.innerHTML; | |
47 | |
48 // If there is any content, update the div, and make it visible. | |
49 if (iframeContent) { | |
50 var divBox = document.getElementById('divBox'); | |
51 divBox.innerHTML = iframeContent ; | |
52 divBox.style.display = "block"; | |
53 } | |
54 } | |
55 | |
56 // Util functions to know if an element is contained inside another element. | |
57 // We use this to know when we mouse out our build status div. | |
58 function containsDOM (container, containee) { | |
59 var isParent = false; | |
60 do { | |
61 if ((isParent = container == containee)) | |
62 break; | |
63 containee = containee.parentNode; | |
64 } while (containee != null); | |
65 | |
66 return isParent; | |
67 } | |
68 | |
69 // OnMouseOut handler. Returns true if the mouse moved out of the element. | |
70 // It is false if the mouse is still in the element, but in a blank part of it, | |
71 // like in an empty table cell. | |
72 function checkMouseLeave(element, event) { | |
73 if (element.contains && event.toElement) { | |
74 return !element.contains(event.toElement); | |
75 } | |
76 else if (event.relatedTarget) { | |
77 return !containsDOM(element, event.relatedTarget); | |
78 } | |
79 } | |
80 | |
81 // Creates a new cookie. | |
82 function createCookie(name, value, day) { | |
83 var date = new Date(); | |
84 date.setTime(date.getTime() + (day * 24 * 60 * 60 * 1000)); | |
85 var expires = "; expires=" + date.toGMTString(); | |
86 document.cookie = name + "=" + value+expires + "; path=/"; | |
87 } | |
88 | |
89 // Returns the vaue of a cookie, or null if it does not exist. | |
90 function readCookie(name) { | |
91 var begin = name + "="; | |
92 var data = document.cookie.split(';'); | |
93 for(var i = 0; i < data.length; i++) { | |
94 var cookie = data[i]; | |
95 while (cookie.charAt(0) == ' ') | |
96 cookie = cookie.substring(1, cookie.length); | |
97 if (cookie.indexOf(begin) == 0) | |
98 return cookie.substring(begin.length, cookie.length); | |
99 } | |
100 | |
101 return null; | |
102 } | |
103 | |
104 // Deletes a cookie. | |
105 function eraseCookie(name) { | |
106 createCookie(name, "", -1); | |
107 } | |
108 | |
109 // Hides all "details" and "comments" section. | |
110 function collapse() { | |
111 // Hide all Comments sections. | |
112 var comments = document.querySelectorAll('.DevComment'); | |
113 for(var i = 0; i < comments.length; i++) { | |
114 comments[i].style.display = "none"; | |
115 } | |
116 | |
117 // Hide all details sections. | |
118 var details = document.querySelectorAll('.DevDetails'); | |
119 for(var i = 0; i < details.length; i++) { | |
120 details[i].style.display = "none"; | |
121 } | |
122 | |
123 // Fix the rounding on the Revision box. (Lower right corner must be round) | |
124 var revisions = document.querySelectorAll('.DevRev'); | |
125 for(var i = 0; i < revisions.length; i++) { | |
126 revisions[i].className = revisions[i].className + ' DevRevCollapse'; | |
127 } | |
128 | |
129 // Fix the rounding on the last category box. (Lower left corner must be rou nd) | |
130 var status = document.querySelectorAll('.last'); | |
131 for(var i = 0; i < status.length; i++) { | |
132 status[i].className = status[i].className + ' DevStatusCollapse'; | |
133 } | |
134 | |
135 // Create a cookie to remember that we want the view to be collapsed. | |
136 createCookie('collapsed', 'true', 30) | |
137 | |
138 // Hide the collapse and the unmerge buttons. | |
139 document.querySelectorAll('.collapse')[0].style.display = 'none' | |
140 document.querySelectorAll('.unmerge')[0].style.display = 'none' | |
141 | |
142 // Activate the merge and expand buttons. | |
143 document.querySelectorAll('.uncollapse')[0].style.display = 'inline' | |
144 document.querySelectorAll('.merge')[0].style.display = 'inline' | |
145 } | |
146 | |
147 // Expands the view. This is the opposite of "Collapse" | |
148 function uncollapse() { | |
149 unmerge(); | |
150 | |
151 // Make the comments visible. | |
152 var comments = document.querySelectorAll('.DevComment'); | |
153 for(var i = 0; i < comments.length; i++) { | |
154 comments[i].style.display = ""; | |
155 } | |
156 | |
157 // Make the details visible. | |
158 var details = document.querySelectorAll('.DevDetails'); | |
159 for(var i = 0; i < details.length; i++) { | |
160 details[i].style.display = ""; | |
161 } | |
162 | |
163 // Remove the round corner (lower right) for the Revision box. | |
164 var revisions = document.querySelectorAll('.DevRev'); | |
165 for(var i = 0; i < revisions.length; i++) { | |
166 revisions[i].className = revisions[i].className.replace('DevRevCollapse' , ''); | |
167 } | |
168 | |
169 // Remoe the round corner (lower left) for the last category box. | |
170 var status = document.querySelectorAll('.DevStatus'); | |
171 for(var i = 0; i < status.length; i++) { | |
172 status[i].className = status[i].className.replace('DevStatusCollapse', ' '); | |
173 } | |
174 | |
175 // Delete the cookies that say that we want to be collapsed or merged. | |
176 eraseCookie('collapsed') | |
177 eraseCookie('merged') | |
178 | |
179 // Display the "collapse" and "merge" buttons. | |
180 document.querySelectorAll('.collapse')[0].style.display = 'inline' | |
181 document.querySelectorAll('.merge')[0].style.display = 'inline' | |
182 | |
183 // Remove the "uncollapse" and "unmerge" buttons. | |
184 document.querySelectorAll('.uncollapse')[0].style.display = 'none' | |
185 document.querySelectorAll('.unmerge')[0].style.display = 'none' | |
186 } | |
187 | |
188 // Merge all the status boxes together. | |
189 function merge() { | |
190 collapse(); | |
191 | |
192 // Hide all the spacing. | |
193 var spacing = document.querySelectorAll('.DevStatusSpacing'); | |
194 for(var i = 0; i < spacing.length; i++) { | |
195 spacing[i].style.display = "none"; | |
196 } | |
197 | |
198 // Each boxes have, in the className, a tag that uniquely represents the | |
199 // build where this data comes from. | |
200 // Since we want to merge all the boxes coming from the same build, we | |
201 // parse the document to find all the builds, and then, for each build, we | |
202 // concatenate the boxes. | |
203 | |
204 var allTags = []; | |
205 all = document.getElementsByTagName('*') | |
206 for(var i = 0; i < all.length; i++) { | |
207 var element = all[i]; | |
208 start = element.className.indexOf('Tag') | |
209 if (start != -1) { | |
210 var className = "" | |
211 end = element.className.indexOf(' ', start) | |
212 if (end != -1) { | |
213 className = element.className.substring(start, end); | |
214 } else { | |
215 className = element.className.substring(start); | |
216 } | |
217 allTags[className] = 1; | |
218 } | 29 } |
219 } | 30 } |
220 | 31 </style> |
221 // Mergeall tags that we found | 32 <link href="/static/css/bootstrap.min.css" rel="stylesheet"> |
222 for (i in allTags) { | 33 {% block head %}{% endblock %} |
223 var current = document.querySelectorAll('.' + i); | 34 </head> |
224 | 35 <body> |
225 // We do the work only if there is more than 1 box with the same | 36 <div class="navbar navbar-fixed-top"> |
226 // build. | 37 <div class="navbar-inner"> |
227 if (current.length > 1) { | 38 <ul class="nav pull-right"> |
228 // Add the noround class to all the boxes. | 39 <li><a href="{{url}}">Original Page</a></li> |
229 for(var i = 0; i < current.length; i++) { | 40 </ul> |
230 current[i].className = current[i].className + ' noround'; | 41 <div class="container"> |
231 } | 42 <button type="button" class="btn btn-navbar" |
232 | 43 data-toggle="collapse" data-target=".nav-collapse"> |
233 // Add the begin class to the first box. | 44 <span class="icon-bar"></span> |
234 current[0].className = current[0].className + ' begin'; | 45 <span class="icon-bar"></span> |
235 | 46 <span class="icon-bar"></span> |
236 // Add the end class to the last box. | 47 </button> |
237 last = current.length - 1; | 48 <a class="brand" href="/buildbot/"> |
238 current[last].className = current[last].className + ' end'; | 49 Buildbot Viewer |
239 } | 50 </a> |
240 } | 51 <div class="nav-collapse collapse"> |
241 | 52 <ul class="nav"> |
242 // Display the "unmerge" button. | 53 {% for crumb, link in breadcrumbs %} |
243 document.querySelectorAll('.unmerge')[0].style.display = 'inline' | 54 <li> |
244 document.querySelectorAll('.uncollapse')[0].style.display = 'inline' | 55 <a href="{{link}}">{{crumb}}</a> |
245 | 56 </li> |
246 // Remove the "merge" button. | 57 {% endfor %} |
247 document.querySelectorAll('.collapse')[0].style.display = 'none' | 58 </ul> |
248 document.querySelectorAll('.merge')[0].style.display = 'none' | 59 </div><!--/.nav-collapse --> |
249 | 60 </div> |
250 // Create a cookie to remember that we want to be merged. | 61 </div> |
251 createCookie('merged', 'true', 30) | 62 </div> |
252 } | 63 <div class="container-fluid"> |
253 | 64 {% block body %}{% endblock %} |
254 // Un-merge the view. This is the opposite of "merge". | 65 {% block footer %} |
255 function unmerge() { | 66 <div class="row"> |
256 // We put back all the spacing. | 67 <div class="span4"> |
257 var spacing = document.querySelectorAll('.DevStatusSpacing'); | 68 {% block sub_footer %}{% endblock sub_footer %} |
258 for(var i = 0; i < spacing.length; i++) { | 69 </div> |
259 spacing[i].style.display = ""; | 70 <div class="span2 pull-right"> |
260 } | 71 <img alt="Chrome" data-g-event="nav-logo" data-g-label= |
261 | 72 "consumer-home" id="logo" src= |
262 // We remove the class added to all the boxes we modified. | 73 "http://www.google.com/intl/en/chrome/assets/common/images/chrome_logo _2x.png"> |
263 var noround = document.querySelectorAll('.noround'); | 74 </div> |
264 for(var i = 0; i < noround.length; i++) { | 75 </div> |
265 noround[i].className = noround[i].className.replace("begin", ''); | 76 {% endblock %} |
266 noround[i].className = noround[i].className.replace("end", ''); | 77 </div> |
267 noround[i].className = noround[i].className.replace("noround", ''); | 78 <script> |
268 } | 79 !function ($) { |
269 | 80 $(function(){ |
270 // Delete the cookie, we don't want to be merged anymore. | 81 window.prettyPrint && prettyPrint() |
271 eraseCookie('merged') | 82 }) |
272 | 83 }(window.jQuery) |
273 // Display the "merge" button. | 84 </script> |
274 document.querySelectorAll('.merge')[0].style.display = 'inline' | 85 </body> |
275 | |
276 // Hide the "unmerge" button. | |
277 document.querySelectorAll('.unmerge')[0].style.display = 'none' | |
278 } | |
279 | |
280 function SetupView() { | |
281 if (readCookie('merged')) { | |
282 merge(); | |
283 } else if (readCookie('collapsed')) { | |
284 collapse(); | |
285 } | |
286 } | |
287 | |
288 document.addEventListener("DOMContentLoaded", SetupView, false); | |
289 | |
290 // ]]> | |
291 </script> | |
292 | |
293 {% if additional_head %} | |
294 {{ additional_head }} | |
295 {% endif %} | |
296 | |
297 </head> | |
298 | |
299 <body{% if body_class %} class="{{ body_class }}"{% endif %}> | |
300 <div style="text-align:right; float: right;"> | |
301 {% if user %} | |
302 {{ user_nickname }} | |
303 - <a href="{{ logout_url }}">Sign Out</a> | |
304 {% else %} | |
305 <a href="{{ login_url }}">Sign In</a> | |
306 {% endif %} | |
307 </div> | |
308 | |
309 <div class="header"> | |
310 <a href="{{ offsite_base }}/.">Home</a> | |
311 - <a href="{{ offsite_base }}/waterfall">Waterfall</a> | |
312 - <a href="{{ offsite_base }}/console">Console</a> | |
313 - <a href="{{ offsite_base }}/builders">Builders</a> | |
314 - <a href="{{ offsite_base }}/one_line_per_build">Recent Builds</a> | |
315 - <a href="{{ offsite_base }}/buildslaves">Buildslaves</a> | |
316 - <a href="{{ offsite_base }}/changes">Changesources</a> | |
317 - <a href="{{ offsite_base }}/json/help">JSON API</a> | |
318 - <a href="{{ offsite_base }}/about">About</a> | |
319 </div> | |
320 | |
321 <hr /> | |
322 {% autoescape off %} | |
323 {{ content }} | |
324 {% endautoescape %} | |
325 </body> | |
326 </html> | 86 </html> |
OLD | NEW |