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

Side by Side Diff: Tools/GardeningServer/scripts/ui.js

Issue 405853002: Delete dead code now that the polymer port of garden-o-matic is done. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE. 23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 var ui = ui || {}; 26 var ui = ui || {};
27 27
28 (function () { 28 (function () {
29 29
30 ui.displayURLForBuilder = function(builderName) 30 // FIXME: Put this all in a more appropriate place.
31 {
32 return config.waterfallURL + '?' + base.queryParam({
33 'builder': builderName
34 });
35 }
36
37 ui.kUseNewWindowForLinksSetting = 'gardenomatic.use-new-window-for-links';
38 31
39 ui.displayNameForBuilder = function(builderName) 32 ui.displayNameForBuilder = function(builderName)
40 { 33 {
41 return builderName.replace(/Webkit /i, ''); 34 return builderName.replace(/Webkit /i, '');
42 } 35 }
43 36
44 ui.urlForCrbug = function(bugID)
45 {
46 return 'http://crbug.com/' + bugID;
47 }
48
49 ui.urlForFlakinessDashboard = function(opt_testNameList) 37 ui.urlForFlakinessDashboard = function(opt_testNameList)
50 { 38 {
51 var testsParameter = opt_testNameList ? opt_testNameList.join(',') : ''; 39 var testsParameter = opt_testNameList ? opt_testNameList.join(',') : '';
52 return 'http://test-results.appspot.com/dashboards/flakiness_dashboard.html# tests=' + encodeURIComponent(testsParameter); 40 return 'http://test-results.appspot.com/dashboards/flakiness_dashboard.html# tests=' + encodeURIComponent(testsParameter);
53 } 41 }
54 42
55 ui.urlForEmbeddedFlakinessDashboard = function(opt_testNameList) 43 ui.urlForEmbeddedFlakinessDashboard = function(opt_testNameList)
56 { 44 {
57 return ui.urlForFlakinessDashboard(opt_testNameList) + '&showChrome=false'; 45 return ui.urlForFlakinessDashboard(opt_testNameList) + '&showChrome=false';
58 } 46 }
59 47
60 ui.setTargetForLink = function(anchor)
61 {
62 if (anchor.href.indexOf('#') === 0)
63 return;
64 if (ui.useNewWindowForLinks)
65 anchor.target = '_blank';
66 else
67 anchor.removeAttribute('target');
68 }
69
70 ui.setUseNewWindowForLinks = function(enabled)
71 {
72 ui.useNewWindowForLinks = enabled;
73 if (enabled)
74 localStorage[ui.kUseNewWindowForLinksSetting] = 'true';
75 else
76 delete localStorage[ui.kUseNewWindowForLinksSetting];
77
78 [].forEach.call(document.querySelectorAll('a'), function(link) {
79 ui.setTargetForLink(link);
80 });
81 }
82 ui.setUseNewWindowForLinks(!!localStorage[ui.kUseNewWindowForLinksSetting]);
83
84 ui.createLinkNode = function(url, textContent)
85 {
86 var link = document.createElement('a');
87 link.href = url;
88 ui.setTargetForLink(link);
89 link.appendChild(document.createTextNode(textContent));
90 return link;
91 }
92
93 ui.onebar = base.extends('div', {
94 init: function()
95 {
96 this.id = 'onebar';
97 this.innerHTML =
98 '<ul>' +
99 '<li><a href="#unexpected">Unexpected Failures</a></li>' +
100 '<li><a href="#results">Results</a></li>' +
101 '</ul>' +
102 '<div id="link-handling"><input type="checkbox" id="new-window-for-l inks"><label for="new-window-for-links">Open links in new window</label></div>' +
103 '<div id="unexpected"></div>' +
104 '<div id="results"></div>';
105 this._tabNames = [
106 'unexpected',
107 'results',
108 ]
109
110 this._tabIndexToSavedScrollOffset = {};
111 this._tabs = $(this).tabs({
112 disabled: [this._tabNames.indexOf('results')],
113 show: function(event, ui) { this._restoreScrollOffset(ui.index); },
114 select: function(event, ui) {
115 this._saveScrollOffset();
116 window.location.hash = ui.tab.hash;
117 }.bind(this)
118 });
119 },
120 _saveScrollOffset: function() {
121 var tabIndex = this._tabs.tabs('option', 'selected');
122 this._tabIndexToSavedScrollOffset[tabIndex] = document.body.scrollTop;
123 },
124 _restoreScrollOffset: function(tabIndex)
125 {
126 document.body.scrollTop = this._tabIndexToSavedScrollOffset[tabIndex] || 0;
127 },
128 _setupHistoryHandlers: function()
129 {
130 function currentHash() {
131 var hash = window.location.hash;
132 return (!hash || hash == '#') ? '#unexpected' : hash;
133 }
134
135 var self = this;
136 window.onhashchange = function(event) {
137 var tabName = currentHash().substring(1);
138 self._selectInternal(tabName);
139 };
140
141 // When navigating from the browser chrome, we'll
142 // scroll to the #tabname contents. popstate fires before
143 // we scroll, so we can save the scroll offset first.
144 window.onpopstate = function() {
145 self._saveScrollOffset();
146 };
147 },
148 _setupLinkSettingHandler: function()
149 {
150 if (ui.useNewWindowForLinks)
151 document.getElementById('new-window-for-links').setAttribute('checke d', true);
152 document.getElementById('new-window-for-links').addEventListener('change ', function(event) {
153 ui.setUseNewWindowForLinks(this.checked);
154 });
155 },
156 attach: function()
157 {
158 document.body.insertBefore(this, document.body.firstChild);
159 this._setupLinkSettingHandler();
160 this._setupHistoryHandlers();
161 },
162 tabNamed: function(tabName)
163 {
164 if (this._tabNames.indexOf(tabName) == -1)
165 return null;
166 tab = document.getElementById(tabName);
167 // We perform this sanity check below to make sure getElementById
168 // hasn't given us a node in some other unrelated part of the document.
169 // that shouldn't happen normally, but it could happen if an attacker
170 // has somehow sneakily added a node to our document.
171 if (tab.parentNode != this)
172 return null;
173 return tab;
174 },
175 unexpected: function()
176 {
177 return this.tabNamed('unexpected');
178 },
179 results: function()
180 {
181 return this.tabNamed('results');
182 },
183 _selectInternal: function(tabName) {
184 var tabIndex = this._tabNames.indexOf(tabName);
185 this._tabs.tabs('enable', tabIndex);
186 this._tabs.tabs('select', tabIndex);
187 },
188 select: function(tabName)
189 {
190 this._saveScrollOffset();
191 this._selectInternal(tabName);
192 window.location = '#' + tabName;
193 }
194 });
195
196 ui.TreeStatus = base.extends('div', {
197 addStatus: function(name)
198 {
199 var label = document.createElement('div');
200 label.textContent = " " + name + ' status: ';
201 this.appendChild(label);
202 var statusSpan = document.createElement('span');
203 statusSpan.textContent = '(Loading...) ';
204 label.appendChild(statusSpan);
205 treestatus.fetchTreeStatus(treestatus.urlByName(name), statusSpan);
206 },
207 init: function()
208 {
209 this.className = 'treestatus';
210 this.addStatus('blink');
211 this.addStatus('chromium');
212 },
213 });
214
215 ui.revisionDetails = base.extends('span', {
216 // We only support 2 levels of visual escalation levels: warning and critica l.
217 warnRollRevisionSpanThreshold: 45,
218 criticalRollRevisionSpanThreshold: 80,
219 classNameForUrgencyLevel: function(rollRevisionSpan) {
220 if (rollRevisionSpan < this.criticalRollRevisionSpanThreshold)
221 return "warning";
222 return "critical";
223 },
224 updateUI: function(totRevision) {
225 this.appendChild(document.createElement("br"));
226 this.appendChild(document.createTextNode('Last roll is to '));
227 this.appendChild(ui.createLinkNode(trac.changesetURL(this.lastRolledRevi sion), this.lastRolledRevision));
228 var rollRevisionSpan = totRevision - this.lastRolledRevision;
229 // Don't clutter the UI if we haven't run behind.
230 if (rollRevisionSpan > this.warnRollRevisionSpanThreshold) {
231 var wrapper = document.createElement("span");
232 wrapper.className = this.classNameForUrgencyLevel(rollRevisionSpan);
233 wrapper.appendChild(document.createTextNode("(" + rollRevisionSpan + " revisions behind)"));
234 this.appendChild(wrapper);
235 }
236 this.appendChild(document.createTextNode(', current autoroll '));
237 if (this.roll) {
238 var linkText = "" + this.roll.fromRevision + ":" + this.roll.toRevis ion;
239 this.appendChild(ui.createLinkNode(this.roll.url, linkText));
240 if (this.roll.isStopped)
241 this.appendChild(document.createTextNode(' (STOPPED) '));
242 } else {
243 this.appendChild(document.createTextNode(' None'));
244 }
245 },
246 init: function() {
247 var theSpan = this;
248 theSpan.appendChild(document.createTextNode('Latest revision processed b y every bot: '));
249
250 var latestRevision = model.latestRevisionWithNoBuildersInFlight();
251 var latestRevisions = model.latestRevisionByBuilder();
252
253 // Get the list of builders sorted with the most recent one first.
254 var builders = Object.keys(latestRevisions);
255 builders.sort(function (a, b) { return parseInt(latestRevisions[b]) - pa rseInt(latestRevisions[a]);});
256
257 var summaryNode = document.createElement('summary');
258 var summaryLinkNode = ui.createLinkNode(trac.changesetURL(latestRevision ), latestRevision);
259 summaryNode.appendChild(summaryLinkNode);
260
261 var revisionsTableNode = document.createElement('table');
262 builders.forEach(function(builderName) {
263 var trNode = document.createElement('tr');
264
265 var tdNode = document.createElement('td');
266 tdNode.appendChild(ui.createLinkNode(ui.displayURLForBuilder(builder Name), builderName.replace('WebKit ', '')));
267 trNode.appendChild(tdNode);
268
269 var tdNode = document.createElement('td');
270 tdNode.appendChild(document.createTextNode(latestRevisions[builderNa me]));
271 trNode.appendChild(tdNode);
272
273 revisionsTableNode.appendChild(trNode);
274 });
275
276 var revisionsNode = document.createElement('details');
277 revisionsNode.appendChild(summaryNode);
278 revisionsNode.appendChild(revisionsTableNode);
279 theSpan.appendChild(revisionsNode);
280
281 // This adds a pop-up when we hover over the summary if the details aren 't being shown.
282 var revisionsPopUp = document.createElement('span')
283 revisionsPopUp.id = 'revisionPopUp';
284 summaryLinkNode.appendChild(revisionsPopUp);
285 revisionsPopUp.appendChild(revisionsTableNode.cloneNode(true));
286
287 summaryLinkNode.addEventListener('mouseover', function(event) {
288 if (!revisionsNode.open) {
289 revisionsPopUp.style.position = 'absolute';
290 revisionsPopUp.style.left = summaryNode.offsetLeft + 'px';
291 revisionsPopUp.style.top = (summaryNode.offsetTop + summaryNode. offsetHeight) + 'px';
292 revisionsPopUp.classList.add('active');
293 }
294 });
295
296 summaryLinkNode.addEventListener('mouseout', function(event) {
297 if (!revisionsNode.open) {
298 revisionsPopUp.classList.remove("active");
299 }
300 });
301
302 var totRevision = model.latestRevision();
303 theSpan.appendChild(document.createTextNode(', trunk is at '));
304 theSpan.appendChild(ui.createLinkNode(trac.changesetURL(totRevision), to tRevision));
305 }
306 });
307
308 })(); 48 })();
OLDNEW
« no previous file with comments | « Tools/GardeningServer/scripts/treestatus.js ('k') | Tools/GardeningServer/scripts/ui_unittests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698