// 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); } };