// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** Information about a particular waterfall. */
function WaterfallInfo(waterfallData) {
var waterfallName = waterfallData[0];
var waterfallUrl = waterfallData[1];
var waterfallShowsAllBots = waterfallData[2];
// Create a table cell that acts as a header for its bot section.
var linkElement = document.createElement('a');
linkElement.href = waterfallUrl;
linkElement.innerHTML = waterfallName;
var thElement = document.createElement('th');
thElement.colSpan = 15;
thElement.className = 'section-header';
thElement.appendChild(linkElement);
this.botInfo = {};
this.inFlight = 0;
this.name = waterfallName;
this.showsAllBots = waterfallShowsAllBots;
this.thElement = thElement;
this.timeLastRequested = 0;
this.rootJsonUrl = waterfallUrl + 'json/';
this.url = waterfallUrl;
}
/** Send an asynchronous request to get the main waterfall's JSON. */
WaterfallInfo.prototype.requestJson = function() {
if (this.inFlight) {
var elapsed = new Date().getTime() - this.timeLastRequested;
if (elapsed < MAX_MILLISECONDS_TO_WAIT) return;
// A response was not received in a reasonable timeframe. Try again.
this.inFlight--;
gNumRequestsInFlight--;
gNumRequestsRetried++;
}
this.inFlight++;
this.timeLastRequested = new Date().getTime();
gNumRequestsInFlight++;
// Create the request and send it off.
var waterfallInfo = this;
var url = this.url + 'json/builders/';
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
waterfallInfo.parseJSON(JSON.parse(request.responseText));
}
};
request.send(null);
};
/** Parse out the data received about the waterfall. */
WaterfallInfo.prototype.parseJSON = function(buildersJson) {
this.inFlight--;
gNumRequestsInFlight--;
// Go through each builder on the waterfall and get the latest status.
var builderNames = Object.keys(buildersJson);
for (var i = 0; i < builderNames.length; ++i) {
var builderName = builderNames[i];
if (!this.showsAllBots && !this.shouldShowBot(builderName)) continue;
// Prepare the bot info.
var builderJson = buildersJson[builderName];
if (!this.botInfo[builderName]) {
this.botInfo[builderName] = new BotInfo(builderName,
builderJson.category);
}
this.botInfo[builderName].update(this.rootJsonUrl, builderJson);
gWaterfallDataIsDirty = true;
}
};
/** Override this function to filter out particular bots. */
WaterfallInfo.prototype.shouldShowBot = function(builderName) {
return true;
};
/** Updates the HTML. */
WaterfallInfo.prototype.updateWaterfallStatusHTML = function() {
var table = document.getElementById('build-info');
// Point at the waterfall.
var headerCell = this.thElement;
headerCell.className =
'section-header' + (this.inFlight > 0 ? ' in-flight' : '');
var headerRow = table.insertRow(-1);
headerRow.appendChild(headerCell);
// Print out useful bits about the bots.
var botNames = sortBotNamesByCategory(this.botInfo);
for (var i = 0; i < botNames.length; ++i) {
var botName = botNames[i];
var botInfo = this.botInfo[botName];
var waterfallBaseUrl = this.url + 'builders/';
var botRowElement = botInfo.createHtml(waterfallBaseUrl);
// Determine whether we should apply keyword filter.
var filter = document.getElementById('text-filter').value.trim();
if (filter.length > 0) {
var keywords = filter.split(' ');
var buildNumbers = Object.keys(botInfo.builds);
var matchesFilter = false;
for (var x = 0; x < buildNumbers.length && !matchesFilter; ++x) {
var buildStatus = botInfo.builds[buildNumbers[x]].statusText;
for (var y = 0; y < keywords.length && !matchesFilter; ++y) {
if (buildStatus.indexOf(keywords[y]) >= 0)
matchesFilter = true;
}
}
if (!matchesFilter)
continue;
}
// If the user doesn't want to see completely green bots, hide it.
var shouldHideStable =
document.getElementById('checkbox-hide-stable').checked;
if (shouldHideStable && botInfo.isSteadyGreen)
continue;
table.appendChild(botRowElement);
}
};