summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuanjo Diaz <juanjo.diazmo@gmail.com>2018-07-05 21:31:56 +0200
committerJuanjo Diaz <juanjo.diazmo@gmail.com>2018-07-12 19:06:57 +0200
commit0e4808bf6f3165f7daa1282af445f6ea7e60de55 (patch)
tree956ae93dd7725a7f9ae92ed4d33a477402688378
parent67fefcf184c1f291292027a785b333ba1a16f0c9 (diff)
downloadnovnc-0e4808bf6f3165f7daa1282af445f6ea7e60de55.tar.gz
Use ES6 classes
Always use the shorthand notation if the function is a method of an object or class `{ foo() { ... } }` or `class bar { foo() { ... } }` unless it's a callback in which case you a fat arrow function should be used `{ cb: () => { ... } }`
-rw-r--r--.eslintrc28
-rw-r--r--app/localization.js29
-rw-r--r--app/ui.js190
-rw-r--r--core/base64.js5
-rw-r--r--core/display.js251
-rw-r--r--core/inflator.js26
-rw-r--r--core/input/keyboard.js89
-rw-r--r--core/input/keysymdef.js2
-rw-r--r--core/input/mouse.js104
-rw-r--r--core/rfb.js741
-rw-r--r--core/util/cursor.js124
-rw-r--r--core/util/eventtarget.js22
-rw-r--r--core/util/strings.js1
-rw-r--r--core/websock.js171
-rw-r--r--tests/.eslintrc14
-rw-r--r--tests/fake.websocket.js50
-rw-r--r--tests/playback-ui.js42
-rw-r--r--tests/playback.js58
-rw-r--r--tests/test.rfb.js36
-rw-r--r--tests/test.webutil.js6
20 files changed, 997 insertions, 992 deletions
diff --git a/.eslintrc b/.eslintrc
index aef4c0d..ea4d655 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,15 +1,17 @@
{
- "env": {
- "browser": true,
- "es6": true
- },
- "parserOptions": {
- "sourceType": "module"
- },
- "extends": "eslint:recommended",
- "rules": {
- "no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
- "no-constant-condition": ["error", { "checkLoops": false }],
- "no-var": "error"
- }
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "parserOptions": {
+ "sourceType": "module"
+ },
+ "extends": "eslint:recommended",
+ "rules": {
+ "no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "no-var": "error",
+ "no-useless-constructor": "error",
+ "object-shorthand": ["error", "methods", { "avoidQuotes": true }],
+ }
}
diff --git a/app/localization.js b/app/localization.js
index 11144f7..6bc8d55 100644
--- a/app/localization.js
+++ b/app/localization.js
@@ -10,17 +10,17 @@
* Localization Utilities
*/
-export function Localizer() {
- // Currently configured language
- this.language = 'en';
+export class Localizer {
+ constructor() {
+ // Currently configured language
+ this.language = 'en';
- // Current dictionary of translations
- this.dictionary = undefined;
-}
+ // Current dictionary of translations
+ this.dictionary = undefined;
+ }
-Localizer.prototype = {
// Configure suitable language based on user preferences
- setup: function (supportedLanguages) {
+ setup(supportedLanguages) {
this.language = 'en'; // Default: US English
/*
@@ -78,21 +78,22 @@ Localizer.prototype = {
return;
}
}
- },
+ }
// Retrieve localised text
- get: function (id) {
+ get(id) {
if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
return this.dictionary[id];
} else {
return id;
}
- },
+ }
// Traverses the DOM and translates relevant fields
// See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
- translateDOM: function () {
+ translateDOM() {
const self = this;
+
function process(elem, enabled) {
function isAnyOf(searchElement, items) {
return items.indexOf(searchElement) !== -1;
@@ -160,8 +161,8 @@ Localizer.prototype = {
}
process(document.body, true);
- },
-};
+ }
+}
export const l10n = new Localizer();
export default l10n.get.bind(l10n);
diff --git a/app/ui.js b/app/ui.js
index f792d01..a8537fb 100644
--- a/app/ui.js
+++ b/app/ui.js
@@ -41,7 +41,7 @@ const UI = {
reconnect_callback: null,
reconnect_password: null,
- prime: function(callback) {
+ prime(callback) {
if (document.readyState === "interactive" || document.readyState === "complete") {
UI.load(callback);
} else {
@@ -51,12 +51,12 @@ const UI = {
// Setup rfb object, load settings from browser storage, then call
// UI.init to setup the UI/menus
- load: function(callback) {
+ load(callback) {
WebUtil.initSettings(UI.start, callback);
},
// Render default UI and initialize settings menu
- start: function(callback) {
+ start(callback) {
// Setup global variables first
UI.isSafari = (navigator.userAgent.indexOf('Safari') !== -1 &&
@@ -116,7 +116,7 @@ const UI = {
}
},
- initFullscreen: function() {
+ initFullscreen() {
// Only show the button if fullscreen is properly supported
// * Safari doesn't support alphanumerical input while in fullscreen
if (!UI.isSafari &&
@@ -130,7 +130,7 @@ const UI = {
}
},
- initSettings: function() {
+ initSettings() {
// Logging selection dropdown
const llevels = ['error', 'warn', 'info', 'debug'];
for (let i = 0; i < llevels.length; i += 1) {
@@ -169,7 +169,7 @@ const UI = {
UI.setupSettingLabels();
},
// Adds a link to the label elements on the corresponding input elements
- setupSettingLabels: function() {
+ setupSettingLabels() {
const labels = document.getElementsByTagName('LABEL');
for (let i = 0; i < labels.length; i++) {
const htmlFor = labels[i].htmlFor;
@@ -195,7 +195,7 @@ const UI = {
* EVENT HANDLERS
* ------v------*/
- addControlbarHandlers: function() {
+ addControlbarHandlers() {
document.getElementById("noVNC_control_bar")
.addEventListener('mousemove', UI.activateControlbar);
document.getElementById("noVNC_control_bar")
@@ -228,7 +228,7 @@ const UI = {
}
},
- addTouchSpecificHandlers: function() {
+ addTouchSpecificHandlers() {
document.getElementById("noVNC_mouse_button0")
.addEventListener('click', function () { UI.setMouseButton(1); });
document.getElementById("noVNC_mouse_button1")
@@ -277,7 +277,7 @@ const UI = {
.addEventListener('touchmove', UI.dragControlbarHandle);
},
- addExtraKeysHandlers: function() {
+ addExtraKeysHandlers() {
document.getElementById("noVNC_toggle_extra_keys_button")
.addEventListener('click', UI.toggleExtraKeys);
document.getElementById("noVNC_toggle_ctrl_button")
@@ -292,7 +292,7 @@ const UI = {
.addEventListener('click', UI.sendCtrlAltDel);
},
- addMachineHandlers: function() {
+ addMachineHandlers() {
document.getElementById("noVNC_shutdown_button")
.addEventListener('click', function() { UI.rfb.machineShutdown(); });
document.getElementById("noVNC_reboot_button")
@@ -303,7 +303,7 @@ const UI = {
.addEventListener('click', UI.togglePowerPanel);
},
- addConnectionControlHandlers: function() {
+ addConnectionControlHandlers() {
document.getElementById("noVNC_disconnect_button")
.addEventListener('click', UI.disconnect);
document.getElementById("noVNC_connect_button")
@@ -315,7 +315,7 @@ const UI = {
.addEventListener('click', UI.setPassword);
},
- addClipboardHandlers: function() {
+ addClipboardHandlers() {
document.getElementById("noVNC_clipboard_button")
.addEventListener('click', UI.toggleClipboardPanel);
document.getElementById("noVNC_clipboard_text")
@@ -326,7 +326,7 @@ const UI = {
// Add a call to save settings when the element changes,
// unless the optional parameter changeFunc is used instead.
- addSettingChangeHandler: function(name, changeFunc) {
+ addSettingChangeHandler(name, changeFunc) {
const settingElem = document.getElementById("noVNC_setting_" + name);
if (changeFunc === undefined) {
changeFunc = function () { UI.saveSetting(name); };
@@ -334,7 +334,7 @@ const UI = {
settingElem.addEventListener('change', changeFunc);
},
- addSettingsHandlers: function() {
+ addSettingsHandlers() {
document.getElementById("noVNC_settings_button")
.addEventListener('click', UI.toggleSettingsPanel);
@@ -357,7 +357,7 @@ const UI = {
UI.addSettingChangeHandler('reconnect_delay');
},
- addFullscreenHandlers: function() {
+ addFullscreenHandlers() {
document.getElementById("noVNC_fullscreen_button")
.addEventListener('click', UI.toggleFullscreen);
@@ -374,7 +374,7 @@ const UI = {
* ------v------*/
// Disable/enable controls depending on connection state
- updateVisualState: function(state) {
+ updateVisualState(state) {
document.documentElement.classList.remove("noVNC_connecting");
document.documentElement.classList.remove("noVNC_connected");
@@ -441,7 +441,7 @@ const UI = {
.classList.remove('noVNC_open');
},
- showStatus: function(text, status_type, time) {
+ showStatus(text, status_type, time) {
const statusElem = document.getElementById('noVNC_status');
clearTimeout(UI.statusTimeout);
@@ -502,12 +502,12 @@ const UI = {
}
},
- hideStatus: function() {
+ hideStatus() {
clearTimeout(UI.statusTimeout);
document.getElementById('noVNC_status').classList.remove("noVNC_open");
},
- activateControlbar: function(event) {
+ activateControlbar(event) {
clearTimeout(UI.idleControlbarTimeout);
// We manipulate the anchor instead of the actual control
// bar in order to avoid creating new a stacking group
@@ -516,27 +516,27 @@ const UI = {
UI.idleControlbarTimeout = window.setTimeout(UI.idleControlbar, 2000);
},
- idleControlbar: function() {
+ idleControlbar() {
document.getElementById('noVNC_control_bar_anchor')
.classList.add("noVNC_idle");
},
- keepControlbar: function() {
+ keepControlbar() {
clearTimeout(UI.closeControlbarTimeout);
},
- openControlbar: function() {
+ openControlbar() {
document.getElementById('noVNC_control_bar')
.classList.add("noVNC_open");
},
- closeControlbar: function() {
+ closeControlbar() {
UI.closeAllPanels();
document.getElementById('noVNC_control_bar')
.classList.remove("noVNC_open");
},
- toggleControlbar: function() {
+ toggleControlbar() {
if (document.getElementById('noVNC_control_bar')
.classList.contains("noVNC_open")) {
UI.closeControlbar();
@@ -545,7 +545,7 @@ const UI = {
}
},
- toggleControlbarSide: function () {
+ toggleControlbarSide() {
// Temporarily disable animation, if bar is displayed, to avoid weird
// movement. The transitionend-event will not fire when display=none.
const bar = document.getElementById('noVNC_control_bar');
@@ -569,7 +569,7 @@ const UI = {
UI.controlbarDrag = true;
},
- showControlbarHint: function (show) {
+ showControlbarHint(show) {
const hint = document.getElementById('noVNC_control_bar_hint');
if (show) {
hint.classList.add("noVNC_active");
@@ -578,7 +578,7 @@ const UI = {
}
},
- dragControlbarHandle: function (e) {
+ dragControlbarHandle(e) {
if (!UI.controlbarGrabbed) return;
const ptr = getPointerEvent(e);
@@ -616,7 +616,7 @@ const UI = {
},
// Move the handle but don't allow any position outside the bounds
- moveControlbarHandle: function (viewportRelativeY) {
+ moveControlbarHandle(viewportRelativeY) {
const handle = document.getElementById("noVNC_control_bar_handle");
const handleHeight = handle.getBoundingClientRect().height;
const controlbarBounds = document.getElementById("noVNC_control_bar")
@@ -653,7 +653,7 @@ const UI = {
handle.style.transform = "translateY(" + parentRelativeY + "px)";
},
- updateControlbarHandle: function () {
+ updateControlbarHandle() {
// Since the control bar is fixed on the viewport and not the page,
// the move function expects coordinates relative the the viewport.
const handle = document.getElementById("noVNC_control_bar_handle");
@@ -661,7 +661,7 @@ const UI = {
UI.moveControlbarHandle(handleBounds.top);
},
- controlbarHandleMouseUp: function(e) {
+ controlbarHandleMouseUp(e) {
if ((e.type == "mouseup") && (e.button != 0)) return;
// mouseup and mousedown on the same place toggles the controlbar
@@ -676,7 +676,7 @@ const UI = {
UI.showControlbarHint(false);
},
- controlbarHandleMouseDown: function(e) {
+ controlbarHandleMouseDown(e) {
if ((e.type == "mousedown") && (e.button != 0)) return;
const ptr = getPointerEvent(e);
@@ -702,7 +702,7 @@ const UI = {
UI.activateControlbar();
},
- toggleExpander: function(e) {
+ toggleExpander(e) {
if (this.classList.contains("noVNC_open")) {
this.classList.remove("noVNC_open");
} else {
@@ -717,7 +717,7 @@ const UI = {
* ------v------*/
// Initial page load read/initialization of settings
- initSetting: function(name, defVal) {
+ initSetting(name, defVal) {
// Check Query string followed by cookie
let val = WebUtil.getConfigVar(name);
if (val === null) {
@@ -729,7 +729,7 @@ const UI = {
},
// Set the new value, update and disable form control setting
- forceSetting: function(name, val) {
+ forceSetting(name, val) {
WebUtil.setSetting(name, val);
UI.updateSetting(name);
UI.disableSetting(name);
@@ -737,7 +737,7 @@ const UI = {
// Update cookie and form control setting. If value is not set, then
// updates from control to current cookie setting.
- updateSetting: function(name) {
+ updateSetting(name) {
// Update the settings control
let value = UI.getSetting(name);
@@ -764,7 +764,7 @@ const UI = {
},
// Save control setting to cookie
- saveSetting: function(name) {
+ saveSetting(name) {
const ctrl = document.getElementById('noVNC_setting_' + name);
let val;
if (ctrl.type === 'checkbox') {
@@ -780,7 +780,7 @@ const UI = {
},
// Read form control compatible setting from cookie
- getSetting: function(name) {
+ getSetting(name) {
const ctrl = document.getElementById('noVNC_setting_' + name);
let val = WebUtil.readSetting(name);
if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
@@ -796,13 +796,13 @@ const UI = {
// These helpers compensate for the lack of parent-selectors and
// previous-sibling-selectors in CSS which are needed when we want to
// disable the labels that belong to disabled input elements.
- disableSetting: function(name) {
+ disableSetting(name) {
const ctrl = document.getElementById('noVNC_setting_' + name);
ctrl.disabled = true;
ctrl.label.classList.add('noVNC_disabled');
},
- enableSetting: function(name) {
+ enableSetting(name) {
const ctrl = document.getElementById('noVNC_setting_' + name);
ctrl.disabled = false;
ctrl.label.classList.remove('noVNC_disabled');
@@ -814,7 +814,7 @@ const UI = {
* PANELS
* ------v------*/
- closeAllPanels: function() {
+ closeAllPanels() {
UI.closeSettingsPanel();
UI.closePowerPanel();
UI.closeClipboardPanel();
@@ -827,7 +827,7 @@ const UI = {
* SETTINGS (panel)
* ------v------*/
- openSettingsPanel: function() {
+ openSettingsPanel() {
UI.closeAllPanels();
UI.openControlbar();
@@ -849,14 +849,14 @@ const UI = {
.classList.add("noVNC_selected");
},
- closeSettingsPanel: function() {
+ closeSettingsPanel() {
document.getElementById('noVNC_settings')
.classList.remove("noVNC_open");
document.getElementById('noVNC_settings_button')
.classList.remove("noVNC_selected");
},
- toggleSettingsPanel: function() {
+ toggleSettingsPanel() {
if (document.getElementById('noVNC_settings')
.classList.contains("noVNC_open")) {
UI.closeSettingsPanel();
@@ -871,7 +871,7 @@ const UI = {
* POWER
* ------v------*/
- openPowerPanel: function() {
+ openPowerPanel() {
UI.closeAllPanels();
UI.openControlbar();
@@ -881,14 +881,14 @@ const UI = {
.classList.add("noVNC_selected");
},
- closePowerPanel: function() {
+ closePowerPanel() {
document.getElementById('noVNC_power')
.classList.remove("noVNC_open");
document.getElementById('noVNC_power_button')
.classList.remove("noVNC_selected");
},
- togglePowerPanel: function() {
+ togglePowerPanel() {
if (document.getElementById('noVNC_power')
.classList.contains("noVNC_open")) {
UI.closePowerPanel();
@@ -898,7 +898,7 @@ const UI = {
},
// Disable/enable power button
- updatePowerButton: function() {
+ updatePowerButton() {
if (UI.connected &&
UI.rfb.capabilities.power &&
!UI.rfb.viewOnly) {
@@ -918,7 +918,7 @@ const UI = {
* CLIPBOARD
* ------v------*/
- openClipboardPanel: function() {
+ openClipboardPanel() {
UI.closeAllPanels();
UI.openControlbar();
@@ -928,14 +928,14 @@ const UI = {
.classList.add("noVNC_selected");
},
- closeClipboardPanel: function() {
+ closeClipboardPanel() {
document.getElementById('noVNC_clipboard')
.classList.remove("noVNC_open");
document.getElementById('noVNC_clipboard_button')
.classList.remove("noVNC_selected");
},
- toggleClipboardPanel: function() {
+ toggleClipboardPanel() {
if (document.getElementById('noVNC_clipboard')
.classList.contains("noVNC_open")) {
UI.closeClipboardPanel();
@@ -944,18 +944,18 @@ const UI = {
}
},
- clipboardReceive: function(e) {
+ clipboardReceive(e) {
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0,40) + "...");
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
Log.Debug("<< UI.clipboardReceive");
},
- clipboardClear: function() {
+ clipboardClear() {
document.getElementById('noVNC_clipboard_text').value = "";
UI.rfb.clipboardPasteFrom("");
},
- clipboardSend: function() {
+ clipboardSend() {
const text = document.getElementById('noVNC_clipboard_text').value;
Log.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "...");
UI.rfb.clipboardPasteFrom(text);
@@ -968,17 +968,17 @@ const UI = {
* CONNECTION
* ------v------*/
- openConnectPanel: function() {
+ openConnectPanel() {
document.getElementById('noVNC_connect_dlg')
.classList.add("noVNC_open");
},
- closeConnectPanel: function() {
+ closeConnectPanel() {
document.getElementById('noVNC_connect_dlg')
.classList.remove("noVNC_open");
},
- connect: function(event, password) {
+ connect(event, password) {
// Ignore when rfb already exists
if (typeof UI.rfb !== 'undefined') {
@@ -1040,7 +1040,7 @@ const UI = {
UI.updateViewOnly(); // requires UI.rfb
},
- disconnect: function() {
+ disconnect() {
UI.closeAllPanels();
UI.rfb.disconnect();
@@ -1054,7 +1054,7 @@ const UI = {
// Don't display the connection settings until we're actually disconnected
},
- reconnect: function() {
+ reconnect() {
UI.reconnect_callback = null;
// if reconnect has been disabled in the meantime, do nothing.
@@ -1065,7 +1065,7 @@ const UI = {
UI.connect(null, UI.reconnect_password);
},
- cancelReconnect: function() {
+ cancelReconnect() {
if (UI.reconnect_callback !== null) {
clearTimeout(UI.reconnect_callback);
UI.reconnect_callback = null;
@@ -1077,7 +1077,7 @@ const UI = {
UI.openConnectPanel();
},
- connectFinished: function (e) {
+ connectFinished(e) {
UI.connected = true;
UI.inhibit_reconnect = false;
@@ -1094,7 +1094,7 @@ const UI = {
UI.rfb.focus();
},
- disconnectFinished: function (e) {
+ disconnectFinished(e) {
const wasConnected = UI.connected;
// This variable is ideally set when disconnection starts, but
@@ -1128,7 +1128,7 @@ const UI = {
UI.openConnectPanel();
},
- securityFailed: function (e) {
+ securityFailed(e) {
let msg = "";
// On security failures we might get a string with a reason
// directly from the server. Note that we can't control if
@@ -1148,7 +1148,7 @@ const UI = {
* PASSWORD
* ------v------*/
- credentials: function(e) {
+ credentials(e) {
// FIXME: handle more types
document.getElementById('noVNC_password_dlg')
.classList.add('noVNC_open');
@@ -1161,7 +1161,7 @@ const UI = {
UI.showStatus(_("Password is required"), "warning");
},
- setPassword: function(e) {
+ setPassword(e) {
// Prevent actually submitting the form
e.preventDefault();
@@ -1181,7 +1181,7 @@ const UI = {
* FULLSCREEN
* ------v------*/
- toggleFullscreen: function() {
+ toggleFullscreen() {
if (document.fullscreenElement || // alternative standard method
document.mozFullScreenElement || // currently working methods
document.webkitFullscreenElement ||
@@ -1210,7 +1210,7 @@ const UI = {
UI.updateFullscreenButton();
},
- updateFullscreenButton: function() {
+ updateFullscreenButton() {
if (document.fullscreenElement || // alternative standard method
document.mozFullScreenElement || // currently working methods
document.webkitFullscreenElement ||
@@ -1230,7 +1230,7 @@ const UI = {
* ------v------*/
// Apply remote resizing or local scaling
- applyResizeMode: function() {
+ applyResizeMode() {
if (!UI.rfb) return;
UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale';
@@ -1244,7 +1244,7 @@ const UI = {
* ------v------*/
// Update parameters that depend on the viewport clip setting
- updateViewClip: function() {
+ updateViewClip() {
if (!UI.rfb) return;
const cur_clip = UI.rfb.clipViewport;
@@ -1265,7 +1265,7 @@ const UI = {
},
// Handle special cases where viewport clipping is locked
- enableDisableViewClip: function() {
+ enableDisableViewClip() {
const resizeSetting = UI.getSetting('resize');
if (isTouchDevice) {
UI.forceSetting('view_clip', true);
@@ -1282,7 +1282,7 @@ const UI = {
* VIEWDRAG
* ------v------*/
- toggleViewDrag: function() {
+ toggleViewDrag() {
if (!UI.rfb) return;
const drag = UI.rfb.dragViewport;
@@ -1290,7 +1290,7 @@ const UI = {
},
// Set the view drag mode which moves the viewport on mouse drags
- setViewDrag: function(drag) {
+ setViewDrag(drag) {
if (!UI.rfb) return;
UI.rfb.dragViewport = drag;
@@ -1298,7 +1298,7 @@ const UI = {
UI.updateViewDrag();
},
- updateViewDrag: function() {
+ updateViewDrag() {
if (!UI.connected) return;
const viewDragButton = document.getElementById('noVNC_view_drag_button');
@@ -1342,7 +1342,7 @@ const UI = {
* KEYBOARD
* ------v------*/
- showVirtualKeyboard: function() {
+ showVirtualKeyboard() {
if (!isTouchDevice) return;
const input = document.getElementById('noVNC_keyboardinput');
@@ -1360,7 +1360,7 @@ const UI = {
}
},
- hideVirtualKeyboard: function() {
+ hideVirtualKeyboard() {
if (!isTouchDevice) return;
const input = document.getElementById('noVNC_keyboardinput');
@@ -1370,7 +1370,7 @@ const UI = {
input.blur();
},
- toggleVirtualKeyboard: function () {
+ toggleVirtualKeyboard() {
if (document.getElementById('noVNC_keyboard_button')
.classList.contains("noVNC_selected")) {
UI.hideVirtualKeyboard();
@@ -1379,7 +1379,7 @@ const UI = {
}
},
- onfocusVirtualKeyboard: function(event) {
+ onfocusVirtualKeyboard(event) {
document.getElementById('noVNC_keyboard_button')
.classList.add("noVNC_selected");
if (UI.rfb) {
@@ -1387,7 +1387,7 @@ const UI = {
}
},
- onblurVirtualKeyboard: function(event) {
+ onblurVirtualKeyboard(event) {
document.getElementById('noVNC_keyboard_button')
.classList.remove("noVNC_selected");
if (UI.rfb) {
@@ -1395,7 +1395,7 @@ const UI = {
}
},
- keepVirtualKeyboard: function(event) {
+ keepVirtualKeyboard(event) {
const input = document.getElementById('noVNC_keyboardinput');
// Only prevent focus change if the virtual keyboard is active
@@ -1423,13 +1423,13 @@ const UI = {
event.preventDefault();
},
- keyboardinputReset: function() {
+ keyboardinputReset() {
const kbi = document.getElementById('noVNC_keyboardinput');
kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
UI.lastKeyboardinput = kbi.value;
},
- keyEvent: function (keysym, code, down) {
+ keyEvent(keysym, code, down) {
if (!UI.rfb) return;
UI.rfb.sendKey(keysym, code, down);
@@ -1439,7 +1439,7 @@ const UI = {
// the keyboardinput element instead and generate the corresponding key events.
// This code is required since some browsers on Android are inconsistent in
// sending keyCodes in the normal keyboard events when using on screen keyboards.
- keyInput: function(event) {
+ keyInput(event) {
if (!UI.rfb) return;
@@ -1506,7 +1506,7 @@ const UI = {
* EXTRA KEYS
* ------v------*/
- openExtraKeys: function() {
+ openExtraKeys() {
UI.closeAllPanels();
UI.openControlbar();
@@ -1516,14 +1516,14 @@ const UI = {
.classList.add("noVNC_selected");
},
- closeExtraKeys: function() {
+ closeExtraKeys() {
document.getElementById('noVNC_modifiers')
.classList.remove("noVNC_open");
document.getElementById('noVNC_toggle_extra_keys_button')
.classList.remove("noVNC_selected");
},
- toggleExtraKeys: function() {
+ toggleExtraKeys() {
if(document.getElementById('noVNC_modifiers')
.classList.contains("noVNC_open")) {
UI.closeExtraKeys();
@@ -1532,15 +1532,15 @@ const UI = {
}
},
- sendEsc: function() {
+ sendEsc() {
UI.rfb.sendKey(KeyTable.XK_Escape, "Escape");
},
- sendTab: function() {
+ sendTab() {
UI.rfb.sendKey(KeyTable.XK_Tab);
},
- toggleCtrl: function() {
+ toggleCtrl() {
const btn = document.getElementById('noVNC_toggle_ctrl_button');
if (btn.classList.contains("noVNC_selected")) {
UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
@@ -1551,7 +1551,7 @@ const UI = {
}
},
- toggleAlt: function() {
+ toggleAlt() {
const btn = document.getElementById('noVNC_toggle_alt_button');
if (btn.classList.contains("noVNC_selected")) {
UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
@@ -1562,7 +1562,7 @@ const UI = {
}
},
- sendCtrlAltDel: function() {
+ sendCtrlAltDel() {
UI.rfb.sendCtrlAltDel();
},
@@ -1572,7 +1572,7 @@ const UI = {
* MISC
* ------v------*/
- setMouseButton: function(num) {
+ setMouseButton(num) {
const view_only = UI.rfb.viewOnly;
if (UI.rfb && !view_only) {
UI.rfb.touchButton = num;
@@ -1590,7 +1590,7 @@ const UI = {
}
},
- updateViewOnly: function() {
+ updateViewOnly() {
if (!UI.rfb) return;
UI.rfb.viewOnly = UI.getSetting('view_only');
@@ -1609,17 +1609,17 @@ const UI = {
UI.setMouseButton(1); //has it's own logic for hiding/showing
},
- updateLogging: function() {
+ updateLogging() {
WebUtil.init_logging(UI.getSetting('logging'));
},
- updateDesktopName: function(e) {
+ updateDesktopName(e) {
UI.desktopName = e.detail.name;
// Display the desktop name in the document title
document.title = e.detail.name + " - noVNC";
},
- bell: function(e) {
+ bell(e) {
if (WebUtil.getConfigVar('bell', 'on') === 'on') {
const promise = document.getElementById('noVNC_bell').play();
// The standards disagree on the return value here
@@ -1638,7 +1638,7 @@ const UI = {
},
//Helper to add options to dropdown.
- addOption: function(selectbox, text, value) {
+ addOption(selectbox, text, value) {
const optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
diff --git a/core/base64.js b/core/base64.js
index d57d986..895aa46 100644
--- a/core/base64.js
+++ b/core/base64.js
@@ -11,7 +11,7 @@ export default {
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
base64Pad : '=',
- encode: function (data) {
+ encode(data) {
"use strict";
let result = '';
const length = data.length;
@@ -54,8 +54,7 @@ export default {
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
],
- decode: function (data, offset) {
- "use strict";
+ decode(data, offset) {
offset = typeof(offset) !== 'undefined' ? offset : 0;
let data_length = data.indexOf('=') - offset;
diff --git a/core/display.js b/core/display.js
index 057b12f..4955ce2 100644
--- a/core/display.js
+++ b/core/display.js
@@ -10,109 +10,112 @@
import * as Log from './util/logging.js';
import Base64 from "./base64.js";
-export default function Display(target) {
- this._drawCtx = null;
- this._c_forceCanvas = false;
+let SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
+try {
+ new ImageData(new Uint8ClampedArray(4), 1, 1);
+ SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
+} catch (ex) {
+ // ignore failure
+}
- this._renderQ = []; // queue drawing actions for in-oder rendering
- this._flushing = false;
+export default class Display {
+ constructor(target) {
+ this._drawCtx = null;
+ this._c_forceCanvas = false;
- // the full frame buffer (logical canvas) size
- this._fb_width = 0;
- this._fb_height = 0;
+ this._renderQ = []; // queue drawing actions for in-oder rendering
+ this._flushing = false;
- this._prevDrawStyle = "";
- this._tile = null;
- this._tile16x16 = null;
- this._tile_x = 0;
- this._tile_y = 0;
+ // the full frame buffer (logical canvas) size
+ this._fb_width = 0;
+ this._fb_height = 0;
- Log.Debug(">> Display.constructor");
+ this._prevDrawStyle = "";
+ this._tile = null;
+ this._tile16x16 = null;
+ this._tile_x = 0;
+ this._tile_y = 0;
- // The visible canvas
- this._target = target;
+ Log.Debug(">> Display.constructor");
- if (!this._target) {
- throw new Error("Target must be set");
- }
+ // The visible canvas
+ this._target = target;
- if (typeof this._target === 'string') {
- throw new Error('target must be a DOM element');
- }
+ if (!this._target) {
+ throw new Error("Target must be set");
+ }
- if (!this._target.getContext) {
- throw new Error("no getContext method");
- }
+ if (typeof this._target === 'string') {
+ throw new Error('target must be a DOM element');
+ }
- this._targetCtx = this._target.getContext('2d');
+ if (!this._target.getContext) {
+ throw new Error("no getContext method");
+ }
- // the visible canvas viewport (i.e. what actually gets seen)
- this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height };
+ this._targetCtx = this._target.getContext('2d');
- // The hidden canvas, where we do the actual rendering
- this._backbuffer = document.createElement('canvas');
- this._drawCtx = this._backbuffer.getContext('2d');
+ // the visible canvas viewport (i.e. what actually gets seen)
+ this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height };
- this._damageBounds = { left:0, top:0,
- right: this._backbuffer.width,
- bottom: this._backbuffer.height };
+ // The hidden canvas, where we do the actual rendering
+ this._backbuffer = document.createElement('canvas');
+ this._drawCtx = this._backbuffer.getContext('2d');
- Log.Debug("User Agent: " + navigator.userAgent);
+ this._damageBounds = { left:0, top:0,
+ right: this._backbuffer.width,
+ bottom: this._backbuffer.height };
- this.clear();
+ Log.Debug("User Agent: " + navigator.userAgent);
- // Check canvas features
- if (!('createImageData' in this._drawCtx)) {
- throw new Error("Canvas does not support createImageData");
- }
+ this.clear();
- this._tile16x16 = this._drawCtx.createImageData(16, 16);
- Log.Debug("<< Display.constructor");
-}
+ // Check canvas features
+ if (!('createImageData' in this._drawCtx)) {
+ throw new Error("Canvas does not support createImageData");
+ }
-let SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
-try {
- new ImageData(new Uint8ClampedArray(4), 1, 1);
- SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
-} catch (ex) {
- // ignore failure
-}
+ this._tile16x16 = this._drawCtx.createImageData(16, 16);
+ Log.Debug("<< Display.constructor");
+
+ // ===== PROPERTIES =====
+
+ this._scale = 1.0;
+ this._clipViewport = false;
+ this.logo = null;
+
+ // ===== EVENT HANDLERS =====
+
+ this.onflush = () => {}; // A flush request has finished
+ }
-Display.prototype = {
// ===== PROPERTIES =====
- _scale: 1.0,
- get scale() { return this._scale; },
+ get scale() { return this._scale; }
set scale(scale) {
this._rescale(scale);
- },
+ }
- _clipViewport: false,
- get clipViewport() { return this._clipViewport; },
+ get clipViewport() { return this._clipViewport; }
set clipViewport(viewport) {
this._clipViewport = viewport;
// May need to readjust the viewport dimensions
const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0);
- },
+ }
get width() {
return this._fb_width;
- },
+ }
+
get height() {
return this._fb_height;
- },
-
- logo: null,
-
- // ===== EVENT HANDLERS =====
-
- onflush: function () {}, // A flush request has finished
+ }
// ===== PUBLIC METHODS =====
- viewportChangePos: function (deltaX, deltaY) {
+ viewportChangePos(deltaX, deltaY) {
const vp = this._viewportLoc;
deltaX = Math.floor(deltaX);
deltaY = Math.floor(deltaY);
@@ -152,9 +155,9 @@ Display.prototype = {
this._damage(vp.x, vp.y, vp.w, vp.h);
this.flip();
- },
+ }
- viewportChangeSize: function(width, height) {
+ viewportChangeSize(width, height) {
if (!this._clipViewport ||
typeof(width) === "undefined" ||
@@ -190,17 +193,17 @@ Display.prototype = {
// Update the visible size of the target canvas
this._rescale(this._scale);
}
- },
+ }
- absX: function (x) {
+ absX(x) {
return x / this._scale + this._viewportLoc.x;
- },
+ }
- absY: function (y) {
+ absY(y) {
return y / this._scale + this._viewportLoc.y;
- },
+ }
- resize: function (width, height) {
+ resize(width, height) {
this._prevDrawStyle = "";
this._fb_width = width;
@@ -232,10 +235,10 @@ Display.prototype = {
const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0);
- },
+ }
// Track what parts of the visible canvas that need updating
- _damage: function(x, y, w, h) {
+ _damage(x, y, w, h) {
if (x < this._damageBounds.left) {
this._damageBounds.left = x;
}
@@ -248,11 +251,11 @@ Display.prototype = {
if ((y + h) > this._damageBounds.bottom) {
this._damageBounds.bottom = y + h;
}
- },
+ }
// Update the visible canvas with the contents of the
// rendering canvas
- flip: function(from_queue) {
+ flip(from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'flip'
@@ -296,9 +299,9 @@ Display.prototype = {
this._damageBounds.left = this._damageBounds.top = 65535;
this._damageBounds.right = this._damageBounds.bottom = 0;
}
- },
+ }
- clear: function () {
+ clear() {
if (this._logo) {
this.resize(this._logo.width, this._logo.height);
this.imageRect(0, 0, this._logo.type, this._logo.data);
@@ -307,21 +310,21 @@ Display.prototype = {
this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
}
this.flip();
- },
+ }
- pending: function() {
+ pending() {
return this._renderQ.length > 0;
- },
+ }
- flush: function() {
+ flush() {
if (this._renderQ.length === 0) {
this.onflush();
} else {
this._flushing = true;
}
- },
+ }
- fillRect: function (x, y, width, height, color, from_queue) {
+ fillRect(x, y, width, height, color, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'fill',
@@ -336,9 +339,9 @@ Display.prototype = {
this._drawCtx.fillRect(x, y, width, height);
this._damage(x, y, width, height);
}
- },
+ }
- copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) {
+ copyImage(old_x, old_y, new_x, new_y, w, h, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'copy',
@@ -367,9 +370,9 @@ Display.prototype = {
new_x, new_y, w, h);
this._damage(new_x, new_y, w, h);
}
- },
+ }
- imageRect: function(x, y, mime, arr) {
+ imageRect(x, y, mime, arr) {
const img = new Image();
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
this._renderQ_push({
@@ -378,10 +381,10 @@ Display.prototype = {
'x': x,
'y': y
});
- },
+ }
// start updating a tile
- startTile: function (x, y, width, height, color) {
+ startTile(x, y, width, height, color) {
this._tile_x = x;
this._tile_y = y;
if (width === 16 && height === 16) {
@@ -401,10 +404,10 @@ Display.prototype = {
data[i + 2] = blue;
data[i + 3] = 255;
}
- },
+ }
// update sub-rectangle of the current tile
- subTile: function (x, y, w, h, color) {
+ subTile(x, y, w, h, color) {
const red = color[2];
const green = color[1];
const blue = color[0];
@@ -422,16 +425,16 @@ Display.prototype = {
data[p + 3] = 255;
}
}
- },
+ }
// draw the current tile to the screen
- finishTile: function () {
+ finishTile() {
this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y);
this._damage(this._tile_x, this._tile_y,
this._tile.width, this._tile.height);
- },
+ }
- blitImage: function (x, y, width, height, arr, offset, from_queue) {
+ blitImage(x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
@@ -449,9 +452,9 @@ Display.prototype = {
} else {
this._bgrxImageData(x, y, width, height, arr, offset);
}
- },
+ }
- blitRgbImage: function (x, y , width, height, arr, offset, from_queue) {
+ blitRgbImage(x, y , width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
@@ -469,9 +472,9 @@ Display.prototype = {
} else {
this._rgbImageData(x, y, width, height, arr, offset);
}
- },
+ }
- blitRgbxImage: function (x, y, width, height, arr, offset, from_queue) {
+ blitRgbxImage(x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
@@ -489,14 +492,14 @@ Display.prototype = {
} else {
this._rgbxImageData(x, y, width, height, arr, offset);
}
- },
+ }
- drawImage: function (img, x, y) {
+ drawImage(img, x, y) {
this._drawCtx.drawImage(img, x, y);
this._damage(x, y, img.width, img.height);
- },
+ }
- autoscale: function (containerWidth, containerHeight) {
+ autoscale(containerWidth, containerHeight) {
const vp = this._viewportLoc;
const targetAspectRatio = containerWidth / containerHeight;
const fbAspectRatio = vp.w / vp.h;
@@ -509,11 +512,11 @@ Display.prototype = {
}
this._rescale(scaleRatio);
- },
+ }
// ===== PRIVATE METHODS =====
- _rescale: function (factor) {
+ _rescale(factor) {
this._scale = factor;
const vp = this._viewportLoc;
@@ -529,17 +532,17 @@ Display.prototype = {
this._target.style.width = width;
this._target.style.height = height;
}
- },
+ }
- _setFillColor: function (color) {
+ _setFillColor(color) {
const newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
if (newStyle !== this._prevDrawStyle) {
this._drawCtx.fillStyle = newStyle;
this._prevDrawStyle = newStyle;
}
- },
+ }
- _rgbImageData: function (x, y, width, height, arr, offset) {
+ _rgbImageData(x, y, width, height, arr, offset) {
const img = this._drawCtx.createImageData(width, height);
const data = img.data;
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
@@ -550,9 +553,9 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
- },
+ }
- _bgrxImageData: function (x, y, width, height, arr, offset) {
+ _bgrxImageData(x, y, width, height, arr, offset) {
const img = this._drawCtx.createImageData(width, height);
const data = img.data;
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
@@ -563,9 +566,9 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
- },
+ }
- _rgbxImageData: function (x, y, width, height, arr, offset) {
+ _rgbxImageData(x, y, width, height, arr, offset) {
// NB(directxman12): arr must be an Type Array view
let img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
@@ -576,25 +579,25 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
- },
+ }
- _renderQ_push: function (action) {
+ _renderQ_push(action) {
this._renderQ.push(action);
if (this._renderQ.length === 1) {
// If this can be rendered immediately it will be, otherwise
// the scanner will wait for the relevant event
this._scan_renderQ();
}
- },
+ }
- _resume_renderQ: function() {
+ _resume_renderQ() {
// "this" is the object that is ready, not the
// display object
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
this._noVNC_display._scan_renderQ();
- },
+ }
- _scan_renderQ: function () {
+ _scan_renderQ() {
let ready = true;
while (ready && this._renderQ.length > 0) {
const a = this._renderQ[0];
@@ -639,5 +642,5 @@ Display.prototype = {
this._flushing = false;
this.onflush();
}
- },
-};
+ }
+}
diff --git a/core/inflator.js b/core/inflator.js
index 48fb719..0eab8fe 100644
--- a/core/inflator.js
+++ b/core/inflator.js
@@ -1,8 +1,17 @@
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
-Inflate.prototype = {
- inflate: function (data, flush, expected) {
+export default class Inflate {
+ constructor() {
+ this.strm = new ZStream();
+ this.chunkSize = 1024 * 10 * 10;
+ this.strm.output = new Uint8Array(this.chunkSize);
+ this.windowBits = 5;
+
+ inflateInit(this.strm, this.windowBits);
+ }
+
+ inflate(data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
@@ -21,18 +30,9 @@ Inflate.prototype = {
inflate(this.strm, flush);
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
- },
+ }
- reset: function () {
+ reset() {
inflateReset(this.strm);
}
-};
-
-export default function Inflate() {
- this.strm = new ZStream();
- this.chunkSize = 1024 * 10 * 10;
- this.strm.output = new Uint8Array(this.chunkSize);
- this.windowBits = 5;
-
- inflateInit(this.strm, this.windowBits);
}
diff --git a/core/input/keyboard.js b/core/input/keyboard.js
index d64298a..5b46748 100644
--- a/core/input/keyboard.js
+++ b/core/input/keyboard.js
@@ -15,32 +15,32 @@ import * as browser from "../util/browser.js";
// Keyboard event handler
//
-export default function Keyboard(target) {
- this._target = target || null;
-
- this._keyDownList = {}; // List of depressed keys
- // (even if they are happy)
- this._pendingKey = null; // Key waiting for keypress
- this._altGrArmed = false; // Windows AltGr detection
-
- // keep these here so we can refer to them later
- this._eventHandlers = {
- 'keyup': this._handleKeyUp.bind(this),
- 'keydown': this._handleKeyDown.bind(this),
- 'keypress': this._handleKeyPress.bind(this),
- 'blur': this._allKeysUp.bind(this),
- 'checkalt': this._checkAlt.bind(this),
- };
-}
+export default class Keyboard {
+ constructor(target) {
+ this._target = target || null;
+
+ this._keyDownList = {}; // List of depressed keys
+ // (even if they are happy)
+ this._pendingKey = null; // Key waiting for keypress
+ this._altGrArmed = false; // Windows AltGr detection
+
+ // keep these here so we can refer to them later
+ this._eventHandlers = {
+ 'keyup': this._handleKeyUp.bind(this),
+ 'keydown': this._handleKeyDown.bind(this),
+ 'keypress': this._handleKeyPress.bind(this),
+ 'blur': this._allKeysUp.bind(this),
+ 'checkalt': this._checkAlt.bind(this),
+ };
-Keyboard.prototype = {
- // ===== EVENT HANDLERS =====
+ // ===== EVENT HANDLERS =====
- onkeyevent: function () {}, // Handler for key press/release
+ this.onkeyevent = () => {}; // Handler for key press/release
+ }
// ===== PRIVATE METHODS =====
- _sendKeyEvent: function (keysym, code, down) {
+ _sendKeyEvent(keysym, code, down) {
if (down) {
this._keyDownList[code] = keysym;
} else {
@@ -54,9 +54,9 @@ Keyboard.prototype = {
Log.Debug("onkeyevent " + (down ? "down" : "up") +
", keysym: " + keysym, ", code: " + code);
this.onkeyevent(keysym, code, down);
- },
+ }
- _getKeyCode: function (e) {
+ _getKeyCode(e) {
const code = KeyboardUtil.getKeycode(e);
if (code !== 'Unidentified') {
return code;
@@ -87,9 +87,9 @@ Keyboard.prototype = {
}
return 'Unidentified';
- },
+ }
- _handleKeyDown: function (e) {
+ _handleKeyDown(e) {
const code = this._getKeyCode(e);
let keysym = KeyboardUtil.getKeysym(e);
@@ -198,10 +198,10 @@ Keyboard.prototype = {
}
this._sendKeyEvent(keysym, code, true);
- },
+ }
// Legacy event for browsers without code/key
- _handleKeyPress: function (e) {
+ _handleKeyPress(e) {
stopEvent(e);
// Are we expecting a keypress?
@@ -226,8 +226,9 @@ Keyboard.prototype = {
}
this._sendKeyEvent(keysym, code, true);
- },
- _handleKeyPressTimeout: function (e) {
+ }
+
+ _handleKeyPressTimeout(e) {
// Did someone manage to sort out the key already?
if (this._pendingKey === null) {
return;
@@ -259,9 +260,9 @@ Keyboard.prototype = {
}
this._sendKeyEvent(keysym, code, true);
- },
+ }
- _handleKeyUp: function (e) {
+ _handleKeyUp(e) {
stopEvent(e);
const code = this._getKeyCode(e);
@@ -282,24 +283,24 @@ Keyboard.prototype = {
}
this._sendKeyEvent(this._keyDownList[code], code, false);
- },
+ }
- _handleAltGrTimeout: function () {
+ _handleAltGrTimeout() {
this._altGrArmed = false;
clearTimeout(this._altGrTimeout);
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
- },
+ }
- _allKeysUp: function () {
+ _allKeysUp() {
Log.Debug(">> Keyboard.allKeysUp");
for (let code in this._keyDownList) {
this._sendKeyEvent(this._keyDownList[code], code, false);
}
Log.Debug("<< Keyboard.allKeysUp");
- },
+ }
// Firefox Alt workaround, see below
- _checkAlt: function (e) {
+ _checkAlt(e) {
if (e.altKey) {
return;
}
@@ -316,11 +317,11 @@ Keyboard.prototype = {
code: code });
target.dispatchEvent(event);
});
- },
+ }
// ===== PUBLIC METHODS =====
- grab: function () {
+ grab() {
//Log.Debug(">> Keyboard.grab");
this._target.addEventListener('keydown', this._eventHandlers.keydown);
@@ -341,13 +342,13 @@ Keyboard.prototype = {
document.addEventListener(type, handler,
{ capture: true,
passive: true });
- });
+ });
}
//Log.Debug("<< Keyboard.grab");
- },
+ }
- ungrab: function () {
+ ungrab() {
//Log.Debug(">> Keyboard.ungrab");
if (browser.isWindows() && browser.isFirefox()) {
@@ -368,5 +369,5 @@ Keyboard.prototype = {
this._allKeysUp();
//Log.Debug(">> Keyboard.ungrab");
- },
-};
+ }
+}
diff --git a/core/input/keysymdef.js b/core/input/keysymdef.js
index 5969b5d..951caca 100644
--- a/core/input/keysymdef.js
+++ b/core/input/keysymdef.js
@@ -670,7 +670,7 @@ const codepoints = {
};
export default {
- lookup : function(u) {
+ lookup(u) {
// Latin-1 is one-to-one mapping
if ((u >= 0x20) && (u <= 0xff)) {
return u;
diff --git a/core/input/mouse.js b/core/input/mouse.js
index 17c8cd5..4a8710e 100644
--- a/core/input/mouse.js
+++ b/core/input/mouse.js
@@ -13,44 +13,44 @@ const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
const WHEEL_STEP_TIMEOUT = 50; // ms
const WHEEL_LINE_HEIGHT = 19;
-export default function Mouse(target) {
- this._target = target || document;
-
- this._doubleClickTimer = null;
- this._lastTouchPos = null;
-
- this._pos = null;
- this._wheelStepXTimer = null;
- this._wheelStepYTimer = null;
- this._accumulatedWheelDeltaX = 0;
- this._accumulatedWheelDeltaY = 0;
-
- this._eventHandlers = {
- 'mousedown': this._handleMouseDown.bind(this),
- 'mouseup': this._handleMouseUp.bind(this),
- 'mousemove': this._handleMouseMove.bind(this),
- 'mousewheel': this._handleMouseWheel.bind(this),
- 'mousedisable': this._handleMouseDisable.bind(this)
- };
-}
+export default class Mouse {
+ constructor(target) {
+ this._target = target || document;
+
+ this._doubleClickTimer = null;
+ this._lastTouchPos = null;
+
+ this._pos = null;
+ this._wheelStepXTimer = null;
+ this._wheelStepYTimer = null;
+ this._accumulatedWheelDeltaX = 0;
+ this._accumulatedWheelDeltaY = 0;
+
+ this._eventHandlers = {
+ 'mousedown': this._handleMouseDown.bind(this),
+ 'mouseup': this._handleMouseUp.bind(this),
+ 'mousemove': this._handleMouseMove.bind(this),
+ 'mousewheel': this._handleMouseWheel.bind(this),
+ 'mousedisable': this._handleMouseDisable.bind(this)
+ };
-Mouse.prototype = {
- // ===== PROPERTIES =====
+ // ===== PROPERTIES =====
- touchButton: 1, // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
+ this.touchButton = 1; // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
- // ===== EVENT HANDLERS =====
+ // ===== EVENT HANDLERS =====
- onmousebutton: function () {}, // Handler for mouse button click/release
- onmousemove: function () {}, // Handler for mouse movement
+ this.onmousebutton = () => {}; // Handler for mouse button click/release
+ this.onmousemove = () => {}; // Handler for mouse movement
+ }
// ===== PRIVATE METHODS =====
- _resetDoubleClickTimer: function () {
+ _resetDoubleClickTimer() {
this._doubleClickTimer = null;
- },
+ }
- _handleMouseButton: function (e, down) {
+ _handleMouseButton(e, down) {
this._updateMousePosition(e);
let pos = this._pos;
@@ -100,25 +100,25 @@ Mouse.prototype = {
this.onmousebutton(pos.x, pos.y, down, bmask);
stopEvent(e);
- },
+ }
- _handleMouseDown: function (e) {
+ _handleMouseDown(e) {
// Touch events have implicit capture
if (e.type === "mousedown") {
setCapture(this._target);
}
this._handleMouseButton(e, 1);
- },
+ }
- _handleMouseUp: function (e) {
+ _handleMouseUp(e) {
this._handleMouseButton(e, 0);
- },
+ }
// Mouse wheel events are sent in steps over VNC. This means that the VNC
// protocol can't handle a wheel event with specific distance or speed.
// Therefor, if we get a lot of small mouse wheel events we combine them.
- _generateWheelStepX: function () {
+ _generateWheelStepX() {
if (this._accumulatedWheelDeltaX < 0) {
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
@@ -129,9 +129,9 @@ Mouse.prototype = {
}
this._accumulatedWheelDeltaX = 0;
- },
+ }
- _generateWheelStepY: function () {
+ _generateWheelStepY() {
if (this._accumulatedWheelDeltaY < 0) {
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
@@ -142,16 +142,16 @@ Mouse.prototype = {
}
this._accumulatedWheelDeltaY = 0;
- },
+ }
- _resetWheelStepTimers: function () {
+ _resetWheelStepTimers() {
window.clearTimeout(this._wheelStepXTimer);
window.clearTimeout(this._wheelStepYTimer);
this._wheelStepXTimer = null;
this._wheelStepYTimer = null;
- },
+ }
- _handleMouseWheel: function (e) {
+ _handleMouseWheel(e) {
this._resetWheelStepTimers();
this._updateMousePosition(e);
@@ -192,15 +192,15 @@ Mouse.prototype = {
}
stopEvent(e);
- },
+ }
- _handleMouseMove: function (e) {
+ _handleMouseMove(e) {
this._updateMousePosition(e);
this.onmousemove(this._pos.x, this._pos.y);
stopEvent(e);
- },
+ }
- _handleMouseDisable: function (e) {
+ _handleMouseDisable(e) {
/*
* Stop propagation if inside canvas area
* Note: This is only needed for the 'click' event as it fails
@@ -210,10 +210,10 @@ Mouse.prototype = {
if (e.target == this._target) {
stopEvent(e);
}
- },
+ }
// Update coordinates relative to target
- _updateMousePosition: function(e) {
+ _updateMousePosition(e) {
e = getPointerEvent(e);
const bounds = this._target.getBoundingClientRect();
let x;
@@ -234,11 +234,11 @@ Mouse.prototype = {
y = e.clientY - bounds.top;
}
this._pos = {x:x, y:y};
- },
+ }
// ===== PUBLIC METHODS =====
- grab: function () {
+ grab() {
const c = this._target;
if (isTouchDevice) {
@@ -257,9 +257,9 @@ Mouse.prototype = {
/* preventDefault() on mousedown doesn't stop this event for some
reason so we have to explicitly block it */
c.addEventListener('contextmenu', this._eventHandlers.mousedisable);
- },
+ }
- ungrab: function () {
+ ungrab() {
const c = this._target;
this._resetWheelStepTimers();
@@ -278,4 +278,4 @@ Mouse.prototype = {
c.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
}
-};
+}
diff --git a/core/rfb.js b/core/rfb.js
index a94542f..ed765e8 100644
--- a/core/rfb.js
+++ b/core/rfb.js
@@ -28,238 +28,247 @@ import "./util/polyfill.js";
// How many seconds to wait for a disconnect to finish
const DISCONNECT_TIMEOUT = 3;
-export default function RFB(target, url, options) {
- if (!target) {
- throw Error("Must specify target");
- }
- if (!url) {
- throw Error("Must specify URL");
- }
+export default class RFB extends EventTargetMixin {
+ constructor(target, url, options) {
+ if (!target) {
+ throw Error("Must specify target");
+ }
+ if (!url) {
+ throw Error("Must specify URL");
+ }
+
+ super();
+
+ this._target = target;
+ this._url = url;
+
+ // Connection details
+ options = options || {};
+ this._rfb_credentials = options.credentials || {};
+ this._shared = 'shared' in options ? !!options.shared : true;
+ this._repeaterID = options.repeaterID || '';
+
+ // Internal state
+ this._rfb_connection_state = '';
+ this._rfb_init_state = '';
+ this._rfb_auth_scheme = '';
+ this._rfb_clean_disconnect = true;
+
+ // Server capabilities
+ this._rfb_version = 0;
+ this._rfb_max_version = 3.8;
+ this._rfb_tightvnc = false;
+ this._rfb_xvp_ver = 0;
+
+ this._fb_width = 0;
+ this._fb_height = 0;
+
+ this._fb_name = "";
+
+ this._capabilities = { power: false };
+
+ this._supportsFence = false;
+
+ this._supportsContinuousUpdates = false;
+ this._enabledContinuousUpdates = false;
+
+ this._supportsSetDesktopSize = false;
+ this._screen_id = 0;
+ this._screen_flags = 0;
+
+ this._qemuExtKeyEventSupported = false;
+
+ // Internal objects
+ this._sock = null; // Websock object
+ this._display = null; // Display object
+ this._flushing = false; // Display flushing state
+ this._keyboard = null; // Keyboard input handler object
+ this._mouse = null; // Mouse input handler object
+
+ // Timers
+ this._disconnTimer = null; // disconnection timer
+ this._resizeTimeout = null; // resize rate limiting
+
+ // Decoder states and stats
+ this._encHandlers = {};
+ this._encStats = {};
+
+ this._FBU = {
+ rects: 0,
+ subrects: 0, // RRE and HEXTILE
+ lines: 0, // RAW
+ tiles: 0, // HEXTILE
+ bytes: 0,
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0,
+ encoding: 0,
+ subencoding: -1,
+ background: null,
+ zlibs: [] // TIGHT zlib streams
+ };
- this._target = target;
- this._url = url;
-
- // Connection details
- options = options || {};
- this._rfb_credentials = options.credentials || {};
- this._shared = 'shared' in options ? !!options.shared : true;
- this._repeaterID = options.repeaterID || '';
-
- // Internal state
- this._rfb_connection_state = '';
- this._rfb_init_state = '';
- this._rfb_auth_scheme = '';
- this._rfb_clean_disconnect = true;
-
- // Server capabilities
- this._rfb_version = 0;
- this._rfb_max_version = 3.8;
- this._rfb_tightvnc = false;
- this._rfb_xvp_ver = 0;
-
- this._fb_width = 0;
- this._fb_height = 0;
-
- this._fb_name = "";
-
- this._capabilities = { power: false };
-
- this._supportsFence = false;
-
- this._supportsContinuousUpdates = false;
- this._enabledContinuousUpdates = false;
-
- this._supportsSetDesktopSize = false;
- this._screen_id = 0;
- this._screen_flags = 0;
-
- this._qemuExtKeyEventSupported = false;
-
- // Internal objects
- this._sock = null; // Websock object
- this._display = null; // Display object
- this._flushing = false; // Display flushing state
- this._keyboard = null; // Keyboard input handler object
- this._mouse = null; // Mouse input handler object
-
- // Timers
- this._disconnTimer = null; // disconnection timer
- this._resizeTimeout = null; // resize rate limiting
-
- // Decoder states and stats
- this._encHandlers = {};
- this._encStats = {};
-
- this._FBU = {
- rects: 0,
- subrects: 0, // RRE and HEXTILE
- lines: 0, // RAW
- tiles: 0, // HEXTILE
- bytes: 0,
- x: 0,
- y: 0,
- width: 0,
- height: 0,
- encoding: 0,
- subencoding: -1,
- background: null,
- zlibs: [] // TIGHT zlib streams
- };
- for (let i = 0; i < 4; i++) {
- this._FBU.zlibs[i] = new Inflator();
- }
+ for (let i = 0; i < 4; i++) {
+ this._FBU.zlibs[i] = new Inflator();
+ }
+
+ this._destBuff = null;
+ this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
- this._destBuff = null;
- this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
-
- this._rre_chunk_sz = 100;
-
- this._timing = {
- last_fbu: 0,
- fbu_total: 0,
- fbu_total_cnt: 0,
- full_fbu_total: 0,
- full_fbu_cnt: 0,
-
- fbu_rt_start: 0,
- fbu_rt_total: 0,
- fbu_rt_cnt: 0,
- pixels: 0
- };
-
- // Mouse state
- this._mouse_buttonMask = 0;
- this._mouse_arr = [];
- this._viewportDragging = false;
- this._viewportDragPos = {};
- this._viewportHasMoved = false;
-
- // Bound event handlers
- this._eventHandlers = {
- focusCanvas: this._focusCanvas.bind(this),
- windowResize: this._windowResize.bind(this),
- };
-
- // main setup
- Log.Debug(">> RFB.constructor");
-
- // Create DOM elements
- this._screen = document.createElement('div');
- this._screen.style.display = 'flex';
- this._screen.style.width = '100%';
- this._screen.style.height = '100%';
- this._screen.style.overflow = 'auto';
- this._screen.style.backgroundColor = 'rgb(40, 40, 40)';
- this._canvas = document.createElement('canvas');
- this._canvas.style.margin = 'auto';
- // Some browsers add an outline on focus
- this._canvas.style.outline = 'none';
- // IE miscalculates width without this :(
- this._canvas.style.flexShrink = '0';
- this._canvas.width = 0;
- this._canvas.height = 0;
- this._canvas.tabIndex = -1;
- this._screen.appendChild(this._canvas);
+ this._rre_chunk_sz = 100;
+
+ this._timing = {
+ last_fbu: 0,
+ fbu_total: 0,
+ fbu_total_cnt: 0,
+ full_fbu_total: 0,
+ full_fbu_cnt: 0,
+
+ fbu_rt_start: 0,
+ fbu_rt_total: 0,
+ fbu_rt_cnt: 0,
+ pixels: 0
+ };
+
+ // Mouse state
+ this._mouse_buttonMask = 0;
+ this._mouse_arr = [];
+ this._viewportDragging = false;
+ this._viewportDragPos = {};
+ this._viewportHasMoved = false;
+
+ // Bound event handlers
+ this._eventHandlers = {
+ focusCanvas: this._focusCanvas.bind(this),
+ windowResize: this._windowResize.bind(this),
+ };
+
+ // main setup
+ Log.Debug(">> RFB.constructor");
+
+ // Create DOM elements
+ this._screen = document.createElement('div');
+ this._screen.style.display = 'flex';
+ this._screen.style.width = '100%';
+ this._screen.style.height = '100%';
+ this._screen.style.overflow = 'auto';
+ this._screen.style.backgroundColor = 'rgb(40, 40, 40)';
+ this._canvas = document.createElement('canvas');
+ this._canvas.style.margin = 'auto';
+ // Some browsers add an outline on focus
+ this._canvas.style.outline = 'none';
+ // IE miscalculates width without this :(
+ this._canvas.style.flexShrink = '0';
+ this._canvas.width = 0;
+ this._canvas.height = 0;
+ this._canvas.tabIndex = -1;
+ this._screen.appendChild(this._canvas);
this._cursor = new Cursor();
- // populate encHandlers with bound versions
- this._encHandlers[encodings.encodingRaw] = RFB.encodingHandlers.RAW.bind(this);
- this._encHandlers[encodings.encodingCopyRect] = RFB.encodingHandlers.COPYRECT.bind(this);
- this._encHandlers[encodings.encodingRRE] = RFB.encodingHandlers.RRE.bind(this);
- this._encHandlers[encodings.encodingHextile] = RFB.encodingHandlers.HEXTILE.bind(this);
- this._encHandlers[encodings.encodingTight] = RFB.encodingHandlers.TIGHT.bind(this, false);
- this._encHandlers[encodings.encodingTightPNG] = RFB.encodingHandlers.TIGHT.bind(this, true);
-
- this._encHandlers[encodings.pseudoEncodingDesktopSize] = RFB.encodingHandlers.DesktopSize.bind(this);
- this._encHandlers[encodings.pseudoEncodingLastRect] = RFB.encodingHandlers.last_rect.bind(this);
- this._encHandlers[encodings.pseudoEncodingCursor] = RFB.encodingHandlers.Cursor.bind(this);
- this._encHandlers[encodings.pseudoEncodingQEMUExtendedKeyEvent] = RFB.encodingHandlers.QEMUExtendedKeyEvent.bind(this);
- this._encHandlers[encodings.pseudoEncodingExtendedDesktopSize] = RFB.encodingHandlers.ExtendedDesktopSize.bind(this);
-
- // NB: nothing that needs explicit teardown should be done
- // before this point, since this can throw an exception
- try {
- this._display = new Display(this._canvas);
- } catch (exc) {
- Log.Error("Display exception: " + exc);
- throw exc;
- }
- this._display.onflush = this._onFlush.bind(this);
- this._display.clear();
-
- this._keyboard = new Keyboard(this._canvas);
- this._keyboard.onkeyevent = this._handleKeyEvent.bind(this);
-
- this._mouse = new Mouse(this._canvas);
- this._mouse.onmousebutton = this._handleMouseButton.bind(this);
- this._mouse.onmousemove = this._handleMouseMove.bind(this);
-
- this._sock = new Websock();
- this._sock.on('message', this._handle_message.bind(this));
- this._sock.on('open', function () {
- if ((this._rfb_connection_state === 'connecting') &&
- (this._rfb_init_state === '')) {
- this._rfb_init_state = 'ProtocolVersion';
- Log.Debug("Starting VNC handshake");
- } else {
- this._fail("Unexpected server connection while " +
- this._rfb_connection_state);
- }
- }.bind(this));
- this._sock.on('close', function (e) {
- Log.Debug("WebSocket on-close event");
- let msg = "";
- if (e.code) {
- msg = "(code: " + e.code;
- if (e.reason) {
- msg += ", reason: " + e.reason;
+ // populate encHandlers with bound versions
+ this._encHandlers[encodings.encodingRaw] = RFB.encodingHandlers.RAW.bind(this);
+ this._encHandlers[encodings.encodingCopyRect] = RFB.encodingHandlers.COPYRECT.bind(this);
+ this._encHandlers[encodings.encodingRRE] = RFB.encodingHandlers.RRE.bind(this);
+ this._encHandlers[encodings.encodingHextile] = RFB.encodingHandlers.HEXTILE.bind(this);
+ this._encHandlers[encodings.encodingTight] = RFB.encodingHandlers.TIGHT.bind(this, false);
+ this._encHandlers[encodings.encodingTightPNG] = RFB.encodingHandlers.TIGHT.bind(this, true);
+
+ this._encHandlers[encodings.pseudoEncodingDesktopSize] = RFB.encodingHandlers.DesktopSize.bind(this);
+ this._encHandlers[encodings.pseudoEncodingLastRect] = RFB.encodingHandlers.last_rect.bind(this);
+ this._encHandlers[encodings.pseudoEncodingCursor] = RFB.encodingHandlers.Cursor.bind(this);
+ this._encHandlers[encodings.pseudoEncodingQEMUExtendedKeyEvent] = RFB.encodingHandlers.QEMUExtendedKeyEvent.bind(this);
+ this._encHandlers[encodings.pseudoEncodingExtendedDesktopSize] = RFB.encodingHandlers.ExtendedDesktopSize.bind(this);
+
+ // NB: nothing that needs explicit teardown should be done
+ // before this point, since this can throw an exception
+ try {
+ this._display = new Display(this._canvas);
+ } catch (exc) {
+ Log.Error("Display exception: " + exc);
+ throw exc;
+ }
+ this._display.onflush = this._onFlush.bind(this);
+ this._display.clear();
+
+ this._keyboard = new Keyboard(this._canvas);
+ this._keyboard.onkeyevent = this._handleKeyEvent.bind(this);
+
+ this._mouse = new Mouse(this._canvas);
+ this._mouse.onmousebutton = this._handleMouseButton.bind(this);
+ this._mouse.onmousemove = this._handleMouseMove.bind(this);
+
+ this._sock = new Websock();
+ this._sock.on('message', this._handle_message.bind(this));
+ this._sock.on('open', function () {
+ if ((this._rfb_connection_state === 'connecting') &&
+ (this._rfb_init_state === '')) {
+ this._rfb_init_state = 'ProtocolVersion';
+ Log.Debug("Starting VNC handshake");
+ } else {
+ this._fail("Unexpected server connection while " +
+ this._rfb_connection_state);
}
- msg += ")";
- }
- switch (this._rfb_connection_state) {
- case 'connecting':
- this._fail("Connection closed " + msg);
- break;
- case 'connected':
- // Handle disconnects that were initiated server-side
- this._updateConnectionState('disconnecting');
- this._updateConnectionState('disconnected');
- break;
- case 'disconnecting':
- // Normal disconnection path
- this._updateConnectionState('disconnected');
- break;
- case 'disconnected':
- this._fail("Unexpected server disconnect " +
- "when already disconnected " + msg);
- break;
- default:
- this._fail("Unexpected server disconnect before connecting " +
- msg);
- break;
- }
- this._sock.off('close');
- }.bind(this));
- this._sock.on('error', function (e) {
- Log.Warn("WebSocket on-error event");
- });
+ }.bind(this));
+ this._sock.on('close', function (e) {
+ Log.Debug("WebSocket on-close event");
+ let msg = "";
+ if (e.code) {
+ msg = "(code: " + e.code;
+ if (e.reason) {
+ msg += ", reason: " + e.reason;
+ }
+ msg += ")";
+ }
+ switch (this._rfb_connection_state) {
+ case 'connecting':
+ this._fail("Connection closed " + msg);
+ break;
+ case 'connected':
+ // Handle disconnects that were initiated server-side
+ this._updateConnectionState('disconnecting');
+ this._updateConnectionState('disconnected');
+ break;
+ case 'disconnecting':
+ // Normal disconnection path
+ this._updateConnectionState('disconnected');
+ break;
+ case 'disconnected':
+ this._fail("Unexpected server disconnect " +
+ "when already disconnected " + msg);
+ break;
+ default:
+ this._fail("Unexpected server disconnect before connecting " +
+ msg);
+ break;
+ }
+ this._sock.off('close');
+ }.bind(this));
+ this._sock.on('error', function (e) {
+ Log.Warn("WebSocket on-error event");
+ });
- // Slight delay of the actual connection so that the caller has
- // time to set up callbacks
- setTimeout(this._updateConnectionState.bind(this, 'connecting'));
+ // Slight delay of the actual connection so that the caller has
+ // time to set up callbacks
+ setTimeout(this._updateConnectionState.bind(this, 'connecting'));
- Log.Debug("<< RFB.constructor");
-}
+ Log.Debug("<< RFB.constructor");
-RFB.prototype = {
- // ===== PROPERTIES =====
+ // ===== PROPERTIES =====
- dragViewport: false,
- focusOnClick: true,
+ this.dragViewport = false;
+ this.focusOnClick = true;
- _viewOnly: false,
- get viewOnly() { return this._viewOnly; },
+ this._viewOnly = false;
+ this._clipViewport = false;
+ this._scaleViewport = false;
+ this._resizeSession = false;
+ }
+
+ // ===== PROPERTIES =====
+
+ get viewOnly() { return this._viewOnly; }
set viewOnly(viewOnly) {
this._viewOnly = viewOnly;
@@ -273,22 +282,20 @@ RFB.prototype = {
this._mouse.grab();
}
}
- },
+ }
- get capabilities() { return this._capabilities; },
+ get capabilities() { return this._capabilities; }
- get touchButton() { return this._mouse.touchButton; },
- set touchButton(button) { this._mouse.touchButton = button; },
+ get touchButton() { return this._mouse.touchButton; }
+ set touchButton(button) { this._mouse.touchButton = button; }
- _clipViewport: false,
- get clipViewport() { return this._clipViewport; },
+ get clipViewport() { return this._clipViewport; }
set clipViewport(viewport) {
this._clipViewport = viewport;
this._updateClip();
- },
+ }
- _scaleViewport: false,
- get scaleViewport() { return this._scaleViewport; },
+ get scaleViewport() { return this._scaleViewport; }
set scaleViewport(scale) {
this._scaleViewport = scale;
// Scaling trumps clipping, so we may need to adjust
@@ -300,32 +307,31 @@ RFB.prototype = {
if (!scale && this._clipViewport) {
this._updateClip();
}
- },
+ }
- _resizeSession: false,
- get resizeSession() { return this._resizeSession; },
+ get resizeSession() { return this._resizeSession; }
set resizeSession(resize) {
this._resizeSession = resize;
if (resize) {
this._requestRemoteResize();
}
- },
+ }
// ===== PUBLIC METHODS =====
- disconnect: function () {
+ disconnect() {
this._updateConnectionState('disconnecting');
this._sock.off('error');
this._sock.off('message');
this._sock.off('open');
- },
+ }
- sendCredentials: function (creds) {
+ sendCredentials(creds) {
this._rfb_credentials = creds;
setTimeout(this._init_msg.bind(this), 0);
- },
+ }
- sendCtrlAltDel: function () {
+ sendCtrlAltDel() {
if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; }
Log.Info("Sending Ctrl-Alt-Del");
@@ -335,23 +341,23 @@ RFB.prototype = {
this.sendKey(KeyTable.XK_Delete, "Delete", false);
this.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
this.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
- },
+ }
- machineShutdown: function () {
+ machineShutdown() {
this._xvpOp(1, 2);
- },
+ }
- machineReboot: function () {
+ machineReboot() {
this._xvpOp(1, 3);
- },
+ }
- machineReset: function () {
+ machineReset() {
this._xvpOp(1, 4);
- },
+ }
// Send a key press. If 'down' is not specified then send a down key
// followed by an up key.
- sendKey: function (keysym, code, down) {
+ sendKey(keysym, code, down) {
if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; }
if (down === undefined) {
@@ -376,24 +382,24 @@ RFB.prototype = {
Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);
RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
}
- },
+ }
- focus: function () {
+ focus() {
this._canvas.focus();
- },
+ }
- blur: function () {
+ blur() {
this._canvas.blur();
- },
+ }
- clipboardPasteFrom: function (text) {
+ clipboardPasteFrom(text) {
if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; }
RFB.messages.clientCutText(this._sock, text);
- },
+ }
// ===== PRIVATE METHODS =====
- _connect: function () {
+ _connect() {
Log.Debug(">> RFB.connect");
Log.Info("connecting to " + this._url);
@@ -423,9 +429,9 @@ RFB.prototype = {
this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas);
Log.Debug("<< RFB.connect");
- },
+ }
- _disconnect: function () {
+ _disconnect() {
Log.Debug(">> RFB.disconnect");
this._cursor.detach();
this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas);
@@ -447,9 +453,9 @@ RFB.prototype = {
}
clearTimeout(this._resizeTimeout);
Log.Debug("<< RFB.disconnect");
- },
+ }
- _print_stats: function () {
+ _print_stats() {
const stats = this._encStats;
Log.Info("Encoding stats for this connection:");
@@ -465,9 +471,9 @@ RFB.prototype = {
const s = stats[key];
Log.Info(" " + encodingName(key) + ": " + s[1] + " rects");
});
- },
+ }
- _focusCanvas: function(event) {
+ _focusCanvas(event) {
// Respect earlier handlers' request to not do side-effects
if (event.defaultPrevented) {
return;
@@ -478,9 +484,9 @@ RFB.prototype = {
}
this.focus();
- },
+ }
- _windowResize: function (event) {
+ _windowResize(event) {
// If the window resized then our screen element might have
// as well. Update the viewport dimensions.
window.requestAnimationFrame(function () {
@@ -497,11 +503,11 @@ RFB.prototype = {
clearTimeout(this._resizeTimeout);
this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), 500);
}
- },
+ }
// Update state of clipping in Display object, and make sure the
// configured viewport matches the current screen size
- _updateClip: function () {
+ _updateClip() {
const cur_clip = this._display.clipViewport;
let new_clip = this._clipViewport;
@@ -521,9 +527,9 @@ RFB.prototype = {
this._display.viewportChangeSize(size.w, size.h);
this._fixScrollbars();
}
- },
+ }
- _updateScale: function () {
+ _updateScale() {
if (!this._scaleViewport) {
this._display.scale = 1.0;
} else {
@@ -531,11 +537,11 @@ RFB.prototype = {
this._display.autoscale(size.w, size.h);
}
this._fixScrollbars();
- },
+ }
// Requests a change of remote desktop size. This message is an extension
// and may only be sent if we have received an ExtendedDesktopSize message
- _requestRemoteResize: function () {
+ _requestRemoteResize() {
clearTimeout(this._resizeTimeout);
this._resizeTimeout = null;
@@ -550,15 +556,15 @@ RFB.prototype = {
Log.Debug('Requested new desktop size: ' +
size.w + 'x' + size.h);
- },
+ }
// Gets the the size of the available screen
- _screenSize: function () {
+ _screenSize() {
return { w: this._screen.offsetWidth,
h: this._screen.offsetHeight };
- },
+ }
- _fixScrollbars: function () {
+ _fixScrollbars() {
// This is a hack because Chrome screws up the calculation
// for when scrollbars are needed. So to fix it we temporarily
// toggle them off and on.
@@ -568,7 +574,7 @@ RFB.prototype = {
// an element's dimensions
this._screen.getBoundingClientRect();
this._screen.style.overflow = orig;
- },
+ }
/*
* Connection states:
@@ -577,7 +583,7 @@ RFB.prototype = {
* disconnecting
* disconnected - permanent state
*/
- _updateConnectionState: function (state) {
+ _updateConnectionState(state) {
const oldstate = this._rfb_connection_state;
if (state === oldstate) {
@@ -670,14 +676,14 @@ RFB.prototype = {
{ clean: this._rfb_clean_disconnect } }));
break;
}
- },
+ }
/* Print errors and disconnect
*
* The parameter 'details' is used for information that
* should be logged but not sent to the user interface.
*/
- _fail: function (details) {
+ _fail(details) {
switch (this._rfb_connection_state) {
case 'disconnecting':
Log.Error("Failed when disconnecting: " + details);
@@ -699,15 +705,15 @@ RFB.prototype = {
this._updateConnectionState('disconnected');
return false;
- },
+ }
- _setCapability: function (cap, val) {
+ _setCapability(cap, val) {
this._capabilities[cap] = val;
this.dispatchEvent(new CustomEvent("capabilities",
- { detail: { capabilities: this._capabilities } }));
- },
+ { detail: { capabilities: this._capabilities } }));
+ }
- _handle_message: function () {
+ _handle_message() {
if (this._sock.rQlen() === 0) {
Log.Warn("handle_message called on an empty receive queue");
return;
@@ -734,13 +740,13 @@ RFB.prototype = {
this._init_msg();
break;
}
- },
+ }
- _handleKeyEvent: function (keysym, code, down) {
+ _handleKeyEvent(keysym, code, down) {
this.sendKey(keysym, code, down);
- },
+ }
- _handleMouseButton: function (x, y, down, bmask) {
+ _handleMouseButton(x, y, down, bmask) {
if (down) {
this._mouse_buttonMask |= bmask;
} else {
@@ -778,9 +784,9 @@ RFB.prototype = {
if (this._rfb_connection_state !== 'connected') { return; }
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
- },
+ }
- _handleMouseMove: function (x, y) {
+ _handleMouseMove(x, y) {
if (this._viewportDragging) {
const deltaX = this._viewportDragPos.x - x;
const deltaY = this._viewportDragPos.y - y;
@@ -805,11 +811,11 @@ RFB.prototype = {
if (this._rfb_connection_state !== 'connected') { return; }
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
- },
+ }
// Message Handlers
- _negotiate_protocol_version: function () {
+ _negotiate_protocol_version() {
if (this._sock.rQlen() < 12) {
return this._fail("Received incomplete protocol version.");
}
@@ -858,9 +864,9 @@ RFB.prototype = {
Log.Debug('Sent ProtocolVersion: ' + cversion);
this._rfb_init_state = 'Security';
- },
+ }
- _negotiate_security: function () {
+ _negotiate_security() {
// Polyfill since IE and PhantomJS doesn't have
// TypedArray.includes()
function includes(item, array) {
@@ -909,7 +915,7 @@ RFB.prototype = {
Log.Debug('Authenticating using scheme: ' + this._rfb_auth_scheme);
return this._init_msg(); // jump to authentication
- },
+ }
/*
* Get the security failure reason if sent from the server and
@@ -921,7 +927,7 @@ RFB.prototype = {
* - The optional parameter security_result_status can be used to
* add a custom status code to the event.
*/
- _handle_security_failure: function (context, security_result_status) {
+ _handle_security_failure(context, security_result_status) {
if (typeof context === 'undefined') {
context = "";
@@ -958,17 +964,17 @@ RFB.prototype = {
return this._fail("Security negotiation failed" + context);
}
- },
+ }
// authentication
- _negotiate_xvp_auth: function () {
+ _negotiate_xvp_auth() {
if (!this._rfb_credentials.username ||
!this._rfb_credentials.password ||
!this._rfb_credentials.target) {
this.dispatchEvent(new CustomEvent(
"credentialsrequired",
{ detail: { types: ["username", "password", "target"] } }));
- return false;
+ return false;
}
const xvp_auth_str = String.fromCharCode(this._rfb_credentials.username.length) +
@@ -978,9 +984,9 @@ RFB.prototype = {
this._sock.send_string(xvp_auth_str);
this._rfb_auth_scheme = 2;
return this._negotiate_authentication();
- },
+ }
- _negotiate_std_vnc_auth: function () {
+ _negotiate_std_vnc_auth() {
if (this._sock.rQwait("auth challenge", 16)) { return false; }
if (!this._rfb_credentials.password) {
@@ -996,9 +1002,9 @@ RFB.prototype = {
this._sock.send(response);
this._rfb_init_state = "SecurityResult";
return true;
- },
+ }
- _negotiate_tight_tunnels: function (numTunnels) {
+ _negotiate_tight_tunnels(numTunnels) {
const clientSupportedTunnelTypes = {
0: { vendor: 'TGHT', signature: 'NOTUNNEL' }
};
@@ -1037,9 +1043,9 @@ RFB.prototype = {
return this._fail("Server wanted tunnels, but doesn't support " +
"the notunnel type");
}
- },
+ }
- _negotiate_tight_auth: function () {
+ _negotiate_tight_auth() {
if (!this._rfb_tightvnc) { // first pass, do the tunnel negotiation
if (this._sock.rQwait("num tunnels", 4)) { return false; }
const numTunnels = this._sock.rQshift32();
@@ -1098,9 +1104,9 @@ RFB.prototype = {
}
return this._fail("No supported sub-auth types!");
- },
+ }
- _negotiate_authentication: function () {
+ _negotiate_authentication() {
switch (this._rfb_auth_scheme) {
case 0: // connection failed
return this._handle_security_failure("authentication scheme");
@@ -1126,9 +1132,9 @@ RFB.prototype = {
return this._fail("Unsupported auth scheme (scheme: " +
this._rfb_auth_scheme + ")");
}
- },
+ }
- _handle_security_result: function () {
+ _handle_security_result() {
if (this._sock.rQwait('VNC auth response ', 4)) { return false; }
const status = this._sock.rQshift32();
@@ -1148,9 +1154,9 @@ RFB.prototype = {
return this._fail("Security handshake failed");
}
}
- },
+ }
- _negotiate_server_init: function () {
+ _negotiate_server_init() {
if (this._sock.rQwait("server initialization", 24)) { return false; }
/* Screen size */
@@ -1254,9 +1260,9 @@ RFB.prototype = {
this._updateConnectionState('connected');
return true;
- },
+ }
- _sendEncodings: function () {
+ _sendEncodings() {
const encs = [];
// In preference order
@@ -1287,7 +1293,7 @@ RFB.prototype = {
}
RFB.messages.clientEncodings(this._sock, encs);
- },
+ }
/* RFB protocol initialization states:
* ProtocolVersion
@@ -1297,7 +1303,7 @@ RFB.prototype = {
* ClientInitialization - not triggered by server message
* ServerInitialization
*/
- _init_msg: function () {
+ _init_msg() {
switch (this._rfb_init_state) {
case 'ProtocolVersion':
return this._negotiate_protocol_version();
@@ -1323,15 +1329,15 @@ RFB.prototype = {
return this._fail("Unknown init state (state: " +
this._rfb_init_state + ")");
}
- },
+ }
- _handle_set_colour_map_msg: function () {
+ _handle_set_colour_map_msg() {
Log.Debug("SetColorMapEntries");
return this._fail("Unexpected SetColorMapEntries message");
- },
+ }
- _handle_server_cut_text: function () {
+ _handle_server_cut_text() {
Log.Debug("ServerCutText");
if (this._sock.rQwait("ServerCutText header", 7, 1)) { return false; }
@@ -1348,9 +1354,9 @@ RFB.prototype = {
{ detail: { text: text } }));
return true;
- },
+ }
- _handle_server_fence_msg: function() {
+ _handle_server_fence_msg() {
if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; }
this._sock.rQskipBytes(3); // Padding
let flags = this._sock.rQshift32();
@@ -1390,9 +1396,9 @@ RFB.prototype = {
RFB.messages.clientFence(this._sock, flags, payload);
return true;
- },
+ }
- _handle_xvp_msg: function () {
+ _handle_xvp_msg() {
if (this._sock.rQwait("XVP version and message", 3, 1)) { return false; }
this._sock.rQskip8(); // Padding
const xvp_ver = this._sock.rQshift8();
@@ -1413,9 +1419,9 @@ RFB.prototype = {
}
return true;
- },
+ }
- _normal_msg: function () {
+ _normal_msg() {
let msg_type;
if (this._FBU.rects > 0) {
msg_type = 0;
@@ -1471,17 +1477,17 @@ RFB.prototype = {
Log.Debug("sock.rQslice(0, 30): " + this._sock.rQslice(0, 30));
return true;
}
- },
+ }
- _onFlush: function() {
+ _onFlush() {
this._flushing = false;
// Resume processing
if (this._sock.rQlen() > 0) {
this._handle_message();
}
- },
+ }
- _framebufferUpdate: function () {
+ _framebufferUpdate() {
if (this._FBU.rects === 0) {
if (this._sock.rQwait("FBU header", 3, 1)) { return false; }
this._sock.rQskip8(); // Padding
@@ -1572,16 +1578,16 @@ RFB.prototype = {
this._display.flip();
return true; // We finished this FBU
- },
+ }
- _updateContinuousUpdates: function() {
+ _updateContinuousUpdates() {
if (!this._enabledContinuousUpdates) { return; }
RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0,
this._fb_width, this._fb_height);
- },
+ }
- _resize: function(width, height) {
+ _resize(width, height) {
this._fb_width = width;
this._fb_height = height;
@@ -1595,20 +1601,26 @@ RFB.prototype = {
this._timing.fbu_rt_start = (new Date()).getTime();
this._updateContinuousUpdates();
- },
+ }
- _xvpOp: function (ver, op) {
+ _xvpOp(ver, op) {
if (this._rfb_xvp_ver < ver) { return; }
Log.Info("Sending XVP operation " + op + " (version " + ver + ")");
RFB.messages.xvpOp(this._sock, ver, op);
- },
-};
+ }
-Object.assign(RFB.prototype, EventTargetMixin);
+ static genDES(password, challenge) {
+ const passwd = [];
+ for (let i = 0; i < password.length; i++) {
+ passwd.push(password.charCodeAt(i));
+ }
+ return (new DES(passwd)).encrypt(challenge);
+ }
+}
// Class Methods
RFB.messages = {
- keyEvent: function (sock, keysym, down) {
+ keyEvent(sock, keysym, down) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1627,7 +1639,7 @@ RFB.messages = {
sock.flush();
},
- QEMUExtendedKeyEvent: function (sock, keysym, down, keycode) {
+ QEMUExtendedKeyEvent(sock, keysym, down, keycode) {
function getRFBkeycode(xt_scancode) {
const upperByte = (keycode >> 8);
const lowerByte = (keycode & 0x00ff);
@@ -1662,7 +1674,7 @@ RFB.messages = {
sock.flush();
},
- pointerEvent: function (sock, x, y, mask) {
+ pointerEvent(sock, x, y, mask) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1681,7 +1693,7 @@ RFB.messages = {
},
// TODO(directxman12): make this unicode compatible?
- clientCutText: function (sock, text) {
+ clientCutText(sock, text) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1691,7 +1703,7 @@ RFB.messages = {
buff[offset + 2] = 0; // padding
buff[offset + 3] = 0; // padding
- const length = text.length;
+ let length = text.length;
buff[offset + 4] = length >> 24;
buff[offset + 5] = length >> 16;
@@ -1707,7 +1719,7 @@ RFB.messages = {
let remaining = length;
while (remaining > 0) {
- const flushSize = Math.min(remaining, (sock._sQbufferSize - sock._sQlen));
+ let flushSize = Math.min(remaining, (sock._sQbufferSize - sock._sQlen));
if (flushSize <= 0) {
this._fail("Clipboard contents could not be sent");
break;
@@ -1725,7 +1737,7 @@ RFB.messages = {
}
},
- setDesktopSize: function (sock, width, height, id, flags) {
+ setDesktopSize(sock, width, height, id, flags) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1761,7 +1773,7 @@ RFB.messages = {
sock.flush();
},
- clientFence: function (sock, flags, payload) {
+ clientFence(sock, flags, payload) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1788,7 +1800,7 @@ RFB.messages = {
sock.flush();
},
- enableContinuousUpdates: function (sock, enable, x, y, width, height) {
+ enableContinuousUpdates(sock, enable, x, y, width, height) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1808,7 +1820,7 @@ RFB.messages = {
sock.flush();
},
- pixelFormat: function (sock, depth, true_color) {
+ pixelFormat(sock, depth, true_color) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1856,7 +1868,7 @@ RFB.messages = {
sock.flush();
},
- clientEncodings: function (sock, encodings) {
+ clientEncodings(sock, encodings) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1881,7 +1893,7 @@ RFB.messages = {
sock.flush();
},
- fbUpdateRequest: function (sock, incremental, x, y, w, h) {
+ fbUpdateRequest(sock, incremental, x, y, w, h) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1907,7 +1919,7 @@ RFB.messages = {
sock.flush();
},
- xvpOp: function (sock, ver, op) {
+ xvpOp(sock, ver, op) {
const buff = sock._sQ;
const offset = sock._sQlen;
@@ -1919,19 +1931,12 @@ RFB.messages = {
sock._sQlen += 4;
sock.flush();
- },
-};
-
-RFB.genDES = function (password, challenge) {
- const passwd = [];
- for (let i = 0; i < password.length; i++) {
- passwd.push(password.charCodeAt(i));
}
- return (new DES(passwd)).encrypt(challenge);
};
+
RFB.encodingHandlers = {
- RAW: function () {
+ RAW() {
if (this._FBU.lines === 0) {
this._FBU.lines = this._FBU.height;
}
@@ -1971,7 +1976,7 @@ RFB.encodingHandlers = {
return true;
},
- COPYRECT: function () {
+ COPYRECT() {
this._FBU.bytes = 4;
if (this._sock.rQwait("COPYRECT", 4)) { return false; }
this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(),
@@ -1983,7 +1988,7 @@ RFB.encodingHandlers = {
return true;
},
- RRE: function () {
+ RRE() {
let color;
if (this._FBU.subrects === 0) {
this._FBU.bytes = 4 + 4;
@@ -2014,7 +2019,7 @@ RFB.encodingHandlers = {
return true;
},
- HEXTILE: function () {
+ HEXTILE() {
const rQ = this._sock.get_rQ();
let rQi = this._sock.get_rQi();
@@ -2132,7 +2137,7 @@ RFB.encodingHandlers = {
return true;
},
- TIGHT: function (isTightPNG) {
+ TIGHT(isTightPNG) {
this._FBU.bytes = 1; // compression-control byte
if (this._sock.rQwait("TIGHT compression-control", this._FBU.bytes)) { return false; }
@@ -2436,12 +2441,12 @@ RFB.encodingHandlers = {
return true;
},
- last_rect: function () {
+ last_rect() {
this._FBU.rects = 0;
return true;
},
- ExtendedDesktopSize: function () {
+ ExtendedDesktopSize() {
this._FBU.bytes = 1;
if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) { return false; }
@@ -2515,14 +2520,14 @@ RFB.encodingHandlers = {
return true;
},
- DesktopSize: function () {
+ DesktopSize() {
this._resize(this._FBU.width, this._FBU.height);
this._FBU.bytes = 0;
this._FBU.rects -= 1;
return true;
},
- Cursor: function () {
+ Cursor() {
Log.Debug(">> set_cursor");
const x = this._FBU.x; // hotspot-x
const y = this._FBU.y; // hotspot-y
@@ -2546,7 +2551,7 @@ RFB.encodingHandlers = {
return true;
},
- QEMUExtendedKeyEvent: function () {
+ QEMUExtendedKeyEvent() {
this._FBU.rects--;
// Old Safari doesn't support creating keyboard events
@@ -2558,5 +2563,5 @@ RFB.encodingHandlers = {
} catch (err) {
// Do nothing
}
- },
+ }
}
diff --git a/core/util/cursor.js b/core/util/cursor.js
index da72723..18aa7be 100644
--- a/core/util/cursor.js
+++ b/core/util/cursor.js
@@ -8,36 +8,36 @@ import { supportsCursorURIs, isTouchDevice } from './browser.js';
const useFallback = !supportsCursorURIs() || isTouchDevice;
-function Cursor(container) {
- this._target = null;
-
- this._canvas = document.createElement('canvas');
-
- if (useFallback) {
- this._canvas.style.position = 'fixed';
- this._canvas.style.zIndex = '65535';
- this._canvas.style.pointerEvents = 'none';
- // Can't use "display" because of Firefox bug #1445997
- this._canvas.style.visibility = 'hidden';
- document.body.appendChild(this._canvas);
- }
-
- this._position = { x: 0, y: 0 };
- this._hotSpot = { x: 0, y: 0 };
-
- this._eventHandlers = {
- 'mouseover': this._handleMouseOver.bind(this),
- 'mouseleave': this._handleMouseLeave.bind(this),
- 'mousemove': this._handleMouseMove.bind(this),
- 'mouseup': this._handleMouseUp.bind(this),
- 'touchstart': this._handleTouchStart.bind(this),
- 'touchmove': this._handleTouchMove.bind(this),
- 'touchend': this._handleTouchEnd.bind(this),
- };
-}
+export default class Cursor {
+ constructor(container) {
+ this._target = null;
+
+ this._canvas = document.createElement('canvas');
+
+ if (useFallback) {
+ this._canvas.style.position = 'fixed';
+ this._canvas.style.zIndex = '65535';
+ this._canvas.style.pointerEvents = 'none';
+ // Can't use "display" because of Firefox bug #1445997
+ this._canvas.style.visibility = 'hidden';
+ document.body.appendChild(this._canvas);
+ }
-Cursor.prototype = {
- attach: function (target) {
+ this._position = { x: 0, y: 0 };
+ this._hotSpot = { x: 0, y: 0 };
+
+ this._eventHandlers = {
+ 'mouseover': this._handleMouseOver.bind(this),
+ 'mouseleave': this._handleMouseLeave.bind(this),
+ 'mousemove': this._handleMouseMove.bind(this),
+ 'mouseup': this._handleMouseUp.bind(this),
+ 'touchstart': this._handleTouchStart.bind(this),
+ 'touchmove': this._handleTouchMove.bind(this),
+ 'touchend': this._handleTouchEnd.bind(this),
+ };
+ }
+
+ attach(target) {
if (this._target) {
this.detach();
}
@@ -61,9 +61,9 @@ Cursor.prototype = {
}
this.clear();
- },
+ }
- detach: function () {
+ detach() {
if (useFallback) {
const options = { capture: true, passive: true };
this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options);
@@ -77,9 +77,9 @@ Cursor.prototype = {
}
this._target = null;
- },
+ }
- change: function (pixels, mask, hotx, hoty, w, h) {
+ change(pixels, mask, hotx, hoty, w, h) {
if ((w === 0) || (h === 0)) {
this.clear();
return;
@@ -125,9 +125,9 @@ Cursor.prototype = {
let url = this._canvas.toDataURL();
this._target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
}
- },
+ }
- clear: function () {
+ clear() {
this._target.style.cursor = 'none';
this._canvas.width = 0;
this._canvas.height = 0;
@@ -135,71 +135,71 @@ Cursor.prototype = {
this._position.y = this._position.y + this._hotSpot.y;
this._hotSpot.x = 0;
this._hotSpot.y = 0;
- },
+ }
- _handleMouseOver: function (event) {
+ _handleMouseOver(event) {
// This event could be because we're entering the target, or
// moving around amongst its sub elements. Let the move handler
// sort things out.
this._handleMouseMove(event);
- },
+ }
- _handleMouseLeave: function (event) {
+ _handleMouseLeave(event) {
this._hideCursor();
- },
+ }
- _handleMouseMove: function (event) {
+ _handleMouseMove(event) {
this._updateVisibility(event.target);
this._position.x = event.clientX - this._hotSpot.x;
this._position.y = event.clientY - this._hotSpot.y;
this._updatePosition();
- },
+ }
- _handleMouseUp: function (event) {
+ _handleMouseUp(event) {
// We might get this event because of a drag operation that
// moved outside of the target. Check what's under the cursor
// now and adjust visibility based on that.
let target = document.elementFromPoint(event.clientX, event.clientY);
this._updateVisibility(target);
- },
+ }
- _handleTouchStart: function (event) {
+ _handleTouchStart(event) {
// Just as for mouseover, we let the move handler deal with it
this._handleTouchMove(event);
- },
+ }
- _handleTouchMove: function (event) {
+ _handleTouchMove(event) {
this._updateVisibility(event.target);
this._position.x = event.changedTouches[0].clientX - this._hotSpot.x;
this._position.y = event.changedTouches[0].clientY - this._hotSpot.y;
this._updatePosition();
- },
+ }
- _handleTouchEnd: function (event) {
+ _handleTouchEnd(event) {
// Same principle as for mouseup
let target = document.elementFromPoint(event.changedTouches[0].clientX,
event.changedTouches[0].clientY);
this._updateVisibility(target);
- },
+ }
- _showCursor: function () {
+ _showCursor() {
if (this._canvas.style.visibility === 'hidden')
this._canvas.style.visibility = '';
- },
+ }
- _hideCursor: function () {
+ _hideCursor() {
if (this._canvas.style.visibility !== 'hidden')
this._canvas.style.visibility = 'hidden';
- },
+ }
// Should we currently display the cursor?
// (i.e. are we over the target, or a child of the target without a
// different cursor set)
- _shouldShowCursor: function (target) {
+ _shouldShowCursor(target) {
// Easy case
if (target === this._target)
return true;
@@ -212,19 +212,17 @@ Cursor.prototype = {
if (window.getComputedStyle(target).cursor !== 'none')
return false;
return true;
- },
+ }
- _updateVisibility: function (target) {
+ _updateVisibility(target) {
if (this._shouldShowCursor(target))
this._showCursor();
else
this._hideCursor();
- },
+ }
- _updatePosition: function () {
+ _updatePosition() {
this._canvas.style.left = this._position.x + "px";
this._canvas.style.top = this._position.y + "px";
- },
-};
-
-export default Cursor;
+ }
+}
diff --git a/core/util/eventtarget.js b/core/util/eventtarget.js
index 2472319..7e56cd5 100644
--- a/core/util/eventtarget.js
+++ b/core/util/eventtarget.js
@@ -6,10 +6,12 @@
* See README.md for usage and integration instructions.
*/
-const EventTargetMixin = {
- _listeners: null,
+export default class EventTargetMixin {
+ constructor() {
+ this._listeners = null;
+ }
- addEventListener: function(type, callback) {
+ addEventListener(type, callback) {
if (!this._listeners) {
this._listeners = new Map();
}
@@ -17,16 +19,16 @@ const EventTargetMixin = {
this._listeners.set(type, new Set());
}
this._listeners.get(type).add(callback);
- },
+ }
- removeEventListener: function(type, callback) {
+ removeEventListener(type, callback) {
if (!this._listeners || !this._listeners.has(type)) {
return;
}
this._listeners.get(type).delete(callback);
- },
+ }
- dispatchEvent: function(event) {
+ dispatchEvent(event) {
if (!this._listeners || !this._listeners.has(event.type)) {
return true;
}
@@ -34,7 +36,5 @@ const EventTargetMixin = {
callback.call(this, event);
}, this);
return !event.defaultPrevented;
- },
-};
-
-export default EventTargetMixin;
+ }
+}
diff --git a/core/util/strings.js b/core/util/strings.js
index d04ac00..b3de547 100644
--- a/core/util/strings.js
+++ b/core/util/strings.js
@@ -10,6 +10,5 @@
* Decode from UTF-8
*/
export function decodeUTF8 (utf8string) {
- "use strict";
return decodeURIComponent(escape(utf8string));
}
diff --git a/core/websock.js b/core/websock.js
index fc77dd0..ce27c5b 100644
--- a/core/websock.js
+++ b/core/websock.js
@@ -14,91 +14,88 @@
import * as Log from './util/logging.js';
-export default function Websock() {
- "use strict";
-
- this._websocket = null; // WebSocket object
-
- this._rQi = 0; // Receive queue index
- this._rQlen = 0; // Next write position in the receive queue
- this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
- this._rQmax = this._rQbufferSize / 8;
- // called in init: this._rQ = new Uint8Array(this._rQbufferSize);
- this._rQ = null; // Receive queue
-
- this._sQbufferSize = 1024 * 10; // 10 KiB
- // called in init: this._sQ = new Uint8Array(this._sQbufferSize);
- this._sQlen = 0;
- this._sQ = null; // Send queue
-
- this._eventHandlers = {
- 'message': function () {},
- 'open': function () {},
- 'close': function () {},
- 'error': function () {}
- };
-}
-
// this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future.
const ENABLE_COPYWITHIN = false;
-
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
-Websock.prototype = {
+export default class Websock {
+ constructor() {
+ this._websocket = null; // WebSocket object
+
+ this._rQi = 0; // Receive queue index
+ this._rQlen = 0; // Next write position in the receive queue
+ this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
+ this._rQmax = this._rQbufferSize / 8;
+ // called in init: this._rQ = new Uint8Array(this._rQbufferSize);
+ this._rQ = null; // Receive queue
+
+ this._sQbufferSize = 1024 * 10; // 10 KiB
+ // called in init: this._sQ = new Uint8Array(this._sQbufferSize);
+ this._sQlen = 0;
+ this._sQ = null; // Send queue
+
+ this._eventHandlers = {
+ message: () => {},
+ open: () => {},
+ close: () => {},
+ error: () => {}
+ };
+ }
+
// Getters and Setters
- get_sQ: function () {
+ get_sQ() {
return this._sQ;
- },
+ }
- get_rQ: function () {
+ get_rQ() {
return this._rQ;
- },
+ }
- get_rQi: function () {
+ get_rQi() {
return this._rQi;
- },
+ }
- set_rQi: function (val) {
+ set_rQi(val) {
this._rQi = val;
- },
+ }
// Receive Queue
- rQlen: function () {
+ rQlen() {
return this._rQlen - this._rQi;
- },
+ }
- rQpeek8: function () {
+ rQpeek8() {
return this._rQ[this._rQi];
- },
+ }
- rQshift8: function () {
+ rQshift8() {
return this._rQ[this._rQi++];
- },
+ }
- rQskip8: function () {
+ rQskip8() {
this._rQi++;
- },
+ }
- rQskipBytes: function (num) {
+ rQskipBytes(num) {
this._rQi += num;
- },
+ }
// TODO(directxman12): test performance with these vs a DataView
- rQshift16: function () {
+ rQshift16() {
return (this._rQ[this._rQi++] << 8) +
this._rQ[this._rQi++];
- },
+ }
- rQshift32: function () {
+ rQshift32() {
return (this._rQ[this._rQi++] << 24) +
(this._rQ[this._rQi++] << 16) +
(this._rQ[this._rQi++] << 8) +
this._rQ[this._rQi++];
- },
+ }
- rQshiftStr: function (len) {
+ rQshiftStr(len) {
if (typeof(len) === 'undefined') { len = this.rQlen(); }
let str = "";
// Handle large arrays in steps to avoid long strings on the stack
@@ -107,37 +104,37 @@ Websock.prototype = {
str += String.fromCharCode.apply(null, part);
}
return str;
- },
+ }
- rQshiftBytes: function (len) {
+ rQshiftBytes(len) {
if (typeof(len) === 'undefined') { len = this.rQlen(); }
this._rQi += len;
return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
- },
+ }
- rQshiftTo: function (target, len) {
+ rQshiftTo(target, len) {
if (len === undefined) { len = this.rQlen(); }
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ
target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
this._rQi += len;
- },
+ }
- rQwhole: function () {
+ rQwhole() {
return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
- },
+ }
- rQslice: function (start, end) {
+ rQslice(start, end) {
if (end) {
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
} else {
return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
}
- },
+ }
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
// to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false.
- rQwait: function (msg, num, goback) {
+ rQwait(msg, num, goback) {
const rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
if (rQlen < num) {
if (goback) {
@@ -149,50 +146,50 @@ Websock.prototype = {
return true; // true means need more data
}
return false;
- },
+ }
// Send Queue
- flush: function () {
+ flush() {
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
this._websocket.send(this._encode_message());
this._sQlen = 0;
}
- },
+ }
- send: function (arr) {
+ send(arr) {
this._sQ.set(arr, this._sQlen);
this._sQlen += arr.length;
this.flush();
- },
+ }
- send_string: function (str) {
+ send_string(str) {
this.send(str.split('').map(function (chr) {
return chr.charCodeAt(0);
}));
- },
+ }
// Event Handlers
- off: function (evt) {
+ off(evt) {
this._eventHandlers[evt] = function () {};
- },
+ }
- on: function (evt, handler) {
+ on(evt, handler) {
this._eventHandlers[evt] = handler;
- },
+ }
- _allocate_buffers: function () {
+ _allocate_buffers() {
this._rQ = new Uint8Array(this._rQbufferSize);
this._sQ = new Uint8Array(this._sQbufferSize);
- },
+ }
- init: function () {
+ init() {
this._allocate_buffers();
this._rQi = 0;
this._websocket = null;
- },
+ }
- open: function (uri, protocols) {
+ open(uri, protocols) {
this.init();
this._websocket = new WebSocket(uri, protocols);
@@ -218,9 +215,9 @@ Websock.prototype = {
this._eventHandlers.error(e);
Log.Debug("<< WebSock.onerror: " + e);
}).bind(this);
- },
+ }
- close: function () {
+ close() {
if (this._websocket) {
if ((this._websocket.readyState === WebSocket.OPEN) ||
(this._websocket.readyState === WebSocket.CONNECTING)) {
@@ -230,16 +227,16 @@ Websock.prototype = {
this._websocket.onmessage = function (e) { return; };
}
- },
+ }
// private methods
- _encode_message: function () {
+ _encode_message() {
// Put in a binary arraybuffer
// according to the spec, you can send ArrayBufferViews with the send method
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
- },
+ }
- _expand_compact_rQ: function (min_fit) {
+ _expand_compact_rQ(min_fit) {
const resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
if (resizeNeeded) {
if (!min_fit) {
@@ -274,9 +271,9 @@ Websock.prototype = {
this._rQlen = this._rQlen - this._rQi;
this._rQi = 0;
- },
+ }
- _decode_message: function (data) {
+ _decode_message(data) {
// push arraybuffer values onto the end
const u8 = new Uint8Array(data);
if (u8.length > this._rQbufferSize - this._rQlen) {
@@ -284,9 +281,9 @@ Websock.prototype = {
}
this._rQ.set(u8, this._rQlen);
this._rQlen += u8.length;
- },
+ }
- _recv_message: function (e) {
+ _recv_message(e) {
this._decode_message(e.data);
if (this.rQlen() > 0) {
this._eventHandlers.message();
@@ -301,4 +298,4 @@ Websock.prototype = {
Log.Debug("Ignoring empty message");
}
}
-};
+}
diff --git a/tests/.eslintrc b/tests/.eslintrc
index 800dcf9..b52ebaf 100644
--- a/tests/.eslintrc
+++ b/tests/.eslintrc
@@ -1,9 +1,9 @@
{
- "env": {
- "node": true,
- "mocha": true
- },
- "globals": {
- "chai": true
- }
+ "env": {
+ "node": true,
+ "mocha": true
+ },
+ "globals": {
+ "chai": true
+ }
} \ No newline at end of file
diff --git a/tests/fake.websocket.js b/tests/fake.websocket.js
index 2e28494..e0290ed 100644
--- a/tests/fake.websocket.js
+++ b/tests/fake.websocket.js
@@ -12,34 +12,34 @@ function make_event(name, props) {
return evt;
}
-export default function FakeWebSocket (uri, protocols) {
- this.url = uri;
- this.binaryType = "arraybuffer";
- this.extensions = "";
+export default class FakeWebSocket {
+ constructor(uri, protocols) {
+ this.url = uri;
+ this.binaryType = "arraybuffer";
+ this.extensions = "";
- if (!protocols || typeof protocols === 'string') {
- this.protocol = protocols;
- } else {
- this.protocol = protocols[0];
- }
+ if (!protocols || typeof protocols === 'string') {
+ this.protocol = protocols;
+ } else {
+ this.protocol = protocols[0];
+ }
- this._send_queue = new Uint8Array(20000);
+ this._send_queue = new Uint8Array(20000);
- this.readyState = FakeWebSocket.CONNECTING;
- this.bufferedAmount = 0;
+ this.readyState = FakeWebSocket.CONNECTING;
+ this.bufferedAmount = 0;
- this.__is_fake = true;
-}
+ this.__is_fake = true;
+ }
-FakeWebSocket.prototype = {
- close: function (code, reason) {
+ close(code, reason) {
this.readyState = FakeWebSocket.CLOSED;
if (this.onclose) {
this.onclose(make_event("close", { 'code': code, 'reason': reason, 'wasClean': true }));
}
- },
+ }
- send: function (data) {
+ send(data) {
if (this.protocol == 'base64') {
data = Base64.decode(data);
} else {
@@ -47,25 +47,25 @@ FakeWebSocket.prototype = {
}
this._send_queue.set(data, this.bufferedAmount);
this.bufferedAmount += data.length;
- },
+ }
- _get_sent_data: function () {
+ _get_sent_data() {
const res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount);
this.bufferedAmount = 0;
return res;
- },
+ }
- _open: function (data) {
+ _open() {
this.readyState = FakeWebSocket.OPEN;
if (this.onopen) {
this.onopen(make_event('open'));
}
- },
+ }
- _receive_data: function (data) {
+ _receive_data(data) {
this.onmessage(make_event("message", { 'data': data }));
}
-};
+}
FakeWebSocket.OPEN = WebSocket.OPEN;
FakeWebSocket.CONNECTING = WebSocket.CONNECTING;
diff --git a/tests/playback-ui.js b/tests/playback-ui.js
index 1565b8f..d2d0869 100644
--- a/tests/playback-ui.js
+++ b/tests/playback-ui.js
@@ -53,26 +53,26 @@ function enableUI() {
encoding = VNC_frame_encoding;
}
-function IterationPlayer (iterations, frames, encoding) {
- this._iterations = iterations;
+class IterationPlayer {
+ constructor(iterations, frames, encoding) {
+ this._iterations = iterations;
- this._iteration = undefined;
- this._player = undefined;
+ this._iteration = undefined;
+ this._player = undefined;
- this._start_time = undefined;
+ this._start_time = undefined;
- this._frames = frames;
- this._encoding = encoding;
+ this._frames = frames;
+ this._encoding = encoding;
- this._state = 'running';
+ this._state = 'running';
this.onfinish = function() {};
this.oniterationfinish = function() {};
this.rfbdisconnected = function() {};
-}
+ }
-IterationPlayer.prototype = {
- start: function (mode) {
+ start(mode) {
this._iteration = 0;
this._start_time = (new Date()).getTime();
@@ -80,9 +80,9 @@ IterationPlayer.prototype = {
this._trafficMgmt = !mode.endsWith('-no-mgmt');
this._nextIteration();
- },
+ }
- _nextIteration: function () {
+ _nextIteration() {
const player = new RecordingPlayer(this._frames, this._encoding, this._disconnected.bind(this));
player.onfinish = this._iterationFinish.bind(this);
@@ -95,9 +95,9 @@ IterationPlayer.prototype = {
}
player.run(this._realtime, this._trafficMgmt);
- },
+ }
- _finish: function () {
+ _finish() {
const endTime = (new Date()).getTime();
const totalDuration = endTime - this._start_time;
@@ -105,18 +105,18 @@ IterationPlayer.prototype = {
evt.duration = totalDuration;
evt.iterations = this._iterations;
this.onfinish(evt);
- },
+ }
- _iterationFinish: function (duration) {
+ _iterationFinish(duration) {
const evt = new Event('iterationfinish');
evt.duration = duration;
evt.number = this._iteration;
this.oniterationfinish(evt);
this._nextIteration();
- },
+ }
- _disconnected: function (clean, frame) {
+ _disconnected(clean, frame) {
if (!clean) {
this._state = 'failed';
}
@@ -127,8 +127,8 @@ IterationPlayer.prototype = {
evt.iteration = this._iteration;
this.onrfbdisconnected(evt);
- },
-};
+ }
+}
function start() {
document.getElementById('startButton').value = "Running";
diff --git a/tests/playback.js b/tests/playback.js
index cbeb20f..6b422d8 100644
--- a/tests/playback.js
+++ b/tests/playback.js
@@ -44,37 +44,37 @@ if (window.setImmediate === undefined) {
window.addEventListener("message", _onMessage);
}
-export default function RecordingPlayer (frames, encoding, disconnected) {
- this._frames = frames;
- this._encoding = encoding;
+export default class RecordingPlayer {
+ constructor(frames, encoding, disconnected) {
+ this._frames = frames;
+ this._encoding = encoding;
- this._disconnected = disconnected;
+ this._disconnected = disconnected;
- if (this._encoding === undefined) {
+ if (this._encoding === undefined) {
const frame = this._frames[0];
const start = frame.indexOf('{', 1) + 1;
- if (frame.slice(start).startsWith('UkZC')) {
- this._encoding = 'base64';
- } else {
- this._encoding = 'binary';
+ if (frame.slice(start).startsWith('UkZC')) {
+ this._encoding = 'base64';
+ } else {
+ this._encoding = 'binary';
+ }
}
- }
- this._rfb = undefined;
- this._frame_length = this._frames.length;
+ this._rfb = undefined;
+ this._frame_length = this._frames.length;
- this._frame_index = 0;
- this._start_time = undefined;
- this._realtime = true;
- this._trafficManagement = true;
+ this._frame_index = 0;
+ this._start_time = undefined;
+ this._realtime = true;
+ this._trafficManagement = true;
- this._running = false;
+ this._running = false;
this.onfinish = function () {};
-}
+ }
-RecordingPlayer.prototype = {
- run: function (realtime, trafficManagement) {
+ run(realtime, trafficManagement) {
// initialize a new RFB
this._rfb = new RFB(document.getElementById('VNC_screen'), 'wss://test');
this._rfb.viewOnly = true;
@@ -92,10 +92,10 @@ RecordingPlayer.prototype = {
this._running = true;
this._queueNextPacket();
- },
+ }
// _enablePlaybackMode mocks out things not required for running playback
- _enablePlaybackMode: function () {
+ _enablePlaybackMode() {
this._rfb._sock.send = function (arr) {};
this._rfb._sock.close = function () {};
this._rfb._sock.flush = function () {};
@@ -103,9 +103,9 @@ RecordingPlayer.prototype = {
this.init();
this._eventHandlers.open();
};
- },
+ }
- _queueNextPacket: function () {
+ _queueNextPacket() {
if (!this._running) { return; }
let frame = this._frames[this._frame_index];
@@ -138,9 +138,9 @@ RecordingPlayer.prototype = {
} else {
setImmediate(this._doPacket.bind(this));
}
- },
+ }
- _doPacket: function () {
+ _doPacket() {
// Avoid having excessive queue buildup in non-realtime mode
if (this._trafficManagement && this._rfb._flushing) {
const player = this;
@@ -170,7 +170,7 @@ RecordingPlayer.prototype = {
this._frame_index++;
this._queueNextPacket();
- },
+ }
_finish() {
if (this._rfb._display.pending()) {
@@ -188,10 +188,10 @@ RecordingPlayer.prototype = {
delete this._rfb;
this.onfinish((new Date()).getTime() - this._start_time);
}
- },
+ }
_handleDisconnect(evt) {
this._running = false;
this._disconnected(evt.detail.clean, this._frame_index);
}
-};
+}
diff --git a/tests/test.rfb.js b/tests/test.rfb.js
index 0ebad9c..cb72f4c 100644
--- a/tests/test.rfb.js
+++ b/tests/test.rfb.js
@@ -194,7 +194,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
describe('#sendCtrlAlDel', function () {
it('should sent ctrl[down]-alt[down]-del[down] then del[up]-alt[up]-ctrl[up]', function () {
- const expected = {_sQ: new Uint8Array(48), _sQlen: 0, flush: function () {}};
+ const expected = {_sQ: new Uint8Array(48), _sQlen: 0, flush: () => {}};
RFB.messages.keyEvent(expected, 0xFFE3, 1);
RFB.messages.keyEvent(expected, 0xFFE9, 1);
RFB.messages.keyEvent(expected, 0xFFFF, 1);
@@ -223,14 +223,14 @@ describe('Remote Frame Buffer Protocol Client', function() {
describe('#sendKey', function () {
it('should send a single key with the given code and state (down = true)', function () {
- const expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
+ const expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: () => {}};
RFB.messages.keyEvent(expected, 123, 1);
client.sendKey(123, 'Key123', true);
expect(client._sock).to.have.sent(expected._sQ);
});
it('should send both a down and up event if the state is not specified', function () {
- const expected = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function () {}};
+ const expected = {_sQ: new Uint8Array(16), _sQlen: 0, flush: () => {}};
RFB.messages.keyEvent(expected, 123, 1);
RFB.messages.keyEvent(expected, 123, 0);
client.sendKey(123, 'Key123');
@@ -253,7 +253,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should send QEMU extended events if supported', function () {
client._qemuExtKeyEventSupported = true;
- const expected = {_sQ: new Uint8Array(12), _sQlen: 0, flush: function () {}};
+ const expected = {_sQ: new Uint8Array(12), _sQlen: 0, flush: () => {}};
RFB.messages.QEMUExtendedKeyEvent(expected, 0x20, true, 0x0039);
client.sendKey(0x20, 'Space', true);
expect(client._sock).to.have.sent(expected._sQ);
@@ -261,7 +261,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should not send QEMU extended events if unknown key code', function () {
client._qemuExtKeyEventSupported = true;
- const expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
+ const expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: () => {}};
RFB.messages.keyEvent(expected, 123, 1);
client.sendKey(123, 'FooBar', true);
expect(client._sock).to.have.sent(expected._sQ);
@@ -287,7 +287,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
describe('#clipboardPasteFrom', function () {
it('should send the given text in a paste event', function () {
const expected = {_sQ: new Uint8Array(11), _sQlen: 0,
- _sQbufferSize: 11, flush: function () {}};
+ _sQbufferSize: 11, flush: () => {}};
RFB.messages.clientCutText(expected, 'abc');
client.clipboardPasteFrom('abc');
expect(client._sock).to.have.sent(expected._sQ);
@@ -1615,7 +1615,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
}
it('should send an update request if there is sufficient data', function () {
- const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}};
+ const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: () => {}};
RFB.messages.fbUpdateRequest(expected_msg, true, 0, 0, 640, 20);
client._framebufferUpdate = function () { return true; };
@@ -1630,7 +1630,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
});
it('should resume receiving an update if we previously did not have enough data', function () {
- const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}};
+ const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: () => {}};
RFB.messages.fbUpdateRequest(expected_msg, true, 0, 0, 640, 20);
// just enough to set FBU.rects
@@ -2040,8 +2040,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
});
it('should respond correctly to ServerFence', function () {
- const expected_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function() {}};
- const incoming_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function() {}};
+ const expected_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: () => {}};
+ const incoming_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: () => {}};
const payload = "foo\x00ab9";
@@ -2065,7 +2065,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
});
it('should enable continuous updates on first EndOfContinousUpdates', function () {
- const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}};
+ const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: () => {}};
RFB.messages.enableContinuousUpdates(expected_msg, true, 0, 0, 640, 20);
@@ -2087,7 +2087,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
});
it('should update continuous updates on resize', function () {
- const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}};
+ const expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: () => {}};
RFB.messages.enableContinuousUpdates(expected_msg, true, 0, 0, 90, 700);
client._resize(450, 160);
@@ -2131,14 +2131,14 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should send a pointer event on mouse button presses', function () {
client._handleMouseButton(10, 12, 1, 0x001);
- const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}};
+ const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: () => {}};
RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x001);
expect(client._sock).to.have.sent(pointer_msg._sQ);
});
it('should send a mask of 1 on mousedown', function () {
client._handleMouseButton(10, 12, 1, 0x001);
- const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}};
+ const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: () => {}};
RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x001);
expect(client._sock).to.have.sent(pointer_msg._sQ);
});
@@ -2146,14 +2146,14 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should send a mask of 0 on mouseup', function () {
client._mouse_buttonMask = 0x001;
client._handleMouseButton(10, 12, 0, 0x001);
- const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}};
+ const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: () => {}};
RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x000);
expect(client._sock).to.have.sent(pointer_msg._sQ);
});
it('should send a pointer event on mouse movement', function () {
client._handleMouseMove(10, 12);
- const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}};
+ const pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: () => {}};
RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x000);
expect(client._sock).to.have.sent(pointer_msg._sQ);
});
@@ -2161,7 +2161,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should set the button mask so that future mouse movements use it', function () {
client._handleMouseButton(10, 12, 1, 0x010);
client._handleMouseMove(13, 9);
- const pointer_msg = {_sQ: new Uint8Array(12), _sQlen: 0, flush: function () {}};
+ const pointer_msg = {_sQ: new Uint8Array(12), _sQlen: 0, flush: () => {}};
RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x010);
RFB.messages.pointerEvent(pointer_msg, 13, 9, 0x010);
expect(client._sock).to.have.sent(pointer_msg._sQ);
@@ -2171,7 +2171,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
describe('Keyboard Event Handlers', function () {
it('should send a key message on a key press', function () {
client._handleKeyEvent(0x41, 'KeyA', true);
- const key_msg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
+ const key_msg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: () => {}};
RFB.messages.keyEvent(key_msg, 0x41, 1);
expect(client._sock).to.have.sent(key_msg._sQ);
});
diff --git a/tests/test.webutil.js b/tests/test.webutil.js
index 90c4bd3..ae28974 100644
--- a/tests/test.webutil.js
+++ b/tests/test.webutil.js
@@ -117,9 +117,9 @@ describe('WebUtil', function() {
window.chrome = {
storage: {
sync: {
- get: function(cb){ cb(settings); },
- set: function(){},
- remove: function() {}
+ get(cb){ cb(settings); },
+ set(){},
+ remove() {}
}
}
};