You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2017/03/19 22:39:17 UTC
[30/52] [partial] incubator-guacamole-website git commit: Add
documentation for 0.9.12-incubating.
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/b8b84d96/doc/0.9.12-incubating/guacamole-common-js/Tunnel.js.html
----------------------------------------------------------------------
diff --git a/doc/0.9.12-incubating/guacamole-common-js/Tunnel.js.html b/doc/0.9.12-incubating/guacamole-common-js/Tunnel.js.html
new file mode 100644
index 0000000..f4530a2
--- /dev/null
+++ b/doc/0.9.12-incubating/guacamole-common-js/Tunnel.js.html
@@ -0,0 +1,1088 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Tunnel.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: Tunnel.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Core object providing abstract communication for Guacamole. This object
+ * is a null implementation whose functions do nothing. Guacamole applications
+ * should use {@link Guacamole.HTTPTunnel} instead, or implement their own tunnel based
+ * on this one.
+ *
+ * @constructor
+ * @see Guacamole.HTTPTunnel
+ */
+Guacamole.Tunnel = function() {
+
+ /**
+ * Connect to the tunnel with the given optional data. This data is
+ * typically used for authentication. The format of data accepted is
+ * up to the tunnel implementation.
+ *
+ * @param {String} data The data to send to the tunnel when connecting.
+ */
+ this.connect = function(data) {};
+
+ /**
+ * Disconnect from the tunnel.
+ */
+ this.disconnect = function() {};
+
+ /**
+ * Send the given message through the tunnel to the service on the other
+ * side. All messages are guaranteed to be received in the order sent.
+ *
+ * @param {...*} elements
+ * The elements of the message to send to the service on the other side
+ * of the tunnel.
+ */
+ this.sendMessage = function(elements) {};
+
+ /**
+ * The current state of this tunnel.
+ *
+ * @type {Number}
+ */
+ this.state = Guacamole.Tunnel.State.CONNECTING;
+
+ /**
+ * The maximum amount of time to wait for data to be received, in
+ * milliseconds. If data is not received within this amount of time,
+ * the tunnel is closed with an error. The default value is 15000.
+ *
+ * @type {Number}
+ */
+ this.receiveTimeout = 15000;
+
+ /**
+ * The UUID uniquely identifying this tunnel. If not yet known, this will
+ * be null.
+ *
+ * @type {String}
+ */
+ this.uuid = null;
+
+ /**
+ * Fired whenever an error is encountered by the tunnel.
+ *
+ * @event
+ * @param {Guacamole.Status} status A status object which describes the
+ * error.
+ */
+ this.onerror = null;
+
+ /**
+ * Fired whenever the state of the tunnel changes.
+ *
+ * @event
+ * @param {Number} state The new state of the client.
+ */
+ this.onstatechange = null;
+
+ /**
+ * Fired once for every complete Guacamole instruction received, in order.
+ *
+ * @event
+ * @param {String} opcode The Guacamole instruction opcode.
+ * @param {Array} parameters The parameters provided for the instruction,
+ * if any.
+ */
+ this.oninstruction = null;
+
+};
+
+/**
+ * The Guacamole protocol instruction opcode reserved for arbitrary internal
+ * use by tunnel implementations. The value of this opcode is guaranteed to be
+ * the empty string (""). Tunnel implementations may use this opcode for any
+ * purpose. It is currently used by the HTTP tunnel to mark the end of the HTTP
+ * response, and by the WebSocket tunnel to transmit the tunnel UUID.
+ *
+ * @constant
+ * @type {String}
+ */
+Guacamole.Tunnel.INTERNAL_DATA_OPCODE = '';
+
+/**
+ * All possible tunnel states.
+ */
+Guacamole.Tunnel.State = {
+
+ /**
+ * A connection is in pending. It is not yet known whether connection was
+ * successful.
+ *
+ * @type {Number}
+ */
+ "CONNECTING": 0,
+
+ /**
+ * Connection was successful, and data is being received.
+ *
+ * @type {Number}
+ */
+ "OPEN": 1,
+
+ /**
+ * The connection is closed. Connection may not have been successful, the
+ * tunnel may have been explicitly closed by either side, or an error may
+ * have occurred.
+ *
+ * @type {Number}
+ */
+ "CLOSED": 2
+
+};
+
+/**
+ * Guacamole Tunnel implemented over HTTP via XMLHttpRequest.
+ *
+ * @constructor
+ * @augments Guacamole.Tunnel
+ *
+ * @param {String} tunnelURL
+ * The URL of the HTTP tunneling service.
+ *
+ * @param {Boolean} [crossDomain=false]
+ * Whether tunnel requests will be cross-domain, and thus must use CORS
+ * mechanisms and headers. By default, it is assumed that tunnel requests
+ * will be made to the same domain.
+ */
+Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {
+
+ /**
+ * Reference to this HTTP tunnel.
+ * @private
+ */
+ var tunnel = this;
+
+ var TUNNEL_CONNECT = tunnelURL + "?connect";
+ var TUNNEL_READ = tunnelURL + "?read:";
+ var TUNNEL_WRITE = tunnelURL + "?write:";
+
+ var POLLING_ENABLED = 1;
+ var POLLING_DISABLED = 0;
+
+ // Default to polling - will be turned off automatically if not needed
+ var pollingMode = POLLING_ENABLED;
+
+ var sendingMessages = false;
+ var outputMessageBuffer = "";
+
+ // If requests are expected to be cross-domain, the cookie that the HTTP
+ // tunnel depends on will only be sent if withCredentials is true
+ var withCredentials = !!crossDomain;
+
+ /**
+ * The current receive timeout ID, if any.
+ * @private
+ */
+ var receive_timeout = null;
+
+ /**
+ * Initiates a timeout which, if data is not received, causes the tunnel
+ * to close with an error.
+ *
+ * @private
+ */
+ function reset_timeout() {
+
+ // Get rid of old timeout (if any)
+ window.clearTimeout(receive_timeout);
+
+ // Set new timeout
+ receive_timeout = window.setTimeout(function () {
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
+ }, tunnel.receiveTimeout);
+
+ }
+
+ /**
+ * Closes this tunnel, signaling the given status and corresponding
+ * message, which will be sent to the onerror handler if the status is
+ * an error status.
+ *
+ * @private
+ * @param {Guacamole.Status} status The status causing the connection to
+ * close;
+ */
+ function close_tunnel(status) {
+
+ // Ignore if already closed
+ if (tunnel.state === Guacamole.Tunnel.State.CLOSED)
+ return;
+
+ // If connection closed abnormally, signal error.
+ if (status.code !== Guacamole.Status.Code.SUCCESS && tunnel.onerror) {
+
+ // Ignore RESOURCE_NOT_FOUND if we've already connected, as that
+ // only signals end-of-stream for the HTTP tunnel.
+ if (tunnel.state === Guacamole.Tunnel.State.CONNECTING
+ || status.code !== Guacamole.Status.Code.RESOURCE_NOT_FOUND)
+ tunnel.onerror(status);
+
+ }
+
+ // Mark as closed
+ tunnel.state = Guacamole.Tunnel.State.CLOSED;
+
+ // Reset output message buffer
+ sendingMessages = false;
+
+ if (tunnel.onstatechange)
+ tunnel.onstatechange(tunnel.state);
+
+ }
+
+
+ this.sendMessage = function() {
+
+ // Do not attempt to send messages if not connected
+ if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
+ return;
+
+ // Do not attempt to send empty messages
+ if (arguments.length === 0)
+ return;
+
+ /**
+ * Converts the given value to a length/string pair for use as an
+ * element in a Guacamole instruction.
+ *
+ * @private
+ * @param value The value to convert.
+ * @return {String} The converted value.
+ */
+ function getElement(value) {
+ var string = new String(value);
+ return string.length + "." + string;
+ }
+
+ // Initialized message with first element
+ var message = getElement(arguments[0]);
+
+ // Append remaining elements
+ for (var i=1; i<arguments.length; i++)
+ message += "," + getElement(arguments[i]);
+
+ // Final terminator
+ message += ";";
+
+ // Add message to buffer
+ outputMessageBuffer += message;
+
+ // Send if not currently sending
+ if (!sendingMessages)
+ sendPendingMessages();
+
+ };
+
+ function sendPendingMessages() {
+
+ // Do not attempt to send messages if not connected
+ if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
+ return;
+
+ if (outputMessageBuffer.length > 0) {
+
+ sendingMessages = true;
+
+ var message_xmlhttprequest = new XMLHttpRequest();
+ message_xmlhttprequest.open("POST", TUNNEL_WRITE + tunnel.uuid);
+ message_xmlhttprequest.withCredentials = withCredentials;
+ message_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
+
+ // Once response received, send next queued event.
+ message_xmlhttprequest.onreadystatechange = function() {
+ if (message_xmlhttprequest.readyState === 4) {
+
+ // If an error occurs during send, handle it
+ if (message_xmlhttprequest.status !== 200)
+ handleHTTPTunnelError(message_xmlhttprequest);
+
+ // Otherwise, continue the send loop
+ else
+ sendPendingMessages();
+
+ }
+ };
+
+ message_xmlhttprequest.send(outputMessageBuffer);
+ outputMessageBuffer = ""; // Clear buffer
+
+ }
+ else
+ sendingMessages = false;
+
+ }
+
+ function handleHTTPTunnelError(xmlhttprequest) {
+
+ var code = parseInt(xmlhttprequest.getResponseHeader("Guacamole-Status-Code"));
+ var message = xmlhttprequest.getResponseHeader("Guacamole-Error-Message");
+
+ close_tunnel(new Guacamole.Status(code, message));
+
+ }
+
+ function handleResponse(xmlhttprequest) {
+
+ var interval = null;
+ var nextRequest = null;
+
+ var dataUpdateEvents = 0;
+
+ // The location of the last element's terminator
+ var elementEnd = -1;
+
+ // Where to start the next length search or the next element
+ var startIndex = 0;
+
+ // Parsed elements
+ var elements = new Array();
+
+ function parseResponse() {
+
+ // Do not handle responses if not connected
+ if (tunnel.state !== Guacamole.Tunnel.State.OPEN) {
+
+ // Clean up interval if polling
+ if (interval !== null)
+ clearInterval(interval);
+
+ return;
+ }
+
+ // Do not parse response yet if not ready
+ if (xmlhttprequest.readyState < 2) return;
+
+ // Attempt to read status
+ var status;
+ try { status = xmlhttprequest.status; }
+
+ // If status could not be read, assume successful.
+ catch (e) { status = 200; }
+
+ // Start next request as soon as possible IF request was successful
+ if (!nextRequest && status === 200)
+ nextRequest = makeRequest();
+
+ // Parse stream when data is received and when complete.
+ if (xmlhttprequest.readyState === 3 ||
+ xmlhttprequest.readyState === 4) {
+
+ reset_timeout();
+
+ // Also poll every 30ms (some browsers don't repeatedly call onreadystatechange for new data)
+ if (pollingMode === POLLING_ENABLED) {
+ if (xmlhttprequest.readyState === 3 && !interval)
+ interval = setInterval(parseResponse, 30);
+ else if (xmlhttprequest.readyState === 4 && !interval)
+ clearInterval(interval);
+ }
+
+ // If canceled, stop transfer
+ if (xmlhttprequest.status === 0) {
+ tunnel.disconnect();
+ return;
+ }
+
+ // Halt on error during request
+ else if (xmlhttprequest.status !== 200) {
+ handleHTTPTunnelError(xmlhttprequest);
+ return;
+ }
+
+ // Attempt to read in-progress data
+ var current;
+ try { current = xmlhttprequest.responseText; }
+
+ // Do not attempt to parse if data could not be read
+ catch (e) { return; }
+
+ // While search is within currently received data
+ while (elementEnd < current.length) {
+
+ // If we are waiting for element data
+ if (elementEnd >= startIndex) {
+
+ // We now have enough data for the element. Parse.
+ var element = current.substring(startIndex, elementEnd);
+ var terminator = current.substring(elementEnd, elementEnd+1);
+
+ // Add element to array
+ elements.push(element);
+
+ // If last element, handle instruction
+ if (terminator === ";") {
+
+ // Get opcode
+ var opcode = elements.shift();
+
+ // Call instruction handler.
+ if (tunnel.oninstruction)
+ tunnel.oninstruction(opcode, elements);
+
+ // Clear elements
+ elements.length = 0;
+
+ }
+
+ // Start searching for length at character after
+ // element terminator
+ startIndex = elementEnd + 1;
+
+ }
+
+ // Search for end of length
+ var lengthEnd = current.indexOf(".", startIndex);
+ if (lengthEnd !== -1) {
+
+ // Parse length
+ var length = parseInt(current.substring(elementEnd+1, lengthEnd));
+
+ // If we're done parsing, handle the next response.
+ if (length === 0) {
+
+ // Clean up interval if polling
+ if (!interval)
+ clearInterval(interval);
+
+ // Clean up object
+ xmlhttprequest.onreadystatechange = null;
+ xmlhttprequest.abort();
+
+ // Start handling next request
+ if (nextRequest)
+ handleResponse(nextRequest);
+
+ // Done parsing
+ break;
+
+ }
+
+ // Calculate start of element
+ startIndex = lengthEnd + 1;
+
+ // Calculate location of element terminator
+ elementEnd = startIndex + length;
+
+ }
+
+ // If no period yet, continue search when more data
+ // is received
+ else {
+ startIndex = current.length;
+ break;
+ }
+
+ } // end parse loop
+
+ }
+
+ }
+
+ // If response polling enabled, attempt to detect if still
+ // necessary (via wrapping parseResponse())
+ if (pollingMode === POLLING_ENABLED) {
+ xmlhttprequest.onreadystatechange = function() {
+
+ // If we receive two or more readyState==3 events,
+ // there is no need to poll.
+ if (xmlhttprequest.readyState === 3) {
+ dataUpdateEvents++;
+ if (dataUpdateEvents >= 2) {
+ pollingMode = POLLING_DISABLED;
+ xmlhttprequest.onreadystatechange = parseResponse;
+ }
+ }
+
+ parseResponse();
+ };
+ }
+
+ // Otherwise, just parse
+ else
+ xmlhttprequest.onreadystatechange = parseResponse;
+
+ parseResponse();
+
+ }
+
+ /**
+ * Arbitrary integer, unique for each tunnel read request.
+ * @private
+ */
+ var request_id = 0;
+
+ function makeRequest() {
+
+ // Make request, increment request ID
+ var xmlhttprequest = new XMLHttpRequest();
+ xmlhttprequest.open("GET", TUNNEL_READ + tunnel.uuid + ":" + (request_id++));
+ xmlhttprequest.withCredentials = withCredentials;
+ xmlhttprequest.send(null);
+
+ return xmlhttprequest;
+
+ }
+
+ this.connect = function(data) {
+
+ // Start waiting for connect
+ reset_timeout();
+
+ // Start tunnel and connect
+ var connect_xmlhttprequest = new XMLHttpRequest();
+ connect_xmlhttprequest.onreadystatechange = function() {
+
+ if (connect_xmlhttprequest.readyState !== 4)
+ return;
+
+ // If failure, throw error
+ if (connect_xmlhttprequest.status !== 200) {
+ handleHTTPTunnelError(connect_xmlhttprequest);
+ return;
+ }
+
+ reset_timeout();
+
+ // Get UUID from response
+ tunnel.uuid = connect_xmlhttprequest.responseText;
+
+ tunnel.state = Guacamole.Tunnel.State.OPEN;
+ if (tunnel.onstatechange)
+ tunnel.onstatechange(tunnel.state);
+
+ // Start reading data
+ handleResponse(makeRequest());
+
+ };
+
+ connect_xmlhttprequest.open("POST", TUNNEL_CONNECT, true);
+ connect_xmlhttprequest.withCredentials = withCredentials;
+ connect_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
+ connect_xmlhttprequest.send(data);
+
+ };
+
+ this.disconnect = function() {
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, "Manually closed."));
+ };
+
+};
+
+Guacamole.HTTPTunnel.prototype = new Guacamole.Tunnel();
+
+/**
+ * Guacamole Tunnel implemented over WebSocket via XMLHttpRequest.
+ *
+ * @constructor
+ * @augments Guacamole.Tunnel
+ * @param {String} tunnelURL The URL of the WebSocket tunneling service.
+ */
+Guacamole.WebSocketTunnel = function(tunnelURL) {
+
+ /**
+ * Reference to this WebSocket tunnel.
+ * @private
+ */
+ var tunnel = this;
+
+ /**
+ * The WebSocket used by this tunnel.
+ * @private
+ */
+ var socket = null;
+
+ /**
+ * The current receive timeout ID, if any.
+ * @private
+ */
+ var receive_timeout = null;
+
+ /**
+ * The WebSocket protocol corresponding to the protocol used for the current
+ * location.
+ * @private
+ */
+ var ws_protocol = {
+ "http:": "ws:",
+ "https:": "wss:"
+ };
+
+ // Transform current URL to WebSocket URL
+
+ // If not already a websocket URL
+ if ( tunnelURL.substring(0, 3) !== "ws:"
+ && tunnelURL.substring(0, 4) !== "wss:") {
+
+ var protocol = ws_protocol[window.location.protocol];
+
+ // If absolute URL, convert to absolute WS URL
+ if (tunnelURL.substring(0, 1) === "/")
+ tunnelURL =
+ protocol
+ + "//" + window.location.host
+ + tunnelURL;
+
+ // Otherwise, construct absolute from relative URL
+ else {
+
+ // Get path from pathname
+ var slash = window.location.pathname.lastIndexOf("/");
+ var path = window.location.pathname.substring(0, slash + 1);
+
+ // Construct absolute URL
+ tunnelURL =
+ protocol
+ + "//" + window.location.host
+ + path
+ + tunnelURL;
+
+ }
+
+ }
+
+ /**
+ * Initiates a timeout which, if data is not received, causes the tunnel
+ * to close with an error.
+ *
+ * @private
+ */
+ function reset_timeout() {
+
+ // Get rid of old timeout (if any)
+ window.clearTimeout(receive_timeout);
+
+ // Set new timeout
+ receive_timeout = window.setTimeout(function () {
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
+ }, tunnel.receiveTimeout);
+
+ }
+
+ /**
+ * Closes this tunnel, signaling the given status and corresponding
+ * message, which will be sent to the onerror handler if the status is
+ * an error status.
+ *
+ * @private
+ * @param {Guacamole.Status} status The status causing the connection to
+ * close;
+ */
+ function close_tunnel(status) {
+
+ // Ignore if already closed
+ if (tunnel.state === Guacamole.Tunnel.State.CLOSED)
+ return;
+
+ // If connection closed abnormally, signal error.
+ if (status.code !== Guacamole.Status.Code.SUCCESS && tunnel.onerror)
+ tunnel.onerror(status);
+
+ // Mark as closed
+ tunnel.state = Guacamole.Tunnel.State.CLOSED;
+ if (tunnel.onstatechange)
+ tunnel.onstatechange(tunnel.state);
+
+ socket.close();
+
+ }
+
+ this.sendMessage = function(elements) {
+
+ // Do not attempt to send messages if not connected
+ if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
+ return;
+
+ // Do not attempt to send empty messages
+ if (arguments.length === 0)
+ return;
+
+ /**
+ * Converts the given value to a length/string pair for use as an
+ * element in a Guacamole instruction.
+ *
+ * @private
+ * @param value The value to convert.
+ * @return {String} The converted value.
+ */
+ function getElement(value) {
+ var string = new String(value);
+ return string.length + "." + string;
+ }
+
+ // Initialized message with first element
+ var message = getElement(arguments[0]);
+
+ // Append remaining elements
+ for (var i=1; i<arguments.length; i++)
+ message += "," + getElement(arguments[i]);
+
+ // Final terminator
+ message += ";";
+
+ socket.send(message);
+
+ };
+
+ this.connect = function(data) {
+
+ reset_timeout();
+
+ // Connect socket
+ socket = new WebSocket(tunnelURL + "?" + data, "guacamole");
+
+ socket.onopen = function(event) {
+ reset_timeout();
+ };
+
+ socket.onclose = function(event) {
+ close_tunnel(new Guacamole.Status(parseInt(event.reason), event.reason));
+ };
+
+ socket.onerror = function(event) {
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SERVER_ERROR, event.data));
+ };
+
+ socket.onmessage = function(event) {
+
+ reset_timeout();
+
+ var message = event.data;
+ var startIndex = 0;
+ var elementEnd;
+
+ var elements = [];
+
+ do {
+
+ // Search for end of length
+ var lengthEnd = message.indexOf(".", startIndex);
+ if (lengthEnd !== -1) {
+
+ // Parse length
+ var length = parseInt(message.substring(elementEnd+1, lengthEnd));
+
+ // Calculate start of element
+ startIndex = lengthEnd + 1;
+
+ // Calculate location of element terminator
+ elementEnd = startIndex + length;
+
+ }
+
+ // If no period, incomplete instruction.
+ else
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SERVER_ERROR, "Incomplete instruction."));
+
+ // We now have enough data for the element. Parse.
+ var element = message.substring(startIndex, elementEnd);
+ var terminator = message.substring(elementEnd, elementEnd+1);
+
+ // Add element to array
+ elements.push(element);
+
+ // If last element, handle instruction
+ if (terminator === ";") {
+
+ // Get opcode
+ var opcode = elements.shift();
+
+ // Update state and UUID when first instruction received
+ if (tunnel.state !== Guacamole.Tunnel.State.OPEN) {
+
+ // Associate tunnel UUID if received
+ if (opcode === Guacamole.Tunnel.INTERNAL_DATA_OPCODE)
+ tunnel.uuid = elements[0];
+
+ // Tunnel is now open and UUID is available
+ tunnel.state = Guacamole.Tunnel.State.OPEN;
+ if (tunnel.onstatechange)
+ tunnel.onstatechange(tunnel.state);
+
+ }
+
+ // Call instruction handler.
+ if (opcode !== Guacamole.Tunnel.INTERNAL_DATA_OPCODE && tunnel.oninstruction)
+ tunnel.oninstruction(opcode, elements);
+
+ // Clear elements
+ elements.length = 0;
+
+ }
+
+ // Start searching for length at character after
+ // element terminator
+ startIndex = elementEnd + 1;
+
+ } while (startIndex < message.length);
+
+ };
+
+ };
+
+ this.disconnect = function() {
+ close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, "Manually closed."));
+ };
+
+};
+
+Guacamole.WebSocketTunnel.prototype = new Guacamole.Tunnel();
+
+/**
+ * Guacamole Tunnel which cycles between all specified tunnels until
+ * no tunnels are left. Another tunnel is used if an error occurs but
+ * no instructions have been received. If an instruction has been
+ * received, or no tunnels remain, the error is passed directly out
+ * through the onerror handler (if defined).
+ *
+ * @constructor
+ * @augments Guacamole.Tunnel
+ * @param {...*} tunnelChain
+ * The tunnels to use, in order of priority.
+ */
+Guacamole.ChainedTunnel = function(tunnelChain) {
+
+ /**
+ * Reference to this chained tunnel.
+ * @private
+ */
+ var chained_tunnel = this;
+
+ /**
+ * Data passed in via connect(), to be used for
+ * wrapped calls to other tunnels' connect() functions.
+ * @private
+ */
+ var connect_data;
+
+ /**
+ * Array of all tunnels passed to this ChainedTunnel through the
+ * constructor arguments.
+ * @private
+ */
+ var tunnels = [];
+
+ /**
+ * The tunnel committed via commit_tunnel(), if any, or null if no tunnel
+ * has yet been committed.
+ *
+ * @private
+ * @type {Guacamole.Tunnel}
+ */
+ var committedTunnel = null;
+
+ // Load all tunnels into array
+ for (var i=0; i<arguments.length; i++)
+ tunnels.push(arguments[i]);
+
+ /**
+ * Sets the current tunnel.
+ *
+ * @private
+ * @param {Guacamole.Tunnel} tunnel The tunnel to set as the current tunnel.
+ */
+ function attach(tunnel) {
+
+ // Set own functions to tunnel's functions
+ chained_tunnel.disconnect = tunnel.disconnect;
+ chained_tunnel.sendMessage = tunnel.sendMessage;
+
+ /**
+ * Fails the currently-attached tunnel, attaching a new tunnel if
+ * possible.
+ *
+ * @private
+ * @param {Guacamole.Status} [status]
+ * An object representing the failure that occured in the
+ * currently-attached tunnel, if known.
+ *
+ * @return {Guacamole.Tunnel}
+ * The next tunnel, or null if there are no more tunnels to try or
+ * if no more tunnels should be tried.
+ */
+ var failTunnel = function failTunnel(status) {
+
+ // Do not attempt to continue using next tunnel on server timeout
+ if (status && status.code === Guacamole.Status.Code.UPSTREAM_TIMEOUT) {
+ tunnels = [];
+ return null;
+ }
+
+ // Get next tunnel
+ var next_tunnel = tunnels.shift();
+
+ // If there IS a next tunnel, try using it.
+ if (next_tunnel) {
+ tunnel.onerror = null;
+ tunnel.oninstruction = null;
+ tunnel.onstatechange = null;
+ attach(next_tunnel);
+ }
+
+ return next_tunnel;
+
+ };
+
+ /**
+ * Use the current tunnel from this point forward. Do not try any more
+ * tunnels, even if the current tunnel fails.
+ *
+ * @private
+ */
+ function commit_tunnel() {
+ tunnel.onstatechange = chained_tunnel.onstatechange;
+ tunnel.oninstruction = chained_tunnel.oninstruction;
+ tunnel.onerror = chained_tunnel.onerror;
+ chained_tunnel.uuid = tunnel.uuid;
+ committedTunnel = tunnel;
+ }
+
+ // Wrap own onstatechange within current tunnel
+ tunnel.onstatechange = function(state) {
+
+ switch (state) {
+
+ // If open, use this tunnel from this point forward.
+ case Guacamole.Tunnel.State.OPEN:
+ commit_tunnel();
+ if (chained_tunnel.onstatechange)
+ chained_tunnel.onstatechange(state);
+ break;
+
+ // If closed, mark failure, attempt next tunnel
+ case Guacamole.Tunnel.State.CLOSED:
+ if (!failTunnel() && chained_tunnel.onstatechange)
+ chained_tunnel.onstatechange(state);
+ break;
+
+ }
+
+ };
+
+ // Wrap own oninstruction within current tunnel
+ tunnel.oninstruction = function(opcode, elements) {
+
+ // Accept current tunnel
+ commit_tunnel();
+
+ // Invoke handler
+ if (chained_tunnel.oninstruction)
+ chained_tunnel.oninstruction(opcode, elements);
+
+ };
+
+ // Attach next tunnel on error
+ tunnel.onerror = function(status) {
+
+ // Mark failure, attempt next tunnel
+ if (!failTunnel(status) && chained_tunnel.onerror)
+ chained_tunnel.onerror(status);
+
+ };
+
+ // Attempt connection
+ tunnel.connect(connect_data);
+
+ }
+
+ this.connect = function(data) {
+
+ // Remember connect data
+ connect_data = data;
+
+ // Get committed tunnel if exists or the first tunnel on the list
+ var next_tunnel = committedTunnel ? committedTunnel : tunnels.shift();
+
+ // Attach first tunnel
+ if (next_tunnel)
+ attach(next_tunnel);
+
+ // If there IS no first tunnel, error
+ else if (chained_tunnel.onerror)
+ chained_tunnel.onerror(Guacamole.Status.Code.SERVER_ERROR, "No tunnels to try.");
+
+ };
+
+};
+
+Guacamole.ChainedTunnel.prototype = new Guacamole.Tunnel();
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li>
<li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR
ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li><li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><
li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onname">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">ons
tatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkey
up</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li><li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown
</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.W
ebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul>
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sat Mar 18 2017 19:26:49 GMT-0700 (PDT)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/b8b84d96/doc/0.9.12-incubating/guacamole-common-js/Version.js.html
----------------------------------------------------------------------
diff --git a/doc/0.9.12-incubating/guacamole-common-js/Version.js.html b/doc/0.9.12-incubating/guacamole-common-js/Version.js.html
new file mode 100644
index 0000000..5f95fa4
--- /dev/null
+++ b/doc/0.9.12-incubating/guacamole-common-js/Version.js.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Version.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: Version.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * The unique ID of this version of the Guacamole JavaScript API. This ID will
+ * be the version string of the guacamole-common-js Maven project, and can be
+ * used in downstream applications as a sanity check that the proper version
+ * of the APIs is being used (in case an older version is cached, for example).
+ *
+ * @type {String}
+ */
+Guacamole.API_VERSION = "0.9.12-incubating";
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li>
<li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR
ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li><li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><
li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onname">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">ons
tatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkey
up</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li><li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown
</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.W
ebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul>
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sat Mar 18 2017 19:26:49 GMT-0700 (PDT)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/b8b84d96/doc/0.9.12-incubating/guacamole-common-js/VideoPlayer.js.html
----------------------------------------------------------------------
diff --git a/doc/0.9.12-incubating/guacamole-common-js/VideoPlayer.js.html b/doc/0.9.12-incubating/guacamole-common-js/VideoPlayer.js.html
new file mode 100644
index 0000000..a0f8c80
--- /dev/null
+++ b/doc/0.9.12-incubating/guacamole-common-js/VideoPlayer.js.html
@@ -0,0 +1,169 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: VideoPlayer.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: VideoPlayer.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Abstract video player which accepts, queues and plays back arbitrary video
+ * data. It is up to implementations of this class to provide some means of
+ * handling a provided Guacamole.InputStream and rendering the received data to
+ * the provided Guacamole.Display.VisibleLayer. Data received along the
+ * provided stream is to be played back immediately.
+ *
+ * @constructor
+ */
+Guacamole.VideoPlayer = function VideoPlayer() {
+
+ /**
+ * Notifies this Guacamole.VideoPlayer that all video up to the current
+ * point in time has been given via the underlying stream, and that any
+ * difference in time between queued video data and the current time can be
+ * considered latency.
+ */
+ this.sync = function sync() {
+ // Default implementation - do nothing
+ };
+
+};
+
+/**
+ * Determines whether the given mimetype is supported by any built-in
+ * implementation of Guacamole.VideoPlayer, and thus will be properly handled
+ * by Guacamole.VideoPlayer.getInstance().
+ *
+ * @param {String} mimetype
+ * The mimetype to check.
+ *
+ * @returns {Boolean}
+ * true if the given mimetype is supported by any built-in
+ * Guacamole.VideoPlayer, false otherwise.
+ */
+Guacamole.VideoPlayer.isSupportedType = function isSupportedType(mimetype) {
+
+ // There are currently no built-in video players (and therefore no
+ // supported types)
+ return false;
+
+};
+
+/**
+ * Returns a list of all mimetypes supported by any built-in
+ * Guacamole.VideoPlayer, in rough order of priority. Beware that only the core
+ * mimetypes themselves will be listed. Any mimetype parameters, even required
+ * ones, will not be included in the list.
+ *
+ * @returns {String[]}
+ * A list of all mimetypes supported by any built-in Guacamole.VideoPlayer,
+ * excluding any parameters.
+ */
+Guacamole.VideoPlayer.getSupportedTypes = function getSupportedTypes() {
+
+ // There are currently no built-in video players (and therefore no
+ // supported types)
+ return [];
+
+};
+
+/**
+ * Returns an instance of Guacamole.VideoPlayer providing support for the given
+ * video format. If support for the given video format is not available, null
+ * is returned.
+ *
+ * @param {Guacamole.InputStream} stream
+ * The Guacamole.InputStream to read video data from.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The destination layer in which this Guacamole.VideoPlayer should play
+ * the received video data.
+ *
+ * @param {String} mimetype
+ * The mimetype of the video data in the provided stream.
+ *
+ * @return {Guacamole.VideoPlayer}
+ * A Guacamole.VideoPlayer instance supporting the given mimetype and
+ * reading from the given stream, or null if support for the given mimetype
+ * is absent.
+ */
+Guacamole.VideoPlayer.getInstance = function getInstance(stream, layer, mimetype) {
+
+ // There are currently no built-in video players
+ return null;
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li>
<li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR
ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li><li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><
li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onname">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">ons
tatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkey
up</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li><li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown
</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.W
ebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul>
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sat Mar 18 2017 19:26:49 GMT-0700 (PDT)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/b8b84d96/doc/0.9.12-incubating/guacamole-common-js/fonts/OpenSans-Bold-webfont.eot
----------------------------------------------------------------------
diff --git a/doc/0.9.12-incubating/guacamole-common-js/fonts/OpenSans-Bold-webfont.eot b/doc/0.9.12-incubating/guacamole-common-js/fonts/OpenSans-Bold-webfont.eot
new file mode 100644
index 0000000..5d20d91
Binary files /dev/null and b/doc/0.9.12-incubating/guacamole-common-js/fonts/OpenSans-Bold-webfont.eot differ