From 3d7bb0203619a2787b16b5cc4b68b16e18a4ee68 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 14 Oct 2017 13:06:03 +0200 Subject: [PATCH] Change some attributes to arguments Some attributes are better suited as arguments, primarily because they are associated with a specific method and cannot be changed later. --- app/ui.js | 15 +++++----- core/display.js | 5 ++-- core/input/keyboard.js | 10 +++---- core/input/mouse.js | 6 ++-- core/rfb.js | 34 ++++++++++----------- docs/API-internal.md | 6 +--- docs/API.md | 17 +++++++---- tests/playback.js | 4 +-- tests/test.display.js | 22 +++++++------- tests/test.keyboard.js | 52 ++++++++++++++++---------------- tests/test.mouse.js | 48 +++++++++++++----------------- tests/test.rfb.js | 67 +++++++++++++++++++++--------------------- vnc_lite.html | 10 +++---- 13 files changed, 144 insertions(+), 152 deletions(-) diff --git a/app/ui.js b/app/ui.js index 3ec3648a..9b4fac19 100644 --- a/app/ui.js +++ b/app/ui.js @@ -202,8 +202,8 @@ var UI = { initRFB: function() { try { - UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'), - 'onNotification': UI.notification, + UI.rfb = new RFB(document.getElementById('noVNC_canvas'), + {'onNotification': UI.notification, 'onUpdateState': UI.updateState, 'onDisconnected': UI.disconnectFinished, 'onCredentialsRequired': UI.credentials, @@ -277,8 +277,8 @@ var UI = { document.getElementById("noVNC_keyboard_button") .addEventListener('click', UI.toggleVirtualKeyboard); - UI.touchKeyboard = new Keyboard({target: document.getElementById('noVNC_keyboardinput'), - onKeyEvent: UI.keyEvent}); + UI.touchKeyboard = new Keyboard(document.getElementById('noVNC_keyboardinput'), + {onKeyEvent: UI.keyEvent}); UI.touchKeyboard.grab(); document.getElementById("noVNC_keyboardinput") .addEventListener('input', UI.keyInput); @@ -1062,9 +1062,6 @@ var UI = { UI.closeAllPanels(); UI.closeConnectPanel(); - UI.rfb.set_shared(UI.getSetting('shared')); - UI.rfb.set_repeaterID(UI.getSetting('repeaterID')); - UI.updateLocalCursor(); UI.updateViewOnly(); @@ -1078,7 +1075,9 @@ var UI = { } url += '/' + path; - UI.rfb.connect(url, { password: password }); + UI.rfb.connect(url, { shared: UI.getSetting('shared'), + repeaterID: UI.getSetting('repeaterID'), + credentials: { password: password } }); }, disconnect: function() { diff --git a/core/display.js b/core/display.js index e3f4293a..e7d8bd3a 100644 --- a/core/display.js +++ b/core/display.js @@ -15,7 +15,7 @@ import { set_defaults, make_properties } from './util/properties.js'; import * as Log from './util/logging.js'; import Base64 from "./base64.js"; -export default function Display(defaults) { +export default function Display(target, defaults) { this._drawCtx = null; this._c_forceCanvas = false; @@ -42,6 +42,8 @@ export default function Display(defaults) { Log.Debug(">> Display.constructor"); // The visible canvas + this._target = target; + if (!this._target) { throw new Error("Target must be set"); } @@ -691,7 +693,6 @@ Display.prototype = { }; make_properties(Display, [ - ['target', 'wo', 'dom'], // Canvas element for rendering ['context', 'ro', 'raw'], // Canvas 2D context for rendering (read-only) ['logo', 'rw', 'raw'], // Logo to display when cleared: {"width": w, "height": h, "type": mime-type, "data": data} ['scale', 'rw', 'float'], // Display area scale factor 0.0 - 1.0 diff --git a/core/input/keyboard.js b/core/input/keyboard.js index fa4a5ae4..6dee460f 100644 --- a/core/input/keyboard.js +++ b/core/input/keyboard.js @@ -18,14 +18,14 @@ import KeyTable from "./keysym.js"; // Keyboard event handler // -export default function Keyboard(defaults) { +export default function Keyboard(target, defaults) { + this._target = target || null; + this._keyDownList = {}; // List of depressed keys // (even if they are happy) this._pendingKey = null; // Key waiting for keypress - set_defaults(this, defaults, { - 'target': null, - }); + set_defaults(this, defaults, {}); // keep these here so we can refer to them later this._eventHandlers = { @@ -338,7 +338,5 @@ Keyboard.prototype = { }; make_properties(Keyboard, [ - ['target', 'wo', 'dom'], // DOM element that captures keyboard input - ['onKeyEvent', 'rw', 'func'] // Handler for key press/release ]); diff --git a/core/input/mouse.js b/core/input/mouse.js index 49b5c395..ae3ca106 100644 --- a/core/input/mouse.js +++ b/core/input/mouse.js @@ -17,7 +17,8 @@ var WHEEL_STEP = 10; // Delta threshold for a mouse wheel step var WHEEL_STEP_TIMEOUT = 50; // ms var WHEEL_LINE_HEIGHT = 19; -export default function Mouse(defaults) { +export default function Mouse(target, defaults) { + this._target = target || document; this._doubleClickTimer = null; this._lastTouchPos = null; @@ -30,7 +31,6 @@ export default function Mouse(defaults) { // Configuration attributes set_defaults(this, defaults, { - 'target': document, 'touchButton': 1 }); @@ -284,8 +284,6 @@ Mouse.prototype = { }; make_properties(Mouse, [ - ['target', 'ro', 'dom'], // DOM element that captures mouse input - ['onMouseButton', 'rw', 'func'], // Handler for mouse button click/release ['onMouseMove', 'rw', 'func'], // Handler for mouse movement ['touchButton', 'rw', 'int'] // Button mask (1, 2, 4) for touch devices (0 means ignore clicks) diff --git a/core/rfb.js b/core/rfb.js index 5b79d3c8..ec638a9c 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -28,11 +28,12 @@ import { encodings, encodingName } from "./encodings.js"; /*jslint white: false, browser: true */ /*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */ -export default function RFB(defaults) { +export default function RFB(target, defaults) { "use strict"; if (!defaults) { defaults = {}; } + this._target = target; // Connection details this._url = ''; @@ -128,12 +129,9 @@ export default function RFB(defaults) { // set the default value on user-facing properties set_defaults(this, defaults, { - 'target': 'null', // VNC display rendering Canvas object 'local_cursor': false, // Request locally rendered cursor - 'shared': true, // Request shared mode 'view_only': false, // Disable client mouse/keyboard 'disconnectTimeout': 3, // Time (s) to wait for disconnection - 'repeaterID': '', // [UltraVNC] RepeaterID to connect to 'viewportDrag': false, // Move the viewport on mouse drags // Callback functions @@ -172,19 +170,19 @@ export default function RFB(defaults) { // NB: nothing that needs explicit teardown should be done // before this point, since this can throw an exception try { - this._display = new Display({target: this._target, - onFlush: this._onFlush.bind(this)}); + this._display = new Display(this._target, + {onFlush: this._onFlush.bind(this)}); } catch (exc) { Log.Error("Display exception: " + exc); throw exc; } this._display.clear(); - this._keyboard = new Keyboard({target: this._target, - onKeyEvent: this._handleKeyEvent.bind(this)}); + this._keyboard = new Keyboard(this._target, + {onKeyEvent: this._handleKeyEvent.bind(this)}); - this._mouse = new Mouse({target: this._target, - onMouseButton: this._handleMouseButton.bind(this), + this._mouse = new Mouse(this._target, + {onMouseButton: this._handleMouseButton.bind(this), onMouseMove: this._handleMouseMove.bind(this)}); this._sock = new Websock(); @@ -243,15 +241,20 @@ export default function RFB(defaults) { RFB.prototype = { // Public methods - connect: function (url, creds) { - this._url = url; - this._rfb_credentials = (creds !== undefined) ? creds : {}; - + connect: function (url, options) { if (!url) { this._fail(_("Must specify URL")); return; } + this._url = url; + + options = options || {} + + this._rfb_credentials = options.credentials || {}; + this._shared = 'shared' in options ? !!options.shared : true; + this._repeaterID = options.repeaterID || ''; + this._rfb_init_state = ''; this._updateConnectionState('connecting'); return true; @@ -1444,15 +1447,12 @@ RFB.prototype = { }; make_properties(RFB, [ - ['target', 'wo', 'dom'], // VNC display rendering Canvas object ['local_cursor', 'rw', 'bool'], // Request locally rendered cursor - ['shared', 'rw', 'bool'], // Request shared mode ['view_only', 'rw', 'bool'], // Disable client mouse/keyboard ['touchButton', 'rw', 'int'], // Button mask (1, 2, 4) for touch devices (0 means ignore clicks) ['scale', 'rw', 'float'], // Display area scale factor ['viewport', 'rw', 'bool'], // Use viewport clipping ['disconnectTimeout', 'rw', 'int'], // Time (s) to wait for disconnection - ['repeaterID', 'rw', 'str'], // [UltraVNC] RepeaterID to connect to ['viewportDrag', 'rw', 'bool'], // Move the viewport on mouse drags ['capabilities', 'ro', 'arr'], // Supported capabilities diff --git a/docs/API-internal.md b/docs/API-internal.md index 8d11d91d..ec6d7ab7 100644 --- a/docs/API-internal.md +++ b/docs/API-internal.md @@ -48,7 +48,6 @@ callback event name, and the callback function. | name | type | mode | default | description | ----------- | ---- | ---- | -------- | ------------ -| target | DOM | WO | document | DOM element that captures mouse input | touchButton | int | RW | 1 | Button mask (1, 2, 4) for which click to send on touch devices. 0 means ignore clicks. ### 2.1.2 Methods @@ -70,9 +69,7 @@ callback event name, and the callback function. ### 2.2.1 Configuration Attributes -| name | type | mode | default | description -| ------- | ---- | ---- | -------- | ------------ -| target | DOM | WO | document | DOM element that captures keyboard input +None ### 2.2.2 Methods @@ -94,7 +91,6 @@ callback event name, and the callback function. | name | type | mode | default | description | ----------- | ----- | ---- | ------- | ------------ -| target | DOM | WO | | Canvas element for rendering | context | raw | RO | | Canvas 2D context for rendering | logo | raw | RW | | Logo to display when cleared: {"width": width, "height": height, "type": mime-type, "data": data} | scale | float | RW | 1.0 | Display area scale factor 0.0 - 1.0 diff --git a/docs/API.md b/docs/API.md index f129a288..63293c0b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -13,7 +13,7 @@ and "set_*" methods respectively. For example, the following initializes an RFB object with the 'view_only' configuration option enabled, then confirms it was set, then disables it: - var rfb = new RFB({'view_only': true}); + var rfb = new RFB(target, {'view_only': true}); if (rfb.get_view_only()) { alert("View Only is set"); } @@ -29,15 +29,12 @@ attribute mode is one of the following: | name | type | mode | default | description | ----------------- | ----- | ---- | ---------- | ------------ -| target | DOM | WO | null | Canvas element for rendering (passed to Display, Mouse and Keyboard) | local_cursor | bool | RW | false | Request locally rendered cursor -| shared | bool | RW | true | Request shared VNC mode | view_only | bool | RW | false | Disable client mouse/keyboard | touchButton | int | RW | 1 | Button mask (1, 2, 4) for which click to send on touch devices. 0 means ignore clicks. | scale | float | RW | 1.0 | Display area scale factor | viewport | bool | RW | false | Use viewport clipping | disconnectTimeout | int | RW | 3 | Time (in seconds) to wait for disconnection -| repeaterID | str | RW | '' | UltraVNC RepeaterID to connect to | viewportDrag | bool | RW | false | Move the viewport on mouse drags | capabilities | arr | RO | [] | Supported capabilities (can include: 'power', 'resize') @@ -50,7 +47,7 @@ object instance. | name | parameters | description | ------------------ | ------------------------------- | ------------ -| connect | (url, credentials) | Connect to the given URL. Optional credentials. +| connect | (url, options) | Connect to the given URL | disconnect | () | Disconnect | sendCredentials | (credentials) | Send credentials after onCredentialsRequired callback | sendCtrlAltDel | () | Send Ctrl-Alt-Del key sequence @@ -64,6 +61,16 @@ object instance. | requestDesktopSize | (width, height) | Send a request to change the remote desktop size. | viewportChangeSize | (width, height) | Change size of the viewport +__connect() details__ + +The connect() call supports the following options: + +| name | type | default | description +| ----------------- | ----- | ---------- | ------------ +| shared | bool | true | Request shared VNC mode +| credentials | obj | {} | Credentials to use when authenticating +| repeaterID | str | '' | UltraVNC RepeaterID to connect to + ## 3 Callbacks diff --git a/tests/playback.js b/tests/playback.js index ffb4859b..c2567a95 100644 --- a/tests/playback.js +++ b/tests/playback.js @@ -77,8 +77,8 @@ export default function RecordingPlayer (frames, encoding, disconnected, notific RecordingPlayer.prototype = { run: function (realtime, trafficManagement) { // initialize a new RFB - this._rfb = new RFB({'target': document.getElementById('VNC_canvas'), - 'view_only': true, + this._rfb = new RFB(document.getElementById('VNC_canvas'), + {'view_only': true, 'onDisconnected': this._handleDisconnect.bind(this), 'onNotification': this._notification}); this._enablePlaybackMode(); diff --git a/tests/test.display.js b/tests/test.display.js index fac0febc..77065872 100644 --- a/tests/test.display.js +++ b/tests/test.display.js @@ -40,19 +40,19 @@ describe('Display/Canvas Helper', function () { describe('checking for cursor uri support', function () { it('should disable cursor URIs if there is no support', function () { _forceCursorURIs(false); - var display = new Display({ target: document.createElement('canvas'), prefer_js: true, viewport: false }); + var display = new Display(document.createElement('canvas'), { prefer_js: true, viewport: false }); expect(display._cursor_uri).to.be.false; }); it('should enable cursor URIs if there is support', function () { _forceCursorURIs(true); - var display = new Display({ target: document.createElement('canvas'), prefer_js: true, viewport: false }); + var display = new Display(document.createElement('canvas'), { prefer_js: true, viewport: false }); expect(display._cursor_uri).to.be.true; }); it('respect the cursor_uri option if there is support', function () { _forceCursorURIs(false); - var display = new Display({ target: document.createElement('canvas'), prefer_js: true, viewport: false, cursor_uri: false }); + var display = new Display(document.createElement('canvas'), { prefer_js: true, viewport: false, cursor_uri: false }); expect(display._cursor_uri).to.be.false; }); }); @@ -60,7 +60,7 @@ describe('Display/Canvas Helper', function () { describe('viewport handling', function () { var display; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: false, viewport: true }); + display = new Display(document.createElement('canvas'), { prefer_js: false, viewport: true }); display.resize(5, 5); display.viewportChangeSize(3, 3); display.viewportChangePos(1, 1); @@ -153,7 +153,7 @@ describe('Display/Canvas Helper', function () { describe('resizing', function () { var display; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: false, viewport: false }); + display = new Display(document.createElement('canvas'), { prefer_js: false, viewport: false }); display.resize(4, 4); }); @@ -214,11 +214,11 @@ describe('Display/Canvas Helper', function () { var canvas; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: false, viewport: true }); + canvas = document.createElement('canvas'); + display = new Display(canvas, { prefer_js: false, viewport: true }); display.resize(4, 4); display.viewportChangeSize(3, 3); display.viewportChangePos(1, 1); - canvas = display.get_target(); document.body.appendChild(canvas); }); @@ -254,9 +254,9 @@ describe('Display/Canvas Helper', function () { var canvas; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: false, viewport: true }); + canvas = document.createElement('canvas'); + display = new Display(canvas, { prefer_js: false, viewport: true }); display.resize(4, 3); - canvas = display.get_target(); document.body.appendChild(canvas); }); @@ -314,7 +314,7 @@ describe('Display/Canvas Helper', function () { function drawing_tests (pref_js) { var display; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: pref_js }); + display = new Display(document.createElement('canvas'), { prefer_js: pref_js }); display.resize(4, 4); }); @@ -428,7 +428,7 @@ describe('Display/Canvas Helper', function () { describe('the render queue processor', function () { var display; beforeEach(function () { - display = new Display({ target: document.createElement('canvas'), prefer_js: false }); + display = new Display(document.createElement('canvas'), { prefer_js: false }); display.resize(4, 4); sinon.spy(display, '_scan_renderQ'); }); diff --git a/tests/test.keyboard.js b/tests/test.keyboard.js index 7fdeb8f9..52f21f0e 100644 --- a/tests/test.keyboard.js +++ b/tests/test.keyboard.js @@ -31,7 +31,7 @@ describe('Key Event Handling', function() { describe('Decode Keyboard Events', function() { it('should decode keydown events', function(done) { if (isIE() || isEdge()) this.skip(); - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -43,7 +43,7 @@ describe('Key Event Handling', function() { it('should decode keyup events', function(done) { if (isIE() || isEdge()) this.skip(); var calls = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -59,12 +59,12 @@ describe('Key Event Handling', function() { describe('Legacy keypress Events', function() { it('should wait for keypress when needed', function() { var callback = sinon.spy(); - var kbd = new Keyboard({onKeyEvent: callback}); + var kbd = new Keyboard(document, {onKeyEvent: callback}); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); expect(callback).to.not.have.been.called; }); it('should decode keypress events', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -76,13 +76,13 @@ describe('Key Event Handling', function() { }); it('should ignore keypress with different code', function() { var callback = sinon.spy(); - var kbd = new Keyboard({onKeyEvent: callback}); + var kbd = new Keyboard(document, {onKeyEvent: callback}); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61})); expect(callback).to.not.have.been.called; }); it('should handle keypress with missing code', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -93,7 +93,7 @@ describe('Key Event Handling', function() { kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61})); }); it('should guess key if no keypress and numeric key', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x32); expect(code).to.be.equal('Digit2'); @@ -103,7 +103,7 @@ describe('Key Event Handling', function() { kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32})); }); it('should guess key if no keypress and alpha key', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -113,7 +113,7 @@ describe('Key Event Handling', function() { kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false})); }); it('should guess key if no keypress and alpha key (with shift)', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x41); expect(code).to.be.equal('KeyA'); @@ -123,7 +123,7 @@ describe('Key Event Handling', function() { kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true})); }); it('should not guess key if no keypress and unknown key', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0); expect(code).to.be.equal('KeyA'); @@ -139,7 +139,7 @@ describe('Key Event Handling', function() { if (isIE() || isEdge()) this.skip(); }); it('should suppress anything with a valid key', function() { - var kbd = new Keyboard({}); + var kbd = new Keyboard(document, {}); var evt = keyevent('keydown', {code: 'KeyA', key: 'a'}); kbd._handleKeyDown(evt); expect(evt.preventDefault).to.have.been.called; @@ -148,13 +148,13 @@ describe('Key Event Handling', function() { expect(evt.preventDefault).to.have.been.called; }); it('should not suppress keys without key', function() { - var kbd = new Keyboard({}); + var kbd = new Keyboard(document, {}); var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); kbd._handleKeyDown(evt); expect(evt.preventDefault).to.not.have.been.called; }); it('should suppress the following keypress event', function() { - var kbd = new Keyboard({}); + var kbd = new Keyboard(document, {}); var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); kbd._handleKeyDown(evt); var evt = keyevent('keypress', {code: 'KeyA', charCode: 0x41}); @@ -168,7 +168,7 @@ describe('Key Event Handling', function() { it('should fake keyup events for virtual keyboards', function(done) { if (isIE() || isEdge()) this.skip(); var count = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch (count++) { case 0: @@ -215,7 +215,7 @@ describe('Key Event Handling', function() { it('should fake keyup events on iOS', function(done) { if (isIE() || isEdge()) this.skip(); var count = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch (count++) { case 0: @@ -240,7 +240,7 @@ describe('Key Event Handling', function() { if (isIE() || isEdge()) this.skip(); }); it('should send release using the same keysym as the press', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -253,7 +253,7 @@ describe('Key Event Handling', function() { }); it('should send the same keysym for multiple presses', function() { var count = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('KeyA'); @@ -266,14 +266,14 @@ describe('Key Event Handling', function() { }); it('should do nothing on keyup events if no keys are down', function() { var callback = sinon.spy(); - var kbd = new Keyboard({onKeyEvent: callback}); + var kbd = new Keyboard(document, {onKeyEvent: callback}); kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'})); expect(callback).to.not.have.been.called; }); describe('Legacy Events', function() { it('should track keys using keyCode if no code', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('Platform65'); @@ -293,7 +293,7 @@ describe('Key Event Handling', function() { kbd._handleKeyDown(keyevent('keydown', {keyCode: 229, key: 'a'})); }); it('should track keys using keyIdentifier if no code', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0x61); expect(code).to.be.equal('Platform65'); @@ -335,7 +335,7 @@ describe('Key Event Handling', function() { it('should change Alt to AltGraph', function() { var count = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch (count++) { case 0: @@ -353,7 +353,7 @@ describe('Key Event Handling', function() { expect(count).to.be.equal(2); }); it('should change left Super to Alt', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0xFFE9); expect(code).to.be.equal('MetaLeft'); @@ -362,7 +362,7 @@ describe('Key Event Handling', function() { kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1})); }); it('should change right Super to left Super', function(done) { - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { expect(keysym).to.be.equal(0xFFEB); expect(code).to.be.equal('MetaRight'); @@ -400,7 +400,7 @@ describe('Key Event Handling', function() { it('should generate fake undo/redo events on press when AltGraph is down', function() { var times_called = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch(times_called++) { case 0: @@ -449,7 +449,7 @@ describe('Key Event Handling', function() { }); it('should no do anything on key release', function() { var times_called = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch(times_called++) { case 7: @@ -469,7 +469,7 @@ describe('Key Event Handling', function() { }); it('should not consider a char modifier to be down on the modifier key itself', function() { var times_called = 0; - var kbd = new Keyboard({ + var kbd = new Keyboard(document, { onKeyEvent: function(keysym, code, down) { switch(times_called++) { case 0: diff --git a/tests/test.mouse.js b/tests/test.mouse.js index a67833c7..905b524c 100644 --- a/tests/test.mouse.js +++ b/tests/test.mouse.js @@ -33,47 +33,44 @@ describe('Mouse Event Handling', function() { describe('Decode Mouse Events', function() { it('should decode mousedown events', function(done) { - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { expect(bmask).to.be.equal(0x01); expect(down).to.be.equal(1); done(); - }, - target: target + } }); mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' })); }); it('should decode mouseup events', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { expect(bmask).to.be.equal(0x01); if (calls++ === 1) { expect(down).to.not.be.equal(1); done(); } - }, - target: target + } }); mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' })); mouse._handleMouseUp(mouseevent('mouseup', { button: '0x01' })); }); it('should decode mousemove events', function(done) { - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseMove: function(x, y) { // Note that target relative coordinates are sent expect(x).to.be.equal(40); expect(y).to.be.equal(10); done(); - }, - target: target + } }); mouse._handleMouseMove(mouseevent('mousemove', { clientX: 50, clientY: 20 })); }); it('should decode mousewheel events', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { calls++; expect(bmask).to.be.equal(1<<6); @@ -83,8 +80,7 @@ describe('Mouse Event Handling', function() { expect(down).to.not.be.equal(1); done(); } - }, - target: target + } }); mouse._handleMouseWheel(mouseevent('mousewheel', { deltaX: 50, deltaY: 0, @@ -99,7 +95,7 @@ describe('Mouse Event Handling', function() { it('should use same pos for 2nd tap if close enough', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { @@ -112,8 +108,7 @@ describe('Mouse Event Handling', function() { expect(y).to.be.equal(36); done(); } - }, - target: target + } }); // touch events are sent in an array of events // with one item for each touch point @@ -132,7 +127,7 @@ describe('Mouse Event Handling', function() { it('should not modify 2nd tap pos if far apart', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { @@ -145,8 +140,7 @@ describe('Mouse Event Handling', function() { expect(y).to.not.be.equal(36); done(); } - }, - target: target + } }); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 78, clientY: 46 }]})); @@ -163,7 +157,7 @@ describe('Mouse Event Handling', function() { it('should not modify 2nd tap pos if not soon enough', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { @@ -176,8 +170,7 @@ describe('Mouse Event Handling', function() { expect(y).to.not.be.equal(36); done(); } - }, - target: target + } }); mouse._handleMouseDown(touchevent( 'touchstart', { touches: [{ clientX: 78, clientY: 46 }]})); @@ -194,7 +187,7 @@ describe('Mouse Event Handling', function() { it('should not modify 2nd tap pos if not touch', function(done) { var calls = 0; - var mouse = new Mouse({ + var mouse = new Mouse(target, { onMouseButton: function(x, y, down, bmask) { calls++; if (calls === 1) { @@ -207,8 +200,7 @@ describe('Mouse Event Handling', function() { expect(y).to.not.be.equal(36); done(); } - }, - target: target + } }); mouse._handleMouseDown(mouseevent( 'mousedown', { button: '0x01', clientX: 78, clientY: 46 })); @@ -232,7 +224,7 @@ describe('Mouse Event Handling', function() { it('should accumulate wheel events if small enough', function () { var callback = sinon.spy(); - var mouse = new Mouse({ onMouseButton: callback, target: target }); + var mouse = new Mouse(target, { onMouseButton: callback }); mouse._handleMouseWheel(mouseevent( 'mousewheel', { clientX: 18, clientY: 40, @@ -265,7 +257,7 @@ describe('Mouse Event Handling', function() { it('should not accumulate large wheel events', function () { var callback = sinon.spy(); - var mouse = new Mouse({ onMouseButton: callback, target: target }); + var mouse = new Mouse(target, { onMouseButton: callback }); mouse._handleMouseWheel(mouseevent( 'mousewheel', { clientX: 18, clientY: 40, @@ -284,7 +276,7 @@ describe('Mouse Event Handling', function() { it('should send even small wheel events after a timeout', function () { var callback = sinon.spy(); - var mouse = new Mouse({ onMouseButton: callback, target: target }); + var mouse = new Mouse(target, { onMouseButton: callback }); mouse._handleMouseWheel(mouseevent( 'mousewheel', { clientX: 18, clientY: 40, @@ -296,7 +288,7 @@ describe('Mouse Event Handling', function() { it('should account for non-zero deltaMode', function () { var callback = sinon.spy(); - var mouse = new Mouse({ onMouseButton: callback, target: target }); + var mouse = new Mouse(target, { onMouseButton: callback }); mouse._handleMouseWheel(mouseevent( 'mousewheel', { clientX: 18, clientY: 40, diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 9ccc2fad..a1d2f9e9 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -10,12 +10,8 @@ import FakeWebSocket from './fake.websocket.js'; import sinon from '../vendor/sinon.js'; function make_rfb (extra_opts) { - if (!extra_opts) { - extra_opts = {}; - } - - extra_opts.target = extra_opts.target || document.createElement('canvas'); - return new RFB(extra_opts); + extra_opts = extra_opts || {}; + return new RFB(document.createElement('canvas'), extra_opts); } var push8 = function (arr, num) { @@ -581,15 +577,6 @@ describe('Remote Frame Buffer Protocol Client', function() { client._sock._websocket._open(); }); - it('should interpret version 000.000 as a repeater', function () { - client._repeaterID = '12345'; - send_ver('000.000', client); - expect(client._rfb_version).to.equal(0); - - var sent_data = client._sock._websocket._get_sent_data(); - expect(new Uint8Array(sent_data.buffer, 0, 9)).to.array.equal(new Uint8Array([73, 68, 58, 49, 50, 51, 52, 53, 0])); - }); - it('should interpret version 003.003 as version 3.3', function () { send_ver('003.003', client); expect(client._rfb_version).to.equal(3.3); @@ -637,19 +624,6 @@ describe('Remote Frame Buffer Protocol Client', function() { }); }); - it('should handle two step repeater negotiation', function () { - client._repeaterID = '12345'; - - send_ver('000.000', client); - expect(client._rfb_version).to.equal(0); - var sent_data = client._sock._websocket._get_sent_data(); - expect(new Uint8Array(sent_data.buffer, 0, 9)).to.array.equal(new Uint8Array([73, 68, 58, 49, 50, 51, 52, 53, 0])); - expect(sent_data).to.have.length(250); - - send_ver('003.008', client); - expect(client._rfb_version).to.equal(3.8); - }); - it('should send back the interpreted version', function () { send_ver('004.000', client); @@ -666,6 +640,29 @@ describe('Remote Frame Buffer Protocol Client', function() { send_ver('003.008', client); expect(client._rfb_init_state).to.equal('Security'); }); + + describe('Repeater', function () { + it('should interpret version 000.000 as a repeater', function () { + client = make_rfb(); + client.connect('wss://host:8675', { repeaterID: "12345" }); + client._sock._websocket._open(); + send_ver('000.000', client); + expect(client._rfb_version).to.equal(0); + + var sent_data = client._sock._websocket._get_sent_data(); + expect(new Uint8Array(sent_data.buffer, 0, 9)).to.array.equal(new Uint8Array([73, 68, 58, 49, 50, 51, 52, 53, 0])); + expect(sent_data).to.have.length(250); + }); + + it('should handle two step repeater negotiation', function () { + client = make_rfb(); + client.connect('wss://host:8675', { repeaterID: "12345" }); + client._sock._websocket._open(); + send_ver('000.000', client); + send_ver('003.008', client); + expect(client._rfb_version).to.equal(3.8); + }); + }); }); describe('Security', function () { @@ -1016,24 +1013,28 @@ describe('Remote Frame Buffer Protocol Client', function() { beforeEach(function () { client = make_rfb(); - client.connect('wss://host:8675'); - client._sock._websocket._open(); - client._rfb_init_state = 'SecurityResult'; }); it('should transition to the ServerInitialisation state', function () { + client.connect('wss://host:8675'); + client._sock._websocket._open(); + client._rfb_init_state = 'SecurityResult'; client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); expect(client._rfb_init_state).to.equal('ServerInitialisation'); }); it('should send 1 if we are in shared mode', function () { - client.set_shared(true); + client.connect('wss://host:8675', { shared: true }); + client._sock._websocket._open(); + client._rfb_init_state = 'SecurityResult'; client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); expect(client._sock).to.have.sent(new Uint8Array([1])); }); it('should send 0 if we are not in shared mode', function () { - client.set_shared(false); + client.connect('wss://host:8675', { shared: false }); + client._sock._websocket._open(); + client._rfb_init_state = 'SecurityResult'; client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); expect(client._sock).to.have.sent(new Uint8Array([0])); }); diff --git a/vnc_lite.html b/vnc_lite.html index c91f564f..95cf2865 100644 --- a/vnc_lite.html +++ b/vnc_lite.html @@ -256,10 +256,8 @@ } try { - rfb = new RFB({'target': document.getElementById('noVNC_canvas'), - 'repeaterID': WebUtil.getConfigVar('repeaterID', ''), - 'local_cursor': WebUtil.getConfigVar('cursor', true), - 'shared': WebUtil.getConfigVar('shared', true), + rfb = new RFB(document.getElementById('noVNC_canvas'), + {'local_cursor': WebUtil.getConfigVar('cursor', true), 'view_only': WebUtil.getConfigVar('view_only', false), 'onNotification': notification, 'onUpdateState': updateState, @@ -287,7 +285,9 @@ } url += '/' + path; - rfb.connect(url, { password: password }); + rfb.connect(url, { repeaterID: WebUtil.getConfigVar('repeaterID', ''), + shared: WebUtil.getConfigVar('shared', true), + credentials: { password: password } }); })();