]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Use ES6 classes
authorJuanjo Diaz <juanjo.diazmo@gmail.com>
Thu, 5 Jul 2018 19:31:56 +0000 (21:31 +0200)
committerJuanjo Diaz <juanjo.diazmo@gmail.com>
Thu, 12 Jul 2018 17:06:57 +0000 (19:06 +0200)
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: () => { ... } }`

20 files changed:
.eslintrc
app/localization.js
app/ui.js
core/base64.js
core/display.js
core/inflator.js
core/input/keyboard.js
core/input/keysymdef.js
core/input/mouse.js
core/rfb.js
core/util/cursor.js
core/util/eventtarget.js
core/util/strings.js
core/websock.js
tests/.eslintrc
tests/fake.websocket.js
tests/playback-ui.js
tests/playback.js
tests/test.rfb.js
tests/test.webutil.js

index aef4c0d0e4ff09d437ea4931dda3fac934ec8c0b..ea4d65504a00d9f77898c9c263d09ecf31bfc993 100644 (file)
--- 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 }],
+    }
 }
index 11144f7c41ad2b4a55dc73183eb45a56b0a53472..6bc8d55f5ee88667d49924d67ce83a7ecbb4b20d 100644 (file)
  * 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);
index f792d01b9a7eea2b05ac423537d5ff90f9e2ef00..a8537fb8cce1198e6211ca98f743015659d74f75 100644 (file)
--- 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;
index d57d986a6d4d8393023617e543f60330465267fb..895aa464d1a424d0ba31ba0ca0ca07741a17b347 100644 (file)
@@ -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;
index 057b12f7838803ca1e04217025ba10fe7f5eef63..4955ce20289c2ea6048926e3dc271f080d93f35d 100644 (file)
 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();
         }
-    },
-};
+    }
+}
index 48fb71937c08d63c772b21505e6dc5607a1b854d..0eab8fe48c2ced5a00c07c098f22681d95dd8093 100644 (file)
@@ -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);
 }
index d64298a8dd93e228cf8a53ca7bd0cbc483a261dc..5b467485aec62aca46d0ee2cd241fcc9183e95ec 100644 (file)
@@ -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");
-    },
-};
+    }
+}
index 5969b5dd9e6a4013eb78b0e6f45612d4bac6280d..951cacab673fa34adf7039eac1c8d4ccab934c7e 100644 (file)
@@ -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;
index 17c8cd51bb77b0d10f2daabee0ef36869ce47b91..4a8710efe5dcc74a2e48ea69a5642bfe86c1a1b5 100644 (file)
@@ -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);
     }
-};
+}
index a94542f6fe6951f3357f5d0efd2f2112247ceb6a..ed765e8784682ec6b9c0d2a6560cfbc07529eb2c 100644 (file)
@@ -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
         }
-    },
+    }
 }
index da72723b395485c4665ce2456d98a092b2ce4d90..18aa7beb8ed717543401837fd645663179e4dc90 100644 (file)
@@ -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;
+    }
+}
index 2472319ce896111a3ab30b0fd488a263ca23cded..7e56cd5cc6671abf7571f125a95ac356f0a99272 100644 (file)
@@ -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;
+   }
+}
index d04ac00e952588c38308887d06d4aaefd3387cbb..b3de5476e4c232e8126d39a07790ec54056c488d 100644 (file)
@@ -10,6 +10,5 @@
  * Decode from UTF-8
  */
 export function decodeUTF8 (utf8string) {
-    "use strict";
     return decodeURIComponent(escape(utf8string));
 }
index fc77dd007eaf05a4936e3cd578f08a4c3d2f2a87..ce27c5b79935a06777d04373b740fec86f8a8e0d 100644 (file)
 
 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");
         }
     }
-};
+}
index 800dcf94cddfeccae8a73d57a75f7699b013b2bf..b52ebaf43b29008b7759e3eb1507bc8321469c1a 100644 (file)
@@ -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
index 2e28494c12b51a4a9bab8141434aea960c1212c1..e0290ed1e35b0492e4191fb104e83b07c250c005 100644 (file)
@@ -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;
index 1565b8ffb8ccb50db424b3c89be688e052870b1f..d2d0869aa11cb307ec9e764501d4c0dc36bb70b1 100644 (file)
@@ -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";
index cbeb20fdc199433cdd2c9deb54ac9ad4581b4b34..6b422d87ad64e3a3c3f52dac380631bbb884e088 100644 (file)
@@ -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);
     }
-};
+}
index 0ebad9c61a48d5acc9a651a0a3e76e26825c5ccd..cb72f4c970dc80af7bebcf52a107642546fbcc44 100644 (file)
@@ -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);
             });
index 90c4bd3cdeefc6fac9406408021fcf4d198238eb..ae289746aeea8c059d98dfd4237deb43591b607d 100644 (file)
@@ -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() {}
                         }
                     }
                 };