Use standard EventTarget interface for events
This commit is contained in:
parent
65fdfeae13
commit
e89eef94aa
50
app/ui.js
50
app/ui.js
|
@ -390,7 +390,7 @@ var UI = {
|
||||||
* VISUAL
|
* VISUAL
|
||||||
* ------v------*/
|
* ------v------*/
|
||||||
|
|
||||||
updateState: function(rfb, state, oldstate) {
|
updateState: function(event) {
|
||||||
var msg;
|
var msg;
|
||||||
|
|
||||||
document.documentElement.classList.remove("noVNC_connecting");
|
document.documentElement.classList.remove("noVNC_connecting");
|
||||||
|
@ -398,7 +398,7 @@ var UI = {
|
||||||
document.documentElement.classList.remove("noVNC_disconnecting");
|
document.documentElement.classList.remove("noVNC_disconnecting");
|
||||||
document.documentElement.classList.remove("noVNC_reconnecting");
|
document.documentElement.classList.remove("noVNC_reconnecting");
|
||||||
|
|
||||||
switch (state) {
|
switch (event.detail.state) {
|
||||||
case 'connecting':
|
case 'connecting':
|
||||||
document.getElementById("noVNC_transition_text").textContent = _("Connecting...");
|
document.getElementById("noVNC_transition_text").textContent = _("Connecting...");
|
||||||
document.documentElement.classList.add("noVNC_connecting");
|
document.documentElement.classList.add("noVNC_connecting");
|
||||||
|
@ -534,8 +534,8 @@ var UI = {
|
||||||
document.getElementById('noVNC_status').classList.remove("noVNC_open");
|
document.getElementById('noVNC_status').classList.remove("noVNC_open");
|
||||||
},
|
},
|
||||||
|
|
||||||
notification: function (rfb, msg, level) {
|
notification: function (e) {
|
||||||
UI.showStatus(msg, level);
|
UI.showStatus(e.detail.message, e.detail.level);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateControlbar: function(event) {
|
activateControlbar: function(event) {
|
||||||
|
@ -966,9 +966,9 @@ var UI = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clipboardReceive: function(rfb, text) {
|
clipboardReceive: function(e) {
|
||||||
Log.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "...");
|
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0,40) + "...");
|
||||||
document.getElementById('noVNC_clipboard_text').value = text;
|
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
|
||||||
Log.Debug("<< UI.clipboardReceive");
|
Log.Debug("<< UI.clipboardReceive");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1040,15 +1040,15 @@ var UI = {
|
||||||
{ shared: UI.getSetting('shared'),
|
{ shared: UI.getSetting('shared'),
|
||||||
repeaterID: UI.getSetting('repeaterID'),
|
repeaterID: UI.getSetting('repeaterID'),
|
||||||
credentials: { password: password } });
|
credentials: { password: password } });
|
||||||
UI.rfb.onnotification = UI.notification;
|
UI.rfb.addEventListener("notification", UI.notification);
|
||||||
UI.rfb.onupdatestate = UI.updateState;
|
UI.rfb.addEventListener("updatestate", UI.updateState);
|
||||||
UI.rfb.ondisconnected = UI.disconnectFinished;
|
UI.rfb.addEventListener("disconnect", UI.disconnectFinished);
|
||||||
UI.rfb.oncredentialsrequired = UI.credentials;
|
UI.rfb.addEventListener("credentialsrequired", UI.credentials);
|
||||||
UI.rfb.oncapabilities = function () { UI.updatePowerButton(); UI.initialResize(); };
|
UI.rfb.addEventListener("capabilities", function () { UI.updatePowerButton(); UI.initialResize(); });
|
||||||
UI.rfb.onclipboard = UI.clipboardReceive;
|
UI.rfb.addEventListener("clipboard", UI.clipboardReceive);
|
||||||
UI.rfb.onbell = UI.bell;
|
UI.rfb.addEventListener("bell", UI.bell);
|
||||||
UI.rfb.onfbresize = UI.updateSessionSize;
|
UI.rfb.addEventListener("fbresize", UI.updateSessionSize);
|
||||||
UI.rfb.ondesktopname = UI.updateDesktopName;
|
UI.rfb.addEventListener("desktopname", UI.updateDesktopName);
|
||||||
},
|
},
|
||||||
|
|
||||||
disconnect: function() {
|
disconnect: function() {
|
||||||
|
@ -1072,9 +1072,9 @@ var UI = {
|
||||||
UI.connect(null, UI.reconnect_password);
|
UI.connect(null, UI.reconnect_password);
|
||||||
},
|
},
|
||||||
|
|
||||||
disconnectFinished: function (rfb, reason) {
|
disconnectFinished: function (e) {
|
||||||
if (typeof reason !== 'undefined') {
|
if (typeof e.detail.reason !== 'undefined') {
|
||||||
UI.showStatus(reason, 'error');
|
UI.showStatus(e.detail.reason, 'error');
|
||||||
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) {
|
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) {
|
||||||
document.getElementById("noVNC_transition_text").textContent = _("Reconnecting...");
|
document.getElementById("noVNC_transition_text").textContent = _("Reconnecting...");
|
||||||
document.documentElement.classList.add("noVNC_reconnecting");
|
document.documentElement.classList.add("noVNC_reconnecting");
|
||||||
|
@ -1105,7 +1105,7 @@ var UI = {
|
||||||
* PASSWORD
|
* PASSWORD
|
||||||
* ------v------*/
|
* ------v------*/
|
||||||
|
|
||||||
credentials: function(rfb, types) {
|
credentials: function(e) {
|
||||||
// FIXME: handle more types
|
// FIXME: handle more types
|
||||||
document.getElementById('noVNC_password_dlg')
|
document.getElementById('noVNC_password_dlg')
|
||||||
.classList.add('noVNC_open');
|
.classList.add('noVNC_open');
|
||||||
|
@ -1656,7 +1656,7 @@ var UI = {
|
||||||
WebUtil.init_logging(UI.getSetting('logging'));
|
WebUtil.init_logging(UI.getSetting('logging'));
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSessionSize: function(rfb, width, height) {
|
updateSessionSize: function(e) {
|
||||||
UI.updateViewClip();
|
UI.updateViewClip();
|
||||||
UI.updateScaling();
|
UI.updateScaling();
|
||||||
UI.fixScrollbars();
|
UI.fixScrollbars();
|
||||||
|
@ -1674,13 +1674,13 @@ var UI = {
|
||||||
screen.style.overflow = "";
|
screen.style.overflow = "";
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDesktopName: function(rfb, name) {
|
updateDesktopName: function(e) {
|
||||||
UI.desktopName = name;
|
UI.desktopName = e.detail.name;
|
||||||
// Display the desktop name in the document title
|
// Display the desktop name in the document title
|
||||||
document.title = name + " - noVNC";
|
document.title = e.detail.name + " - noVNC";
|
||||||
},
|
},
|
||||||
|
|
||||||
bell: function(rfb) {
|
bell: function(e) {
|
||||||
if (WebUtil.getConfigVar('bell', 'on') === 'on') {
|
if (WebUtil.getConfigVar('bell', 'on') === 'on') {
|
||||||
var promise = document.getElementById('noVNC_bell').play();
|
var promise = document.getElementById('noVNC_bell').play();
|
||||||
// The standards disagree on the return value here
|
// The standards disagree on the return value here
|
||||||
|
|
60
core/rfb.js
60
core/rfb.js
|
@ -14,6 +14,7 @@ import * as Log from './util/logging.js';
|
||||||
import _ from './util/localization.js';
|
import _ from './util/localization.js';
|
||||||
import { decodeUTF8 } from './util/strings.js';
|
import { decodeUTF8 } from './util/strings.js';
|
||||||
import { browserSupportsCursorURIs, isTouchDevice } from './util/browsers.js';
|
import { browserSupportsCursorURIs, isTouchDevice } from './util/browsers.js';
|
||||||
|
import EventTargetMixin from './util/eventtarget.js';
|
||||||
import Display from "./display.js";
|
import Display from "./display.js";
|
||||||
import Keyboard from "./input/keyboard.js";
|
import Keyboard from "./input/keyboard.js";
|
||||||
import Mouse from "./input/mouse.js";
|
import Mouse from "./input/mouse.js";
|
||||||
|
@ -24,6 +25,7 @@ import KeyTable from "./input/keysym.js";
|
||||||
import XtScancode from "./input/xtscancodes.js";
|
import XtScancode from "./input/xtscancodes.js";
|
||||||
import Inflator from "./inflator.js";
|
import Inflator from "./inflator.js";
|
||||||
import { encodings, encodingName } from "./encodings.js";
|
import { encodings, encodingName } from "./encodings.js";
|
||||||
|
import "./util/polyfill.js";
|
||||||
|
|
||||||
/*jslint white: false, browser: true */
|
/*jslint white: false, browser: true */
|
||||||
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
|
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
|
||||||
|
@ -265,18 +267,6 @@ RFB.prototype = {
|
||||||
|
|
||||||
get isClipped() { return this._display.isClipped; },
|
get isClipped() { return this._display.isClipped; },
|
||||||
|
|
||||||
// ===== EVENT HANDLERS =====
|
|
||||||
|
|
||||||
onupdatestate: function () {}, // onupdatestate(rfb, state, oldstate): connection state change
|
|
||||||
onnotification: function () {}, // onnotification(rfb, msg, level, options): notification for the UI
|
|
||||||
ondisconnected: function () {}, // ondisconnected(rfb, reason): disconnection finished
|
|
||||||
oncredentialsrequired: function () {}, // oncredentialsrequired(rfb, types): VNC credentials are required
|
|
||||||
onclipboard: function () {}, // onclipboard(rfb, text): RFB clipboard contents received
|
|
||||||
onbell: function () {}, // onbell(rfb): RFB Bell message received
|
|
||||||
onfbresize: function () {}, // onfbresize(rfb, width, height): frame buffer resized
|
|
||||||
ondesktopname: function () {}, // ondesktopname(rfb, name): desktop name received
|
|
||||||
oncapabilities: function () {}, // oncapabilities(rfb, caps): the supported capabilities has changed
|
|
||||||
|
|
||||||
// ===== PUBLIC METHODS =====
|
// ===== PUBLIC METHODS =====
|
||||||
|
|
||||||
disconnect: function () {
|
disconnect: function () {
|
||||||
|
@ -510,7 +500,8 @@ RFB.prototype = {
|
||||||
// State change actions
|
// State change actions
|
||||||
|
|
||||||
this._rfb_connection_state = state;
|
this._rfb_connection_state = state;
|
||||||
this.onupdatestate(this, state, oldstate);
|
var event = new CustomEvent("updatestate", { detail: { state: state } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
|
||||||
var smsg = "New state '" + state + "', was '" + oldstate + "'.";
|
var smsg = "New state '" + state + "', was '" + oldstate + "'.";
|
||||||
Log.Debug(smsg);
|
Log.Debug(smsg);
|
||||||
|
@ -526,14 +517,16 @@ RFB.prototype = {
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'disconnected':
|
case 'disconnected':
|
||||||
// Call ondisconnected callback after onupdatestate since
|
// Fire disconnected event after updatestate event since
|
||||||
// we don't know if the UI only displays the latest message
|
// we don't know if the UI only displays the latest message
|
||||||
if (this._rfb_disconnect_reason !== "") {
|
if (this._rfb_disconnect_reason !== "") {
|
||||||
this.ondisconnected(this, this._rfb_disconnect_reason);
|
event = new CustomEvent("disconnect",
|
||||||
|
{ detail: { reason: this._rfb_disconnect_reason } });
|
||||||
} else {
|
} else {
|
||||||
// No reason means clean disconnect
|
// No reason means clean disconnect
|
||||||
this.ondisconnected(this);
|
event = new CustomEvent("disconnect", { detail: {} });
|
||||||
}
|
}
|
||||||
|
this.dispatchEvent(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'connecting':
|
case 'connecting':
|
||||||
|
@ -603,12 +596,16 @@ RFB.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onnotification(this, msg, level);
|
var event = new CustomEvent("notification",
|
||||||
|
{ detail: { message: msg, level: level } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setCapability: function (cap, val) {
|
_setCapability: function (cap, val) {
|
||||||
this._capabilities[cap] = val;
|
this._capabilities[cap] = val;
|
||||||
this.oncapabilities(this, this._capabilities);
|
var event = new CustomEvent("capabilities",
|
||||||
|
{ detail: { capabilities: this._capabilities } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
},
|
},
|
||||||
|
|
||||||
_handle_message: function () {
|
_handle_message: function () {
|
||||||
|
@ -818,7 +815,9 @@ RFB.prototype = {
|
||||||
if (!this._rfb_credentials.username ||
|
if (!this._rfb_credentials.username ||
|
||||||
!this._rfb_credentials.password ||
|
!this._rfb_credentials.password ||
|
||||||
!this._rfb_credentials.target) {
|
!this._rfb_credentials.target) {
|
||||||
this.oncredentialsrequired(this, ["username", "password", "target"]);
|
var event = new CustomEvent("credentialsrequired",
|
||||||
|
{ detail: { types: ["username", "password", "target"] } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +834,9 @@ RFB.prototype = {
|
||||||
if (this._sock.rQwait("auth challenge", 16)) { return false; }
|
if (this._sock.rQwait("auth challenge", 16)) { return false; }
|
||||||
|
|
||||||
if (!this._rfb_credentials.password) {
|
if (!this._rfb_credentials.password) {
|
||||||
this.oncredentialsrequired(this, ["password"]);
|
var event = new CustomEvent("credentialsrequired",
|
||||||
|
{ detail: { types: ["password"] } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,7 +1073,9 @@ RFB.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're past the point where we could backtrack, so it's safe to call this
|
// we're past the point where we could backtrack, so it's safe to call this
|
||||||
this.ondesktopname(this, this._fb_name);
|
var event = new CustomEvent("desktopname",
|
||||||
|
{ detail: { name: this._fb_name } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
|
||||||
this._resize(width, height);
|
this._resize(width, height);
|
||||||
|
|
||||||
|
@ -1189,7 +1192,9 @@ RFB.prototype = {
|
||||||
|
|
||||||
if (this._viewOnly) { return true; }
|
if (this._viewOnly) { return true; }
|
||||||
|
|
||||||
this.onclipboard(this, text);
|
var event = new CustomEvent("clipboard",
|
||||||
|
{ detail: { text: text } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1285,7 +1290,8 @@ RFB.prototype = {
|
||||||
|
|
||||||
case 2: // Bell
|
case 2: // Bell
|
||||||
Log.Debug("Bell");
|
Log.Debug("Bell");
|
||||||
this.onbell(this);
|
var event = new CustomEvent("bell", { detail: {} });
|
||||||
|
this.dispatchEvent(event);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 3: // ServerCutText
|
case 3: // ServerCutText
|
||||||
|
@ -1437,7 +1443,11 @@ RFB.prototype = {
|
||||||
this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4);
|
this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4);
|
||||||
|
|
||||||
this._display.resize(this._fb_width, this._fb_height);
|
this._display.resize(this._fb_width, this._fb_height);
|
||||||
this.onfbresize(this, this._fb_width, this._fb_height);
|
|
||||||
|
var event = new CustomEvent("fbresize",
|
||||||
|
{ detail: { width: this._fb_width,
|
||||||
|
height: this._fb_height } });
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
|
||||||
this._timing.fbu_rt_start = (new Date()).getTime();
|
this._timing.fbu_rt_start = (new Date()).getTime();
|
||||||
this._updateContinuousUpdates();
|
this._updateContinuousUpdates();
|
||||||
|
@ -1450,6 +1460,8 @@ RFB.prototype = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Object.assign(RFB.prototype, EventTargetMixin);
|
||||||
|
|
||||||
// Class Methods
|
// Class Methods
|
||||||
RFB.messages = {
|
RFB.messages = {
|
||||||
keyEvent: function (sock, keysym, down) {
|
keyEvent: function (sock, keysym, down) {
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright 2017 Pierre Ossman for Cendio AB
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var EventTargetMixin = {
|
||||||
|
_listeners: null,
|
||||||
|
|
||||||
|
addEventListener: function(type, callback) {
|
||||||
|
if (!this._listeners) {
|
||||||
|
this._listeners = new Map();
|
||||||
|
}
|
||||||
|
if (!this._listeners.has(type)) {
|
||||||
|
this._listeners.set(type, new Set());
|
||||||
|
}
|
||||||
|
this._listeners.get(type).add(callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeEventListener: function(type, callback) {
|
||||||
|
if (!this._listeners || !this._listeners.has(type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._listeners.get(type).delete(callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
dispatchEvent: function(event) {
|
||||||
|
if (!this._listeners || !this._listeners.has(event.type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this._listeners.get(event.type).forEach(function (callback) {
|
||||||
|
callback.call(this, event);
|
||||||
|
}, this);
|
||||||
|
return !event.defaultPrevented;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EventTargetMixin;
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright 2017 Pierre Ossman for noVNC
|
||||||
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Polyfills to provide new APIs in old browsers */
|
||||||
|
|
||||||
|
/* Object.assign() (taken from MDN) */
|
||||||
|
if (typeof Object.assign != 'function') {
|
||||||
|
// Must be writable: true, enumerable: false, configurable: true
|
||||||
|
Object.defineProperty(Object, "assign", {
|
||||||
|
value: function assign(target, varArgs) { // .length of function is 2
|
||||||
|
'use strict';
|
||||||
|
if (target == null) { // TypeError if undefined or null
|
||||||
|
throw new TypeError('Cannot convert undefined or null to object');
|
||||||
|
}
|
||||||
|
|
||||||
|
var to = Object(target);
|
||||||
|
|
||||||
|
for (var index = 1; index < arguments.length; index++) {
|
||||||
|
var nextSource = arguments[index];
|
||||||
|
|
||||||
|
if (nextSource != null) { // Skip over if undefined or null
|
||||||
|
for (var nextKey in nextSource) {
|
||||||
|
// Avoid bugs when hasOwnProperty is shadowed
|
||||||
|
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||||
|
to[nextKey] = nextSource[nextKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
},
|
||||||
|
writable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CustomEvent constructor (taken from MDN) */
|
||||||
|
(function () {
|
||||||
|
function CustomEvent ( event, params ) {
|
||||||
|
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||||
|
var evt = document.createEvent( 'CustomEvent' );
|
||||||
|
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
|
||||||
|
return evt;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomEvent.prototype = window.Event.prototype;
|
||||||
|
|
||||||
|
if (typeof window.CustomEvent !== "function") {
|
||||||
|
window.CustomEvent = CustomEvent;
|
||||||
|
}
|
||||||
|
})();
|
169
docs/API.md
169
docs/API.md
|
@ -56,39 +56,41 @@ protocol stream.
|
||||||
| `power` | `boolean` | Machine power control is available
|
| `power` | `boolean` | Machine power control is available
|
||||||
| `resize` | `boolean` | The framebuffer can be resized
|
| `resize` | `boolean` | The framebuffer can be resized
|
||||||
|
|
||||||
### Event handlers
|
### Events
|
||||||
|
|
||||||
[`RFB.onupdatestate()`](#rfbonupdatestate)
|
[`updatestate`](#updatestate)
|
||||||
- An event handler called when the connection state of the `RFB`
|
- The `updatestate` event is fired when the connection state of the
|
||||||
object changes.
|
`RFB` object changes.
|
||||||
|
|
||||||
[`RFB.onnotification()`](#rfbonnotification)
|
[`notification`](#notification)
|
||||||
- An event handler called when the `RFB` usage has a message to
|
- The `notification` event is fired when the `RFB` usage has a
|
||||||
display to the user.
|
message to display to the user.
|
||||||
|
|
||||||
[`RFB.ondisconnected()`](#rfbondisconnected)
|
[`disconnect`](#disconnected)
|
||||||
- An event handler called when the `RFB` object disconnects.
|
- The `disconnect` event is fired when the `RFB` object disconnects.
|
||||||
|
|
||||||
[`RFB.oncredentialsrequired()`](#rfboncredentialsrequired)
|
[`credentialsrequired`](#credentialsrequired)
|
||||||
- An event hander called when more credentials must be given to
|
- The `credentialsrequired` event is fired when more credentials must
|
||||||
continue.
|
be given to continue.
|
||||||
|
|
||||||
[`RFB.onclipboard()`](#rfbonclipboard)
|
[`clipboard`](#clipboard)
|
||||||
- An event handler called when clipboard data is received from the
|
- The `clipboard` event is fired when clipboard data is received from
|
||||||
server.
|
the server.
|
||||||
|
|
||||||
[`RFB.onbell()`](#rfbonbell)
|
[`bell`](#bell)
|
||||||
- An event handler called when a audible bell request is received
|
- The `bell` event is fired when a audible bell request is received
|
||||||
from the server.
|
from the server.
|
||||||
|
|
||||||
[`RFB.onfbresize()`](#rfbonfbresize)
|
[`fbresize`](#fbresize)
|
||||||
- An event handler called when the framebuffer size is changed.
|
- The `fbresize` event is fired when the framebuffer size is changed.
|
||||||
|
|
||||||
[`RFB.ondesktopname()`](#rfbondesktopname)
|
[`desktopname`](#desktopname)
|
||||||
- An event handler called when the remote desktop name changes.
|
- The `desktopname` event is fired when the remote desktop name
|
||||||
|
changes.
|
||||||
|
|
||||||
[`RFB.oncapabilities()`](#rfboncapabilities)
|
[`capabilities`](#capabilities)
|
||||||
- An event handler called when `RFB.capabilities` is updated.
|
- The `capabilities` event is fired when `RFB.capabilities` is
|
||||||
|
updated.
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
|
@ -96,9 +98,8 @@ protocol stream.
|
||||||
- Disconnect from the server.
|
- Disconnect from the server.
|
||||||
|
|
||||||
[`RFB.sendCredentials()`](#rfbsendcredentials)
|
[`RFB.sendCredentials()`](#rfbsendcredentials)
|
||||||
- Send credentials to server. Should be called after
|
- Send credentials to server. Should be called after the
|
||||||
[`oncredentialsrequired`](#rfboncredentialsrequired) has been
|
[`credentialsrequired`](#credentialsrequired) event has fired.
|
||||||
called.
|
|
||||||
|
|
||||||
[`RFB.sendKey()`](#rfbsendKey)
|
[`RFB.sendKey()`](#rfbsendKey)
|
||||||
- Send a key event.
|
- Send a key event.
|
||||||
|
@ -175,10 +176,13 @@ connection to a specified VNC server.
|
||||||
- A `DOMString` specifying the ID to provide to any VNC repeater
|
- A `DOMString` specifying the ID to provide to any VNC repeater
|
||||||
encountered.
|
encountered.
|
||||||
|
|
||||||
#### RFB.onupdatestate
|
#### updatestate
|
||||||
|
|
||||||
The `onupdatestate` event handler is fired after the noVNC connection
|
The `updatestate` event is fired after the noVNC connection state
|
||||||
state changes. Here is a list of the states that are reported:
|
changes. The `detail` property is an `Object` containg the property
|
||||||
|
`state` with the new connection state.
|
||||||
|
|
||||||
|
Here is a list of the states that are reported:
|
||||||
|
|
||||||
| connection state | description
|
| connection state | description
|
||||||
| ----------------- | ------------
|
| ----------------- | ------------
|
||||||
|
@ -191,91 +195,66 @@ Note that a `RFB` objects can not transition from the disconnected
|
||||||
state in any way, a new instance of the object has to be created for
|
state in any way, a new instance of the object has to be created for
|
||||||
new connections.
|
new connections.
|
||||||
|
|
||||||
##### Syntax
|
#### notification
|
||||||
|
|
||||||
RFB.onupdatestate = function(rfb, state) { ... }
|
The `notification` event is fired when the `RFB` object wants a message
|
||||||
|
displayed to the user. The `detail` property is an `Object` containing
|
||||||
|
the following properties:
|
||||||
|
|
||||||
#### RFB.onnotification
|
| Property | Type | Description
|
||||||
|
| --------- | ----------- | -----------
|
||||||
|
| `message` | `DOMString` | The message to display
|
||||||
|
| `level` | `DOMString` | The severity of the message
|
||||||
|
|
||||||
The `onnotification` event handler is fired when the `RFB` object wants
|
The following levels are currently defined:
|
||||||
a message displayed to the user. **`msg`** is a `DOMString` specifying
|
|
||||||
the actual message, and **`level`** is a `DOMString` indicating the
|
|
||||||
severity of the message. The following levels are currently defined:
|
|
||||||
|
|
||||||
- `"normal"`
|
- `"normal"`
|
||||||
- `"warn"`
|
- `"warn"`
|
||||||
- `"error"`
|
- `"error"`
|
||||||
|
|
||||||
##### Syntax
|
#### disconnect
|
||||||
|
|
||||||
RFB.onnotification = function(rfb, msg, level) { ... }
|
The `disconnect` event is fired when the connection has been
|
||||||
|
terminated. The `detail` property is an `Object` the optionally
|
||||||
|
contains the property `reason`. `reason` is a `DOMString` specifying
|
||||||
|
the reason in the event of an unexpected termination. `reason` will be
|
||||||
|
omitted for a clean termination.
|
||||||
|
|
||||||
#### RFB.ondisconnected
|
#### credentialsrequired
|
||||||
|
|
||||||
The `ondisconnected` event handler is fired when the connection has
|
The `credentialsrequired` event is fired when the server requests more
|
||||||
been terminated. **`reason`** is `undefined` for a clean termination
|
credentials than were specified to [`RFB()`](#rfb-1). The `detail`
|
||||||
and a `DOMString` specifying the reason in the event of an unexpected
|
property is an `Object` containing the property `types` which is an
|
||||||
termination.
|
`Array` of `DOMString` listing the credentials that are required.
|
||||||
|
|
||||||
##### Syntax
|
#### clipboard
|
||||||
|
|
||||||
RFB.ondisconnected = function(rfb, reason) { ... }
|
The `clipboard` event is fired when the server has sent clipboard data.
|
||||||
|
The `detail` property is an `Object` containing the property `text`
|
||||||
|
which is a `DOMString` with the clipboard data.
|
||||||
|
|
||||||
#### RFB.oncredentialsrequired
|
#### bell
|
||||||
|
|
||||||
The `oncredentialsrequired` event handler is fired when the server
|
The `bell` event is fired when the server has requested an audible
|
||||||
requests more credentials than were specified to [`RFB()`](#rfb-1). The
|
bell.
|
||||||
**`types`** argument is a list of all the credentials that are
|
|
||||||
required.
|
|
||||||
|
|
||||||
##### Syntax
|
#### fbresize
|
||||||
|
|
||||||
RFB.oncredentialsrequired = function(rfb, types) { ... }
|
The `fbresize` event is fired when the framebuffer has changed
|
||||||
|
dimensions. The `detail` property is an `Object` with the properties
|
||||||
|
`width` and `height` specifying the new dimensions.
|
||||||
|
|
||||||
#### RFB.onclipboard
|
#### desktopname
|
||||||
|
|
||||||
The `onclipboard` event handler is fired when the server has sent
|
The `desktopname` event is fired when the name of the remote desktop
|
||||||
clipboard data.
|
changes. The `detail` property is an `Object` with the property `name`
|
||||||
|
which is a `DOMString` specifying the new name.
|
||||||
|
|
||||||
##### Syntax
|
#### capabilities
|
||||||
|
|
||||||
RFB.onclipboard = function(rfb, text) { ... }
|
The `capabilities` event is fired whenever an entry is added or removed
|
||||||
|
from `RFB.capabilities`. The `detail` property is an `Object` with the
|
||||||
#### RFB.onbell
|
property `capabilities` containing the new value of `RFB.capabilities`.
|
||||||
|
|
||||||
The `onbell` event handler is fired when the server has requested an
|
|
||||||
audible bell.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.onbell = function(rfb) { ... }
|
|
||||||
|
|
||||||
#### RFB.onfbresize
|
|
||||||
|
|
||||||
The `onfbresize` event handler is fired when the framebuffer has
|
|
||||||
changed dimensions.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.onfbresize = function(rfb, width, height) { ... }
|
|
||||||
|
|
||||||
#### RFB.ondesktopname
|
|
||||||
|
|
||||||
The `ondesktopname` event handler is fired when the name of the remote
|
|
||||||
desktop changes.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.ondesktopname = function(rfb, name) { ... }
|
|
||||||
|
|
||||||
#### RFB.oncapabilities
|
|
||||||
|
|
||||||
The `oncapabilities` event handler is fired whenever an entry is added
|
|
||||||
or removed from `RFB.capabilities`.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.oncapabilities = function(rfb, capabilites) { ... }
|
|
||||||
|
|
||||||
#### RFB.disconnect()
|
#### RFB.disconnect()
|
||||||
|
|
||||||
|
@ -289,7 +268,7 @@ connected server.
|
||||||
#### RFB.sendCredentials()
|
#### RFB.sendCredentials()
|
||||||
|
|
||||||
The `RFB.sendCredentials()` method is used to provide the missing
|
The `RFB.sendCredentials()` method is used to provide the missing
|
||||||
credentials after `RFB.oncredentialsrequired` has been fired.
|
credentials after a `credentialsrequired` event has been fired.
|
||||||
|
|
||||||
##### Syntax
|
##### Syntax
|
||||||
|
|
||||||
|
@ -405,7 +384,7 @@ the framebuffer. The capability `resize` must be set for this method to
|
||||||
have any effect.
|
have any effect.
|
||||||
|
|
||||||
Note that this is merely a request and the server may deny it.
|
Note that this is merely a request and the server may deny it.
|
||||||
[`RFB.onfbresize`](#rfbonfbresize) will be called when the framebuffer
|
The [`fbresize`](#fbresize) event will be fired when the framebuffer
|
||||||
actually changes dimensions.
|
actually changes dimensions.
|
||||||
|
|
||||||
##### Syntax
|
##### Syntax
|
||||||
|
|
|
@ -68,10 +68,11 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
describe('#RFB', function () {
|
describe('#RFB', function () {
|
||||||
it('should set the current state to "connecting"', function () {
|
it('should set the current state to "connecting"', function () {
|
||||||
var client = new RFB(document.createElement('canvas'), 'wss://host:8675');
|
var client = new RFB(document.createElement('canvas'), 'wss://host:8675');
|
||||||
client.onupdatestate = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("updatestate", spy);
|
||||||
this.clock.tick();
|
this.clock.tick();
|
||||||
expect(client.onupdatestate).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(client.onupdatestate).to.have.been.calledWith(client, 'connecting');
|
expect(spy.args[0][0].detail.state).to.equal('connecting');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should actually connect to the websocket', function () {
|
it('should actually connect to the websocket', function () {
|
||||||
|
@ -90,11 +91,12 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the current state to "disconnecting"', function () {
|
it('should set the current state to "disconnecting"', function () {
|
||||||
client.onupdatestate = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("updatestate", spy);
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
expect(client.onupdatestate).to.have.been.calledTwice;
|
expect(spy).to.have.been.calledTwice;
|
||||||
expect(client.onupdatestate).to.have.been.calledWith(client, 'disconnecting');
|
expect(spy.args[0][0].detail.state).to.equal('disconnecting');
|
||||||
expect(client.onupdatestate).to.have.been.calledWith(client, 'disconnected');
|
expect(spy.args[1][0].detail.state).to.equal('disconnected');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should unregister error event handler', function () {
|
it('should unregister error event handler', function () {
|
||||||
|
@ -319,10 +321,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the updateState callback', function () {
|
it('should call the updateState callback', function () {
|
||||||
client.onupdatestate = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("updatestate", spy);
|
||||||
client._updateConnectionState('disconnecting');
|
client._updateConnectionState('disconnecting');
|
||||||
var spy = client.onupdatestate;
|
expect(spy.args[0][0].detail.state).to.equal('disconnecting');
|
||||||
expect(spy.args[0][1]).to.equal('disconnecting');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the rfb_connection_state', function () {
|
it('should set the rfb_connection_state', function () {
|
||||||
|
@ -338,19 +340,19 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore state changes to the same state', function () {
|
it('should ignore state changes to the same state', function () {
|
||||||
client.onupdatestate = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("updatestate", spy);
|
||||||
client._rfb_connection_state = 'connecting';
|
client._rfb_connection_state = 'connecting';
|
||||||
client._updateConnectionState('connecting');
|
client._updateConnectionState('connecting');
|
||||||
var spy = client.onupdatestate;
|
|
||||||
expect(spy).to.not.have.been.called;
|
expect(spy).to.not.have.been.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore illegal state changes', function () {
|
it('should ignore illegal state changes', function () {
|
||||||
client.onupdatestate = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("updatestate", spy);
|
||||||
client._rfb_connection_state = 'connected';
|
client._rfb_connection_state = 'connected';
|
||||||
client._updateConnectionState('disconnected');
|
client._updateConnectionState('disconnected');
|
||||||
expect(client._rfb_connection_state).to.not.equal('disconnected');
|
expect(client._rfb_connection_state).to.not.equal('disconnected');
|
||||||
var spy = client.onupdatestate;
|
|
||||||
expect(spy).to.not.have.been.called;
|
expect(spy).to.not.have.been.called;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -389,13 +391,12 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
it('should result in disconnect callback with message when reason given', function () {
|
it('should result in disconnect callback with message when reason given', function () {
|
||||||
client._rfb_connection_state = 'connected';
|
client._rfb_connection_state = 'connected';
|
||||||
client.ondisconnected = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("disconnect", spy);
|
||||||
client._fail('a reason');
|
client._fail('a reason');
|
||||||
var spy = client.ondisconnected;
|
|
||||||
this.clock.tick(2000);
|
this.clock.tick(2000);
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0].length).to.equal(2);
|
expect(spy.args[0][0].detail.reason).to.equal('a reason');
|
||||||
expect(spy.args[0][1]).to.equal('a reason');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -405,18 +406,18 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
beforeEach(function () { client = make_rfb(); });
|
beforeEach(function () { client = make_rfb(); });
|
||||||
|
|
||||||
it('should call the notification callback', function () {
|
it('should call the notification callback', function () {
|
||||||
client.onnotification = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("notification", spy);
|
||||||
client._notification('notify!', 'warn');
|
client._notification('notify!', 'warn');
|
||||||
var spy = client.onnotification;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal('notify!');
|
expect(spy.args[0][0].detail.message).to.equal('notify!');
|
||||||
expect(spy.args[0][2]).to.equal('warn');
|
expect(spy.args[0][0].detail.level).to.equal('warn');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not call the notification callback when level is invalid', function () {
|
it('should not call the notification callback when level is invalid', function () {
|
||||||
client.onnotification = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("notification", spy);
|
||||||
client._notification('notify!', 'invalid');
|
client._notification('notify!', 'invalid');
|
||||||
var spy = client.onnotification;
|
|
||||||
expect(spy).to.not.have.been.called;
|
expect(spy).to.not.have.been.called;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -459,40 +460,40 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
beforeEach(function () { client = make_rfb(); });
|
beforeEach(function () { client = make_rfb(); });
|
||||||
|
|
||||||
it('should call the disconnect callback if the state is "disconnected"', function () {
|
it('should call the disconnect callback if the state is "disconnected"', function () {
|
||||||
client.ondisconnected = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("disconnect", spy);
|
||||||
client._rfb_connection_state = 'disconnecting';
|
client._rfb_connection_state = 'disconnecting';
|
||||||
client._rfb_disconnect_reason = "error";
|
client._rfb_disconnect_reason = "error";
|
||||||
client._updateConnectionState('disconnected');
|
client._updateConnectionState('disconnected');
|
||||||
var spy = client.ondisconnected;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal("error");
|
expect(spy.args[0][0].detail.reason).to.equal("error");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not call the disconnect callback if the state is not "disconnected"', function () {
|
it('should not call the disconnect callback if the state is not "disconnected"', function () {
|
||||||
client.ondisconnected = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("disconnect", spy);
|
||||||
client._sock._websocket.close = function () {}; // explicitly don't call onclose
|
client._sock._websocket.close = function () {}; // explicitly don't call onclose
|
||||||
client._updateConnectionState('disconnecting');
|
client._updateConnectionState('disconnecting');
|
||||||
var spy = client.ondisconnected;
|
|
||||||
expect(spy).to.not.have.been.called;
|
expect(spy).to.not.have.been.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the disconnect callback without msg when no reason given', function () {
|
it('should call the disconnect callback without msg when no reason given', function () {
|
||||||
client.ondisconnected = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("disconnect", spy);
|
||||||
client._rfb_connection_state = 'disconnecting';
|
client._rfb_connection_state = 'disconnecting';
|
||||||
client._rfb_disconnect_reason = "";
|
client._rfb_disconnect_reason = "";
|
||||||
client._updateConnectionState('disconnected');
|
client._updateConnectionState('disconnected');
|
||||||
var spy = client.ondisconnected;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0].length).to.equal(1);
|
expect(spy.args[0].length).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the updateState callback before the disconnect callback', function () {
|
it('should call the updateState callback before the disconnect callback', function () {
|
||||||
client.ondisconnected = sinon.spy();
|
var updateStateSpy = sinon.spy();
|
||||||
client.onupdatestate = sinon.spy();
|
var disconnectSpy = sinon.spy();
|
||||||
|
client.addEventListener("disconnect", disconnectSpy);
|
||||||
|
client.addEventListener("updatestate", updateStateSpy);
|
||||||
client._rfb_connection_state = 'disconnecting';
|
client._rfb_connection_state = 'disconnecting';
|
||||||
client._updateConnectionState('disconnected');
|
client._updateConnectionState('disconnected');
|
||||||
var updateStateSpy = client.onupdatestate;
|
|
||||||
var disconnectSpy = client.ondisconnected;
|
|
||||||
expect(updateStateSpy.calledBefore(disconnectSpy)).to.be.true;
|
expect(updateStateSpy.calledBefore(disconnectSpy)).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -715,18 +716,18 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
client._rfb_version = 3.8;
|
client._rfb_version = 3.8;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the onCredentialsRequired callback if missing a password', function () {
|
it('should fire the credentialsrequired event if missing a password', function () {
|
||||||
client.oncredentialsrequired = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("credentialsrequired", spy);
|
||||||
send_security(2, client);
|
send_security(2, client);
|
||||||
|
|
||||||
var challenge = [];
|
var challenge = [];
|
||||||
for (var i = 0; i < 16; i++) { challenge[i] = i; }
|
for (var i = 0; i < 16; i++) { challenge[i] = i; }
|
||||||
client._sock._websocket._receive_data(new Uint8Array(challenge));
|
client._sock._websocket._receive_data(new Uint8Array(challenge));
|
||||||
|
|
||||||
var spy = client.oncredentialsrequired;
|
|
||||||
expect(client._rfb_credentials).to.be.empty;
|
expect(client._rfb_credentials).to.be.empty;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.have.members(["password"]);
|
expect(spy.args[0][0].detail.types).to.have.members(["password"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should encrypt the password with DES and then send it back', function () {
|
it('should encrypt the password with DES and then send it back', function () {
|
||||||
|
@ -769,26 +770,26 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(client._negotiate_std_vnc_auth).to.have.been.calledOnce;
|
expect(client._negotiate_std_vnc_auth).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the onCredentialsRequired callback if all credentials are missing', function() {
|
it('should fire the credentialsrequired event if all credentials are missing', function() {
|
||||||
client.oncredentialsrequired = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("credentialsrequired", spy);
|
||||||
client._rfb_credentials = {};
|
client._rfb_credentials = {};
|
||||||
send_security(22, client);
|
send_security(22, client);
|
||||||
|
|
||||||
var spy = client.oncredentialsrequired;
|
|
||||||
expect(client._rfb_credentials).to.be.empty;
|
expect(client._rfb_credentials).to.be.empty;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.have.members(["username", "password", "target"]);
|
expect(spy.args[0][0].detail.types).to.have.members(["username", "password", "target"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the onCredentialsRequired callback if some credentials are missing', function() {
|
it('should fire the credentialsrequired event if some credentials are missing', function() {
|
||||||
client.oncredentialsrequired = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("credentialsrequired", spy);
|
||||||
client._rfb_credentials = { username: 'user',
|
client._rfb_credentials = { username: 'user',
|
||||||
target: 'target' };
|
target: 'target' };
|
||||||
send_security(22, client);
|
send_security(22, client);
|
||||||
|
|
||||||
var spy = client.oncredentialsrequired;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.have.members(["username", "password", "target"]);
|
expect(spy.args[0][0].detail.types).to.have.members(["username", "password", "target"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send user and target separately', function () {
|
it('should send user and target separately', function () {
|
||||||
|
@ -998,13 +999,13 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
// NB(sross): we just warn, not fail, for endian-ness and shifts, so we don't test them
|
// NB(sross): we just warn, not fail, for endian-ness and shifts, so we don't test them
|
||||||
|
|
||||||
it('should set the framebuffer name and call the callback', function () {
|
it('should set the framebuffer name and call the callback', function () {
|
||||||
client.ondesktopname = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("desktopname", spy);
|
||||||
send_server_init({ name: 'some name' }, client);
|
send_server_init({ name: 'some name' }, client);
|
||||||
|
|
||||||
var spy = client.ondesktopname;
|
|
||||||
expect(client._fb_name).to.equal('some name');
|
expect(client._fb_name).to.equal('some name');
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal('some name');
|
expect(spy.args[0][0].detail.name).to.equal('some name');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle the extended init message of the tight encoding', function () {
|
it('should handle the extended init message of the tight encoding', function () {
|
||||||
|
@ -1027,16 +1028,16 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the resize callback and resize the display', function () {
|
it('should call the resize callback and resize the display', function () {
|
||||||
client.onfbresize = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("fbresize", spy);
|
||||||
sinon.spy(client._display, 'resize');
|
sinon.spy(client._display, 'resize');
|
||||||
send_server_init({ width: 27, height: 32 }, client);
|
send_server_init({ width: 27, height: 32 }, client);
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
|
||||||
expect(client._display.resize).to.have.been.calledOnce;
|
expect(client._display.resize).to.have.been.calledOnce;
|
||||||
expect(client._display.resize).to.have.been.calledWith(27, 32);
|
expect(client._display.resize).to.have.been.calledWith(27, 32);
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal(27);
|
expect(spy.args[0][0].detail.width).to.equal(27);
|
||||||
expect(spy.args[0][2]).to.equal(32);
|
expect(spy.args[0][0].detail.height).to.equal(32);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should grab the mouse and keyboard', function () {
|
it('should grab the mouse and keyboard', function () {
|
||||||
|
@ -1436,13 +1437,14 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle the DesktopSize pseduo-encoding', function () {
|
it('should handle the DesktopSize pseduo-encoding', function () {
|
||||||
client.onfbresize = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("fbresize", spy);
|
||||||
sinon.spy(client._display, 'resize');
|
sinon.spy(client._display, 'resize');
|
||||||
send_fbu_msg([{ x: 0, y: 0, width: 20, height: 50, encoding: -223 }], [[]], client);
|
send_fbu_msg([{ x: 0, y: 0, width: 20, height: 50, encoding: -223 }], [[]], client);
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy).to.have.been.calledWith(sinon.match.any, 20, 50);
|
expect(spy.args[0][0].detail.width).to.equal(20);
|
||||||
|
expect(spy.args[0][0].detail.height).to.equal(50);
|
||||||
|
|
||||||
expect(client._fb_width).to.equal(20);
|
expect(client._fb_width).to.equal(20);
|
||||||
expect(client._fb_height).to.equal(50);
|
expect(client._fb_height).to.equal(50);
|
||||||
|
@ -1452,6 +1454,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('the ExtendedDesktopSize pseudo-encoding handler', function () {
|
describe('the ExtendedDesktopSize pseudo-encoding handler', function () {
|
||||||
|
var resizeSpy;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
client._supportsSetDesktopSize = false;
|
client._supportsSetDesktopSize = false;
|
||||||
// a really small frame
|
// a really small frame
|
||||||
|
@ -1459,7 +1463,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
client._fb_height = 4;
|
client._fb_height = 4;
|
||||||
client._display.resize(4, 4);
|
client._display.resize(4, 4);
|
||||||
sinon.spy(client._display, 'resize');
|
sinon.spy(client._display, 'resize');
|
||||||
client.onfbresize = sinon.spy();
|
resizeSpy = sinon.spy();
|
||||||
|
client.addEventListener("fbresize", resizeSpy);
|
||||||
});
|
});
|
||||||
|
|
||||||
function make_screen_data (nr_of_screens) {
|
function make_screen_data (nr_of_screens) {
|
||||||
|
@ -1479,7 +1484,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should call callback when resize is supported', function () {
|
it('should call callback when resize is supported', function () {
|
||||||
client.oncapabilities = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("capabilities", spy);
|
||||||
|
|
||||||
expect(client._supportsSetDesktopSize).to.be.false;
|
expect(client._supportsSetDesktopSize).to.be.false;
|
||||||
expect(client.capabilities.resize).to.be.false;
|
expect(client.capabilities.resize).to.be.false;
|
||||||
|
@ -1492,8 +1498,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
make_screen_data(1), client);
|
make_screen_data(1), client);
|
||||||
|
|
||||||
expect(client._supportsSetDesktopSize).to.be.true;
|
expect(client._supportsSetDesktopSize).to.be.true;
|
||||||
expect(client.oncapabilities).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(client.oncapabilities.args[0][1].resize).to.be.true;
|
expect(spy.args[0][0].detail.capabilities.resize).to.be.true;
|
||||||
expect(client.capabilities.resize).to.be.true;
|
expect(client.capabilities.resize).to.be.true;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -1511,9 +1517,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(client._display.resize).to.have.been.calledOnce;
|
expect(client._display.resize).to.have.been.calledOnce;
|
||||||
expect(client._display.resize).to.have.been.calledWith(20, 50);
|
expect(client._display.resize).to.have.been.calledWith(20, 50);
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
expect(resizeSpy).to.have.been.calledOnce;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(resizeSpy.args[0][0].detail.width).to.equal(20);
|
||||||
expect(spy).to.have.been.calledWith(sinon.match.any, 20, 50);
|
expect(resizeSpy.args[0][0].detail.height).to.equal(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a resize requested by another client', function () {
|
it('should handle a resize requested by another client', function () {
|
||||||
|
@ -1530,9 +1536,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(client._display.resize).to.have.been.calledOnce;
|
expect(client._display.resize).to.have.been.calledOnce;
|
||||||
expect(client._display.resize).to.have.been.calledWith(20, 50);
|
expect(client._display.resize).to.have.been.calledWith(20, 50);
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
expect(resizeSpy).to.have.been.calledOnce;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(resizeSpy.args[0][0].detail.width).to.equal(20);
|
||||||
expect(spy).to.have.been.calledWith(sinon.match.any, 20, 50);
|
expect(resizeSpy.args[0][0].detail.height).to.equal(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to recieve requests which contain data for multiple screens', function () {
|
it('should be able to recieve requests which contain data for multiple screens', function () {
|
||||||
|
@ -1549,9 +1555,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(client._display.resize).to.have.been.calledOnce;
|
expect(client._display.resize).to.have.been.calledOnce;
|
||||||
expect(client._display.resize).to.have.been.calledWith(60, 50);
|
expect(client._display.resize).to.have.been.calledWith(60, 50);
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
expect(resizeSpy).to.have.been.calledOnce;
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(resizeSpy.args[0][0].detail.width).to.equal(60);
|
||||||
expect(spy).to.have.been.calledWith(sinon.match.any, 60, 50);
|
expect(resizeSpy.args[0][0].detail.height).to.equal(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not handle a failed request', function () {
|
it('should not handle a failed request', function () {
|
||||||
|
@ -1567,8 +1573,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
expect(client._display.resize).to.not.have.been.called;
|
expect(client._display.resize).to.not.have.been.called;
|
||||||
|
|
||||||
var spy = client.onfbresize;
|
expect(resizeSpy).to.not.have.been.called;
|
||||||
expect(spy).to.not.have.been.called;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1585,19 +1590,20 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
describe('XVP Message Handling', function () {
|
describe('XVP Message Handling', function () {
|
||||||
it('should send a notification on XVP_FAIL', function () {
|
it('should send a notification on XVP_FAIL', function () {
|
||||||
client.onnotification = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("notification", spy);
|
||||||
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 0]));
|
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 0]));
|
||||||
var spy = client.onnotification;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal('XVP Operation Failed');
|
expect(spy.args[0][0].detail.message).to.equal('XVP Operation Failed');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {
|
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {
|
||||||
client.oncapabilities = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("capabilities", spy);
|
||||||
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1]));
|
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1]));
|
||||||
expect(client._rfb_xvp_ver).to.equal(10);
|
expect(client._rfb_xvp_ver).to.equal(10);
|
||||||
expect(client.oncapabilities).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(client.oncapabilities.args[0][1].power).to.be.true;
|
expect(spy.args[0][0].detail.capabilities.power).to.be.true;
|
||||||
expect(client.capabilities.power).to.be.true;
|
expect(client.capabilities.power).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1613,18 +1619,19 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
var data = [3, 0, 0, 0];
|
var data = [3, 0, 0, 0];
|
||||||
push32(data, expected_str.length);
|
push32(data, expected_str.length);
|
||||||
for (var i = 0; i < expected_str.length; i++) { data.push(expected_str.charCodeAt(i)); }
|
for (var i = 0; i < expected_str.length; i++) { data.push(expected_str.charCodeAt(i)); }
|
||||||
client.onclipboard = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("clipboard", spy);
|
||||||
|
|
||||||
client._sock._websocket._receive_data(new Uint8Array(data));
|
client._sock._websocket._receive_data(new Uint8Array(data));
|
||||||
var spy = client.onclipboard;
|
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.args[0][1]).to.equal(expected_str);
|
expect(spy.args[0][0].detail.text).to.equal(expected_str);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire the bell callback on Bell', function () {
|
it('should fire the bell callback on Bell', function () {
|
||||||
client.onbell = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("bell", spy);
|
||||||
client._sock._websocket._receive_data(new Uint8Array([2]));
|
client._sock._websocket._receive_data(new Uint8Array([2]));
|
||||||
expect(client.onbell).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond correctly to ServerFence', function () {
|
it('should respond correctly to ServerFence', function () {
|
||||||
|
@ -1850,9 +1857,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should process all normal messages directly', function () {
|
it('should process all normal messages directly', function () {
|
||||||
client.onbell = sinon.spy();
|
var spy = sinon.spy();
|
||||||
|
client.addEventListener("bell", spy);
|
||||||
client._sock._websocket._receive_data(new Uint8Array([0x02, 0x02]));
|
client._sock._websocket._receive_data(new Uint8Array([0x02, 0x02]));
|
||||||
expect(client.onbell).to.have.been.calledTwice;
|
expect(spy).to.have.been.calledTwice;
|
||||||
});
|
});
|
||||||
|
|
||||||
// open events
|
// open events
|
||||||
|
|
|
@ -98,10 +98,10 @@
|
||||||
UIresize();
|
UIresize();
|
||||||
doneInitialResize = true;
|
doneInitialResize = true;
|
||||||
}
|
}
|
||||||
function updateDesktopName(rfb, name) {
|
function updateDesktopName(e) {
|
||||||
desktopName = name;
|
desktopName = e.detail.name;
|
||||||
}
|
}
|
||||||
function credentials(rfb, types) {
|
function credentials(e) {
|
||||||
var html;
|
var html;
|
||||||
|
|
||||||
var form = document.createElement('form');
|
var form = document.createElement('form');
|
||||||
|
@ -148,9 +148,9 @@
|
||||||
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_" + level);
|
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_" + level);
|
||||||
document.getElementById('noVNC_status').textContent = text;
|
document.getElementById('noVNC_status').textContent = text;
|
||||||
}
|
}
|
||||||
function updateState(rfb, state, oldstate) {
|
function updateState(e) {
|
||||||
var cad = document.getElementById('sendCtrlAltDelButton');
|
var cad = document.getElementById('sendCtrlAltDelButton');
|
||||||
switch (state) {
|
switch (e.detail.state) {
|
||||||
case 'connecting':
|
case 'connecting':
|
||||||
status("Connecting", "normal");
|
status("Connecting", "normal");
|
||||||
break;
|
break;
|
||||||
|
@ -172,11 +172,11 @@
|
||||||
status("Disconnected", "normal");
|
status("Disconnected", "normal");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
status(state, "warn");
|
status(e.detail.state, "warn");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state === 'connected') {
|
if (e.detail.state === 'connected') {
|
||||||
cad.disabled = false;
|
cad.disabled = false;
|
||||||
} else {
|
} else {
|
||||||
cad.disabled = true;
|
cad.disabled = true;
|
||||||
|
@ -184,13 +184,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
function disconnected(rfb, reason) {
|
function disconnect(e) {
|
||||||
if (typeof(reason) !== 'undefined') {
|
if (typeof(e.detail.reason) !== 'undefined') {
|
||||||
status(reason, "error");
|
status(e.detail.reason, "error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function notification(rfb, msg, level) {
|
function notification(e) {
|
||||||
status(msg, level);
|
status(e.detail.message, e.detail.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onresize = function () {
|
window.onresize = function () {
|
||||||
|
@ -275,12 +275,12 @@
|
||||||
shared: WebUtil.getConfigVar('shared', true),
|
shared: WebUtil.getConfigVar('shared', true),
|
||||||
credentials: { password: password } });
|
credentials: { password: password } });
|
||||||
rfb.viewOnly = WebUtil.getConfigVar('view_only', false);
|
rfb.viewOnly = WebUtil.getConfigVar('view_only', false);
|
||||||
rfb.onnotification = notification;
|
rfb.addEventListener("notification", notification);
|
||||||
rfb.onupdatestate = updateState;
|
rfb.addEventListener("updatestate", updateState);
|
||||||
rfb.ondisconnected = disconnected;
|
rfb.addEventListener("disconnect", disconnect);
|
||||||
rfb.oncapabilities = function () { updatePowerButtons(); initialResize(); };
|
rfb.addEventListener("capabilities", function () { updatePowerButtons(); initialResize(); });
|
||||||
rfb.oncredentialsrequired = credentials;
|
rfb.addEventListener("credentialsrequired", credentials);
|
||||||
rfb.ondesktopname = updateDesktopName;
|
rfb.addEventListener("desktopname", updateDesktopName);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
Loading…
Reference in New Issue