Index: native_client_sdk/src/web/index.html |
diff --git a/native_client_sdk/src/web/index.html b/native_client_sdk/src/web/index.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..469c9105f7c2dd82a52a42ebfbde54cadedf15d0 |
--- /dev/null |
+++ b/native_client_sdk/src/web/index.html |
@@ -0,0 +1,297 @@ |
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
+<html> |
+ <head> |
+ <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"> |
+ <script language="javascript"> |
+ // Split a string in 2 parts. The first is the leading number, if any, |
+ // the second is the string following the numbers. |
+ function splitNum(s) { |
+ var results = new Array(); |
+ results[0] = 'None'; |
+ for (var i = 0; i < s.length; i++) { |
+ var substr = s.substr(0, i+1) |
+ if (isNaN(substr)) { |
+ // Not a number anymore. |
+ results[1] = s.substr(i) |
+ break; |
+ } else { |
+ // This is a number. update the results. |
+ results[0] = parseFloat(substr); |
+ } |
+ } |
+ return results; |
+ } |
+ |
+ // Compare 2 strings using a custom alphanumerical algorithm. |
+ // This is similar to a normal string sort, except that we sort |
+ // first by leading digits, if any. |
+ // For example: |
+ // 100hello > 2goodbye |
+ // Numbers anywhere else in the string are compared using the normal |
+ // sort algorithm. |
+ function alphanumCompare(a, b) { |
+ var parsedA = splitNum(a); |
+ var parsedB = splitNum(b); |
+ var numA = parsedA[0]; |
+ var numB = parsedB[0]; |
+ var strA = parsedA[1]; |
+ var strB = parsedB[1]; |
+ |
+ if (isNaN(numA) == false && isNaN(numB) == false) { |
+ // They both start with numbers. |
+ if (numA < numB) return -1; |
+ if (numA > numB) return 1; |
+ // Identical. Fallback to string. |
+ return (strA < strB) ? -1 : (strA > strB ? 1 : 0) |
+ } |
+ |
+ // If only one starts with a number, we start with that one as |
+ // the lowest. |
+ if (isNaN(numA) == false) return -1 |
+ if (isNaN(numB) == false) return 1 |
+ |
+ // They are both strings. |
+ return (a < b) ? -1 : (a > b ? 1 : 0) |
+ } |
+ </script> |
+ </head> |
+ <body> |
+ <script type="application/javascript"> |
+ String.prototype.startsWith = function(str) { |
+ return (this.match('^' + str) == str) |
+ } |
+ |
+ // Helper function to retrieve the value of a GET query parameter. |
+ // Greatly inspired from http://alturl.com/8rj7a |
+ function getParameter(parameterName) { |
+ // Add '=' to the parameter name (i.e. parameterName=value) |
+ var parameterName = parameterName + '='; |
+ var queryString = window.location.search.substring(1); |
+ if (queryString.length <= 0) { |
+ return ''; |
+ } |
+ |
+ // Find the beginning of the string |
+ begin = queryString.indexOf(parameterName); |
+ |
+ // If the parameter name is not found, skip it, otherwise return the |
+ // value. |
+ if (begin == -1) { |
+ return ''; |
+ } |
+ |
+ // Add the length (integer) to the beginning. |
+ begin += parameterName.length; |
+ |
+ // Multiple parameters are separated by the '&' sign. |
+ end = queryString.indexOf ('&', begin); |
+ |
+ if (end == -1) { |
+ end = queryString.length; |
+ } |
+ |
+ // Return the string. |
+ return unescape(queryString.substring(begin, end)); |
+ } |
+ |
+ // Given a tag and a node, returns the value for this tag on this node. |
+ function getNodeValue(node, tag) { |
+ return node.getElementsByTagName(tag)[0].firstChild.nodeValue; |
+ } |
+ |
+ // Displays the directory listing given the XML and path. |
+ function displayList(xmlstring, root, path, pathRoot) { |
+ // Display the header |
+ document.write('<h1>Index of /' + path + '</h1>'); |
+ |
+ // Start the table for the results. |
+ document.write('<table style="border-spacing:15px 0px;">'); |
+ |
+ var sortOrder = getParameter('sort'); |
+ var sortLink = location.pathname + '?path=' + path; |
+ if (sortOrder != 'desc') { |
+ sortLink += '&sort=desc'; |
+ } |
+ |
+ // Display the table header. |
+ document.write('<tr><th><img src="' + root + pathRoot + |
+ 'icons/blank.gif" alt="[ICO]"></th>'); |
+ document.write('<th><a href="' + sortLink + '">Name</a></th>'); |
+ document.write('<th>Last modified</th>'); |
+ document.write('<th>Size</th>'); |
+ document.write('<th>Storage Class</th>'); |
+ document.write('<th>ETag</th></tr>'); |
+ document.write('<tr><th colspan="6"><hr></th></tr>'); |
+ |
+ // Display the 'go back' button. |
+ if (path != '') { |
+ var backpath = location.pathname; |
+ |
+ // If there is more than one section delimited by '/' in the current |
+ // path we truncate the last section and append the rest to backpath. |
+ var delimiter = path.lastIndexOf('/'); |
+ if (delimiter >= 0) { |
+ delimiter = path.substr(0, delimiter).lastIndexOf('/'); |
+ if (delimiter >= 0) { |
+ backpath += '?path='; |
+ backpath += path.substr(0, delimiter+1); |
+ } |
+ } |
+ |
+ document.write('<tr><td valign="top"><img src="' + root + pathRoot + |
+ 'icons/back.gif" alt="[DIR]"></td>'); |
+ document.write('<td><a href="'); |
+ document.write(backpath); |
+ document.write('">Parent Directory</a></td>'); |
+ document.write('<td> </td>'); |
+ document.write('<td align="right"> - </td></tr>'); |
+ } |
+ |
+ // Set up the variables. |
+ var directories = new Array(); |
+ var files = new Array(); |
+ |
+ for (var iter = 0; iter < xmlstrings.length; iter++) { |
+ var xmlstring = xmlstrings[iter]; |
+ // Parse the XML output. |
+ var parser = new DOMParser(); |
+ var xmlDoc = parser.parseFromString(xmlstring, 'text/xml'); |
+ |
+ // Get the main element. |
+ var results = xmlDoc.getElementsByTagName('ListBucketResult'); |
+ |
+ // Get all the directories. |
+ var prefixes = results[0].getElementsByTagName('CommonPrefixes'); |
+ for (var i = 0; i < prefixes.length; i++) { |
+ var prefix = getNodeValue(prefixes[i], 'Prefix'); |
+ directories.push(prefix.substr(path.length)); |
+ } |
+ |
+ // Get all the files. |
+ var contents = results[0].getElementsByTagName('Contents'); |
+ for (var i = 0; i < contents.length; i++) { |
+ var obj = new Object(); |
+ obj.keyName = getNodeValue(contents[i], 'Key'); |
+ obj.lastModified = getNodeValue(contents[i], 'LastModified'); |
+ obj.eTag = getNodeValue(contents[i], 'ETag'); |
+ obj.size = getNodeValue(contents[i], 'Size'); |
+ files.push(obj); |
+ } |
+ } |
+ |
+ files.sort(alphanumCompare); |
+ directories.sort(alphanumCompare); |
+ |
+ // Reverse the list for a descending sort. |
+ if (sortOrder == 'desc') { |
+ files.reverse(); |
+ directories.reverse(); |
+ } |
+ |
+ // Display the directories. |
+ for (var i = 0; i < directories.length; i++) { |
+ var lnk = location.pathname.substr(0, location.pathname.indexOf('?')); |
+ lnk += '?path=' + path + directories[i]; |
+ |
+ document.write('<tr>'); |
+ document.write('<td valign="top"><img src="' + root + pathRoot + |
+ 'icons/folder.gif" alt="[DIR]"></td>'); |
+ document.write('<td><a href="' + lnk + '">' + |
+ directories[i].split('/')[0] + '</a></td>'); |
+ document.write('<td align="right">-</td>'); |
+ document.write('<td align="right">-</td>'); |
+ document.write('<td align="right">-</td>'); |
+ document.write('<td align="right">-</td>'); |
+ document.write('</tr>'); |
+ } |
+ |
+ // Display the files. |
+ for (var i = 0; i < files.length; i++) { |
+ var link = root + files[i].keyName; |
+ var filename = files[i].keyName.substr(path.length); |
+ var size = files[i].size / 1024 / 1024; |
+ var lastModified = files[i].lastModified.replace('T', ' '); |
+ lastModified = lastModified.substr(0, lastModified.indexOf('.')); |
+ |
+ // Remove the entries we don't want to show. |
+ if (filename == '') { |
+ continue; |
+ } |
+ |
+ if (filename.indexOf('$folder$') >= 0) { |
+ continue; |
+ } |
+ |
+ // Display the row. |
+ document.write('<tr>'); |
+ document.write('<td valign="top"><img src="' + root + pathRoot + |
+ 'icons/binary.gif" alt="[DIR]"></td>'); |
+ document.write('<td><a href="' + link + '">' + filename + |
+ '</a></td>'); |
+ document.write('<td align="right">' + lastModified + '</td>'); |
+ document.write('<td align="right">' + size.toFixed(2) + 'MB</td>'); |
+ document.write('<td align="right"><pre>' + |
+ files[i].eTag.split('"')[1] + '</pre></td>'); |
+ document.write('</tr>'); |
+ } |
+ |
+ // Close the table. |
+ document.write('<tr><th colspan="6"><hr></th></tr>'); |
+ document.write('</table>'); |
+ } |
+ |
+ var xmlstrings = new Array(); |
+ |
+ function fetchAndDisplay(marker) { |
+ var path = getParameter('path'); |
+ var lastSlash = location.pathname.lastIndexOf("/"); |
+ var filename = location.pathname.substring(lastSlash + 1); |
+ var firstSlash = location.pathname.indexOf("/", 1); |
+ var root = location.pathname.substring(0, firstSlash + 1); |
+ var pathRoot = location.pathname.substring(firstSlash + 1, |
+ lastSlash + 1); |
+ if (!path) { |
+ path = location.pathname.substring(firstSlash + 1, lastSlash + 1); |
+ } |
+ |
+ var markerParam = ''; |
+ if (marker != '') { |
+ markerParam = '&marker=' + marker; |
+ } |
+ |
+ var http = new XMLHttpRequest(); |
+ http.open('GET', |
+ root + '?delimiter=/&prefix=' + path + markerParam, |
+ true); |
+ http.onreadystatechange = useHttpResponse; |
+ http.send(null); |
+ function useHttpResponse() { |
+ if (http.readyState == 4) { |
+ var xmlstring = http.responseText; |
+ xmlstrings.push(xmlstring); |
+ |
+ // Check if the data is truncated. if so, we need to request the |
+ // rest. |
+ var parser = new DOMParser(); |
+ var xmlDoc = parser.parseFromString(xmlstring, 'text/xml'); |
+ |
+ // Get the main element. |
+ var results = xmlDoc.getElementsByTagName('ListBucketResult'); |
+ |
+ // Get IsTruncated. |
+ var truncated = getNodeValue(results[0], 'IsTruncated'); |
+ var nextMarker = ''; |
+ if (truncated == 'true') { |
+ nextMarker = getNodeValue(results[0], 'NextMarker'); |
+ fetchAndDisplay(nextMarker); |
+ } else { |
+ displayList(xmlstrings, root, path, pathRoot); |
+ } |
+ } |
+ } |
+ } |
+ |
+ fetchAndDisplay(''); |
+ </script> |
+ </body> |
+</html> |