Home | History | Annotate | Download | only in web
      1 <!DOCTYPE html>
      2 <!-- much of this is stolen from omahaproxy.appspot.com/viewer -->
      3 <html>
      4   <head>
      5     <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
      6     <title>NaCl SDK Manifest Viewer</title>
      7   </head>
      8   <style type="text/css" media="screen">
      9     body {
     10       font-family: monospace;
     11       font-size: 10pt;
     12     }
     13 
     14     table {
     15       border-collapse: collapse;
     16       border-color: rgb(100, 100, 100);
     17       border-style: solid;
     18       border-width: 1px 0px 1px 0px;
     19     }
     20 
     21     table td {
     22       padding: 3px;
     23       border-color: rgb(100, 100, 100);
     24       border-style: solid;
     25       border-width: 0px 1px 0px 1px;
     26     }
     27 
     28     thead {
     29       background-color: lightblue;
     30       font-weight: bold;
     31       border-style: solid;
     32       border-color: rgb(100, 100, 100);
     33       border-width: 0px 0px 2px 0px;
     34       text-align: center;
     35     }
     36 
     37     tbody tr:nth-child(odd) {
     38       background-color: rgb(230, 230, 230);
     39     }
     40 
     41     tbody tr:hover {
     42       background-color: orange;
     43     }
     44 
     45     td a {
     46       padding: 3px;
     47     }
     48 
     49     #log > span {
     50       display: block;
     51     }
     52 
     53     #log > span.highlight {
     54       font-weight: bold;
     55     }
     56 
     57     #log > span.missing {
     58       color: #f00;
     59     }
     60   </style>
     61   <body>
     62     <h1>NaCl SDK Manifest Viewer</h1>
     63     <table>
     64       <thead id="columns">
     65       </thead>
     66       <tbody id="rows">
     67       </tbody>
     68     </table>
     69     <h2>Most recent upload log:</h2>
     70     <div id="log">
     71     </div>
     72     <script type="application/javascript">
     73       function loadText(url, callback) {
     74         var xhr = new XMLHttpRequest();
     75         xhr.open('GET', url, true);
     76         xhr.onreadystatechange = function (e) {
     77           if (xhr.readyState == 4) {
     78             if (xhr.status == 200) {
     79               callback(xhr.responseText);
     80             } else {
     81               console.log("Failed to load "+url+": error " + xhr.status);
     82             }
     83           }
     84         }
     85         xhr.send(null);
     86       }
     87 
     88       function loadJson(url, callback) {
     89         loadText(url, function (text) {
     90           callback(JSON.parse(text));
     91         });
     92       }
     93 
     94       function removeAllChildren(elm) {
     95         while (elm.childNodes.length) {
     96           elm.removeChild(elm.firstChild);
     97         }
     98       }
     99 
    100       function display(data) {
    101         data = data.bundles;
    102 
    103         var columnsElm = document.getElementById('columns');
    104         var rowsElm = document.getElementById('rows');
    105         removeAllChildren(columnsElm);
    106         removeAllChildren(rowsElm);
    107 
    108         // Create the column headers.
    109         var tr = document.createElement('tr');
    110         var columns = [
    111           'name', 'version', 'revision', 'trunk_revision', 'chrome_version', 'win', 'mac', 'linux', 'all'
    112         ];
    113         columns.forEach(function(column) {
    114           var td = document.createElement('td');
    115           var text = document.createTextNode(column);
    116           td.appendChild(text);
    117           tr.appendChild(td);
    118         });
    119         columnsElm.appendChild(tr);
    120 
    121         data.forEach(function(row) {
    122           var tr = document.createElement('tr');
    123           columns.forEach(function(column) {
    124             var td = document.createElement('td');
    125             var node = makeCell(row, column);
    126             if (node) {
    127               td.appendChild(node);
    128             }
    129             tr.appendChild(td);
    130           });
    131           rowsElm.appendChild(tr);
    132         });
    133       }
    134 
    135       function makeCell(row, column) {
    136         var platforms = ['win', 'mac', 'linux', 'all'];
    137 
    138         if (platforms.indexOf(column) !== -1) {
    139           return makePlatformCell(row, column);
    140         } else if (column === 'trunk_revision') {
    141           return makeTrunkRevisionCell(row);
    142         } else if (column === 'chrome_version') {
    143           return makeChromeVersionCell(row);
    144         } else {
    145           return document.createTextNode(row[column]);
    146         }
    147       }
    148 
    149       function makePlatformCell(row, column) {
    150         var archives = row.archives;
    151         for (var k = 0; k < archives.length; ++k) {
    152           if (column !== archives[k].host_os) {
    153             continue;
    154           }
    155 
    156           // Convert the URL to a short name:
    157           // https://.../36.0.1974.2/naclsdk_linux.tar.bz2 -> naclsdk_linux
    158           var url = archives[k].url;
    159           var lastSlash = url.lastIndexOf('/');
    160           var nextDot = url.indexOf('.', lastSlash);
    161           var name = url.substr(lastSlash + 1, nextDot - lastSlash - 1);
    162 
    163           var node = document.createElement('a');
    164           node.setAttribute('href', url);
    165           node.appendChild(document.createTextNode(name));
    166           return node;
    167         }
    168         return null;
    169       }
    170 
    171       function makeTrunkRevisionCell(row) {
    172         var url = row.archives[0].url;
    173         var version = versionFromUrl(url);
    174         if (version) {
    175           var node = document.createTextNode('');
    176           baseTrunkRevisionFromVersion(version, function(node) {
    177             return function(revision) {
    178               node.textContent = revision;
    179             };
    180           }(node));
    181           return node;
    182         }
    183         return null;
    184       }
    185 
    186       function makeChromeVersionCell(row) {
    187         var url = row.archives[0].url;
    188         var version = versionFromUrl(url);
    189         if (version) {
    190           return document.createTextNode(version);
    191         }
    192         return null;
    193       }
    194 
    195       function versionFromUrl(url) {
    196         // Extract the Chrome version from an archive URL.
    197         // It should look something like:
    198         // https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/36.0.1974.2/naclsdk_win.tar.bz2
    199         var lastSlash = url.lastIndexOf('/');
    200         var penultimateSlash = url.lastIndexOf('/', lastSlash - 1);
    201         // The version is between these two slashes.
    202         var version = url.substr(penultimateSlash + 1,
    203                                  lastSlash - penultimateSlash - 1);
    204         // It is a chrome version if it matches one of these regexes:
    205         if (/trunk\.\d+/.test(version)) {
    206           // Trunk version.
    207           return version;
    208         } else if (/\d+\.\d+\.\d+\.\d+/.test(version)) {
    209           // Branch version.
    210           return version;
    211         } else {
    212           // Not a version.
    213           return null;
    214         }
    215       }
    216 
    217       function baseTrunkRevisionFromVersion(version, callback) {
    218         if (version.indexOf('trunk', 0) === 0) {
    219           callback(version.substr(6));  // Skip "trunk."
    220         } else {
    221           revisionFromVersion(baseTrunkVersionFromVersion(version), callback);
    222         }
    223       }
    224 
    225       function baseTrunkVersionFromVersion(version) {
    226         var lastDot = version.lastIndexOf('.');
    227         return version.substr(0, lastDot) + '.0';
    228       }
    229 
    230       function revisionFromVersion(version, callback) {
    231         var url = 'http://omahaproxy.appspot.com/revision.json?version='+version;
    232         loadJson(url, function(data) {
    233           callback(data.chromium_revision);
    234         });
    235       }
    236 
    237       function displayLog(text) {
    238         var lines = text.split('\n');
    239         var logEl = document.getElementById('log');
    240         lines.forEach(function (line) {
    241           var spanEl = document.createElement('span');
    242           spanEl.textContent = line;
    243           if (line.indexOf('>>>', 0) === 0) {
    244             spanEl.classList.add('highlight');
    245           } else if (line.indexOf('Missing archives') !== -1) {
    246             spanEl.classList.add('missing');
    247           }
    248           logEl.appendChild(spanEl);
    249         });
    250       }
    251 
    252       loadJson('naclsdk_manifest2.json', display);
    253       loadText('naclsdk_manifest2.json.log', displayLog);
    254     </script>
    255   </body>
    256 </html>
    257