Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <ry@tinyclouds.org>2009-05-18 21:33:05 +0400
committerRyan <ry@tinyclouds.org>2009-05-18 21:33:05 +0400
commitedc38b4134e362138a505f2999d8049b735bd9f2 (patch)
treedb756ca7b66e3fdec661b685bf2a1149508288c5 /website
parent9c70bf356be1a66d0abf70662f2894a97f7ad148 (diff)
Use parseUri() for req.uri. Update docs.
Diffstat (limited to 'website')
-rw-r--r--website/node.html143
-rw-r--r--website/sh_main.js545
-rw-r--r--website/sh_vim-dark.css4
3 files changed, 636 insertions, 56 deletions
diff --git a/website/node.html b/website/node.html
index 4c9ff9d7b07..71cfa866ba0 100644
--- a/website/node.html
+++ b/website/node.html
@@ -68,7 +68,7 @@ a:hover { text-decoration: underline; }
}
</style>
-<script type="text/javascript" src="sh_main.min.js"></script>
+<script type="text/javascript" src="sh_main.js"></script>
<script type="text/javascript" src="sh_javascript.min.js"></script>
<link type="text/css" rel="stylesheet" href="sh_vim-dark.css">
@@ -84,10 +84,12 @@ a:hover { text-decoration: underline; }
<ol>
<li><a href="#timers">Timers</a>
<li><a href="#files">File System</a>
- <li><a href="#tcp">TCP</a>
- <li><a href="#http">HTTP</a>
+ <li><a href="#tcp">tcp</a>
+ <li><a href="#http">http</a>
<ol>
<li><a href="#http_server">Server</a>
+ <li><a href="#http_server_request">ServerRequest</a>
+ <li><a href="#http_server_response">ServerResponse</a>
<li><a href="#http_client">Client</a>
</ol>
<li><a href="#modules">Modules</a>
@@ -99,11 +101,12 @@ a:hover { text-decoration: underline; }
<h1><a href="http://tinyclouds.org/node">Node</a></h1>
-<p id="introduction"> Node is a purely asynchronous I/O framework for <a
+<p id="introduction"> Purely asynchronous I/O for <a
href="http://code.google.com/p/v8/">V8 javascript</a>.
-<p>This is an example of a web server written with Node which listens on
-port 8000 and responds with "Hello World" after waiting two seconds:
+<p>This is an example of a web server written with Node which responds with
+"Hello World" after waiting two seconds:
+
<pre class="sh_javascript">new node.http.Server(function (req, res) {
setTimeout(function () {
res.sendHeader(200, [["Content-Type", "text/plain"]]);
@@ -111,7 +114,20 @@ port 8000 and responds with "Hello World" after waiting two seconds:
res.finish();
}, 2000);
}).listen(8000);
-</pre>
+puts("Server running at http://127.0.0.1:8000/");</pre>
+
+<p> Execution does not block on <code
+class="sh_javascript">setTimeout()</code>
+nor
+<code
+class="sh_javascript">listen(8000)</code>.
+File I/O is also preformed without blocking.
+In fact, not a single function in Node blocks execution.
+There isn't even a call to run the event loop.
+
+<p> Programmers using this environment will find it difficult to design
+their systems ineffiencely. It's impossible to make a database call from a
+web server and block other requests.
<p> Check out <a href="#api">the API documentation</a> for more examples.
@@ -224,26 +240,35 @@ See <a
<h3 id="files">File System</h3>
-<h3 id="tcp">TCP</h3>
+<h3 id="tcp"><code>node.tcp</code></h3>
-<h3 id="http">HTTP (<code class="sh_javascript">node.http</code>)</h3>
+<h3 id="http"><code>node.http</code></h3>
<p> Node provides a web server and client interface. The interface is rather
low-level but complete. For example, it does not parse
<code class="sh_javascript">application/x-www-form-urlencoded</code> message bodies. The interface
does abstract the Transfer-Encoding (i.e. chuncked or identity), Message
-boundarys, and Keep-Alive connections.
+boundaries, and Keep-Alive connections.
+
+<h4 id="http_server"><code class="sh_javascript">node.http.Server</code></h4>
-<h4 id="http_server">HTTP Server (<code class="sh_javascript">node.http.Server</code>)</h4>
<dl>
- <dt><code class="sh_javascript">new Server(request_handler, options)</code></dt>
+ <dt><code class="sh_javascript">var server = new node.http.Server(request_handler, options);</code></dt>
<dd>
- <p>Creates a new web server. The <code class="sh_javascript">options</code> argument accepts
- the same values as the options argument for
- <code class="sh_javascript">node.tcp.Server</code> does. The options argument is optional.
+ <p>Creates a new web server.
+
+ <p>
+ The <code>options</code> argument is optional.
+ The <code
+ class="sh_javascript">options</code> argument accepts the same values
+ as the options argument for <code
+ class="sh_javascript">node.tcp.Server</code> does.
+
+ <p>The <code class="sh_javascript">request_handler</code> is a
+ callback which is made on each request with a
+ <code>ServerRequest</code> and
+ <code>ServerResponse</code> arguments.
- <p>The <code class="sh_javascript">request_handler</code> is a function which is called on
- each request with a <code class="sh_javascript">Message</code> object argument.
</dd>
<dt><code class="sh_javascript">server.listen(port, hostname)</code>
@@ -261,26 +286,37 @@ boundarys, and Keep-Alive connections.
</dl>
-<h4>HTTP Request Message (<code class="sh_javascript">node.http.Message</code>)</h4>
+<h4 id="http_server_request"><code class="sh_javascript">node.http.ServerRequest</code></h4>
-<p> This object is only created internally&mdash;not by the user. It is passed
-as an argument to the <code class="sh_javascript">request_handler</code> callback in a web server.
+<p> This object is created internally by a HTTP server&mdash;not by the user.
+It is passed as the first argument to the <code
+class="sh_javascript">request_handler</code> callback.
-<p> This object, unlike in other HTTP APIs, is used as an interface for both
-the request and response. Members and callbacks reference request data, like
-<code class="sh_javascript">msg.method</code> and <code class="sh_javascript">msg.onBody</code>. The methods are for
-sending a response to this message. Like <code class="sh_javascript">msg.sendHeader()</code> and
-<code class="sh_javascript">msg.sendBody()</code>.
<dl>
- <dt><code class="sh_javascript">msg.method</code>
+ <dt><code class="sh_javascript">req.method</code>
<dd>The request method as a string. Read only. Example: <code class="sh_javascript">"GET"</code>,
<code class="sh_javascript">"DELETE"</code>.</dd>
- <dt><code class="sh_javascript">msg.uri</code>
- <dd>The request URI as a string. Read only.
- Example: <code class="sh_javascript">"/index.html?hello=world"</code>.</dd>
-
- <dt><code class="sh_javascript">msg.headers</code>
+ <dt><code class="sh_javascript">req.uri</code>
+ <dd> URI object. Has many fields.
+ <dt><code>req.uri.toString()</code>
+ <dd> The original URI found in the status line.
+ <dt><code>req.uri.anchor</code>
+ <dt><code>req.uri.query</code>
+ <dt><code>req.uri.file</code>
+ <dt><code>req.uri.directory</code>
+ <dt><code>req.uri.path</code>
+ <dt><code>req.uri.relative</code>
+ <dt><code>req.uri.port</code>
+ <dt><code>req.uri.host</code>
+ <dt><code>req.uri.password</code>
+ <dt><code>req.uri.user</code>
+ <dt><code>req.uri.authority</code>
+ <dt><code>req.uri.protocol</code>
+ <dt><code>req.uri.source</code>
+ <dt><code>req.uri.queryKey</code>
+
+ <dt><code class="sh_javascript">req.headers</code>
<dd>The request headers expressed as an array of 2-element arrays. Read only.
Example:
<pre class="sh_javascript">
@@ -291,40 +327,41 @@ sending a response to this message. Like <code class="sh_javascript">msg.sendHea
]
</pre>
- <dt><code class="sh_javascript">msg.http_version</code></dt>
+ <dt><code class="sh_javascript">req.http_version</code></dt>
<dd>The HTTP protocol version as a string. Read only. Examples: <code class="sh_javascript">"1.1"</code>,
<code class="sh_javascript">"1.0"</code>
- <dt><code class="sh_javascript">msg.connection</code></dt>
- <dd> A reference to the <code class="sh_javascript">node.tcp.Connection</code> object. Read
- only. Note that multiple messages can be sent on a single connection.
- </dd>
-
- <dt><code class="sh_javascript">msg.onBody</code></dt>
+ <dt><code class="sh_javascript">req.onBody</code></dt>
<dd>Callback. Should be set by the user to be informed of when a piece
of the message body is received. Example:
<pre class="sh_javascript">
-msg.onBody = function (chunk) {
+req.onBody = function (chunk) {
puts("part of the body: " + chunk);
-}
+};
</pre>
A chunk of the body is given as the single argument. The transfer-encoding
has been removed.
- <p>The body chunk is either a String in the case of utf8 encoding or an
- array of numbers in the case of raw encoding.
- <dt><code class="sh_javascript">msg.onBodyComplete</code></dt>
+ <p>The body chunk is either a String in the case of UTF-8 encoding or an
+ array of numbers in the case of raw encoding. The body encoding is set with
+ <code class="sh_javascript">req.setBodyEncoding()</code>.
+
+ <dt><code class="sh_javascript">req.onBodyComplete</code></dt>
<dd>Callback. Made exactly once for each message. No arguments. After
<code class="sh_javascript">onBodyComplete</code> is executed <code class="sh_javascript">onBody</code> will no longer be called.
</dd>
- <dt><code class="sh_javascript">msg.setBodyEncoding(encoding)</code></dt>
+ <dt><code class="sh_javascript">req.setBodyEncoding(encoding)</code></dt>
<dd>
Set the encoding for the request body. Either <code class="sh_javascript">"utf8"</code> or
<code class="sh_javascript">"raw"</code>. Defaults to raw.
<big>TODO</big>
+</dl>
- <dt><code class="sh_javascript">msg.sendHeader(status_code, headers)</code></dt>
+<h4 id="http_server_response"><code class="sh_javascript">node.http.ServerResponse</code></h4>
+
+<dl>
+ <dt><code class="sh_javascript">res.sendHeader(status_code, headers)</code></dt>
<dd>
Sends a response header to the request. The status code is a 3-digit
HTTP status code, like <code class="sh_javascript">404</code>. The second argument,
@@ -334,28 +371,26 @@ msg.onBody = function (chunk) {
<p>Example:
<pre class="sh_javascript">
var body = "hello world";
-msg.sendHeader( 200
- , [ ["Content-Length", body.length]
- , ["Content-Type", "text/plain"]
- ]
- );
+res.sendHeader(200, [ ["Content-Length", body.length]
+ , ["Content-Type", "text/plain"]
+ ]);
</pre>
This method must only be called once on a message and it must be called
- before <code class="sh_javascript">msg.finish()</code> is called.
+ before <code class="sh_javascript">res.finish()</code> is called.
</dd>
- <dt><code class="sh_javascript">msg.sendBody(chunk)</code></dt>
+ <dt><code class="sh_javascript">res.sendBody(chunk)</code></dt>
<dd>
This method must be called after <code class="sh_javascript">sendHeader</code> was called. It
sends a chunk of the response body. This method may be called multiple
times to provide successive parts of the body.
</dd>
- <dt><code class="sh_javascript">msg.finish()</code></dt>
+ <dt><code class="sh_javascript">res.finish()</code></dt>
<dd>
This method signals that all of the response headers and body has been
sent; that server should consider this message complete.
- The method, <code class="sh_javascript">msg.finish()</code>, MUST be called on each response.
+ The method, <code class="sh_javascript">res.finish()</code>, MUST be called on each response.
</dl>
diff --git a/website/sh_main.js b/website/sh_main.js
new file mode 100644
index 00000000000..87182662c27
--- /dev/null
+++ b/website/sh_main.js
@@ -0,0 +1,545 @@
+/*
+SHJS - Syntax Highlighting in JavaScript
+Copyright (C) 2007, 2008 gnombat@users.sourceforge.net
+License: http://shjs.sourceforge.net/doc/gplv3.html
+*/
+
+if (! this.sh_languages) {
+ this.sh_languages = {};
+}
+var sh_requests = {};
+
+function sh_isEmailAddress(url) {
+ if (/^mailto:/.test(url)) {
+ return false;
+ }
+ return url.indexOf('@') !== -1;
+}
+
+function sh_setHref(tags, numTags, inputString) {
+ var url = inputString.substring(tags[numTags - 2].pos, tags[numTags - 1].pos);
+ if (url.length >= 2 && url.charAt(0) === '<' && url.charAt(url.length - 1) === '>') {
+ url = url.substr(1, url.length - 2);
+ }
+ if (sh_isEmailAddress(url)) {
+ url = 'mailto:' + url;
+ }
+ tags[numTags - 2].node.href = url;
+}
+
+/*
+Konqueror has a bug where the regular expression /$/g will not match at the end
+of a line more than once:
+
+ var regex = /$/g;
+ var match;
+
+ var line = '1234567890';
+ regex.lastIndex = 10;
+ match = regex.exec(line);
+
+ var line2 = 'abcde';
+ regex.lastIndex = 5;
+ match = regex.exec(line2); // fails
+*/
+function sh_konquerorExec(s) {
+ var result = [''];
+ result.index = s.length;
+ result.input = s;
+ return result;
+}
+
+/**
+Highlights all elements containing source code in a text string. The return
+value is an array of objects, each representing an HTML start or end tag. Each
+object has a property named pos, which is an integer representing the text
+offset of the tag. Every start tag also has a property named node, which is the
+DOM element started by the tag. End tags do not have this property.
+@param inputString a text string
+@param language a language definition object
+@return an array of tag objects
+*/
+function sh_highlightString(inputString, language) {
+ if (/Konqueror/.test(navigator.userAgent)) {
+ if (! language.konquered) {
+ for (var s = 0; s < language.length; s++) {
+ for (var p = 0; p < language[s].length; p++) {
+ var r = language[s][p][0];
+ if (r.source === '$') {
+ r.exec = sh_konquerorExec;
+ }
+ }
+ }
+ language.konquered = true;
+ }
+ }
+
+ var a = document.createElement('a');
+ var span = document.createElement('span');
+
+ // the result
+ var tags = [];
+ var numTags = 0;
+
+ // each element is a pattern object from language
+ var patternStack = [];
+
+ // the current position within inputString
+ var pos = 0;
+
+ // the name of the current style, or null if there is no current style
+ var currentStyle = null;
+
+ var output = function(s, style) {
+ var length = s.length;
+ // this is more than just an optimization - we don't want to output empty <span></span> elements
+ if (length === 0) {
+ return;
+ }
+ if (! style) {
+ var stackLength = patternStack.length;
+ if (stackLength !== 0) {
+ var pattern = patternStack[stackLength - 1];
+ // check whether this is a state or an environment
+ if (! pattern[3]) {
+ // it's not a state - it's an environment; use the style for this environment
+ style = pattern[1];
+ }
+ }
+ }
+ if (currentStyle !== style) {
+ if (currentStyle) {
+ tags[numTags++] = {pos: pos};
+ if (currentStyle === 'sh_url') {
+ sh_setHref(tags, numTags, inputString);
+ }
+ }
+ if (style) {
+ var clone;
+ if (style === 'sh_url') {
+ clone = a.cloneNode(false);
+ }
+ else {
+ clone = span.cloneNode(false);
+ }
+ clone.className = style;
+ tags[numTags++] = {node: clone, pos: pos};
+ }
+ }
+ pos += length;
+ currentStyle = style;
+ };
+
+ var endOfLinePattern = /\r\n|\r|\n/g;
+ endOfLinePattern.lastIndex = 0;
+ var inputStringLength = inputString.length;
+ while (pos < inputStringLength) {
+ var start = pos;
+ var end;
+ var startOfNextLine;
+ var endOfLineMatch = endOfLinePattern.exec(inputString);
+ if (endOfLineMatch === null) {
+ end = inputStringLength;
+ startOfNextLine = inputStringLength;
+ }
+ else {
+ end = endOfLineMatch.index;
+ startOfNextLine = endOfLinePattern.lastIndex;
+ }
+
+ var line = inputString.substring(start, end);
+
+ var matchCache = [];
+ for (;;) {
+ var posWithinLine = pos - start;
+
+ var stateIndex;
+ var stackLength = patternStack.length;
+ if (stackLength === 0) {
+ stateIndex = 0;
+ }
+ else {
+ // get the next state
+ stateIndex = patternStack[stackLength - 1][2];
+ }
+
+ var state = language[stateIndex];
+ var numPatterns = state.length;
+ var mc = matchCache[stateIndex];
+ if (! mc) {
+ mc = matchCache[stateIndex] = [];
+ }
+ var bestMatch = null;
+ var bestPatternIndex = -1;
+ for (var i = 0; i < numPatterns; i++) {
+ var match;
+ if (i < mc.length && (mc[i] === null || posWithinLine <= mc[i].index)) {
+ match = mc[i];
+ }
+ else {
+ var regex = state[i][0];
+ regex.lastIndex = posWithinLine;
+ match = regex.exec(line);
+ mc[i] = match;
+ }
+ if (match !== null && (bestMatch === null || match.index < bestMatch.index)) {
+ bestMatch = match;
+ bestPatternIndex = i;
+ if (match.index === posWithinLine) {
+ break;
+ }
+ }
+ }
+
+ if (bestMatch === null) {
+ output(line.substring(posWithinLine), null);
+ break;
+ }
+ else {
+ // got a match
+ if (bestMatch.index > posWithinLine) {
+ output(line.substring(posWithinLine, bestMatch.index), null);
+ }
+
+ var pattern = state[bestPatternIndex];
+
+ var newStyle = pattern[1];
+ var matchedString;
+ if (newStyle instanceof Array) {
+ for (var subexpression = 0; subexpression < newStyle.length; subexpression++) {
+ matchedString = bestMatch[subexpression + 1];
+ output(matchedString, newStyle[subexpression]);
+ }
+ }
+ else {
+ matchedString = bestMatch[0];
+ output(matchedString, newStyle);
+ }
+
+ switch (pattern[2]) {
+ case -1:
+ // do nothing
+ break;
+ case -2:
+ // exit
+ patternStack.pop();
+ break;
+ case -3:
+ // exitall
+ patternStack.length = 0;
+ break;
+ default:
+ // this was the start of a delimited pattern or a state/environment
+ patternStack.push(pattern);
+ break;
+ }
+ }
+ }
+
+ // end of the line
+ if (currentStyle) {
+ tags[numTags++] = {pos: pos};
+ if (currentStyle === 'sh_url') {
+ sh_setHref(tags, numTags, inputString);
+ }
+ currentStyle = null;
+ }
+ pos = startOfNextLine;
+ }
+
+ return tags;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DOM-dependent functions
+
+function sh_getClasses(element) {
+ var result = [];
+ var htmlClass = element.className;
+ if (htmlClass && htmlClass.length > 0) {
+ var htmlClasses = htmlClass.split(' ');
+ for (var i = 0; i < htmlClasses.length; i++) {
+ if (htmlClasses[i].length > 0) {
+ result.push(htmlClasses[i]);
+ }
+ }
+ }
+ return result;
+}
+
+function sh_addClass(element, name) {
+ var htmlClasses = sh_getClasses(element);
+ for (var i = 0; i < htmlClasses.length; i++) {
+ if (name.toLowerCase() === htmlClasses[i].toLowerCase()) {
+ return;
+ }
+ }
+ htmlClasses.push(name);
+ element.className = htmlClasses.join(' ');
+}
+
+/**
+Extracts the tags from an HTML DOM NodeList.
+@param nodeList a DOM NodeList
+@param result an object with text, tags and pos properties
+*/
+function sh_extractTagsFromNodeList(nodeList, result) {
+ var length = nodeList.length;
+ for (var i = 0; i < length; i++) {
+ var node = nodeList.item(i);
+ switch (node.nodeType) {
+ case 1:
+ if (node.nodeName.toLowerCase() === 'br') {
+ var terminator;
+ if (/MSIE/.test(navigator.userAgent)) {
+ terminator = '\r';
+ }
+ else {
+ terminator = '\n';
+ }
+ result.text.push(terminator);
+ result.pos++;
+ }
+ else {
+ result.tags.push({node: node.cloneNode(false), pos: result.pos});
+ sh_extractTagsFromNodeList(node.childNodes, result);
+ result.tags.push({pos: result.pos});
+ }
+ break;
+ case 3:
+ case 4:
+ result.text.push(node.data);
+ result.pos += node.length;
+ break;
+ }
+ }
+}
+
+/**
+Extracts the tags from the text of an HTML element. The extracted tags will be
+returned as an array of tag objects. See sh_highlightString for the format of
+the tag objects.
+@param element a DOM element
+@param tags an empty array; the extracted tag objects will be returned in it
+@return the text of the element
+@see sh_highlightString
+*/
+function sh_extractTags(element, tags) {
+ var result = {};
+ result.text = [];
+ result.tags = tags;
+ result.pos = 0;
+ sh_extractTagsFromNodeList(element.childNodes, result);
+ return result.text.join('');
+}
+
+/**
+Merges the original tags from an element with the tags produced by highlighting.
+@param originalTags an array containing the original tags
+@param highlightTags an array containing the highlighting tags - these must not overlap
+@result an array containing the merged tags
+*/
+function sh_mergeTags(originalTags, highlightTags) {
+ var numOriginalTags = originalTags.length;
+ if (numOriginalTags === 0) {
+ return highlightTags;
+ }
+
+ var numHighlightTags = highlightTags.length;
+ if (numHighlightTags === 0) {
+ return originalTags;
+ }
+
+ var result = [];
+ var originalIndex = 0;
+ var highlightIndex = 0;
+
+ while (originalIndex < numOriginalTags && highlightIndex < numHighlightTags) {
+ var originalTag = originalTags[originalIndex];
+ var highlightTag = highlightTags[highlightIndex];
+
+ if (originalTag.pos <= highlightTag.pos) {
+ result.push(originalTag);
+ originalIndex++;
+ }
+ else {
+ result.push(highlightTag);
+ if (highlightTags[highlightIndex + 1].pos <= originalTag.pos) {
+ highlightIndex++;
+ result.push(highlightTags[highlightIndex]);
+ highlightIndex++;
+ }
+ else {
+ // new end tag
+ result.push({pos: originalTag.pos});
+
+ // new start tag
+ highlightTags[highlightIndex] = {node: highlightTag.node.cloneNode(false), pos: originalTag.pos};
+ }
+ }
+ }
+
+ while (originalIndex < numOriginalTags) {
+ result.push(originalTags[originalIndex]);
+ originalIndex++;
+ }
+
+ while (highlightIndex < numHighlightTags) {
+ result.push(highlightTags[highlightIndex]);
+ highlightIndex++;
+ }
+
+ return result;
+}
+
+/**
+Inserts tags into text.
+@param tags an array of tag objects
+@param text a string representing the text
+@return a DOM DocumentFragment representing the resulting HTML
+*/
+function sh_insertTags(tags, text) {
+ var doc = document;
+
+ var result = document.createDocumentFragment();
+ var tagIndex = 0;
+ var numTags = tags.length;
+ var textPos = 0;
+ var textLength = text.length;
+ var currentNode = result;
+
+ // output one tag or text node every iteration
+ while (textPos < textLength || tagIndex < numTags) {
+ var tag;
+ var tagPos;
+ if (tagIndex < numTags) {
+ tag = tags[tagIndex];
+ tagPos = tag.pos;
+ }
+ else {
+ tagPos = textLength;
+ }
+
+ if (tagPos <= textPos) {
+ // output the tag
+ if (tag.node) {
+ // start tag
+ var newNode = tag.node;
+ currentNode.appendChild(newNode);
+ currentNode = newNode;
+ }
+ else {
+ // end tag
+ currentNode = currentNode.parentNode;
+ }
+ tagIndex++;
+ }
+ else {
+ // output text
+ currentNode.appendChild(doc.createTextNode(text.substring(textPos, tagPos)));
+ textPos = tagPos;
+ }
+ }
+
+ return result;
+}
+
+/**
+Highlights an element containing source code. Upon completion of this function,
+the element will have been placed in the "sh_sourceCode" class.
+@param element a DOM <pre> element containing the source code to be highlighted
+@param language a language definition object
+*/
+function sh_highlightElement(element, language) {
+ sh_addClass(element, 'sh_sourceCode');
+ var originalTags = [];
+ var inputString = sh_extractTags(element, originalTags);
+ var highlightTags = sh_highlightString(inputString, language);
+ var tags = sh_mergeTags(originalTags, highlightTags);
+ var documentFragment = sh_insertTags(tags, inputString);
+ while (element.hasChildNodes()) {
+ element.removeChild(element.firstChild);
+ }
+ element.appendChild(documentFragment);
+}
+
+function sh_getXMLHttpRequest() {
+ if (window.ActiveXObject) {
+ return new ActiveXObject('Msxml2.XMLHTTP');
+ }
+ else if (window.XMLHttpRequest) {
+ return new XMLHttpRequest();
+ }
+ throw 'No XMLHttpRequest implementation available';
+}
+
+function sh_load(language, element, prefix, suffix) {
+ if (language in sh_requests) {
+ sh_requests[language].push(element);
+ return;
+ }
+ sh_requests[language] = [element];
+ var request = sh_getXMLHttpRequest();
+ var url = prefix + 'sh_' + language + suffix;
+ request.open('GET', url, true);
+ request.onreadystatechange = function () {
+ if (request.readyState === 4) {
+ try {
+ if (! request.status || request.status === 200) {
+ eval(request.responseText);
+ var elements = sh_requests[language];
+ for (var i = 0; i < elements.length; i++) {
+ sh_highlightElement(elements[i], sh_languages[language]);
+ }
+ }
+ else {
+ throw 'HTTP error: status ' + request.status;
+ }
+ }
+ finally {
+ request = null;
+ }
+ }
+ };
+ request.send(null);
+}
+
+/**
+Highlights all elements containing source code on the current page. Elements
+containing source code must be "pre" elements with a "class" attribute of
+"sh_LANGUAGE", where LANGUAGE is a valid language identifier; e.g., "sh_java"
+identifies the element as containing "java" language source code.
+*/
+function highlight(prefix, suffix, tag) {
+ var nodeList = document.getElementsByTagName(tag);
+ for (var i = 0; i < nodeList.length; i++) {
+ var element = nodeList.item(i);
+ var htmlClasses = sh_getClasses(element);
+ for (var j = 0; j < htmlClasses.length; j++) {
+ var htmlClass = htmlClasses[j].toLowerCase();
+ if (htmlClass === 'sh_sourcecode') {
+ continue;
+ }
+ if (htmlClass.substr(0, 3) === 'sh_') {
+ var language = htmlClass.substring(3);
+ if (language in sh_languages) {
+ sh_highlightElement(element, sh_languages[language]);
+ }
+ else if (typeof(prefix) === 'string' && typeof(suffix) === 'string') {
+ sh_load(language, element, prefix, suffix);
+ }
+ else {
+ throw 'Found <' + tag + '> element with class="' + htmlClass + '", but no such language exists';
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+
+function sh_highlightDocument(prefix, suffix) {
+ highlight(prefix, suffix, 'code');
+ highlight(prefix, suffix, 'pre');
+}
diff --git a/website/sh_vim-dark.css b/website/sh_vim-dark.css
index 74d7cefb7b9..ae1d75c4ad8 100644
--- a/website/sh_vim-dark.css
+++ b/website/sh_vim-dark.css
@@ -4,7 +4,7 @@
font-style: normal;
}
-.sh_sourceCode .sh_symbol , pre.sh_sourceCode .sh_cbracket {
+.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket {
color: #bbd;
}
@@ -12,7 +12,7 @@
font-style: italic;
}
-.sh_sourceCode .sh_string, pre.sh_sourceCode .sh_regexp, pre.sh_sourceCode .sh_number
+.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number
{
color: #daa;
}