From c77d9fcc4e752047388a404d7eeed6db6af39b2a Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Mon, 11 Apr 2016 14:32:14 -0600 Subject: [PATCH 01/65] Added an '--ssl-only' option to noVNC launch script. This will pass through to Websockify, allowing a user to specify that only ssl-secured connections will be allowed. --- utils/launch.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/utils/launch.sh b/utils/launch.sh index ecee06cd..bbce453e 100755 --- a/utils/launch.sh +++ b/utils/launch.sh @@ -5,7 +5,7 @@ usage() { echo "$*" echo fi - echo "Usage: ${NAME} [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT]" + echo "Usage: ${NAME} [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT] [--ssl-only]" echo echo "Starts the WebSockets proxy and a mini-webserver and " echo "provides a cut-and-paste URL to go to." @@ -18,6 +18,8 @@ usage() { echo " Default: self.pem" echo " --web WEB Path to web files (e.g. vnc.html)" echo " Default: ./" + echo " --ssl-only Disable non-https connections." + echo " " exit 2 } @@ -29,6 +31,7 @@ VNC_DEST="localhost:5900" CERT="" WEB="" proxy_pid="" +SSLONLY="" die() { echo "$*" @@ -55,6 +58,7 @@ while [ "$*" ]; do --vnc) VNC_DEST="${OPTARG}"; shift ;; --cert) CERT="${OPTARG}"; shift ;; --web) WEB="${OPTARG}"; shift ;; + --ssl-only) SSLONLY="--ssl-only" ;; -h|--help) usage ;; -*) usage "Unknown chrooter option: ${param}" ;; *) break ;; @@ -134,7 +138,7 @@ fi echo "Starting webserver and WebSockets proxy on port ${PORT}" #${HERE}/websockify --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} & -${WEBSOCKIFY} --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} & +${WEBSOCKIFY} ${SSLONLY} --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} & proxy_pid="$!" sleep 1 if ! ps -p ${proxy_pid} >/dev/null; then From 27a1f6cb9505171fef9f604941bf54a2e1f0abcb Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Mon, 11 Apr 2016 14:42:42 -0600 Subject: [PATCH 02/65] Tweaked message printed based on whether or not http is available. --- utils/launch.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/launch.sh b/utils/launch.sh index bbce453e..db610662 100755 --- a/utils/launch.sh +++ b/utils/launch.sh @@ -148,7 +148,12 @@ if ! ps -p ${proxy_pid} >/dev/null; then fi echo -e "\n\nNavigate to this URL:\n" -echo -e " http://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n" +if [ "x$SSLONLY" == "x" ]; then + echo -e " http://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n" +else + echo -e " https://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n" +fi + echo -e "Press Ctrl-C to exit\n\n" wait ${proxy_pid} From f52105bc88ebd18d5cb3fba817173e99600cdc3f Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 12 May 2016 16:43:19 +0200 Subject: [PATCH 03/65] Add fallback value for devicePixelRatio In IE 10 for example, devicePixelRatio doesn't exist which caused the code to fail by setting the thresholds to zero. --- include/input.js | 5 +++-- include/rfb.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/input.js b/include/input.js index 5d9e209e..fa6ba44a 100644 --- a/include/input.js +++ b/include/input.js @@ -212,7 +212,7 @@ var Keyboard, Mouse; // Touch device // When two touches occur within 500 ms of each other and are - // closer than 20 pixels together a double click is triggered. + // close enough together a double click is triggered. if (down == 1) { if (this._doubleClickTimer === null) { this._lastTouchPos = pos; @@ -229,7 +229,8 @@ var Keyboard, Mouse; // The goal is to trigger on a certain physical width, the // devicePixelRatio brings us a bit closer but is not optimal. - if (d < 20 * window.devicePixelRatio) { + var threshold = 20 * (window.devicePixelRatio || 1); + if (d < threshold) { pos = this._lastTouchPos; } } diff --git a/include/rfb.js b/include/rfb.js index 3e9344bb..48fa5a8c 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -617,7 +617,7 @@ var RFB; // The goal is to trigger on a certain physical width, the // devicePixelRatio brings us a bit closer but is not optimal. - var dragThreshold = 10 * window.devicePixelRatio; + var dragThreshold = 10 * (window.devicePixelRatio || 1); if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || Math.abs(deltaY) > dragThreshold)) { From 553864e85813f886b9c60b4825c8d4b714cae695 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 17:27:17 +0200 Subject: [PATCH 04/65] Switch names between the container and the screen The noVNC_container now contains the logo and the screen. While the noVNC_screen in turn contains the canvas. --- include/base.css | 9 +++++---- include/ui.js | 28 +++++++++++++++------------- vnc.html | 4 ++-- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/include/base.css b/include/base.css index 2769357e..af284717 100644 --- a/include/base.css +++ b/include/base.css @@ -113,9 +113,7 @@ html { float:right; } -/* Do not set width/height for VNC_screen or VNC_canvas or incorrect - * scaling will occur. Canvas resizes to remote VNC settings */ -#noVNC_screen { +#noVNC_container { display: table; width:100%; height:100%; @@ -124,7 +122,7 @@ html { /*border-top-left-radius: 800px 600px;*/ } -#noVNC_container { +#noVNC_screen { display: none; position: absolute; margin: 0px; @@ -137,6 +135,9 @@ html { height: auto; } +/* Do not set width/height for VNC_canvas or incorrect + * scaling will occur. Canvas size depends on remote VNC + * settings and noVNC settings. */ #noVNC_canvas { position: absolute; left: 0; diff --git a/include/ui.js b/include/ui.js index cfdedb3a..066a35a7 100644 --- a/include/ui.js +++ b/include/ui.js @@ -248,7 +248,7 @@ var UI; onresize: function (callback) { if (!UI.rfb) return; - var size = UI.getCanvasLimit(); + var size = UI.screenSize(); if (size && UI.rfb_state === 'normal' && UI.rfb.get_display()) { var display = UI.rfb.get_display(); @@ -278,17 +278,19 @@ var UI; } }, - getCanvasLimit: function () { - var container = $D('noVNC_container'); + // The screen is always the same size as the available + // viewport minus the height of the control bar + screenSize: function () { + var screen = $D('noVNC_screen'); // Hide the scrollbars until the size is calculated - container.style.overflow = "hidden"; + screen.style.overflow = "hidden"; - var pos = Util.getPosition(container); + var pos = Util.getPosition(screen); var w = pos.width; var h = pos.height; - container.style.overflow = "visible"; + screen.style.overflow = "visible"; if (isNaN(w) || isNaN(h)) { return false; @@ -687,7 +689,7 @@ var UI; break; case 'disconnected': $D('noVNC_logo').style.display = "block"; - $D('noVNC_container').style.display = "none"; + $D('noVNC_screen').style.display = "none"; /* falls through */ case 'loaded': klass = "noVNC_status_normal"; @@ -844,7 +846,7 @@ var UI; //Close dialog. setTimeout(UI.setBarPosition, 100); $D('noVNC_logo').style.display = "none"; - $D('noVNC_container').style.display = "inline"; + $D('noVNC_screen').style.display = "inline"; }, disconnect: function() { @@ -855,7 +857,7 @@ var UI; UI.rfb.set_onFBUComplete(UI.FBUComplete); $D('noVNC_logo').style.display = "block"; - $D('noVNC_container').style.display = "none"; + $D('noVNC_screen').style.display = "none"; // Don't display the connection settings until we're actually disconnected }, @@ -919,19 +921,19 @@ var UI; // If clipping, update clipping settings display.set_viewport(true); - var size = UI.getCanvasLimit(); + var size = UI.screenSize(); if (size) { display.set_maxWidth(size.w); display.set_maxHeight(size.h); // Hide potential scrollbars that can skew the position - $D('noVNC_container').style.overflow = "hidden"; + $D('noVNC_screen').style.overflow = "hidden"; // The x position marks the left margin of the canvas, // remove the margin from both sides to keep it centered var new_w = size.w - (2 * Util.getPosition($D('noVNC_canvas')).x); - $D('noVNC_container').style.overflow = "visible"; + $D('noVNC_screen').style.overflow = "visible"; display.viewportChangeSize(new_w, size.h); } @@ -1218,7 +1220,7 @@ var UI; $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px'; $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; - var vncwidth = $D('noVNC_screen').style.offsetWidth; + var vncwidth = $D('noVNC_container').style.offsetWidth; $D('noVNC-control-bar').style.width = vncwidth + 'px'; } diff --git a/vnc.html b/vnc.html index f64c750c..c0f242c0 100644 --- a/vnc.html +++ b/vnc.html @@ -207,11 +207,11 @@ -
+

no
VNC

-
+
Canvas not supported. From 777cb7a0c573e16656a30b538e8d0e280cc69975 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 18:01:15 +0200 Subject: [PATCH 05/65] Cleanup for the resize related functions Renamed functions, added clarifying comments and moved the resize related functions closer to the other viewport functions. --- include/rfb.js | 2 + include/ui.js | 147 ++++++++++++++++++++++++++----------------------- 2 files changed, 81 insertions(+), 68 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index 48fa5a8c..9e4525b5 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -311,6 +311,8 @@ var RFB; this._sock.flush(); }, + // Requests a change of remote desktop size. This message is an extension + // and may only be sent if we have received an ExtendedDesktopSize message setDesktopSize: function (width, height) { if (this._rfb_state !== "normal") { return; } diff --git a/include/ui.js b/include/ui.js index 066a35a7..6a6b6f40 100644 --- a/include/ui.js +++ b/include/ui.js @@ -1,7 +1,7 @@ /* * noVNC: HTML5 VNC client * Copyright (C) 2012 Joel Martin - * Copyright (C) 2015 Samuel Mannehed for Cendio AB + * Copyright (C) 2016 Samuel Mannehed for Cendio AB * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. @@ -132,7 +132,7 @@ var UI; UI.setBarPosition(); Util.addEvent(window, 'resize', function () { - UI.onresize(); + UI.applyResizeMode(); UI.setViewClip(); UI.updateViewDrag(); UI.setBarPosition(); @@ -188,7 +188,7 @@ var UI; 'onUpdateState': UI.updateState, 'onXvpInit': UI.updateXvpVisualState, 'onClipboard': UI.clipReceive, - 'onFBUComplete': UI.FBUComplete, + 'onFBUComplete': UI.initialResize, 'onFBResize': UI.updateViewDrag, 'onDesktopName': UI.updateDocumentTitle}); return true; @@ -245,60 +245,6 @@ var UI; $D("noVNC_resize").onchange = UI.enableDisableViewClip; }, - onresize: function (callback) { - if (!UI.rfb) return; - - var size = UI.screenSize(); - - if (size && UI.rfb_state === 'normal' && UI.rfb.get_display()) { - var display = UI.rfb.get_display(); - var scaleType = UI.getSetting('resize'); - if (scaleType === 'remote') { - // use remote resizing - - // When the local window has been resized, wait until the size remains - // the same for 0.5 seconds before sending the request for changing - // the resolution of the session - clearTimeout(UI.resizeTimeout); - UI.resizeTimeout = setTimeout(function(){ - display.set_maxWidth(size.w); - display.set_maxHeight(size.h); - Util.Debug('Attempting setDesktopSize(' + - size.w + ', ' + size.h + ')'); - UI.rfb.setDesktopSize(size.w, size.h); - }, 500); - } else if (scaleType === 'scale' || scaleType === 'downscale') { - // use local scaling - - var downscaleOnly = scaleType === 'downscale'; - var scaleRatio = display.autoscale(size.w, size.h, downscaleOnly); - UI.rfb.get_mouse().set_scale(scaleRatio); - Util.Debug('Scaling by ' + UI.rfb.get_mouse().get_scale()); - } - } - }, - - // The screen is always the same size as the available - // viewport minus the height of the control bar - screenSize: function () { - var screen = $D('noVNC_screen'); - - // Hide the scrollbars until the size is calculated - screen.style.overflow = "hidden"; - - var pos = Util.getPosition(screen); - var w = pos.width; - var h = pos.height; - - screen.style.overflow = "visible"; - - if (isNaN(w) || isNaN(h)) { - return false; - } else { - return {w: w, h: h}; - } - }, - // Read form control compatible setting from cookie getSetting: function(name) { var ctrl = $D('noVNC_' + name); @@ -792,16 +738,6 @@ var UI; } }, - // This resize can not be done until we know from the first Frame Buffer Update - // if it is supported or not. - // The resize is needed to make sure the server desktop size is updated to the - // corresponding size of the current local window when reconnecting to an - // existing session. - FBUComplete: function(rfb, fbu) { - UI.onresize(); - UI.rfb.set_onFBUComplete(function() { }); - }, - // Display the desktop name in the document title updateDocumentTitle: function(rfb, name) { document.title = name + " - noVNC"; @@ -854,7 +790,7 @@ var UI; UI.rfb.disconnect(); // Restore the callback used for initial resize - UI.rfb.set_onFBUComplete(UI.FBUComplete); + UI.rfb.set_onFBUComplete(UI.initialResize); $D('noVNC_logo').style.display = "block"; $D('noVNC_screen').style.display = "none"; @@ -888,6 +824,81 @@ var UI; Util.Debug("<< UI.clipSend"); }, + + // Apply remote resizing or local scaling + applyResizeMode: function () { + if (!UI.rfb) return; + + var screen = UI.screenSize(); + + if (screen && UI.rfb_state === 'normal' && UI.rfb.get_display()) { + + var display = UI.rfb.get_display(); + var resizeMode = UI.getSetting('resize'); + + if (resizeMode === 'remote') { + + // Request changing the resolution of the remote display to + // the size of the local browser viewport. + + // In order to not send multiple requests before the browser-resize + // is finished we wait 0.5 seconds before sending the request. + clearTimeout(UI.resizeTimeout); + UI.resizeTimeout = setTimeout(function(){ + + // Limit the viewport to the size of the browser window + display.set_maxWidth(screen.w); + display.set_maxHeight(screen.h); + + Util.Debug('Attempting setDesktopSize(' + + screen.w + ', ' + screen.h + ')'); + + // Request a remote size covering the viewport + UI.rfb.setDesktopSize(screen.w, screen.h); + }, 500); + + } else if (resizeMode === 'scale' || resizeMode === 'downscale') { + var downscaleOnly = resizeMode === 'downscale'; + var scaleRatio = display.autoscale(screen.w, screen.h, downscaleOnly); + UI.rfb.get_mouse().set_scale(scaleRatio); + Util.Debug('Scaling by ' + UI.rfb.get_mouse().get_scale()); + } + } + }, + + // The screen is always the same size as the available viewport + // in the browser window minus the height of the control bar + screenSize: function () { + var screen = $D('noVNC_screen'); + + // Hide the scrollbars until the size is calculated + screen.style.overflow = "hidden"; + + var pos = Util.getPosition(screen); + var w = pos.width; + var h = pos.height; + + screen.style.overflow = "visible"; + + if (isNaN(w) || isNaN(h)) { + return false; + } else { + return {w: w, h: h}; + } + }, + + // Normally we only apply the current resize mode after a window resize + // event. This means that when a new connection is opened, there is no + // resize mode active. + // We have to wait until the first FBU because this is where the client + // will find the supported encodings of the server. Some calls later in + // the chain is dependant on knowing the server-capabilities. + initialResize: function(rfb, fbu) { + UI.applyResizeMode(); + // After doing this once, we remove the callback. + UI.rfb.set_onFBUComplete(function() { }); + }, + // Set and configure viewport clipping setViewClip: function(clip) { var display; From 29475d772847013b53878fef22103d1538477395 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 18:40:13 +0200 Subject: [PATCH 06/65] Moved UpdateState and UpdateVisualState --- include/ui.js | 207 +++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 104 deletions(-) diff --git a/include/ui.js b/include/ui.js index 6a6b6f40..1c87438e 100644 --- a/include/ui.js +++ b/include/ui.js @@ -245,6 +245,109 @@ var UI; $D("noVNC_resize").onchange = UI.enableDisableViewClip; }, + updateState: function(rfb, state, oldstate, msg) { + UI.rfb_state = state; + var klass; + switch (state) { + case 'failed': + case 'fatal': + klass = "noVNC_status_error"; + break; + case 'normal': + klass = "noVNC_status_normal"; + break; + case 'disconnected': + $D('noVNC_logo').style.display = "block"; + $D('noVNC_screen').style.display = "none"; + /* falls through */ + case 'loaded': + klass = "noVNC_status_normal"; + break; + case 'password': + UI.toggleConnectPanel(); + + $D('noVNC_connect_button').value = "Send Password"; + $D('noVNC_connect_button').onclick = UI.setPassword; + $D('noVNC_password').focus(); + + klass = "noVNC_status_warn"; + break; + default: + klass = "noVNC_status_warn"; + break; + } + + if (typeof(msg) !== 'undefined') { + $D('noVNC-control-bar').setAttribute("class", klass); + $D('noVNC_status').innerHTML = msg; + } + + UI.updateVisualState(); + }, + + // Disable/enable controls depending on connection state + updateVisualState: function() { + var connected = UI.rfb && UI.rfb_state === 'normal'; + + //Util.Debug(">> updateVisualState"); + $D('noVNC_encrypt').disabled = connected; + $D('noVNC_true_color').disabled = connected; + if (Util.browserSupportsCursorURIs()) { + $D('noVNC_cursor').disabled = connected; + } else { + UI.updateSetting('cursor', !UI.isTouchDevice); + $D('noVNC_cursor').disabled = true; + } + + UI.enableDisableViewClip(); + $D('noVNC_resize').disabled = connected; + $D('noVNC_shared').disabled = connected; + $D('noVNC_view_only').disabled = connected; + $D('noVNC_path').disabled = connected; + $D('noVNC_repeaterID').disabled = connected; + + if (connected) { + UI.setViewClip(); + UI.setMouseButton(1); + $D('clipboardButton').style.display = "inline"; + $D('showKeyboard').style.display = "inline"; + $D('noVNC_extra_keys').style.display = ""; + $D('sendCtrlAltDelButton').style.display = "inline"; + } else { + UI.setMouseButton(); + $D('clipboardButton').style.display = "none"; + $D('showKeyboard').style.display = "none"; + $D('noVNC_extra_keys').style.display = "none"; + $D('sendCtrlAltDelButton').style.display = "none"; + UI.updateXvpVisualState(0); + } + + // State change disables viewport dragging. + // It is enabled (toggled) by direct click on the button + UI.updateViewDrag(false); + + switch (UI.rfb_state) { + case 'fatal': + case 'failed': + case 'disconnected': + $D('connectButton').style.display = ""; + $D('disconnectButton').style.display = "none"; + UI.connSettingsOpen = false; + UI.toggleConnectPanel(); + break; + case 'loaded': + $D('connectButton').style.display = ""; + $D('disconnectButton').style.display = "none"; + break; + default: + $D('connectButton').style.display = "none"; + $D('disconnectButton').style.display = ""; + break; + } + + //Util.Debug("<< updateVisualState"); + }, + // Read form control compatible setting from cookie getSetting: function(name) { var ctrl = $D('noVNC_' + name); @@ -575,7 +678,6 @@ var UI; }, - setPassword: function() { UI.rfb.sendPassword($D('noVNC_password').value); //Reset connect button. @@ -622,109 +724,6 @@ var UI; } }, - updateState: function(rfb, state, oldstate, msg) { - UI.rfb_state = state; - var klass; - switch (state) { - case 'failed': - case 'fatal': - klass = "noVNC_status_error"; - break; - case 'normal': - klass = "noVNC_status_normal"; - break; - case 'disconnected': - $D('noVNC_logo').style.display = "block"; - $D('noVNC_screen').style.display = "none"; - /* falls through */ - case 'loaded': - klass = "noVNC_status_normal"; - break; - case 'password': - UI.toggleConnectPanel(); - - $D('noVNC_connect_button').value = "Send Password"; - $D('noVNC_connect_button').onclick = UI.setPassword; - $D('noVNC_password').focus(); - - klass = "noVNC_status_warn"; - break; - default: - klass = "noVNC_status_warn"; - break; - } - - if (typeof(msg) !== 'undefined') { - $D('noVNC-control-bar').setAttribute("class", klass); - $D('noVNC_status').innerHTML = msg; - } - - UI.updateVisualState(); - }, - - // Disable/enable controls depending on connection state - updateVisualState: function() { - var connected = UI.rfb && UI.rfb_state === 'normal'; - - //Util.Debug(">> updateVisualState"); - $D('noVNC_encrypt').disabled = connected; - $D('noVNC_true_color').disabled = connected; - if (Util.browserSupportsCursorURIs()) { - $D('noVNC_cursor').disabled = connected; - } else { - UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; - } - - UI.enableDisableViewClip(); - $D('noVNC_resize').disabled = connected; - $D('noVNC_shared').disabled = connected; - $D('noVNC_view_only').disabled = connected; - $D('noVNC_path').disabled = connected; - $D('noVNC_repeaterID').disabled = connected; - - if (connected) { - UI.setViewClip(); - UI.setMouseButton(1); - $D('clipboardButton').style.display = "inline"; - $D('showKeyboard').style.display = "inline"; - $D('noVNC_extra_keys').style.display = ""; - $D('sendCtrlAltDelButton').style.display = "inline"; - } else { - UI.setMouseButton(); - $D('clipboardButton').style.display = "none"; - $D('showKeyboard').style.display = "none"; - $D('noVNC_extra_keys').style.display = "none"; - $D('sendCtrlAltDelButton').style.display = "none"; - UI.updateXvpVisualState(0); - } - - // State change disables viewport dragging. - // It is enabled (toggled) by direct click on the button - UI.updateViewDrag(false); - - switch (UI.rfb_state) { - case 'fatal': - case 'failed': - case 'disconnected': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; - UI.connSettingsOpen = false; - UI.toggleConnectPanel(); - break; - case 'loaded': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; - break; - default: - $D('connectButton').style.display = "none"; - $D('disconnectButton').style.display = ""; - break; - } - - //Util.Debug("<< updateVisualState"); - }, - // Disable/enable XVP button updateXvpVisualState: function(ver) { if (ver >= 1) { From 0bd2cbacaae3e6c211d48dc6e6d75268a17acc95 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 18:42:10 +0200 Subject: [PATCH 07/65] Remove whitespace from function definitions --- include/ui.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/ui.js b/include/ui.js index 1c87438e..f73e6e41 100644 --- a/include/ui.js +++ b/include/ui.js @@ -47,7 +47,7 @@ var UI; // Setup rfb object, load settings from browser storage, then call // UI.init to setup the UI/menus - load: function (callback) { + load: function(callback) { WebUtil.initSettings(UI.start, callback); }, @@ -182,7 +182,7 @@ var UI; } }, - initRFB: function () { + initRFB: function() { try { UI.rfb = new RFB({'target': $D('noVNC_canvas'), 'onUpdateState': UI.updateState, @@ -825,7 +825,7 @@ var UI; // Apply remote resizing or local scaling - applyResizeMode: function () { + applyResizeMode: function() { if (!UI.rfb) return; var screen = UI.screenSize(); @@ -867,7 +867,7 @@ var UI; // The screen is always the same size as the available viewport // in the browser window minus the height of the control bar - screenSize: function () { + screenSize: function() { var screen = $D('noVNC_screen'); // Hide the scrollbars until the size is calculated @@ -951,7 +951,7 @@ var UI; }, // Handle special cases where clipping is forced on/off or locked - enableDisableViewClip: function () { + enableDisableViewClip: function() { var resizeElem = $D('noVNC_resize'); var connected = UI.rfb && UI.rfb_state === 'normal'; From 45c70c9e23567a5b1d6985668211c227459b2af9 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 18:47:55 +0200 Subject: [PATCH 08/65] Moved and changed order of the setting-functions --- include/ui.js | 160 +++++++++++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/include/ui.js b/include/ui.js index f73e6e41..c67077f4 100644 --- a/include/ui.js +++ b/include/ui.js @@ -348,17 +348,14 @@ var UI; //Util.Debug("<< updateVisualState"); }, - // Read form control compatible setting from cookie - getSetting: function(name) { - var ctrl = $D('noVNC_' + name); - var val = WebUtil.readSetting(name); - if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { - if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { - val = false; - } else { - val = true; - } + // Initial page load read/initialization of settings + initSetting: function(name, defVal) { + // Check Query string followed by cookie + var val = WebUtil.getConfigVar(name); + if (val === null) { + val = WebUtil.readSetting(name, defVal); } + UI.updateSetting(name, val); return val; }, @@ -410,23 +407,85 @@ var UI; return val; }, - // Initial page load read/initialization of settings - initSetting: function(name, defVal) { - // Check Query string followed by cookie - var val = WebUtil.getConfigVar(name); - if (val === null) { - val = WebUtil.readSetting(name, defVal); - } - UI.updateSetting(name, val); - return val; - }, - // Force a setting to be a certain value forceSetting: function(name, val) { UI.updateSetting(name, val); return val; }, + // Read form control compatible setting from cookie + getSetting: function(name) { + var ctrl = $D('noVNC_' + name); + var val = WebUtil.readSetting(name); + if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { + if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { + val = false; + } else { + val = true; + } + } + return val; + }, + + // Open menu + openSettingsMenu: function() { + // Close the description panel + $D('noVNC_description').style.display = "none"; + // Close clipboard panel if open + if (UI.clipboardOpen === true) { + UI.toggleClipboardPanel(); + } + // Close connection settings if open + if (UI.connSettingsOpen === true) { + UI.toggleConnectPanel(); + } + // Close XVP panel if open + if (UI.xvpOpen === true) { + UI.toggleXvpPanel(); + } + $D('noVNC_settings').style.display = "block"; + $D('settingsButton').className = "noVNC_status_button_selected"; + UI.settingsOpen = true; + }, + + // Close menu (without applying settings) + closeSettingsMenu: function() { + $D('noVNC_settings').style.display = "none"; + $D('settingsButton').className = "noVNC_status_button"; + UI.settingsOpen = false; + }, + + // Toggle the settings menu: + // On open, settings are refreshed from saved cookies. + // On close, settings are applied + toggleSettingsPanel: function() { + // Close the description panel + $D('noVNC_description').style.display = "none"; + if (UI.settingsOpen) { + UI.settingsApply(); + UI.closeSettingsMenu(); + } else { + UI.updateSetting('encrypt'); + UI.updateSetting('true_color'); + if (Util.browserSupportsCursorURIs()) { + UI.updateSetting('cursor'); + } else { + UI.updateSetting('cursor', !UI.isTouchDevice); + $D('noVNC_cursor').disabled = true; + } + UI.updateSetting('clip'); + UI.updateSetting('resize'); + UI.updateSetting('shared'); + UI.updateSetting('view_only'); + UI.updateSetting('path'); + UI.updateSetting('repeaterID'); + UI.updateSetting('stylesheet'); + UI.updateSetting('logging'); + + UI.openSettingsMenu(); + } + }, + // Show the popup status togglePopupStatus: function(text) { @@ -587,65 +646,6 @@ var UI; } }, - // Toggle the settings menu: - // On open, settings are refreshed from saved cookies. - // On close, settings are applied - toggleSettingsPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - if (UI.settingsOpen) { - UI.settingsApply(); - UI.closeSettingsMenu(); - } else { - UI.updateSetting('encrypt'); - UI.updateSetting('true_color'); - if (Util.browserSupportsCursorURIs()) { - UI.updateSetting('cursor'); - } else { - UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; - } - UI.updateSetting('clip'); - UI.updateSetting('resize'); - UI.updateSetting('shared'); - UI.updateSetting('view_only'); - UI.updateSetting('path'); - UI.updateSetting('repeaterID'); - UI.updateSetting('stylesheet'); - UI.updateSetting('logging'); - - UI.openSettingsMenu(); - } - }, - - // Open menu - openSettingsMenu: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close clipboard panel if open - if (UI.clipboardOpen === true) { - UI.toggleClipboardPanel(); - } - // Close connection settings if open - if (UI.connSettingsOpen === true) { - UI.toggleConnectPanel(); - } - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - $D('noVNC_settings').style.display = "block"; - $D('settingsButton').className = "noVNC_status_button_selected"; - UI.settingsOpen = true; - }, - - // Close menu (without applying settings) - closeSettingsMenu: function() { - $D('noVNC_settings').style.display = "none"; - $D('settingsButton').className = "noVNC_status_button"; - UI.settingsOpen = false; - }, - // Save/apply settings when 'Apply' button is pressed settingsApply: function() { //Util.Debug(">> settingsApply"); From 4e471b5b55fa2272e3c72b0df8848dabc3196965 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 19:04:32 +0200 Subject: [PATCH 09/65] Moved and split the popupStatus function Now if popupStatus is called twice it will refresh the duration of the popup. If you want to wait 1.5 seconds and close the popup you can click the popup itself. --- include/ui.js | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/include/ui.js b/include/ui.js index c67077f4..72878376 100644 --- a/include/ui.js +++ b/include/ui.js @@ -221,8 +221,8 @@ var UI; $D("xvpShutdownButton").onclick = UI.xvpShutdown; $D("xvpRebootButton").onclick = UI.xvpReboot; $D("xvpResetButton").onclick = UI.xvpReset; - $D("noVNC_status").onclick = UI.togglePopupStatus; - $D("noVNC_popup_status").onclick = UI.togglePopupStatus; + $D("noVNC_status").onclick = UI.popupStatus; + $D("noVNC_popup_status").onclick = UI.closePopup; $D("xvpButton").onclick = UI.toggleXvpPanel; $D("clipboardButton").onclick = UI.toggleClipboardPanel; $D("fullscreenButton").onclick = UI.toggleFullscreen; @@ -348,6 +348,31 @@ var UI; //Util.Debug("<< updateVisualState"); }, + popupStatus: function(text) { + var psp = $D('noVNC_popup_status'); + + clearTimeout(UI.popupStatusTimeout); + + if (typeof text === 'string') { + psp.innerHTML = text; + } else { + psp.innerHTML = $D('noVNC_status').innerHTML; + } + psp.style.display = "block"; + psp.style.left = window.innerWidth/2 - + parseInt(window.getComputedStyle(psp).width)/2 -30 + "px"; + + // Show the popup for a maximum of 1.5 seconds + UI.popupStatusTimeout = setTimeout(function() { + UI.closePopup(); + }, 1500); + }, + + closePopup: function() { + clearTimeout(UI.popupStatusTimeout); + $D('noVNC_popup_status').style.display = "none"; + }, + // Initial page load read/initialization of settings initSetting: function(name, defVal) { // Check Query string followed by cookie @@ -486,31 +511,6 @@ var UI; } }, - - // Show the popup status - togglePopupStatus: function(text) { - var psp = $D('noVNC_popup_status'); - - var closePopup = function() { psp.style.display = "none"; }; - - if (window.getComputedStyle(psp).display === 'none') { - if (typeof text === 'string') { - psp.innerHTML = text; - } else { - psp.innerHTML = $D('noVNC_status').innerHTML; - } - psp.style.display = "block"; - psp.style.left = window.innerWidth/2 - - parseInt(window.getComputedStyle(psp).width)/2 -30 + "px"; - - // Show the popup for a maximum of 1.5 seconds - UI.popupStatusTimeout = setTimeout(function() { closePopup(); }, 1500); - } else { - clearTimeout(UI.popupStatusTimeout); - closePopup(); - } - }, - // Show the XVP panel toggleXvpPanel: function() { // Close the description panel @@ -968,7 +968,7 @@ var UI; // The browser is IE and we are in fullscreen mode. // - We need to force clipping while in fullscreen since // scrollbars doesn't work. - UI.togglePopupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen"); + UI.popupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen"); UI.rememberedClipSetting = UI.getSetting('clip'); UI.setViewClip(true); $D('noVNC_clip').disabled = true; From cd611a5326ed9053b94501c453f99fd24c7dfb11 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 19:13:35 +0200 Subject: [PATCH 10/65] Renamed showExtraKeys to toggleExtraKeys --- images/{showextrakeys.png => toggleextrakeys.png} | Bin include/base.css | 4 ++-- include/ui.js | 8 ++++---- vnc.html | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename images/{showextrakeys.png => toggleextrakeys.png} (100%) diff --git a/images/showextrakeys.png b/images/toggleextrakeys.png similarity index 100% rename from images/showextrakeys.png rename to images/toggleextrakeys.png diff --git a/include/base.css b/include/base.css index af284717..59e90c5b 100644 --- a/include/base.css +++ b/include/base.css @@ -442,7 +442,7 @@ html { margin-left: 0px; } -#showExtraKeysButton { display: none; } +#toggleExtraKeysButton { display: none; } #toggleCtrlButton { display: inline; } #toggleAltButton { display: inline; } #sendTabButton { display: inline; } @@ -476,7 +476,7 @@ html { padding-right: 0px; } /* collapse the extra keys on lower resolutions */ - #showExtraKeysButton { + #toggleExtraKeysButton { display: inline; } #toggleCtrlButton { diff --git a/include/ui.js b/include/ui.js index 72878376..843f38f0 100644 --- a/include/ui.js +++ b/include/ui.js @@ -211,7 +211,7 @@ var UI; $D("keyboardinput").onblur = UI.keyInputBlur; $D("keyboardinput").onsubmit = function () { return false; }; - $D("showExtraKeysButton").onclick = UI.showExtraKeys; + $D("toggleExtraKeysButton").onclick = UI.toggleExtraKeys; $D("toggleCtrlButton").onclick = UI.toggleCtrl; $D("toggleAltButton").onclick = UI.toggleAlt; $D("sendTabButton").onclick = UI.sendTab; @@ -1159,21 +1159,21 @@ var UI; UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100); }, - showExtraKeys: function() { + toggleExtraKeys: function() { UI.keepKeyboard(); if(UI.extraKeysVisible === false) { $D('toggleCtrlButton').style.display = "inline"; $D('toggleAltButton').style.display = "inline"; $D('sendTabButton').style.display = "inline"; $D('sendEscButton').style.display = "inline"; - $D('showExtraKeysButton').className = "noVNC_status_button_selected"; + $D('toggleExtraKeysButton').className = "noVNC_status_button_selected"; UI.extraKeysVisible = true; } else if(UI.extraKeysVisible === true) { $D('toggleCtrlButton').style.display = ""; $D('toggleAltButton').style.display = ""; $D('sendTabButton').style.display = ""; $D('sendEscButton').style.display = ""; - $D('showExtraKeysButton').className = "noVNC_status_button"; + $D('toggleExtraKeysButton').className = "noVNC_status_button"; UI.extraKeysVisible = false; } }, diff --git a/vnc.html b/vnc.html index c0f242c0..cdf45dc9 100644 --- a/vnc.html +++ b/vnc.html @@ -74,8 +74,8 @@ autocorrect="off" autocomplete="off" spellcheck="false" mozactionhint="Enter">
- + Date: Tue, 26 Apr 2016 23:21:32 +0200 Subject: [PATCH 11/65] Clarify comments and variable names for viewDrag --- include/ui.js | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/include/ui.js b/include/ui.js index 843f38f0..872b9e97 100644 --- a/include/ui.js +++ b/include/ui.js @@ -984,38 +984,36 @@ var UI; } }, - // Update the viewport drag/move button + // Update the viewport drag state updateViewDrag: function(drag) { if (!UI.rfb) return; - var vmb = $D('noVNC_view_drag_button'); + var viewDragButton = $D('noVNC_view_drag_button'); - // Check if viewport drag is possible + // Check if viewport drag is possible. It is only possible + // if the remote display is clipping the client display. if (UI.rfb_state === 'normal' && UI.rfb.get_display().get_viewport() && UI.rfb.get_display().clippingDisplay()) { - // Show and enable the drag button - vmb.style.display = "inline"; - vmb.disabled = false; + viewDragButton.style.display = "inline"; + viewDragButton.disabled = false; } else { - // The VNC content is the same size as - // or smaller than the display - + // The size of the remote display is the same or smaller + // than the client display. Make sure viewport drag isn't + // active when it can't be used. if (UI.rfb.get_viewportDrag) { - // Turn off viewport drag when it's - // active since it can't be used here - vmb.className = "noVNC_status_button"; + viewDragButton.className = "noVNC_status_button"; UI.rfb.set_viewportDrag(false); } - // Disable or hide the drag button + // The button is disabled instead of hidden on touch devices if (UI.rfb_state === 'normal' && UI.isTouchDevice) { - vmb.style.display = "inline"; - vmb.disabled = true; + viewDragButton.style.display = "inline"; + viewDragButton.disabled = true; } else { - vmb.style.display = "none"; + viewDragButton.style.display = "none"; } return; } @@ -1023,10 +1021,10 @@ var UI; if (typeof(drag) !== "undefined" && typeof(drag) !== "object") { if (drag) { - vmb.className = "noVNC_status_button_selected"; + viewDragButton.className = "noVNC_status_button_selected"; UI.rfb.set_viewportDrag(true); } else { - vmb.className = "noVNC_status_button"; + viewDragButton.className = "noVNC_status_button"; UI.rfb.set_viewportDrag(false); } } @@ -1035,12 +1033,12 @@ var UI; toggleViewDrag: function() { if (!UI.rfb) return; - var vmb = $D('noVNC_view_drag_button'); + var viewDragButton = $D('noVNC_view_drag_button'); if (UI.rfb.get_viewportDrag()) { - vmb.className = "noVNC_status_button"; + viewDragButton.className = "noVNC_status_button"; UI.rfb.set_viewportDrag(false); } else { - vmb.className = "noVNC_status_button_selected"; + viewDragButton.className = "noVNC_status_button_selected"; UI.rfb.set_viewportDrag(true); } }, From ab81ddf5d48e83bde15c272eea9f993300ea7c21 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 23:26:13 +0200 Subject: [PATCH 12/65] Move the connect and disconnect functions --- include/ui.js | 171 +++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 86 deletions(-) diff --git a/include/ui.js b/include/ui.js index 872b9e97..60fb49f5 100644 --- a/include/ui.js +++ b/include/ui.js @@ -569,7 +569,91 @@ var UI; } }, - // Toggle fullscreen mode + // Show the connection settings panel/menu + toggleConnectPanel: function() { + // Close the description panel + $D('noVNC_description').style.display = "none"; + // Close connection settings if open + if (UI.settingsOpen === true) { + UI.settingsApply(); + UI.closeSettingsMenu(); + $D('connectButton').className = "noVNC_status_button"; + } + // Close clipboard panel if open + if (UI.clipboardOpen === true) { + UI.toggleClipboardPanel(); + } + // Close XVP panel if open + if (UI.xvpOpen === true) { + UI.toggleXvpPanel(); + } + + // Toggle Connection Panel + if (UI.connSettingsOpen === true) { + $D('noVNC_controls').style.display = "none"; + $D('connectButton').className = "noVNC_status_button"; + UI.connSettingsOpen = false; + UI.saveSetting('host'); + UI.saveSetting('port'); + UI.saveSetting('token'); + //UI.saveSetting('password'); + } else { + $D('noVNC_controls').style.display = "block"; + $D('connectButton').className = "noVNC_status_button_selected"; + UI.connSettingsOpen = true; + $D('noVNC_host').focus(); + } + }, + + connect: function() { + UI.closeSettingsMenu(); + UI.toggleConnectPanel(); + + var host = $D('noVNC_host').value; + var port = $D('noVNC_port').value; + var password = $D('noVNC_password').value; + var token = $D('noVNC_token').value; + var path = $D('noVNC_path').value; + + //if token is in path then ignore the new token variable + if (token) { + path = WebUtil.injectParamIfMissing(path, "token", token); + } + + if ((!host) || (!port)) { + throw new Error("Must set host and port"); + } + + if (!UI.initRFB()) return; + + UI.rfb.set_encrypt(UI.getSetting('encrypt')); + UI.rfb.set_true_color(UI.getSetting('true_color')); + UI.rfb.set_local_cursor(UI.getSetting('cursor')); + UI.rfb.set_shared(UI.getSetting('shared')); + UI.rfb.set_view_only(UI.getSetting('view_only')); + UI.rfb.set_repeaterID(UI.getSetting('repeaterID')); + + UI.rfb.connect(host, port, password, path); + + //Close dialog. + setTimeout(UI.setBarPosition, 100); + $D('noVNC_logo').style.display = "none"; + $D('noVNC_screen').style.display = "inline"; + }, + + disconnect: function() { + UI.closeSettingsMenu(); + UI.rfb.disconnect(); + + // Restore the callback used for initial resize + UI.rfb.set_onFBUComplete(UI.initialResize); + + $D('noVNC_logo').style.display = "block"; + $D('noVNC_screen').style.display = "none"; + + // Don't display the connection settings until we're actually disconnected + }, + toggleFullscreen: function() { if (document.fullscreenElement || // alternative standard method document.mozFullScreenElement || // currently working methods @@ -610,42 +694,6 @@ var UI; } }, - // Show the connection settings panel/menu - toggleConnectPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close connection settings if open - if (UI.settingsOpen === true) { - UI.settingsApply(); - UI.closeSettingsMenu(); - $D('connectButton').className = "noVNC_status_button"; - } - // Close clipboard panel if open - if (UI.clipboardOpen === true) { - UI.toggleClipboardPanel(); - } - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - - // Toggle Connection Panel - if (UI.connSettingsOpen === true) { - $D('noVNC_controls').style.display = "none"; - $D('connectButton').className = "noVNC_status_button"; - UI.connSettingsOpen = false; - UI.saveSetting('host'); - UI.saveSetting('port'); - UI.saveSetting('token'); - //UI.saveSetting('password'); - } else { - $D('noVNC_controls').style.display = "block"; - $D('connectButton').className = "noVNC_status_button_selected"; - UI.connSettingsOpen = true; - $D('noVNC_host').focus(); - } - }, - // Save/apply settings when 'Apply' button is pressed settingsApply: function() { //Util.Debug(">> settingsApply"); @@ -748,55 +796,6 @@ var UI; Util.Debug("<< UI.clipReceive"); }, - connect: function() { - UI.closeSettingsMenu(); - UI.toggleConnectPanel(); - - var host = $D('noVNC_host').value; - var port = $D('noVNC_port').value; - var password = $D('noVNC_password').value; - var token = $D('noVNC_token').value; - var path = $D('noVNC_path').value; - - //if token is in path then ignore the new token variable - if (token) { - path = WebUtil.injectParamIfMissing(path, "token", token); - } - - if ((!host) || (!port)) { - throw new Error("Must set host and port"); - } - - if (!UI.initRFB()) return; - - UI.rfb.set_encrypt(UI.getSetting('encrypt')); - UI.rfb.set_true_color(UI.getSetting('true_color')); - UI.rfb.set_local_cursor(UI.getSetting('cursor')); - UI.rfb.set_shared(UI.getSetting('shared')); - UI.rfb.set_view_only(UI.getSetting('view_only')); - UI.rfb.set_repeaterID(UI.getSetting('repeaterID')); - - UI.rfb.connect(host, port, password, path); - - //Close dialog. - setTimeout(UI.setBarPosition, 100); - $D('noVNC_logo').style.display = "none"; - $D('noVNC_screen').style.display = "inline"; - }, - - disconnect: function() { - UI.closeSettingsMenu(); - UI.rfb.disconnect(); - - // Restore the callback used for initial resize - UI.rfb.set_onFBUComplete(UI.initialResize); - - $D('noVNC_logo').style.display = "block"; - $D('noVNC_screen').style.display = "none"; - - // Don't display the connection settings until we're actually disconnected - }, - displayBlur: function() { if (!UI.rfb) return; From 9e45354efcc4a7519f213fc9f68165c77d07f431 Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 23:29:15 +0200 Subject: [PATCH 13/65] Renamed and moved updateXvpButton --- include/ui.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/ui.js b/include/ui.js index 60fb49f5..23157728 100644 --- a/include/ui.js +++ b/include/ui.js @@ -186,7 +186,7 @@ var UI; try { UI.rfb = new RFB({'target': $D('noVNC_canvas'), 'onUpdateState': UI.updateState, - 'onXvpInit': UI.updateXvpVisualState, + 'onXvpInit': UI.updateXvpButton, 'onClipboard': UI.clipReceive, 'onFBUComplete': UI.initialResize, 'onFBResize': UI.updateViewDrag, @@ -319,7 +319,7 @@ var UI; $D('showKeyboard').style.display = "none"; $D('noVNC_extra_keys').style.display = "none"; $D('sendCtrlAltDelButton').style.display = "none"; - UI.updateXvpVisualState(0); + UI.updateXvpButton(0); } // State change disables viewport dragging. @@ -540,6 +540,19 @@ var UI; } }, + // Disable/enable XVP button + updateXvpButton: function(ver) { + if (ver >= 1) { + $D('xvpButton').style.display = 'inline'; + } else { + $D('xvpButton').style.display = 'none'; + // Close XVP panel if open + if (UI.xvpOpen === true) { + UI.toggleXvpPanel(); + } + } + }, + // Show the clipboard panel toggleClipboardPanel: function() { // Close the description panel @@ -772,19 +785,6 @@ var UI; } }, - // Disable/enable XVP button - updateXvpVisualState: function(ver) { - if (ver >= 1) { - $D('xvpButton').style.display = 'inline'; - } else { - $D('xvpButton').style.display = 'none'; - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - } - }, - // Display the desktop name in the document title updateDocumentTitle: function(rfb, name) { document.title = name + " - noVNC"; From fdf21468d3a69fd0a2189317a03a11db135b40ed Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 23:41:58 +0200 Subject: [PATCH 14/65] Renamed and moved keyboard and mouse functions --- include/ui.js | 88 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/include/ui.js b/include/ui.js index 23157728..db0b3c17 100644 --- a/include/ui.js +++ b/include/ui.js @@ -208,7 +208,7 @@ var UI; $D("showKeyboard").onclick = UI.showKeyboard; $D("keyboardinput").oninput = UI.keyInput; - $D("keyboardinput").onblur = UI.keyInputBlur; + $D("keyboardinput").onblur = UI.hideKeyboard; $D("keyboardinput").onsubmit = function () { return false; }; $D("toggleExtraKeysButton").onclick = UI.toggleExtraKeys; @@ -749,10 +749,6 @@ var UI; return false; }, - sendCtrlAltDel: function() { - UI.rfb.sendCtrlAltDel(); - }, - xvpShutdown: function() { UI.rfb.xvpShutdown(); }, @@ -765,26 +761,6 @@ var UI; UI.rfb.xvpReset(); }, - setMouseButton: function(num) { - if (typeof num === 'undefined') { - // Disable mouse buttons - num = -1; - } - if (UI.rfb) { - UI.rfb.get_mouse().set_touchButton(num); - } - - var blist = [0, 1,2,4]; - for (var b = 0; b < blist.length; b++) { - var button = $D('noVNC_mouse_button' + blist[b]); - if (blist[b] === num) { - button.style.display = ""; - } else { - button.style.display = "none"; - } - } - }, - // Display the desktop name in the document title updateDocumentTitle: function(rfb, name) { document.title = name + " - noVNC"; @@ -1042,6 +1018,26 @@ var UI; } }, + setMouseButton: function(num) { + if (typeof num === 'undefined') { + // Disable mouse buttons + num = -1; + } + if (UI.rfb) { + UI.rfb.get_mouse().set_touchButton(num); + } + + var blist = [0, 1,2,4]; + for (var b = 0; b < blist.length; b++) { + var button = $D('noVNC_mouse_button' + blist[b]); + if (blist[b] === num) { + button.style.display = ""; + } else { + button.style.display = "none"; + } + } + }, + // On touch devices, show the OS keyboard showKeyboard: function() { var kbi = $D('keyboardinput'); @@ -1060,6 +1056,16 @@ var UI; } }, + hideKeyboard: function() { + $D('showKeyboard').className = "noVNC_status_button"; + //Weird bug in iOS if you change keyboardVisible + //here it does not actually occur so next time + //you click keyboard icon it doesnt work. + UI.hideKeyboardTimeout = setTimeout(function() { + UI.keyboardVisible = false; + },100); + }, + keepKeyboard: function() { clearTimeout(UI.hideKeyboardTimeout); if(UI.keyboardVisible === true) { @@ -1148,14 +1154,6 @@ var UI; } }, - keyInputBlur: function() { - $D('showKeyboard').className = "noVNC_status_button"; - //Weird bug in iOS if you change keyboardVisible - //here it does not actually occur so next time - //you click keyboard icon it doesnt work. - UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100); - }, - toggleExtraKeys: function() { UI.keepKeyboard(); if(UI.extraKeysVisible === false) { @@ -1175,6 +1173,16 @@ var UI; } }, + sendEsc: function() { + UI.keepKeyboard(); + UI.rfb.sendKey(XK_Escape); + }, + + sendTab: function() { + UI.keepKeyboard(); + UI.rfb.sendKey(XK_Tab); + }, + toggleCtrl: function() { UI.keepKeyboard(); if(UI.ctrlOn === false) { @@ -1201,18 +1209,8 @@ var UI; } }, - sendTab: function() { - UI.keepKeyboard(); - UI.rfb.sendKey(XK_Tab); - }, - - sendEsc: function() { - UI.keepKeyboard(); - UI.rfb.sendKey(XK_Escape); - }, - - setKeyboard: function() { - UI.keyboardVisible = false; + sendCtrlAltDel: function() { + UI.rfb.sendCtrlAltDel(); }, //Helper to add options to dropdown. From afcf031a682e32c37a1bad24b1bd61bf02c3525e Mon Sep 17 00:00:00 2001 From: samhed Date: Tue, 26 Apr 2016 23:59:44 +0200 Subject: [PATCH 15/65] Send the xvp keys from anonymous functions --- include/ui.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/include/ui.js b/include/ui.js index db0b3c17..0e35f87f 100644 --- a/include/ui.js +++ b/include/ui.js @@ -218,9 +218,9 @@ var UI; $D("sendEscButton").onclick = UI.sendEsc; $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel; - $D("xvpShutdownButton").onclick = UI.xvpShutdown; - $D("xvpRebootButton").onclick = UI.xvpReboot; - $D("xvpResetButton").onclick = UI.xvpReset; + $D("xvpShutdownButton").onclick = function() { UI.rfb.xvpShutdown(); }, + $D("xvpRebootButton").onclick = function() { UI.rfb.xvpReboot(); }, + $D("xvpResetButton").onclick = function() { UI.rfb.xvpReset(); }, $D("noVNC_status").onclick = UI.popupStatus; $D("noVNC_popup_status").onclick = UI.closePopup; $D("xvpButton").onclick = UI.toggleXvpPanel; @@ -749,18 +749,6 @@ var UI; return false; }, - xvpShutdown: function() { - UI.rfb.xvpShutdown(); - }, - - xvpReboot: function() { - UI.rfb.xvpReboot(); - }, - - xvpReset: function() { - UI.rfb.xvpReset(); - }, - // Display the desktop name in the document title updateDocumentTitle: function(rfb, name) { document.title = name + " - noVNC"; From 95dd60011c4097a0b7408a429fe68518576d24d2 Mon Sep 17 00:00:00 2001 From: samhed Date: Wed, 27 Apr 2016 00:29:25 +0200 Subject: [PATCH 16/65] Group together related functions and add dividers Dividers between the different parts of the UI has been added in order to easier get an overview. --- include/ui.js | 264 +++++++++++++++++++++++++++++++------------------- 1 file changed, 166 insertions(+), 98 deletions(-) diff --git a/include/ui.js b/include/ui.js index 0e35f87f..e04c0f50 100644 --- a/include/ui.js +++ b/include/ui.js @@ -245,6 +245,12 @@ var UI; $D("noVNC_resize").onchange = UI.enableDisableViewClip; }, +/* ------^------- + * /INIT + * ============== + * VISUAL + * ------v------*/ + updateState: function(rfb, state, oldstate, msg) { UI.rfb_state = state; var klass; @@ -373,6 +379,12 @@ var UI; $D('noVNC_popup_status').style.display = "none"; }, +/* ------^------- + * /VISUAL + * ============== + * SETTINGS + * ------v------*/ + // Initial page load read/initialization of settings initSetting: function(name, defVal) { // Check Query string followed by cookie @@ -452,6 +464,37 @@ var UI; return val; }, + // Save/apply settings when 'Apply' button is pressed + settingsApply: function() { + //Util.Debug(">> settingsApply"); + UI.saveSetting('encrypt'); + UI.saveSetting('true_color'); + if (Util.browserSupportsCursorURIs()) { + UI.saveSetting('cursor'); + } + + UI.saveSetting('resize'); + + if (UI.getSetting('resize') === 'downscale' || UI.getSetting('resize') === 'scale') { + UI.forceSetting('clip', false); + } + + UI.saveSetting('clip'); + UI.saveSetting('shared'); + UI.saveSetting('view_only'); + UI.saveSetting('path'); + UI.saveSetting('repeaterID'); + UI.saveSetting('stylesheet'); + UI.saveSetting('logging'); + + // Settings with immediate (non-connected related) effect + WebUtil.selectStylesheet(UI.getSetting('stylesheet')); + WebUtil.init_logging(UI.getSetting('logging')); + UI.setViewClip(); + UI.updateViewDrag(); + //Util.Debug("<< settingsApply"); + }, + // Open menu openSettingsMenu: function() { // Close the description panel @@ -511,6 +554,12 @@ var UI; } }, +/* ------^------- + * /SETTINGS + * ============== + * XVP + * ------v------*/ + // Show the XVP panel toggleXvpPanel: function() { // Close the description panel @@ -553,6 +602,12 @@ var UI; } }, +/* ------^------- + * /XVP + * ============== + * CLIPBOARD + * ------v------*/ + // Show the clipboard panel toggleClipboardPanel: function() { // Close the description panel @@ -582,6 +637,30 @@ var UI; } }, + clipReceive: function(rfb, text) { + Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); + $D('noVNC_clipboard_text').value = text; + Util.Debug("<< UI.clipReceive"); + }, + + clipClear: function() { + $D('noVNC_clipboard_text').value = ""; + UI.rfb.clipboardPasteFrom(""); + }, + + clipSend: function() { + var text = $D('noVNC_clipboard_text').value; + Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); + UI.rfb.clipboardPasteFrom(text); + Util.Debug("<< UI.clipSend"); + }, + +/* ------^------- + * /CLIPBOARD + * ============== + * CONNECTION + * ------v------*/ + // Show the connection settings panel/menu toggleConnectPanel: function() { // Close the description panel @@ -667,6 +746,22 @@ var UI; // Don't display the connection settings until we're actually disconnected }, + setPassword: function() { + UI.rfb.sendPassword($D('noVNC_password').value); + //Reset connect button. + $D('noVNC_connect_button').value = "Connect"; + $D('noVNC_connect_button').onclick = UI.connect; + //Hide connection panel. + UI.toggleConnectPanel(); + return false; + }, + +/* ------^------- + * /CONNECTION + * ============== + * FULLSCREEN + * ------v------*/ + toggleFullscreen: function() { if (document.fullscreenElement || // alternative standard method document.mozFullScreenElement || // currently working methods @@ -707,85 +802,11 @@ var UI; } }, - // Save/apply settings when 'Apply' button is pressed - settingsApply: function() { - //Util.Debug(">> settingsApply"); - UI.saveSetting('encrypt'); - UI.saveSetting('true_color'); - if (Util.browserSupportsCursorURIs()) { - UI.saveSetting('cursor'); - } - - UI.saveSetting('resize'); - - if (UI.getSetting('resize') === 'downscale' || UI.getSetting('resize') === 'scale') { - UI.forceSetting('clip', false); - } - - UI.saveSetting('clip'); - UI.saveSetting('shared'); - UI.saveSetting('view_only'); - UI.saveSetting('path'); - UI.saveSetting('repeaterID'); - UI.saveSetting('stylesheet'); - UI.saveSetting('logging'); - - // Settings with immediate (non-connected related) effect - WebUtil.selectStylesheet(UI.getSetting('stylesheet')); - WebUtil.init_logging(UI.getSetting('logging')); - UI.setViewClip(); - UI.updateViewDrag(); - //Util.Debug("<< settingsApply"); - }, - - - setPassword: function() { - UI.rfb.sendPassword($D('noVNC_password').value); - //Reset connect button. - $D('noVNC_connect_button').value = "Connect"; - $D('noVNC_connect_button').onclick = UI.connect; - //Hide connection panel. - UI.toggleConnectPanel(); - return false; - }, - - // Display the desktop name in the document title - updateDocumentTitle: function(rfb, name) { - document.title = name + " - noVNC"; - }, - - clipReceive: function(rfb, text) { - Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); - $D('noVNC_clipboard_text').value = text; - Util.Debug("<< UI.clipReceive"); - }, - - displayBlur: function() { - if (!UI.rfb) return; - - UI.rfb.get_keyboard().set_focused(false); - UI.rfb.get_mouse().set_focused(false); - }, - - displayFocus: function() { - if (!UI.rfb) return; - - UI.rfb.get_keyboard().set_focused(true); - UI.rfb.get_mouse().set_focused(true); - }, - - clipClear: function() { - $D('noVNC_clipboard_text').value = ""; - UI.rfb.clipboardPasteFrom(""); - }, - - clipSend: function() { - var text = $D('noVNC_clipboard_text').value; - Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); - UI.rfb.clipboardPasteFrom(text); - Util.Debug("<< UI.clipSend"); - }, - +/* ------^------- + * /FULLSCREEN + * ============== + * RESIZE + * ------v------*/ // Apply remote resizing or local scaling applyResizeMode: function() { @@ -861,6 +882,12 @@ var UI; UI.rfb.set_onFBUComplete(function() { }); }, +/* ------^------- + * /RESIZE + * ============== + * CLIPPING + * ------v------*/ + // Set and configure viewport clipping setViewClip: function(clip) { var display; @@ -947,6 +974,12 @@ var UI; } }, +/* ------^------- + * /CLIPPING + * ============== + * VIEWDRAG + * ------v------*/ + // Update the viewport drag state updateViewDrag: function(drag) { if (!UI.rfb) return; @@ -1006,25 +1039,11 @@ var UI; } }, - setMouseButton: function(num) { - if (typeof num === 'undefined') { - // Disable mouse buttons - num = -1; - } - if (UI.rfb) { - UI.rfb.get_mouse().set_touchButton(num); - } - - var blist = [0, 1,2,4]; - for (var b = 0; b < blist.length; b++) { - var button = $D('noVNC_mouse_button' + blist[b]); - if (blist[b] === num) { - button.style.display = ""; - } else { - button.style.display = "none"; - } - } - }, +/* ------^------- + * /VIEWDRAG + * ============== + * KEYBOARD + * ------v------*/ // On touch devices, show the OS keyboard showKeyboard: function() { @@ -1201,6 +1220,51 @@ var UI; UI.rfb.sendCtrlAltDel(); }, +/* ------^------- + * /KEYBOARD + * ============== + * MISC + * ------v------*/ + + setMouseButton: function(num) { + if (typeof num === 'undefined') { + // Disable mouse buttons + num = -1; + } + if (UI.rfb) { + UI.rfb.get_mouse().set_touchButton(num); + } + + var blist = [0, 1,2,4]; + for (var b = 0; b < blist.length; b++) { + var button = $D('noVNC_mouse_button' + blist[b]); + if (blist[b] === num) { + button.style.display = ""; + } else { + button.style.display = "none"; + } + } + }, + + displayBlur: function() { + if (!UI.rfb) return; + + UI.rfb.get_keyboard().set_focused(false); + UI.rfb.get_mouse().set_focused(false); + }, + + displayFocus: function() { + if (!UI.rfb) return; + + UI.rfb.get_keyboard().set_focused(true); + UI.rfb.get_mouse().set_focused(true); + }, + + // Display the desktop name in the document title + updateDocumentTitle: function(rfb, name) { + document.title = name + " - noVNC"; + }, + //Helper to add options to dropdown. addOption: function(selectbox, text, value) { var optn = document.createElement("OPTION"); @@ -1217,5 +1281,9 @@ var UI; $D('noVNC-control-bar').style.width = vncwidth + 'px'; } +/* ------^------- + * /MISC + * ============== + */ }; })(); From 4d26f58e0d711144ec6bcdabf26811db1c457238 Mon Sep 17 00:00:00 2001 From: samhed Date: Wed, 27 Apr 2016 00:31:50 +0200 Subject: [PATCH 17/65] Change name of clipboard functions There were a high risk of confusion between clipboard functions and clipping functions. --- include/ui.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/ui.js b/include/ui.js index e04c0f50..7a8600a9 100644 --- a/include/ui.js +++ b/include/ui.js @@ -187,7 +187,7 @@ var UI; UI.rfb = new RFB({'target': $D('noVNC_canvas'), 'onUpdateState': UI.updateState, 'onXvpInit': UI.updateXvpButton, - 'onClipboard': UI.clipReceive, + 'onClipboard': UI.clipboardReceive, 'onFBUComplete': UI.initialResize, 'onFBResize': UI.updateViewDrag, 'onDesktopName': UI.updateDocumentTitle}); @@ -233,8 +233,8 @@ var UI; $D("noVNC_clipboard_text").onfocus = UI.displayBlur; $D("noVNC_clipboard_text").onblur = UI.displayFocus; - $D("noVNC_clipboard_text").onchange = UI.clipSend; - $D("noVNC_clipboard_clear_button").onclick = UI.clipClear; + $D("noVNC_clipboard_text").onchange = UI.clipboardSend; + $D("noVNC_clipboard_clear_button").onclick = UI.clipboardClear; $D("noVNC_settings_menu").onmouseover = UI.displayBlur; $D("noVNC_settings_menu").onmouseover = UI.displayFocus; @@ -637,22 +637,22 @@ var UI; } }, - clipReceive: function(rfb, text) { - Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); + clipboardReceive: function(rfb, text) { + Util.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "..."); $D('noVNC_clipboard_text').value = text; - Util.Debug("<< UI.clipReceive"); + Util.Debug("<< UI.clipboardReceive"); }, - clipClear: function() { + clipboardClear: function() { $D('noVNC_clipboard_text').value = ""; UI.rfb.clipboardPasteFrom(""); }, - clipSend: function() { + clipboardSend: function() { var text = $D('noVNC_clipboard_text').value; - Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); + Util.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "..."); UI.rfb.clipboardPasteFrom(text); - Util.Debug("<< UI.clipSend"); + Util.Debug("<< UI.clipboardSend"); }, /* ------^------- From a20a8987650a7a3080706fe1c3678cf4f2e855ad Mon Sep 17 00:00:00 2001 From: samhed Date: Wed, 27 Apr 2016 00:41:16 +0200 Subject: [PATCH 18/65] Timeouts should always use anonymous functions While you CAN pass functions in strings, it is not the correct way of doing it. The browsers are just being nice. --- include/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ui.js b/include/ui.js index 7a8600a9..3146ae6c 100644 --- a/include/ui.js +++ b/include/ui.js @@ -728,7 +728,7 @@ var UI; UI.rfb.connect(host, port, password, path); //Close dialog. - setTimeout(UI.setBarPosition, 100); + setTimeout(function () { UI.setBarPosition; } ); $D('noVNC_logo').style.display = "none"; $D('noVNC_screen').style.display = "inline"; }, From 682fd02be65107ed9267969ff21e3661bddda5ba Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Sat, 30 Apr 2016 04:35:19 +0200 Subject: [PATCH 19/65] Change the names of settings-elements This change was made in order to make it easier to distinguish settings-elements from other elements. One example of the problem that was solved is the two elements "noVNC_clip" and "noVNC_clipboard" where the first is the setting for clipping mode. That element was now renamed to "noVNC_setting_clip". --- include/base.css | 14 +++++----- include/ui.js | 66 ++++++++++++++++++++++++------------------------ vnc.html | 34 ++++++++++++------------- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/include/base.css b/include/base.css index 59e90c5b..56e03c3a 100644 --- a/include/base.css +++ b/include/base.css @@ -1,7 +1,7 @@ /* * noVNC base CSS * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB + * Copyright (C) 2016 Samuel Mannehed for Cendio AB * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). */ @@ -30,18 +30,18 @@ html { padding-bottom:8px; } -#noVNC_host { +#noVNC_setting_host { width:150px; } -#noVNC_port { +#noVNC_setting_port { width: 80px; } -#noVNC_password { +#noVNC_setting_password { width: 150px; } -#noVNC_encrypt { +#noVNC_setting_encrypt { } -#noVNC_path { +#noVNC_setting_path { width: 100px; } #noVNC_connect_button { @@ -109,7 +109,7 @@ html { padding: 0px; } -#noVNC_apply { +#noVNC_settings_apply { float:right; } diff --git a/include/ui.js b/include/ui.js index 3146ae6c..53c6e560 100644 --- a/include/ui.js +++ b/include/ui.js @@ -60,13 +60,13 @@ var UI; var sheets = WebUtil.getStylesheets(); var i; for (i = 0; i < sheets.length; i += 1) { - UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title); + UI.addOption($D('noVNC_setting_stylesheet'),sheets[i].title, sheets[i].title); } // Logging selection dropdown var llevels = ['error', 'warn', 'info', 'debug']; for (i = 0; i < llevels.length; i += 1) { - UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]); + UI.addOption($D('noVNC_setting_logging'),llevels[i], llevels[i]); } // Settings with immediate effects @@ -114,7 +114,7 @@ var UI; UI.updateVisualState(); - $D('noVNC_host').focus(); + $D('noVNC_setting_host').focus(); // Show mouse selector buttons on touch screen devices if (UI.isTouchDevice) { @@ -238,11 +238,11 @@ var UI; $D("noVNC_settings_menu").onmouseover = UI.displayBlur; $D("noVNC_settings_menu").onmouseover = UI.displayFocus; - $D("noVNC_apply").onclick = UI.settingsApply; + $D("noVNC_settings_apply").onclick = UI.settingsApply; $D("noVNC_connect_button").onclick = UI.connect; - $D("noVNC_resize").onchange = UI.enableDisableViewClip; + $D("noVNC_setting_resize").onchange = UI.enableDisableViewClip; }, /* ------^------- @@ -274,7 +274,7 @@ var UI; $D('noVNC_connect_button').value = "Send Password"; $D('noVNC_connect_button').onclick = UI.setPassword; - $D('noVNC_password').focus(); + $D('noVNC_setting_password').focus(); klass = "noVNC_status_warn"; break; @@ -296,21 +296,21 @@ var UI; var connected = UI.rfb && UI.rfb_state === 'normal'; //Util.Debug(">> updateVisualState"); - $D('noVNC_encrypt').disabled = connected; - $D('noVNC_true_color').disabled = connected; + $D('noVNC_setting_encrypt').disabled = connected; + $D('noVNC_setting_true_color').disabled = connected; if (Util.browserSupportsCursorURIs()) { - $D('noVNC_cursor').disabled = connected; + $D('noVNC_setting_cursor').disabled = connected; } else { UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; + $D('noVNC_setting_cursor').disabled = true; } UI.enableDisableViewClip(); - $D('noVNC_resize').disabled = connected; - $D('noVNC_shared').disabled = connected; - $D('noVNC_view_only').disabled = connected; - $D('noVNC_path').disabled = connected; - $D('noVNC_repeaterID').disabled = connected; + $D('noVNC_setting_resize').disabled = connected; + $D('noVNC_setting_shared').disabled = connected; + $D('noVNC_setting_view_only').disabled = connected; + $D('noVNC_setting_path').disabled = connected; + $D('noVNC_setting_repeaterID').disabled = connected; if (connected) { UI.setViewClip(); @@ -408,7 +408,7 @@ var UI; // Update the settings control value = UI.getSetting(name); - var ctrl = $D('noVNC_' + name); + var ctrl = $D('noVNC_setting_' + name); if (ctrl.type === 'checkbox') { ctrl.checked = value; @@ -431,7 +431,7 @@ var UI; // Save control setting to cookie saveSetting: function(name) { - var val, ctrl = $D('noVNC_' + name); + var val, ctrl = $D('noVNC_setting_' + name); if (ctrl.type === 'checkbox') { val = ctrl.checked; } else if (typeof ctrl.options !== 'undefined') { @@ -452,7 +452,7 @@ var UI; // Read form control compatible setting from cookie getSetting: function(name) { - var ctrl = $D('noVNC_' + name); + var ctrl = $D('noVNC_setting_' + name); var val = WebUtil.readSetting(name); if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { @@ -539,7 +539,7 @@ var UI; UI.updateSetting('cursor'); } else { UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; + $D('noVNC_setting_cursor').disabled = true; } UI.updateSetting('clip'); UI.updateSetting('resize'); @@ -693,7 +693,7 @@ var UI; $D('noVNC_controls').style.display = "block"; $D('connectButton').className = "noVNC_status_button_selected"; UI.connSettingsOpen = true; - $D('noVNC_host').focus(); + $D('noVNC_setting_host').focus(); } }, @@ -701,11 +701,11 @@ var UI; UI.closeSettingsMenu(); UI.toggleConnectPanel(); - var host = $D('noVNC_host').value; - var port = $D('noVNC_port').value; - var password = $D('noVNC_password').value; - var token = $D('noVNC_token').value; - var path = $D('noVNC_path').value; + var host = $D('noVNC_setting_host').value; + var port = $D('noVNC_setting_port').value; + var password = $D('noVNC_setting_password').value; + var token = $D('noVNC_setting_token').value; + var path = $D('noVNC_setting_path').value; //if token is in path then ignore the new token variable if (token) { @@ -747,7 +747,7 @@ var UI; }, setPassword: function() { - UI.rfb.sendPassword($D('noVNC_password').value); + UI.rfb.sendPassword($D('noVNC_setting_password').value); //Reset connect button. $D('noVNC_connect_button').value = "Connect"; $D('noVNC_connect_button').onclick = UI.connect; @@ -942,18 +942,18 @@ var UI; // Handle special cases where clipping is forced on/off or locked enableDisableViewClip: function() { - var resizeElem = $D('noVNC_resize'); + var resizeSetting = $D('noVNC_setting_resize'); var connected = UI.rfb && UI.rfb_state === 'normal'; if (UI.isSafari) { // Safari auto-hides the scrollbars which makes them // impossible to use in most cases UI.setViewClip(true); - $D('noVNC_clip').disabled = true; - } else if (resizeElem.value === 'downscale' || resizeElem.value === 'scale') { + $D('noVNC_setting_clip').disabled = true; + } else if (resizeSetting.value === 'downscale' || resizeSetting.value === 'scale') { // Disable clipping if we are scaling UI.setViewClip(false); - $D('noVNC_clip').disabled = true; + $D('noVNC_setting_clip').disabled = true; } else if (document.msFullscreenElement) { // The browser is IE and we are in fullscreen mode. // - We need to force clipping while in fullscreen since @@ -961,13 +961,13 @@ var UI; UI.popupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen"); UI.rememberedClipSetting = UI.getSetting('clip'); UI.setViewClip(true); - $D('noVNC_clip').disabled = true; + $D('noVNC_setting_clip').disabled = true; } else if (document.body.msRequestFullscreen && UI.rememberedClip !== null) { // Restore view clip to what it was before fullscreen on IE UI.setViewClip(UI.rememberedClipSetting); - $D('noVNC_clip').disabled = connected || UI.isTouchDevice; + $D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice; } else { - $D('noVNC_clip').disabled = connected || UI.isTouchDevice; + $D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice; if (UI.isTouchDevice) { UI.setViewClip(true); } diff --git a/vnc.html b/vnc.html index cdf45dc9..9d583738 100644 --- a/vnc.html +++ b/vnc.html @@ -5,7 +5,7 @@

  • -
  • +
  • @@ -196,10 +196,10 @@
      -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    From 3f2c25a60fc08514b6f5c9ccdfb5dab14fc59b80 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Thu, 26 May 2016 23:15:39 +0200 Subject: [PATCH 20/65] Use a consistent naming convention for elements * Element names we use "_" as word-delimiter, not "-" * Element names use less camel-case * Element names end with the type * Element names always start with noVNC_ --- include/base.css | 40 ++++++------- include/black.css | 2 +- include/blue.css | 2 +- include/ui.js | 142 +++++++++++++++++++++++----------------------- vnc.html | 44 +++++++------- 5 files changed, 115 insertions(+), 115 deletions(-) diff --git a/include/base.css b/include/base.css index 56e03c3a..8d88c0f5 100644 --- a/include/base.css +++ b/include/base.css @@ -56,10 +56,10 @@ html { #noVNC_view_drag_button { display: none; } -#sendCtrlAltDelButton { +#noVNC_sendCtrlAltDel_button { display: none; } -#fullscreenButton { +#noVNC_fullscreen_button { display: none; } #noVNC_xvp_buttons { @@ -77,13 +77,13 @@ html { position: relative; } -.noVNC-buttons-left { +.noVNC_buttons_left { float: left; z-index: 1; position: relative; } -.noVNC-buttons-right { +.noVNC_buttons_right { float:right; right: 0px; z-index: 2; @@ -233,7 +233,7 @@ html { right:85px; } -#keyboardinput { +#noVNC_keyboardinput { width:1px; height:1px; background-color:#fff; @@ -278,7 +278,7 @@ html { } /* Control bar */ -#noVNC-control-bar { +#noVNC_control_bar { position:fixed; display:block; @@ -427,11 +427,11 @@ html { font-size: 180px; } -.noVNC-buttons-left { +.noVNC_buttons_left { padding-left: 10px; } -.noVNC-buttons-right { +.noVNC_buttons_right { padding-right: 10px; } @@ -442,11 +442,11 @@ html { margin-left: 0px; } -#toggleExtraKeysButton { display: none; } -#toggleCtrlButton { display: inline; } -#toggleAltButton { display: inline; } -#sendTabButton { display: inline; } -#sendEscButton { display: inline; } +#noVNC_toggleExtraKeys_button { display: none; } +#noVNC_toggleCtrl_button { display: inline; } +#noVNC_toggleAlt_button { display: inline; } +#noVNC_sendTab_button { display: inline; } +#noVNC_sendEsc_button { display: inline; } /* left-align the status text on lower resolutions */ @media screen and (max-width: 800px){ @@ -469,35 +469,35 @@ html { .noVNC_status_button { font-size: 10px; } - .noVNC-buttons-left { + .noVNC_buttons_left { padding-left: 0px; } - .noVNC-buttons-right { + .noVNC_buttons_right { padding-right: 0px; } /* collapse the extra keys on lower resolutions */ - #toggleExtraKeysButton { + #noVNC_toggleExtraKeys_button { display: inline; } - #toggleCtrlButton { + #noVNC_toggleCtrl_button { display: none; position: absolute; top: 30px; left: 0px; } - #toggleAltButton { + #noVNC_toggleAlt_button { display: none; position: absolute; top: 65px; left: 0px; } - #sendTabButton { + #noVNC_sendTab_button { display: none; position: absolute; top: 100px; left: 0px; } - #sendEscButton { + #noVNC_sendEsc_button { display: none; position: absolute; top: 135px; diff --git a/include/black.css b/include/black.css index 7d940c5a..5c4558dc 100644 --- a/include/black.css +++ b/include/black.css @@ -6,7 +6,7 @@ * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). */ -#keyboardinput { +#noVNC_keyboardinput { background-color:#000; } diff --git a/include/blue.css b/include/blue.css index b2a0adcc..4ab53bde 100644 --- a/include/blue.css +++ b/include/blue.css @@ -58,7 +58,7 @@ color:#fff; } -#keyboardinput { +#noVNC_keyboardinput { background-color:#04073d; } diff --git a/include/ui.js b/include/ui.js index 53c6e560..37de7b6e 100644 --- a/include/ui.js +++ b/include/ui.js @@ -148,7 +148,7 @@ var UI; document.documentElement.mozRequestFullScreen || document.documentElement.webkitRequestFullscreen || document.body.msRequestFullscreen)) { - $D('fullscreenButton').style.display = "inline"; + $D('noVNC_fullscreen_button').style.display = "inline"; Util.addEvent(window, 'fullscreenchange', UI.updateFullscreenButton); Util.addEvent(window, 'mozfullscreenchange', UI.updateFullscreenButton); Util.addEvent(window, 'webkitfullscreenchange', UI.updateFullscreenButton); @@ -205,31 +205,31 @@ var UI; $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); }; $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); }; $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); }; - $D("showKeyboard").onclick = UI.showKeyboard; + $D("noVNC_keyboard_button").onclick = UI.showKeyboard; - $D("keyboardinput").oninput = UI.keyInput; - $D("keyboardinput").onblur = UI.hideKeyboard; - $D("keyboardinput").onsubmit = function () { return false; }; + $D("noVNC_keyboardinput").oninput = UI.keyInput; + $D("noVNC_keyboardinput").onblur = UI.hideKeyboard; + $D("noVNC_keyboardinput").onsubmit = function () { return false; }; - $D("toggleExtraKeysButton").onclick = UI.toggleExtraKeys; - $D("toggleCtrlButton").onclick = UI.toggleCtrl; - $D("toggleAltButton").onclick = UI.toggleAlt; - $D("sendTabButton").onclick = UI.sendTab; - $D("sendEscButton").onclick = UI.sendEsc; + $D("noVNC_toggleExtraKeys_button").onclick = UI.toggleExtraKeys; + $D("noVNC_toggleCtrl_button").onclick = UI.toggleCtrl; + $D("noVNC_toggleAlt_button").onclick = UI.toggleAlt; + $D("noVNC_sendTab_button").onclick = UI.sendTab; + $D("noVNC_sendEsc_button").onclick = UI.sendEsc; - $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel; - $D("xvpShutdownButton").onclick = function() { UI.rfb.xvpShutdown(); }, - $D("xvpRebootButton").onclick = function() { UI.rfb.xvpReboot(); }, - $D("xvpResetButton").onclick = function() { UI.rfb.xvpReset(); }, + $D("noVNC_sendCtrlAltDel_button").onclick = UI.sendCtrlAltDel; + $D("noVNC_xvpShutdown_button").onclick = function() { UI.rfb.xvpShutdown(); }, + $D("noVNC_xvpReboot_button").onclick = function() { UI.rfb.xvpReboot(); }, + $D("noVNC_xvpReset_button").onclick = function() { UI.rfb.xvpReset(); }, $D("noVNC_status").onclick = UI.popupStatus; $D("noVNC_popup_status").onclick = UI.closePopup; - $D("xvpButton").onclick = UI.toggleXvpPanel; - $D("clipboardButton").onclick = UI.toggleClipboardPanel; - $D("fullscreenButton").onclick = UI.toggleFullscreen; - $D("settingsButton").onclick = UI.toggleSettingsPanel; - $D("connectButton").onclick = UI.toggleConnectPanel; - $D("disconnectButton").onclick = UI.disconnect; - $D("descriptionButton").onclick = UI.toggleConnectPanel; + $D("noVNC_toggleXvp_button").onclick = UI.toggleXvpPanel; + $D("noVNC_clipboard_button").onclick = UI.toggleClipboardPanel; + $D("noVNC_fullscreen_button").onclick = UI.toggleFullscreen; + $D("noVNC_settings_button").onclick = UI.toggleSettingsPanel; + $D("noVNC_connectPanel_button").onclick = UI.toggleConnectPanel; + $D("noVNC_disconnect_button").onclick = UI.disconnect; + $D("noVNC_description_button").onclick = UI.toggleConnectPanel; $D("noVNC_clipboard_text").onfocus = UI.displayBlur; $D("noVNC_clipboard_text").onblur = UI.displayFocus; @@ -284,7 +284,7 @@ var UI; } if (typeof(msg) !== 'undefined') { - $D('noVNC-control-bar').setAttribute("class", klass); + $D('noVNC_control_bar').setAttribute("class", klass); $D('noVNC_status').innerHTML = msg; } @@ -315,16 +315,16 @@ var UI; if (connected) { UI.setViewClip(); UI.setMouseButton(1); - $D('clipboardButton').style.display = "inline"; - $D('showKeyboard').style.display = "inline"; + $D('noVNC_clipboard_button').style.display = "inline"; + $D('noVNC_keyboard_button').style.display = "inline"; $D('noVNC_extra_keys').style.display = ""; - $D('sendCtrlAltDelButton').style.display = "inline"; + $D('noVNC_sendCtrlAltDel_button').style.display = "inline"; } else { UI.setMouseButton(); - $D('clipboardButton').style.display = "none"; - $D('showKeyboard').style.display = "none"; + $D('noVNC_clipboard_button').style.display = "none"; + $D('noVNC_keyboard_button').style.display = "none"; $D('noVNC_extra_keys').style.display = "none"; - $D('sendCtrlAltDelButton').style.display = "none"; + $D('noVNC_sendCtrlAltDel_button').style.display = "none"; UI.updateXvpButton(0); } @@ -336,18 +336,18 @@ var UI; case 'fatal': case 'failed': case 'disconnected': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; + $D('noVNC_connectPanel_button').style.display = ""; + $D('noVNC_disconnect_button').style.display = "none"; UI.connSettingsOpen = false; UI.toggleConnectPanel(); break; case 'loaded': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; + $D('noVNC_connectPanel_button').style.display = ""; + $D('noVNC_disconnect_button').style.display = "none"; break; default: - $D('connectButton').style.display = "none"; - $D('disconnectButton').style.display = ""; + $D('noVNC_connectPanel_button').style.display = "none"; + $D('noVNC_disconnect_button').style.display = ""; break; } @@ -512,14 +512,14 @@ var UI; UI.toggleXvpPanel(); } $D('noVNC_settings').style.display = "block"; - $D('settingsButton').className = "noVNC_status_button_selected"; + $D('noVNC_settings_button').className = "noVNC_status_button_selected"; UI.settingsOpen = true; }, // Close menu (without applying settings) closeSettingsMenu: function() { $D('noVNC_settings').style.display = "none"; - $D('settingsButton').className = "noVNC_status_button"; + $D('noVNC_settings_button').className = "noVNC_status_button"; UI.settingsOpen = false; }, @@ -580,11 +580,11 @@ var UI; // Toggle XVP panel if (UI.xvpOpen === true) { $D('noVNC_xvp').style.display = "none"; - $D('xvpButton').className = "noVNC_status_button"; + $D('noVNC_toggleXvp_button').className = "noVNC_status_button"; UI.xvpOpen = false; } else { $D('noVNC_xvp').style.display = "block"; - $D('xvpButton').className = "noVNC_status_button_selected"; + $D('noVNC_toggleXvp_button').className = "noVNC_status_button_selected"; UI.xvpOpen = true; } }, @@ -592,9 +592,9 @@ var UI; // Disable/enable XVP button updateXvpButton: function(ver) { if (ver >= 1) { - $D('xvpButton').style.display = 'inline'; + $D('noVNC_toggleXvp_button').style.display = 'inline'; } else { - $D('xvpButton').style.display = 'none'; + $D('noVNC_toggleXvp_button').style.display = 'none'; // Close XVP panel if open if (UI.xvpOpen === true) { UI.toggleXvpPanel(); @@ -628,11 +628,11 @@ var UI; // Toggle Clipboard Panel if (UI.clipboardOpen === true) { $D('noVNC_clipboard').style.display = "none"; - $D('clipboardButton').className = "noVNC_status_button"; + $D('noVNC_clipboard_button').className = "noVNC_status_button"; UI.clipboardOpen = false; } else { $D('noVNC_clipboard').style.display = "block"; - $D('clipboardButton').className = "noVNC_status_button_selected"; + $D('noVNC_clipboard_button').className = "noVNC_status_button_selected"; UI.clipboardOpen = true; } }, @@ -669,7 +669,7 @@ var UI; if (UI.settingsOpen === true) { UI.settingsApply(); UI.closeSettingsMenu(); - $D('connectButton').className = "noVNC_status_button"; + $D('noVNC_connectPanel_button').className = "noVNC_status_button"; } // Close clipboard panel if open if (UI.clipboardOpen === true) { @@ -683,7 +683,7 @@ var UI; // Toggle Connection Panel if (UI.connSettingsOpen === true) { $D('noVNC_controls').style.display = "none"; - $D('connectButton').className = "noVNC_status_button"; + $D('noVNC_connectPanel_button').className = "noVNC_status_button"; UI.connSettingsOpen = false; UI.saveSetting('host'); UI.saveSetting('port'); @@ -691,7 +691,7 @@ var UI; //UI.saveSetting('password'); } else { $D('noVNC_controls').style.display = "block"; - $D('connectButton').className = "noVNC_status_button_selected"; + $D('noVNC_connectPanel_button').className = "noVNC_status_button_selected"; UI.connSettingsOpen = true; $D('noVNC_setting_host').focus(); } @@ -796,9 +796,9 @@ var UI; document.mozFullScreenElement || // currently working methods document.webkitFullscreenElement || document.msFullscreenElement ) { - $D('fullscreenButton').className = "noVNC_status_button_selected"; + $D('noVNC_fullscreen_button').className = "noVNC_status_button_selected"; } else { - $D('fullscreenButton').className = "noVNC_status_button"; + $D('noVNC_fullscreen_button').className = "noVNC_status_button"; } }, @@ -1047,8 +1047,8 @@ var UI; // On touch devices, show the OS keyboard showKeyboard: function() { - var kbi = $D('keyboardinput'); - var skb = $D('showKeyboard'); + var kbi = $D('noVNC_keyboardinput'); + var skb = $D('noVNC_keyboard_button'); var l = kbi.value.length; if(UI.keyboardVisible === false) { kbi.focus(); @@ -1064,7 +1064,7 @@ var UI; }, hideKeyboard: function() { - $D('showKeyboard').className = "noVNC_status_button"; + $D('noVNC_keyboard_button').className = "noVNC_status_button"; //Weird bug in iOS if you change keyboardVisible //here it does not actually occur so next time //you click keyboard icon it doesnt work. @@ -1076,16 +1076,16 @@ var UI; keepKeyboard: function() { clearTimeout(UI.hideKeyboardTimeout); if(UI.keyboardVisible === true) { - $D('keyboardinput').focus(); - $D('showKeyboard').className = "noVNC_status_button_selected"; + $D('noVNC_keyboardinput').focus(); + $D('noVNC_keyboard_button').className = "noVNC_status_button_selected"; } else if(UI.keyboardVisible === false) { - $D('keyboardinput').blur(); - $D('showKeyboard').className = "noVNC_status_button"; + $D('noVNC_keyboardinput').blur(); + $D('noVNC_keyboard_button').className = "noVNC_status_button"; } }, keyboardinputReset: function() { - var kbi = $D('keyboardinput'); + var kbi = $D('noVNC_keyboardinput'); kbi.value = new Array(UI.defaultKeyboardinputLen).join("_"); UI.lastKeyboardinput = kbi.value; }, @@ -1164,18 +1164,18 @@ var UI; toggleExtraKeys: function() { UI.keepKeyboard(); if(UI.extraKeysVisible === false) { - $D('toggleCtrlButton').style.display = "inline"; - $D('toggleAltButton').style.display = "inline"; - $D('sendTabButton').style.display = "inline"; - $D('sendEscButton').style.display = "inline"; - $D('toggleExtraKeysButton').className = "noVNC_status_button_selected"; + $D('noVNC_toggleCtrl_button').style.display = "inline"; + $D('noVNC_toggleAlt_button').style.display = "inline"; + $D('noVNC_sendTab_button').style.display = "inline"; + $D('noVNC_sendEsc_button').style.display = "inline"; + $D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button_selected"; UI.extraKeysVisible = true; } else if(UI.extraKeysVisible === true) { - $D('toggleCtrlButton').style.display = ""; - $D('toggleAltButton').style.display = ""; - $D('sendTabButton').style.display = ""; - $D('sendEscButton').style.display = ""; - $D('toggleExtraKeysButton').className = "noVNC_status_button"; + $D('noVNC_toggleCtrl_button').style.display = ""; + $D('noVNC_toggleAlt_button').style.display = ""; + $D('noVNC_sendTab_button').style.display = ""; + $D('noVNC_sendEsc_button').style.display = ""; + $D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button"; UI.extraKeysVisible = false; } }, @@ -1194,11 +1194,11 @@ var UI; UI.keepKeyboard(); if(UI.ctrlOn === false) { UI.rfb.sendKey(XK_Control_L, true); - $D('toggleCtrlButton').className = "noVNC_status_button_selected"; + $D('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected"; UI.ctrlOn = true; } else if(UI.ctrlOn === true) { UI.rfb.sendKey(XK_Control_L, false); - $D('toggleCtrlButton').className = "noVNC_status_button"; + $D('noVNC_toggleCtrl_button').className = "noVNC_status_button"; UI.ctrlOn = false; } }, @@ -1207,11 +1207,11 @@ var UI; UI.keepKeyboard(); if(UI.altOn === false) { UI.rfb.sendKey(XK_Alt_L, true); - $D('toggleAltButton').className = "noVNC_status_button_selected"; + $D('noVNC_toggleAlt_button').className = "noVNC_status_button_selected"; UI.altOn = true; } else if(UI.altOn === true) { UI.rfb.sendKey(XK_Alt_L, false); - $D('toggleAltButton').className = "noVNC_status_button"; + $D('noVNC_toggleAlt_button').className = "noVNC_status_button"; UI.altOn = false; } }, @@ -1274,11 +1274,11 @@ var UI; }, setBarPosition: function() { - $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px'; + $D('noVNC_control_bar').style.top = (window.pageYOffset) + 'px'; $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; var vncwidth = $D('noVNC_container').style.offsetWidth; - $D('noVNC-control-bar').style.width = vncwidth + 'px'; + $D('noVNC_control_bar').style.width = vncwidth + 'px'; } /* ------^------- diff --git a/vnc.html b/vnc.html index 9d583738..2990aacf 100644 --- a/vnc.html +++ b/vnc.html @@ -48,9 +48,9 @@ -
    +
    -
    +
    @@ -64,26 +64,26 @@ -
    + id="noVNC_toggleExtraKeys_button" class="noVNC_status_button"> + id="noVNC_toggleCtrl_button" class="noVNC_status_button"> + id="noVNC_toggleAlt_button" class="noVNC_status_button"> + id="noVNC_sendTab_button" class="noVNC_status_button"> + id="noVNC_sendEsc_button" class="noVNC_status_button">
    @@ -91,27 +91,27 @@
    -
    +
    @@ -128,7 +128,7 @@ and website for more information.
    - +
    @@ -147,9 +147,9 @@
    - - - + + +
    @@ -204,7 +204,7 @@
    -
    +
    From a1dbbcc1a71ca88a7e3e2fd0e47362744b69c265 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Fri, 27 May 2016 09:36:00 +0200 Subject: [PATCH 21/65] Consistent closing tags for void elements --- vnc.html | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/vnc.html b/vnc.html index 2990aacf..0b653065 100644 --- a/vnc.html +++ b/vnc.html @@ -16,20 +16,20 @@ --> noVNC - + - + - + - + @@ -53,19 +53,19 @@
    + title="Move/Drag Viewport" />
    + id="noVNC_mouse_button0" class="noVNC_status_button" /> + id="noVNC_mouse_button1" class="noVNC_status_button" /> + id="noVNC_mouse_button2" class="noVNC_status_button" /> + id="noVNC_mouse_button4" class="noVNC_status_button" /> + value="Keyboard" title="Show Keyboard" /> @@ -141,7 +141,7 @@
    + value="Clear" />
    @@ -157,14 +157,14 @@
      -
    • Encrypt
    • -
    • True Color
    • -
    • Local Cursor
    • -
    • Clip to Window
    • -
    • Shared Mode
    • -
    • View Only
    • +
    • Encrypt
    • +
    • True Color
    • +
    • Local Cursor
    • +
    • Clip to Window
    • +
    • Shared Mode
    • +
    • View Only

    • -
    • Path
    • +
    • Path
    • -
    • Repeater ID
    • +
    • Repeater ID


    • -
    • +
    @@ -199,8 +199,8 @@
  • -
  • -
  • +
  • +
  • From ae11605141f345d38bf1e5fcf8fb85c42c771145 Mon Sep 17 00:00:00 2001 From: Samuel Date: Thu, 2 Jun 2016 22:37:52 +0200 Subject: [PATCH 22/65] Split the setDesktopSize function (#618) In order to follow the surrounding coding-standards, the setDesktopSize client message is split from the public function which now is called requestDesktopSize(). --- include/rfb.js | 58 +++++++++++++++++++++++++++++++---------------- include/ui.js | 4 ++-- tests/test.rfb.js | 8 +++---- vnc_auto.html | 2 +- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index 48fa5a8c..7340fad2 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -311,28 +311,13 @@ var RFB; this._sock.flush(); }, - setDesktopSize: function (width, height) { + requestDesktopSize: function (width, height) { if (this._rfb_state !== "normal") { return; } if (this._supportsSetDesktopSize) { - - var arr = [251]; // msg-type - arr.push8(0); // padding - arr.push16(width); // width - arr.push16(height); // height - - arr.push8(1); // number-of-screens - arr.push8(0); // padding - - // screen array - arr.push32(this._screen_id); // id - arr.push16(0); // x-position - arr.push16(0); // y-position - arr.push16(width); // width - arr.push16(height); // height - arr.push32(this._screen_flags); // flags - - this._sock.send(arr); + RFB.messages.setDesktopSize(this._sock, width, height, + this._screen_id, this._screen_flags); + this._sock.flush(); } }, @@ -1340,6 +1325,41 @@ var RFB; sock._sQlen += 8 + n; }, + setDesktopSize: function (sock, width, height, id, flags) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 251; // msg-type + buff[offset + 1] = 0; // padding + buff[offset + 2] = width >> 8; // width + buff[offset + 3] = width; + buff[offset + 4] = height >> 8; // height + buff[offset + 5] = height; + + buff[offset + 6] = 1; // number-of-screens + buff[offset + 7] = 0; // padding + + // screen array + buff[offset + 8] = id >> 24; // id + buff[offset + 9] = id >> 16; + buff[offset + 10] = id >> 8; + buff[offset + 11] = id; + buff[offset + 12] = 0; // x-position + buff[offset + 13] = 0; + buff[offset + 14] = 0; // y-position + buff[offset + 15] = 0; + buff[offset + 16] = width >> 8; // width + buff[offset + 17] = width; + buff[offset + 18] = height >> 8; // height + buff[offset + 19] = height; + buff[offset + 20] = flags >> 24; // flags + buff[offset + 21] = flags >> 16; + buff[offset + 22] = flags >> 8; + buff[offset + 23] = flags; + + sock._sQlen += 24; + }, + pixelFormat: function (sock, bpp, depth, true_color) { var buff = sock._sQ; var offset = sock._sQlen; diff --git a/include/ui.js b/include/ui.js index cfdedb3a..95bc1356 100644 --- a/include/ui.js +++ b/include/ui.js @@ -263,9 +263,9 @@ var UI; UI.resizeTimeout = setTimeout(function(){ display.set_maxWidth(size.w); display.set_maxHeight(size.h); - Util.Debug('Attempting setDesktopSize(' + + Util.Debug('Attempting requestDesktopSize(' + size.w + ', ' + size.h + ')'); - UI.rfb.setDesktopSize(size.w, size.h); + UI.rfb.requestDesktopSize(size.w, size.h); }, 500); } else if (scaleType === 'scale' || scaleType === 'downscale') { // use local scaling diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 1b73986f..a0f2fa70 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -219,7 +219,7 @@ describe('Remote Frame Buffer Protocol Client', function() { }); }); - describe("#setDesktopSize", function () { + describe("#requestDesktopSize", function () { beforeEach(function() { client._sock = new Websock(); client._sock.open('ws://', 'binary'); @@ -244,19 +244,19 @@ describe('Remote Frame Buffer Protocol Client', function() { expected.push16(2); // height expected.push32(0); // flags - client.setDesktopSize(1, 2); + client.requestDesktopSize(1, 2); expect(client._sock).to.have.sent(new Uint8Array(expected)); }); it('should not send the request if the client has not recieved a ExtendedDesktopSize rectangle', function () { client._supportsSetDesktopSize = false; - client.setDesktopSize(1,2); + client.requestDesktopSize(1,2); expect(client._sock.flush).to.not.have.been.called; }); it('should not send the request if we are not in a normal state', function () { client._rfb_state = "broken"; - client.setDesktopSize(1,2); + client.requestDesktopSize(1,2); expect(client._sock.flush).to.not.have.been.called; }); }); diff --git a/vnc_auto.html b/vnc_auto.html index 73174713..bbf94d7b 100644 --- a/vnc_auto.html +++ b/vnc_auto.html @@ -92,7 +92,7 @@ var controlbarH = $D('noVNC_status_bar').offsetHeight; var padding = 5; if (innerW !== undefined && innerH !== undefined) - rfb.setDesktopSize(innerW, innerH - controlbarH - padding); + rfb.requestDesktopSize(innerW, innerH - controlbarH - padding); } } function FBUComplete(rfb, fbu) { From 5a20f425d4fddf67aef14c25ccea7d3fc2315677 Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 2 Jun 2016 14:53:22 +0200 Subject: [PATCH 23/65] Clean up encodings array List pseudo-encodings seperately and sorted by encoding number. --- include/rfb.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index c022969b..f426c15e 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -43,18 +43,20 @@ var RFB; ['HEXTILE', 0x05 ], ['RRE', 0x02 ], ['RAW', 0x00 ], - ['DesktopSize', -223 ], - ['Cursor', -239 ], // Psuedo-encoding settings + //['JPEG_quality_lo', -32 ], ['JPEG_quality_med', -26 ], //['JPEG_quality_hi', -23 ], //['compress_lo', -255 ], ['compress_hi', -247 ], + + ['DesktopSize', -223 ], ['last_rect', -224 ], - ['xvp', -309 ], - ['ExtendedDesktopSize', -308 ] + ['Cursor', -239 ], + ['ExtendedDesktopSize', -308 ], + ['xvp', -309 ] ]; this._encHandlers = {}; From 3af1a3a05b8d251faaa552c8dee2b3294fc9d357 Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 2 Jun 2016 14:57:44 +0200 Subject: [PATCH 24/65] Avoid unnecessary delays We only use setTimeout() to avoid hanging the browser, not because we actually want a delay. So let's use the smallest delay there is. --- include/rfb.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index f426c15e..fa2401dd 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -255,7 +255,7 @@ var RFB; sendPassword: function (passwd) { this._rfb_password = passwd; this._rfb_state = 'Authentication'; - setTimeout(this._init_msg.bind(this), 1); + setTimeout(this._init_msg.bind(this), 0); }, sendCtrlAltDel: function () { @@ -549,7 +549,7 @@ var RFB; this._msgTimer = setTimeout(function () { this._msgTimer = null; this._handle_message(); - }.bind(this), 10); + }.bind(this), 0); } else { Util.Debug("More data to process, existing timer"); } From cf0236de18a3790badd0892ed4de4c2dc95ce91d Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 3 Jun 2016 14:13:15 +0200 Subject: [PATCH 25/65] Fix typo in pointer event test --- tests/test.rfb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test.rfb.js b/tests/test.rfb.js index a0f2fa70..08159040 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -1741,7 +1741,7 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send a mask of 1 on mousedown', function () { client._mouse._onMouseButton(10, 12, 1, 0x001); var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0}; - RFB.messages.pointerEvent(pointer_msg, 0, 10, 12, 0x001); + RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x001); expect(client._sock).to.have.sent(pointer_msg._sQ); }); From b1538a0fa4d9e6e98fdd06eed1a8699d11c8fdc0 Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 3 Jun 2016 14:13:35 +0200 Subject: [PATCH 26/65] Fix 'sent' assertion We were completely mishandling the length of the data. Make sure we look at the length of the websocket rather than the websock object, and also compare with the expected length. --- tests/assertions.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/assertions.js b/tests/assertions.js index 4bd0cf40..fa122dc3 100644 --- a/tests/assertions.js +++ b/tests/assertions.js @@ -37,10 +37,14 @@ chai.use(function (_chai, utils) { }; var data = obj._websocket._get_sent_data(); var same = true; - for (var i = 0; i < obj.length; i++) { - if (data[i] != target_data[i]) { - same = false; - break; + if (data.length != target_data.length) { + same = false; + } else { + for (var i = 0; i < data.length; i++) { + if (data[i] != target_data[i]) { + same = false; + break; + } } } if (!same) { From 89d2837fa8e3f0498bbac7b7194f453d88bcbc1f Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 2 Jun 2016 15:09:00 +0200 Subject: [PATCH 27/65] Always flush socket after each message Make sure our messages go away right away, rather than having to remember to call flush from the caller, or causing extra delays by waiting for the send timer. This should result in a more responsive system. --- include/rfb.js | 25 +++++++------------------ tests/test.rfb.js | 35 +++++++++++++++-------------------- 2 files changed, 22 insertions(+), 38 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index fa2401dd..14e0aa62 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -67,7 +67,6 @@ var RFB; this._display = null; // Display object this._keyboard = null; // Keyboard input handler object this._mouse = null; // Mouse input handler object - this._sendTimer = null; // Send Queue check timer this._disconnTimer = null; // disconnection timer this._msgTimer = null; // queued handle_msg timer @@ -268,8 +267,6 @@ var RFB; RFB.messages.keyEvent(this._sock, XK_Delete, 0); RFB.messages.keyEvent(this._sock, XK_Alt_L, 0); RFB.messages.keyEvent(this._sock, XK_Control_L, 0); - - this._sock.flush(); }, xvpOp: function (ver, op) { @@ -303,14 +300,11 @@ var RFB; RFB.messages.keyEvent(this._sock, code, 1); RFB.messages.keyEvent(this._sock, code, 0); } - - this._sock.flush(); }, clipboardPasteFrom: function (text) { if (this._rfb_state !== 'normal') { return; } RFB.messages.clientCutText(this._sock, text); - this._sock.flush(); }, // Requests a change of remote desktop size. This message is an extension @@ -386,11 +380,6 @@ var RFB; }, _cleanupSocket: function (state) { - if (this._sendTimer) { - clearInterval(this._sendTimer); - this._sendTimer = null; - } - if (this._msgTimer) { clearInterval(this._msgTimer); this._msgTimer = null; @@ -564,7 +553,6 @@ var RFB; _handleKeyPress: function (keysym, down) { if (this._view_only) { return; } // View only, skip keyboard, events RFB.messages.keyEvent(this._sock, keysym, down); - this._sock.flush(); }, _handleMouseButton: function (x, y, down, bmask) { @@ -670,10 +658,6 @@ var RFB; this._rfb_version = this._rfb_max_version; } - // Send updates either at a rate of 1 update per 50ms, or - // whatever slower rate the network can handle - this._sendTimer = setInterval(this._sock.flush.bind(this._sock), 50); - var cversion = "00" + parseInt(this._rfb_version, 10) + ".00" + ((this._rfb_version * 10) % 10); this._sock.send_string("RFB " + cversion + "\n"); @@ -992,7 +976,6 @@ var RFB; this._timing.fbu_rt_start = (new Date()).getTime(); this._timing.pixels = 0; - this._sock.flush(); if (this._encrypt) { this._updateState('normal', 'Connected (encrypted) to: ' + this._fb_name); @@ -1095,7 +1078,6 @@ var RFB; var ret = this._framebufferUpdate(); if (ret) { RFB.messages.fbUpdateRequests(this._sock, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height); - this._sock.flush(); } return ret; @@ -1285,6 +1267,7 @@ var RFB; buff[offset + 7] = keysym; sock._sQlen += 8; + sock.flush(); }, pointerEvent: function (sock, x, y, mask) { @@ -1302,6 +1285,7 @@ var RFB; buff[offset + 5] = y; sock._sQlen += 6; + sock.flush(); }, // TODO(directxman12): make this unicode compatible? @@ -1327,6 +1311,7 @@ var RFB; } sock._sQlen += 8 + n; + sock.flush(); }, setDesktopSize: function (sock, width, height, id, flags) { @@ -1362,6 +1347,7 @@ var RFB; buff[offset + 23] = flags; sock._sQlen += 24; + sock.flush(); }, pixelFormat: function (sock, bpp, depth, true_color) { @@ -1397,6 +1383,7 @@ var RFB; buff[offset + 19] = 0; // padding sock._sQlen += 20; + sock.flush(); }, clientEncodings: function (sock, encodings, local_cursor, true_color) { @@ -1431,6 +1418,7 @@ var RFB; buff[offset + 3] = cnt; sock._sQlen += j - offset; + sock.flush(); }, fbUpdateRequests: function (sock, cleanDirty, fb_width, fb_height) { @@ -1477,6 +1465,7 @@ var RFB; buff[offset + 9] = h & 0xFF; sock._sQlen += 10; + sock.flush(); } }; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 08159040..aed339c8 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -132,7 +132,7 @@ describe('Remote Frame Buffer Protocol Client', function() { }); it('should sent ctrl[down]-alt[down]-del[down] then del[up]-alt[up]-ctrl[up]', function () { - var expected = {_sQ: new Uint8Array(48), _sQlen: 0}; + var expected = {_sQ: new Uint8Array(48), _sQlen: 0, flush: function () {}}; RFB.messages.keyEvent(expected, 0xFFE3, 1); RFB.messages.keyEvent(expected, 0xFFE9, 1); RFB.messages.keyEvent(expected, 0xFFFF, 1); @@ -168,14 +168,14 @@ describe('Remote Frame Buffer Protocol Client', function() { }); it('should send a single key with the given code and state (down = true)', function () { - var expected = {_sQ: new Uint8Array(8), _sQlen: 0}; + var expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}}; RFB.messages.keyEvent(expected, 123, 1); client.sendKey(123, 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 () { - var expected = {_sQ: new Uint8Array(16), _sQlen: 0}; + var expected = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function () {}}; RFB.messages.keyEvent(expected, 123, 1); RFB.messages.keyEvent(expected, 123, 0); client.sendKey(123); @@ -206,7 +206,7 @@ describe('Remote Frame Buffer Protocol Client', function() { }); it('should send the given text in a paste event', function () { - var expected = {_sQ: new Uint8Array(11), _sQlen: 0}; + var expected = {_sQ: new Uint8Array(11), _sQlen: 0, flush: function () {}}; RFB.messages.clientCutText(expected, 'abc'); client.clipboardPasteFrom('abc'); expect(client._sock).to.have.sent(expected._sQ); @@ -571,13 +571,6 @@ describe('Remote Frame Buffer Protocol Client', function() { expect(client._rfb_version).to.equal(3.8); }); - it('should initialize the flush interval', function () { - client._sock.flush = sinon.spy(); - send_ver('003.008', client); - this.clock.tick(100); - expect(client._sock.flush).to.have.been.calledThrice; - }); - it('should send back the interpreted version', function () { send_ver('004.000', client); @@ -1070,7 +1063,9 @@ describe('Remote Frame Buffer Protocol Client', function() { client.set_true_color(true); client.set_local_cursor(false); // we skip the cursor encoding - var expected = {_sQ: new Uint8Array(34 + 4 * (client._encodings.length - 1)), _sQlen: 0}; + var expected = {_sQ: new Uint8Array(34 + 4 * (client._encodings.length - 1)), + _sQlen: 0, + flush: function () {}}; RFB.messages.pixelFormat(expected, 4, 3, true); RFB.messages.clientEncodings(expected, client._encodings, false, true); var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, @@ -1161,7 +1156,7 @@ describe('Remote Frame Buffer Protocol Client', function() { } it('should send an update request if there is sufficient data', function () { - var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0}; + var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, dirtyBoxes: [ { x: 0, y: 0, w: 240, h: 20 } ] }; RFB.messages.fbUpdateRequests(expected_msg, expected_cdr, 240, 20); @@ -1178,7 +1173,7 @@ describe('Remote Frame Buffer Protocol Client', function() { }); it('should resume receiving an update if we previously did not have enough data', function () { - var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0}; + var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, dirtyBoxes: [ { x: 0, y: 0, w: 240, h: 20 } ] }; RFB.messages.fbUpdateRequests(expected_msg, expected_cdr, 240, 20); @@ -1733,14 +1728,14 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send a pointer event on mouse button presses', function () { client._mouse._onMouseButton(10, 12, 1, 0x001); - var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0}; + var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}}; 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._mouse._onMouseButton(10, 12, 1, 0x001); - var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0}; + var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}}; RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x001); expect(client._sock).to.have.sent(pointer_msg._sQ); }); @@ -1748,14 +1743,14 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send a mask of 0 on mouseup', function () { client._mouse_buttonMask = 0x001; client._mouse._onMouseButton(10, 12, 0, 0x001); - var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0}; + var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}}; 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._mouse._onMouseMove(10, 12); - var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0}; + var pointer_msg = {_sQ: new Uint8Array(6), _sQlen: 0, flush: function () {}}; RFB.messages.pointerEvent(pointer_msg, 10, 12, 0x000); expect(client._sock).to.have.sent(pointer_msg._sQ); }); @@ -1763,7 +1758,7 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should set the button mask so that future mouse movements use it', function () { client._mouse._onMouseButton(10, 12, 1, 0x010); client._mouse._onMouseMove(13, 9); - var pointer_msg = {_sQ: new Uint8Array(12), _sQlen: 0}; + var pointer_msg = {_sQ: new Uint8Array(12), _sQlen: 0, flush: function () {}}; 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); @@ -1829,7 +1824,7 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send a key message on a key press', function () { client._keyboard._onKeyPress(1234, 1); - var key_msg = {_sQ: new Uint8Array(8), _sQlen: 0}; + var key_msg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}}; RFB.messages.keyEvent(key_msg, 1234, 1); expect(client._sock).to.have.sent(key_msg._sQ); }); From 37195e4b5e776d1ce19a65ba72009536de7dcd67 Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 3 Jun 2016 15:22:19 +0200 Subject: [PATCH 28/65] Lower level check for framebuffer update requests Try to avoid using helper functions with complex logic when verifying results as those helper functions are also something we want to verify. Also add a test for a mix of clean and dirty areas specifically to make sure that helper function behaves properly. --- tests/test.rfb.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/test.rfb.js b/tests/test.rfb.js index aed339c8..a0fdf8f2 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -1068,9 +1068,7 @@ describe('Remote Frame Buffer Protocol Client', function() { flush: function () {}}; RFB.messages.pixelFormat(expected, 4, 3, true); RFB.messages.clientEncodings(expected, client._encodings, false, true); - var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, - dirtyBoxes: [ { x: 0, y: 0, w: 27, h: 32 } ] }; - RFB.messages.fbUpdateRequests(expected, expected_cdr, 27, 32); + RFB.messages.fbUpdateRequest(expected, false, 0, 0, 27, 32); send_server_init({ width: 27, height: 32 }, client); expect(client._sock).to.have.sent(expected._sQ); @@ -1157,9 +1155,7 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send an update request if there is sufficient data', function () { var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; - var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, - dirtyBoxes: [ { x: 0, y: 0, w: 240, h: 20 } ] }; - RFB.messages.fbUpdateRequests(expected_msg, expected_cdr, 240, 20); + RFB.messages.fbUpdateRequest(expected_msg, false, 0, 0, 240, 20); client._framebufferUpdate = function () { return true; }; client._sock._websocket._receive_data(new Uint8Array([0])); @@ -1174,9 +1170,7 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should resume receiving an update if we previously did not have enough data', function () { var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; - var expected_cdr = { cleanBox: { x: 0, y: 0, w: 0, h: 0 }, - dirtyBoxes: [ { x: 0, y: 0, w: 240, h: 20 } ] }; - RFB.messages.fbUpdateRequests(expected_msg, expected_cdr, 240, 20); + RFB.messages.fbUpdateRequest(expected_msg, false, 0, 0, 240, 20); // just enough to set FBU.rects client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 3])); @@ -1188,6 +1182,21 @@ describe('Remote Frame Buffer Protocol Client', function() { expect(client._sock).to.have.sent(expected_msg._sQ); }); + it('should send a request for both clean and dirty areas', function () { + var expected_msg = {_sQ: new Uint8Array(20), _sQlen: 0, flush: function() {}}; + var expected_cdr = { cleanBox: { x: 0, y: 0, w: 120, h: 20 }, + dirtyBoxes: [ { x: 120, y: 0, w: 120, h: 20 } ] }; + + RFB.messages.fbUpdateRequest(expected_msg, true, 0, 0, 120, 20); + RFB.messages.fbUpdateRequest(expected_msg, false, 120, 0, 120, 20); + + client._framebufferUpdate = function () { return true; }; + client._display.getCleanDirtyReset = function () { return expected_cdr; }; + client._sock._websocket._receive_data(new Uint8Array([0])); + + expect(client._sock).to.have.sent(expected_msg._sQ); + }); + it('should parse out information from a header before any actual data comes in', function () { client.set_onFBUReceive(sinon.spy()); var rect_info = { x: 8, y: 11, width: 27, height: 32, encoding: 0x02, encodingName: 'RRE' }; From 3df13262394515efe5877ce33fd0dbdf35e1b743 Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 2 Jun 2016 16:00:33 +0200 Subject: [PATCH 29/65] Add support for fences We don't actually use these, but servers may require this for other features. --- include/rfb.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++- tests/test.rfb.js | 25 +++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/include/rfb.js b/include/rfb.js index 14e0aa62..71672ffe 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -56,7 +56,8 @@ var RFB; ['last_rect', -224 ], ['Cursor', -239 ], ['ExtendedDesktopSize', -308 ], - ['xvp', -309 ] + ['xvp', -309 ], + ['Fence', -312 ] ]; this._encHandlers = {}; @@ -70,6 +71,8 @@ var RFB; this._disconnTimer = null; // disconnection timer this._msgTimer = null; // queued handle_msg timer + this._supportsFence = false; + // Frame buffer update state this._FBU = { rects: 0, @@ -1041,6 +1044,42 @@ var RFB; return true; }, + _handle_server_fence_msg: function() { + if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; } + this._sock.rQskipBytes(3); // Padding + var flags = this._sock.rQshift32(); + var length = this._sock.rQshift8(); + + if (this._sock.rQwait("ServerFence payload", length, 9)) { return false; } + var payload = this._sock.rQshiftStr(length); // FIXME: 64 bytes max + + this._supportsFence = true; + + /* + * Fence flags + * + * (1<<0) - BlockBefore + * (1<<1) - BlockAfter + * (1<<2) - SyncNext + * (1<<31) - Request + */ + + if (!(flags & (1<<31))) { + return this._fail("Unexpected fence response"); + } + + // Filter out unsupported flags + // FIXME: support syncNext + flags &= (1<<0) | (1<<1); + + // BlockBefore and BlockAfter are automatically handled by + // the fact that we process each incoming message + // synchronuosly. + RFB.messages.clientFence(this._sock, flags, payload); + + return true; + }, + _handle_xvp_msg: function () { if (this._sock.rQwait("XVP version and message", 3, 1)) { return false; } this._sock.rQskip8(); // Padding @@ -1092,6 +1131,9 @@ var RFB; case 3: // ServerCutText return this._handle_server_cut_text(); + case 248: // ServerFence + return this._handle_server_fence_msg(); + case 250: // XVP return this._handle_xvp_msg(); @@ -1350,6 +1392,33 @@ var RFB; sock.flush(); }, + clientFence: function (sock, flags, payload) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 248; // msg-type + + buff[offset + 1] = 0; // padding + buff[offset + 2] = 0; // padding + buff[offset + 3] = 0; // padding + + buff[offset + 4] = flags >> 24; // flags + buff[offset + 5] = flags >> 16; + buff[offset + 6] = flags >> 8; + buff[offset + 7] = flags; + + var n = payload.length; + + buff[offset + 8] = n; // length + + for (var i = 0; i < n; i++) { + buff[offset + 9 + i] = payload.charCodeAt(i); + } + + sock._sQlen += 9 + n; + sock.flush(); + }, + pixelFormat: function (sock, bpp, depth, true_color) { var buff = sock._sQ; var offset = sock._sQlen; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index a0fdf8f2..be6aa1b2 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -1705,6 +1705,31 @@ describe('Remote Frame Buffer Protocol Client', function() { expect(client.get_onBell()).to.have.been.calledOnce; }); + it('should respond correctly to ServerFence', function () { + var expected_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function() {}}; + var incoming_msg = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function() {}}; + + var payload = "foo\x00ab9"; + + // ClientFence and ServerFence are identical in structure + RFB.messages.clientFence(expected_msg, (1<<0) | (1<<1), payload); + RFB.messages.clientFence(incoming_msg, 0xffffffff, payload); + + client._sock._websocket._receive_data(incoming_msg._sQ); + + expect(client._sock).to.have.sent(expected_msg._sQ); + + expected_msg._sQlen = 0; + incoming_msg._sQlen = 0; + + RFB.messages.clientFence(expected_msg, (1<<0), payload); + RFB.messages.clientFence(incoming_msg, (1<<0) | (1<<31), payload); + + client._sock._websocket._receive_data(incoming_msg._sQ); + + expect(client._sock).to.have.sent(expected_msg._sQ); + }); + it('should fail on an unknown message type', function () { client._sock._websocket._receive_data(new Uint8Array([87])); expect(client._rfb_state).to.equal('failed'); From 3daa86cbae4fa3d6af18b32e300dd1bf66a005ea Mon Sep 17 00:00:00 2001 From: samhed Date: Wed, 8 Jun 2016 16:02:37 +0200 Subject: [PATCH 30/65] Update vnc_auto after the screen namechange Commit 553864e85813f886b9c60b4825c8d4b714cae695 changed the name of noVNC_screen to noVNC_container, vnc_auto.html was not updated accordingly. Fixes #621 --- vnc_auto.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnc_auto.html b/vnc_auto.html index bbf94d7b..2d81cca7 100644 --- a/vnc_auto.html +++ b/vnc_auto.html @@ -46,7 +46,7 @@ -
    +
    From b2cdd558590c942150838d99c7429ec9a43329ce Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 10 Jun 2016 17:15:42 +0200 Subject: [PATCH 31/65] Proper error handling for tight filters Don't throw an exception when we encounter an unsupported tight subencoding. --- include/rfb.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index c022969b..d0e6c8f7 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -2011,8 +2011,7 @@ var RFB; } else { // Filter 0, Copy could be valid here, but servers don't send it as an explicit filter // Filter 2, Gradient is valid but not use if jpeg is enabled - // TODO(directxman12): why aren't we just calling '_fail' here - throw new Error("Unsupported tight subencoding received, filter: " + filterId); + this._fail("Unsupported tight subencoding received, filter: " + filterId); } break; case "copy": From 15e733f5330345b41e91927adaa2ce8f984f0593 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Mon, 13 Jun 2016 10:22:43 -0500 Subject: [PATCH 32/65] Clarify that utils/launch.sh is MPL-2.0 Also, note in the top-level license file that the default noVNC license for files that are not explicitly marked or mentioned in the LICENSE.txt file are by default MPL-2.0 licensed. --- LICENSE.txt | 4 ++++ utils/launch.sh | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/LICENSE.txt b/LICENSE.txt index 924d2b0c..f217929f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -57,6 +57,10 @@ licenses (all MPL 2.0 compatible): utils/inflator.partial.js include/inflator.js : MIT (for pako) +Any other files not mentioned above are typically marked with +a copyright/license header at the top of the file. The default noVNC +license is MPL-2.0. + The following license texts are included: docs/LICENSE.MPL-2.0 diff --git a/utils/launch.sh b/utils/launch.sh index ecee06cd..af350b0a 100755 --- a/utils/launch.sh +++ b/utils/launch.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +# Copyright 2016 Joel Martin +# Copyright 2016 Solly Ross +# Licensed under MPL 2.0 or any later version (see LICENSE.txt) + usage() { if [ "$*" ]; then echo "$*" From 67685d0700ad3f26e59fd3a5309dad2d2d993782 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Fri, 1 Jul 2016 14:50:30 -0400 Subject: [PATCH 33/65] Fix missing mistyped setTimeout handler in UI This commit fixes a mistyped setTimeout handler that would result in the desired function not getting called (due to a missing set of parentheses). It also removes some uncessary anonymous functions, and just passes the function objects directly to setTimeout. --- include/ui.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/ui.js b/include/ui.js index 4fc6f09d..be56d513 100644 --- a/include/ui.js +++ b/include/ui.js @@ -369,9 +369,7 @@ var UI; parseInt(window.getComputedStyle(psp).width)/2 -30 + "px"; // Show the popup for a maximum of 1.5 seconds - UI.popupStatusTimeout = setTimeout(function() { - UI.closePopup(); - }, 1500); + UI.popupStatusTimeout = setTimeout(UI.closePopup, 1500); }, closePopup: function() { @@ -728,7 +726,7 @@ var UI; UI.rfb.connect(host, port, password, path); //Close dialog. - setTimeout(function () { UI.setBarPosition; } ); + setTimeout(UI.setBarPosition, 100); $D('noVNC_logo').style.display = "none"; $D('noVNC_screen').style.display = "inline"; }, @@ -1155,7 +1153,7 @@ var UI; // text has been added to the field event.target.blur(); // This has to be ran outside of the input handler in order to work - setTimeout(function() { UI.keepKeyboard(); }, 0); + setTimeout(UI.keepKeyboard, 0); } else { UI.lastKeyboardinput = newValue; } From 5230ab676472cc48c06237ea861938c905782651 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Fri, 1 Jul 2016 14:16:09 -0400 Subject: [PATCH 34/65] Release 0.6.0 This bumps the release version to 0.6.0 --- docs/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/VERSION b/docs/VERSION index bd73f470..5a2a5806 100644 --- a/docs/VERSION +++ b/docs/VERSION @@ -1 +1 @@ -0.4 +0.6 From da82b3426c27bf1a79f671c5825d68ab8c0c5d9f Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Mon, 4 Jul 2016 15:29:00 -0400 Subject: [PATCH 35/65] Release 0.6.1 Fixes version number mismatch (also adds more detailed instructions for releasing). Fixes #628 --- docs/VERSION | 2 +- docs/release.txt | 43 ++++++++++++++++++++++++++++++++++--------- package.json | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/docs/VERSION b/docs/VERSION index 5a2a5806..ee6cdce3 100644 --- a/docs/VERSION +++ b/docs/VERSION @@ -1 +1 @@ -0.6 +0.6.1 diff --git a/docs/release.txt b/docs/release.txt index 1660b9b8..3e036354 100644 --- a/docs/release.txt +++ b/docs/release.txt @@ -1,9 +1,34 @@ -- Update and commit docs/VERSION -- Create version tag and tarball from tag - WVER=0.3 - git tag v${WVER} - git push origin master - git push origin v${WVER} - git archive --format=tar --prefix=novnc-${WVER}/ v${WVER} > novnc-${WVER}.tar - gzip novnc-${WVER}.tar -- Upload tarball to repo +- Decide a new version number X.Y.Z (follow SemVer) +- Update version in package.json +- Update version in docs/VERSION +- Commit the change with a commit like "Release X.Y.Z" +- Add a new release on GitHub called "vX.Y.Z", and populate it with + release notes of the following form (where A.B.C is the last release): + +Major Changes Since A.B.C +========================= + +*Insert warnings here about incompatibilities* + +*Thanks to all the contributors who filed bugs, added features, and fixed bugs +during this release :tada:* + +App-visible Changes +------------------- + +- *feature* a feature which improves the app usage (#PRNUM) +- *bugfix* a bug fix which fixes the app usage (#PRNUM) +- *refactor* a refactor which changes the app usage (#PRNUM) + +Library-visible Changes +----------------------- + +- *feature* a feature which improves the noVNC APIs (#PRNUM) +- *bugfix* a bug fix which fixes the noVNC APIs (#PRNUM) +- *refactor* a refactor which changes the noVNC APIs (#PRNUM) + +App-internals Changes +--------------------- + +- *bugfix* a bug fix with affects the internals of noVNC only (#PRNUM) +- *refactor* a refactor which affects the internals of noVNC only (#PRNUM) diff --git a/package.json b/package.json index 8f12f879..3db93eb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "noVNC", - "version": "0.5.1", + "version": "0.6.1", "description": "An HTML5 VNC client", "main": "karma.conf.js", "directories": { From 6024677ffaf9dcd3ada1d5771bd7c41ad3003df0 Mon Sep 17 00:00:00 2001 From: "Alexander E. Patrakov" Date: Sun, 31 Jul 2016 21:55:04 +0500 Subject: [PATCH 36/65] Fixed RGB data buffer size (#615) --- include/display.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/display.js b/include/display.js index a492817d..665fd3d2 100644 --- a/include/display.js +++ b/include/display.js @@ -496,7 +496,7 @@ var Display; // 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, // this probably isn't getting called *nearly* as much - var new_arr = new Uint8Array(width * height * 4); + var new_arr = new Uint8Array(width * height * 3); new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); this.renderQ_push({ 'type': 'blitRgb', From 83d3e02fd90fe29251083447f13ef92acfcfa1a1 Mon Sep 17 00:00:00 2001 From: nunojusto Date: Tue, 16 Aug 2016 22:10:14 +0100 Subject: [PATCH 37/65] Update launch.sh Just a correction of port in use test algoritm. This way we will not have problems when using port X and having some other service using zyX or any *X port --- utils/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/launch.sh b/utils/launch.sh index af350b0a..36119541 100755 --- a/utils/launch.sh +++ b/utils/launch.sh @@ -69,7 +69,7 @@ done which netstat >/dev/null 2>&1 \ || die "Must have netstat installed" -netstat -ltn | grep -qs "${PORT} .*LISTEN" \ +netstat -ltn | grep -qs ":${PORT} .*LISTEN" \ && die "Port ${PORT} in use. Try --listen PORT" trap "cleanup" TERM QUIT INT EXIT From 6521c6ac0f260fb4719a8805e3799da17d48f35e Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Tue, 22 Dec 2015 15:16:52 -0500 Subject: [PATCH 38/65] Fix ImageData Constructor Support Detection Our support detection for the `ImageData(data, width, height)` constructor would fail in certain browsers because the size of a 1x1 ImageData's Uint8ClampedArray is 4, not 1. --- include/display.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/display.js b/include/display.js index a492817d..a6a57227 100644 --- a/include/display.js +++ b/include/display.js @@ -17,7 +17,7 @@ var Display; var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false; try { - new ImageData(new Uint8ClampedArray(1), 1, 1); + new ImageData(new Uint8ClampedArray(4), 1, 1); SUPPORTS_IMAGEDATA_CONSTRUCTOR = true; } catch (ex) { // ignore failure From c7925074c43ee36d5ae078ead14ba249e7272457 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Wed, 24 Feb 2016 16:13:06 -0500 Subject: [PATCH 39/65] Revert poor workaround for brief Firefox bug This commit reverts a fix for a bug which briefly occured on certain nightlies of Firefox. It was never intended to persist in the code base, and is causing other actual errors to be swallowed. --- include/rfb.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index d0e6c8f7..694c14ba 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -1165,14 +1165,7 @@ var RFB; this._timing.last_fbu = (new Date()).getTime(); - var handler = this._encHandlers[this._FBU.encoding]; - try { - //ret = this._encHandlers[this._FBU.encoding](); - ret = handler(); - } catch (ex) { - console.log("missed " + this._FBU.encoding + ": " + handler); - ret = this._encHandlers[this._FBU.encoding](); - } + ret = this._encHandlers[this._FBU.encoding](); now = (new Date()).getTime(); this._timing.cur_fbu += (now - this._timing.last_fbu); From e961641fa996a1dec440a0ca2550da6397adec93 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Thu, 25 Aug 2016 14:40:21 +0200 Subject: [PATCH 40/65] Fix the extra keys Commit 529c64e1036b622ff971b1a0cd13856837d3a9eb broke this. #shame# --- include/ui.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/ui.js b/include/ui.js index be56d513..2684f987 100644 --- a/include/ui.js +++ b/include/ui.js @@ -33,6 +33,7 @@ var UI; connSettingsOpen: false, clipboardOpen: false, keyboardVisible: false, + extraKeysVisible: false, isTouchDevice: false, isSafari: false, @@ -40,10 +41,8 @@ var UI; lastKeyboardinput: null, defaultKeyboardinputLen: 100, - shiftDown: false, - ctrlDown: false, - altDown: false, - altGrDown: false, + ctrlOn: false, + altOn: false, // Setup rfb object, load settings from browser storage, then call // UI.init to setup the UI/menus From 9d16e512ba839108afd8a478efaf852c3ffd0404 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Thu, 25 Aug 2016 15:16:04 +0200 Subject: [PATCH 41/65] Proper spacing --- include/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ui.js b/include/ui.js index 2684f987..ae2fdb67 100644 --- a/include/ui.js +++ b/include/ui.js @@ -33,7 +33,7 @@ var UI; connSettingsOpen: false, clipboardOpen: false, keyboardVisible: false, - extraKeysVisible: false, + extraKeysVisible: false, isTouchDevice: false, isSafari: false, From b9efece4a8b896a533cfd456098246011dc35f84 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Thu, 25 Aug 2016 15:32:15 +0200 Subject: [PATCH 42/65] Fix window close warning The code didn't follow current API for the beforeunload event. --- include/ui.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/ui.js b/include/ui.js index ae2fdb67..058ae5a4 100644 --- a/include/ui.js +++ b/include/ui.js @@ -156,11 +156,17 @@ var UI; Util.addEvent(window, 'load', UI.keyboardinputReset); + // While connected we want to display a confirmation dialogue + // if the user tries to leave the page Util.addEvent(window, 'beforeunload', function () { if (UI.rfb && UI.rfb_state === 'normal') { - return "You are currently connected."; + var msg = "You are currently connected."; + e.returnValue = msg; + return msg; + else { + return void 0; // To prevent the dialogue when disconnected } - } ); + }); // Show description by default when hosted at for kanaka.github.com if (location.host === "kanaka.github.io") { From da17d0369de93d9f879840978b6852295a456787 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Thu, 25 Aug 2016 16:49:02 +0200 Subject: [PATCH 43/65] Add missing event argument and curly bracket --- include/ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ui.js b/include/ui.js index 058ae5a4..03863634 100644 --- a/include/ui.js +++ b/include/ui.js @@ -158,12 +158,12 @@ var UI; // While connected we want to display a confirmation dialogue // if the user tries to leave the page - Util.addEvent(window, 'beforeunload', function () { + Util.addEvent(window, 'beforeunload', function (e) { if (UI.rfb && UI.rfb_state === 'normal') { var msg = "You are currently connected."; e.returnValue = msg; return msg; - else { + } else { return void 0; // To prevent the dialogue when disconnected } }); From 76a86ff51436ed3e4cf5125ca8d58240b52e9c37 Mon Sep 17 00:00:00 2001 From: samhed Date: Thu, 2 Jun 2016 16:41:38 +0200 Subject: [PATCH 44/65] Add support for ContinuousUpdates Instead of requesting frame buffer updates we can, if the server supports it, continuously recieve frame buffer updates at a rate determined by the server. The server can use fencing messages and measure response times to determine how often it will continue to send updates. --- include/rfb.js | 67 +++++++++++++++++++++++++++++++++++++++++---- tests/test.rfb.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 6 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index 71672ffe..e6597af2 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -57,7 +57,8 @@ var RFB; ['Cursor', -239 ], ['ExtendedDesktopSize', -308 ], ['xvp', -309 ], - ['Fence', -312 ] + ['Fence', -312 ], + ['ContinuousUpdates', -313 ] ]; this._encHandlers = {}; @@ -73,6 +74,9 @@ var RFB; this._supportsFence = false; + this._supportsContinuousUpdates = false; + this._enabledContinuousUpdates = false; + // Frame buffer update state this._FBU = { rects: 0, @@ -975,7 +979,7 @@ var RFB; RFB.messages.pixelFormat(this._sock, this._fb_Bpp, this._fb_depth, this._true_color); RFB.messages.clientEncodings(this._sock, this._encodings, this._local_cursor, this._true_color); - RFB.messages.fbUpdateRequests(this._sock, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height); + RFB.messages.fbUpdateRequests(this._sock, false, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height); this._timing.fbu_rt_start = (new Date()).getTime(); this._timing.pixels = 0; @@ -1051,7 +1055,13 @@ var RFB; var length = this._sock.rQshift8(); if (this._sock.rQwait("ServerFence payload", length, 9)) { return false; } - var payload = this._sock.rQshiftStr(length); // FIXME: 64 bytes max + + if (length > 64) { + Util.Warn("Bad payload length (" + length + ") in fence response"); + length = 64; + } + + var payload = this._sock.rQshiftStr(length); this._supportsFence = true; @@ -1116,7 +1126,10 @@ var RFB; case 0: // FramebufferUpdate var ret = this._framebufferUpdate(); if (ret) { - RFB.messages.fbUpdateRequests(this._sock, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height); + RFB.messages.fbUpdateRequests(this._sock, + this._enabledContinuousUpdates, + this._display.getCleanDirtyReset(), + this._fb_width, this._fb_height); } return ret; @@ -1131,6 +1144,20 @@ var RFB; case 3: // ServerCutText return this._handle_server_cut_text(); + case 150: // EndOfContinuousUpdates + var first = !(this._supportsContinuousUpdates); + this._supportsContinuousUpdates = true; + this._enabledContinuousUpdates = false; + if (first) { + this._enabledContinuousUpdates = true; + this._updateContinuousUpdates(); + Util.Info("Enabling continuous updates."); + } else { + // FIXME: We need to send a framebufferupdaterequest here + // if we add support for turning off continuous updates + } + return true; + case 248: // ServerFence return this._handle_server_fence_msg(); @@ -1245,6 +1272,13 @@ var RFB; return true; // We finished this FBU }, + + _updateContinuousUpdates: function() { + if (!this._enabledContinuousUpdates) { return; } + + RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, + this._fb_width, this._fb_height); + } }; Util.make_properties(RFB, [ @@ -1419,6 +1453,26 @@ var RFB; sock.flush(); }, + enableContinuousUpdates: function (sock, enable, x, y, width, height) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 150; // msg-type + buff[offset + 1] = enable; // enable-flag + + buff[offset + 2] = x >> 8; // x + buff[offset + 3] = x; + buff[offset + 4] = y >> 8; // y + buff[offset + 5] = y; + buff[offset + 6] = width >> 8; // width + buff[offset + 7] = width; + buff[offset + 8] = height >> 8; // height + buff[offset + 9] = height; + + sock._sQlen += 10; + sock.flush(); + }, + pixelFormat: function (sock, bpp, depth, true_color) { var buff = sock._sQ; var offset = sock._sQlen; @@ -1490,12 +1544,12 @@ var RFB; sock.flush(); }, - fbUpdateRequests: function (sock, cleanDirty, fb_width, fb_height) { + fbUpdateRequests: function (sock, onlyNonInc, cleanDirty, fb_width, fb_height) { var offsetIncrement = 0; var cb = cleanDirty.cleanBox; var w, h; - if (cb.w > 0 && cb.h > 0) { + if (!onlyNonInc && (cb.w > 0 && cb.h > 0)) { w = typeof cb.w === "undefined" ? fb_width : cb.w; h = typeof cb.h === "undefined" ? fb_height : cb.h; // Request incremental for clean box @@ -2102,6 +2156,7 @@ var RFB; this._display.resize(this._fb_width, this._fb_height); this._onFBResize(this, this._fb_width, this._fb_height); this._timing.fbu_rt_start = (new Date()).getTime(); + this._updateContinuousUpdates(); this._FBU.bytes = 0; this._FBU.rects -= 1; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index be6aa1b2..65ce5f88 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -1197,6 +1197,33 @@ describe('Remote Frame Buffer Protocol Client', function() { expect(client._sock).to.have.sent(expected_msg._sQ); }); + it('should only request non-incremental rects in continuous updates mode', function () { + var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; + var expected_cdr = { cleanBox: { x: 0, y: 0, w: 120, h: 20 }, + dirtyBoxes: [ { x: 120, y: 0, w: 120, h: 20 } ] }; + + RFB.messages.fbUpdateRequest(expected_msg, false, 120, 0, 120, 20); + + client._enabledContinuousUpdates = true; + client._framebufferUpdate = function () { return true; }; + client._display.getCleanDirtyReset = function () { return expected_cdr; }; + client._sock._websocket._receive_data(new Uint8Array([0])); + + expect(client._sock).to.have.sent(expected_msg._sQ); + }); + + it('should not send a request in continuous updates mode when clean', function () { + var expected_cdr = { cleanBox: { x: 0, y: 0, w: 240, h: 20 }, + dirtyBoxes: [] }; + + client._enabledContinuousUpdates = true; + client._framebufferUpdate = function () { return true; }; + client._display.getCleanDirtyReset = function () { return expected_cdr; }; + client._sock._websocket._receive_data(new Uint8Array([0])); + + expect(client._sock._websocket._get_sent_data()).to.have.length(0); + }); + it('should parse out information from a header before any actual data comes in', function () { client.set_onFBUReceive(sinon.spy()); var rect_info = { x: 8, y: 11, width: 27, height: 32, encoding: 0x02, encodingName: 'RRE' }; @@ -1730,6 +1757,49 @@ describe('Remote Frame Buffer Protocol Client', function() { expect(client._sock).to.have.sent(expected_msg._sQ); }); + it('should enable continuous updates on first EndOfContinousUpdates', function () { + var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; + + RFB.messages.enableContinuousUpdates(expected_msg, true, 0, 0, 640, 20); + + expect(client._enabledContinuousUpdates).to.be.false; + + client._sock._websocket._receive_data(new Uint8Array([150])); + + expect(client._enabledContinuousUpdates).to.be.true; + expect(client._sock).to.have.sent(expected_msg._sQ); + }); + + it('should disable continuous updates on subsequent EndOfContinousUpdates', function () { + client._enabledContinuousUpdates = true; + client._supportsContinuousUpdates = true; + + client._sock._websocket._receive_data(new Uint8Array([150])); + + expect(client._enabledContinuousUpdates).to.be.false; + }); + + it('should update continuous updates on resize', function () { + var expected_msg = {_sQ: new Uint8Array(10), _sQlen: 0, flush: function() {}}; + RFB.messages.enableContinuousUpdates(expected_msg, true, 0, 0, 90, 700); + + client._FBU.width = 450; + client._FBU.height = 160; + + client._encHandlers.handle_FB_resize(); + + expect(client._sock._websocket._get_sent_data()).to.have.length(0); + + client._enabledContinuousUpdates = true; + + client._FBU.width = 90; + client._FBU.height = 700; + + client._encHandlers.handle_FB_resize(); + + expect(client._sock).to.have.sent(expected_msg._sQ); + }); + it('should fail on an unknown message type', function () { client._sock._websocket._receive_data(new Uint8Array([87])); expect(client._rfb_state).to.equal('failed'); From 12f4747ced89de7f37609d7740936f7a3a677d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20Tu=E1=BA=A5n=20Anh?= Date: Fri, 26 Aug 2016 16:09:22 +0700 Subject: [PATCH 45/65] Removing unused import (#642) --- utils/json2graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/json2graph.py b/utils/json2graph.py index f9ae27d3..8992382f 100755 --- a/utils/json2graph.py +++ b/utils/json2graph.py @@ -7,7 +7,7 @@ Licensed under MPL-2.0 (see docs/LICENSE.MPL-2.0) ''' # a bar plot with errorbars -import sys, json, pprint +import sys, json import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties From c4df8ca92cd3bfcc669d03edca8cc050e0030801 Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 26 Aug 2016 12:18:28 +0200 Subject: [PATCH 46/65] Remove bad trailing commas --- include/rfb.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index 8d268b04..dd3ad8f2 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -153,7 +153,7 @@ var RFB; 'onFBUComplete': function () { }, // onFBUComplete(rfb, fbu): RFB FBU received and processed 'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized 'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received - 'onXvpInit': function () { }, // onXvpInit(version): XVP extensions active for this connection + 'onXvpInit': function () { } // onXvpInit(version): XVP extensions active for this connection }); // main setup @@ -1297,7 +1297,7 @@ var RFB; ['onFBUComplete', 'rw', 'func'], // onFBUComplete(rfb, fbu): RFB FBU received and processed ['onFBResize', 'rw', 'func'], // onFBResize(rfb, width, height): frame buffer resized ['onDesktopName', 'rw', 'func'], // onDesktopName(rfb, name): desktop name received - ['onXvpInit', 'rw', 'func'], // onXvpInit(version): XVP extensions active for this connection + ['onXvpInit', 'rw', 'func'] // onXvpInit(version): XVP extensions active for this connection ]); RFB.prototype.set_local_cursor = function (cursor) { From 9104d3b5672c1391fd40ff32e6bac7b5d3ed86a6 Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 26 Aug 2016 12:19:30 +0200 Subject: [PATCH 47/65] Remove unnecessary debug logging --- include/rfb.js | 1 - 1 file changed, 1 deletion(-) diff --git a/include/rfb.js b/include/rfb.js index dd3ad8f2..3e7ee7d2 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -1836,7 +1836,6 @@ var RFB; for (var i = 0; i < 4; i++) { if ((resetStreams >> i) & 1) { this._FBU.zlibs[i].reset(); - console.debug('RESET!'); Util.Info("Reset zlib stream " + i); } } From 4e0c36dda708628836dc6f5d68fc40d05c7716d9 Mon Sep 17 00:00:00 2001 From: samhed Date: Fri, 26 Aug 2016 12:20:51 +0200 Subject: [PATCH 48/65] Add missing return values --- include/rfb.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/rfb.js b/include/rfb.js index 3e7ee7d2..bc5555ab 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -249,6 +249,7 @@ var RFB; } this._updateState('connect'); + return true; }, disconnect: function () { @@ -274,6 +275,7 @@ var RFB; RFB.messages.keyEvent(this._sock, XK_Delete, 0); RFB.messages.keyEvent(this._sock, XK_Alt_L, 0); RFB.messages.keyEvent(this._sock, XK_Control_L, 0); + return true; }, xvpOp: function (ver, op) { @@ -307,6 +309,7 @@ var RFB; RFB.messages.keyEvent(this._sock, code, 1); RFB.messages.keyEvent(this._sock, code, 0); } + return true; }, clipboardPasteFrom: function (text) { @@ -822,7 +825,7 @@ var RFB; } } - this._fail("No supported sub-auth types!"); + return this._fail("No supported sub-auth types!"); }, _negotiate_authentication: function () { @@ -873,6 +876,8 @@ var RFB; return false; case 2: return this._fail("Too many auth attempts"); + default: + return this._fail("Unknown SecurityResult"); } }, @@ -989,6 +994,7 @@ var RFB; } else { this._updateState('normal', 'Connected (unencrypted) to: ' + this._fb_name); } + return true; }, _init_msg: function () { @@ -1012,6 +1018,9 @@ var RFB; case 'ServerInitialisation': return this._negotiate_server_init(); + + default: + return this._fail("Unknown state: " + this._rfb_state); } }, From 99feba6ba8fee5b3a2b2dc99dc25e9179c560d31 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Fri, 26 Aug 2016 15:47:03 -0300 Subject: [PATCH 49/65] QEMU RFB extension - new file xtscancodes.js This new file contains the XT scancode mapping that the extension will use in rfb.js file. Signed-off-by: Daniel Henrique Barboza --- LICENSE.txt | 5 +- include/ui.js | 5 +- include/xtscancodes.js | 146 ++++++++++++++++++++++++++++++++++++++++ karma.conf.js | 1 + tests/input.html | 9 +-- tests/vnc_perf.html | 5 +- tests/vnc_playback.html | 5 +- vnc_auto.html | 5 +- 8 files changed, 167 insertions(+), 14 deletions(-) create mode 100644 include/xtscancodes.js diff --git a/LICENSE.txt b/LICENSE.txt index f217929f..2ec4a642 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -17,6 +17,7 @@ is not limited to): include/util.js include/websock.js include/webutil.js + include/xtscancodes.js The HTML, CSS, font and images files that included with the noVNC source distibution (or repository) are not considered part of the @@ -45,7 +46,7 @@ the noVNC core library. Here is a list of those files and the original licenses (all MPL 2.0 compatible): include/base64.js : MPL 2.0 - + include/des.js : Various BSD style licenses include/chrome-app/tcp-stream.js @@ -53,7 +54,7 @@ licenses (all MPL 2.0 compatible): utils/websockify utils/websocket.py : LGPL 3 - + utils/inflator.partial.js include/inflator.js : MIT (for pako) diff --git a/include/ui.js b/include/ui.js index 03863634..d69a4f6d 100644 --- a/include/ui.js +++ b/include/ui.js @@ -18,8 +18,9 @@ var UI; // Load supporting scripts window.onscriptsload = function () { UI.load(); }; Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", - "keysymdef.js", "keyboard.js", "input.js", "display.js", - "rfb.js", "keysym.js", "inflator.js"]); + "keysymdef.js", "xtscancodes.js", "keyboard.js", + "input.js", "display.js", "rfb.js", "keysym.js", + "inflator.js"]); UI = { diff --git a/include/xtscancodes.js b/include/xtscancodes.js new file mode 100644 index 00000000..d19a0174 --- /dev/null +++ b/include/xtscancodes.js @@ -0,0 +1,146 @@ +var XtScancode = {}; +XtScancode["Escape"] = 0x0001; +XtScancode["Digit1"] = 0x0002; +XtScancode["Digit2"] = 0x0003; +XtScancode["Digit3"] = 0x0004; +XtScancode["Digit4"] = 0x0005; +XtScancode["Digit5"] = 0x0006; +XtScancode["Digit6"] = 0x0007; +XtScancode["Digit7"] = 0x0008; +XtScancode["Digit8"] = 0x0009; +XtScancode["Digit9"] = 0x000A; +XtScancode["Digit0"] = 0x000B; +XtScancode["Minus"] = 0x000C; +XtScancode["Equal"] = 0x000D; +XtScancode["Backspace"] = 0x000E; +XtScancode["Tab"] = 0x000F; +XtScancode["KeyQ"] = 0x0010; +XtScancode["KeyW"] = 0x0011; +XtScancode["KeyE"] = 0x0012; +XtScancode["KeyR"] = 0x0013; +XtScancode["KeyT"] = 0x0014; +XtScancode["KeyY"] = 0x0015; +XtScancode["KeyU"] = 0x0016; +XtScancode["KeyI"] = 0x0017; +XtScancode["KeyO"] = 0x0018; +XtScancode["KeyP"] = 0x0019; +XtScancode["BracketLeft"] = 0x001A; +XtScancode["BracketRight"] = 0x001B; +XtScancode["Enter"] = 0x001C; +XtScancode["ControlLeft"] = 0x001D; +XtScancode["KeyA"] = 0x001E; +XtScancode["KeyS"] = 0x001F; +XtScancode["KeyD"] = 0x0020; +XtScancode["KeyF"] = 0x0021; +XtScancode["KeyG"] = 0x0022; +XtScancode["KeyH"] = 0x0023; +XtScancode["KeyJ"] = 0x0024; +XtScancode["KeyK"] = 0x0025; +XtScancode["KeyL"] = 0x0026; +XtScancode["Semicolon"] = 0x0027; +XtScancode["Quote"] = 0x0028; +XtScancode["Backquote"] = 0x0029; +XtScancode["ShiftLeft"] = 0x002A; +XtScancode["Backslash"] = 0x002B; +XtScancode["KeyZ"] = 0x002C; +XtScancode["KeyX"] = 0x002D; +XtScancode["KeyC"] = 0x002E; +XtScancode["KeyV"] = 0x002F; +XtScancode["KeyB"] = 0x0030; +XtScancode["KeyN"] = 0x0031; +XtScancode["KeyM"] = 0x0032; +XtScancode["Comma"] = 0x0033; +XtScancode["Period"] = 0x0034; +XtScancode["Slash"] = 0x0035; +XtScancode["ShiftRight"] = 0x0036; +XtScancode["NumpadMultiply"] = 0x0037; +XtScancode["AltLeft"] = 0x0038; +XtScancode["Space"] = 0x0039; +XtScancode["CapsLock"] = 0x003A; +XtScancode["F1"] = 0x003B; +XtScancode["F2"] = 0x003C; +XtScancode["F3"] = 0x003D; +XtScancode["F4"] = 0x003E; +XtScancode["F5"] = 0x003F; +XtScancode["F6"] = 0x0040; +XtScancode["F7"] = 0x0041; +XtScancode["F8"] = 0x0042; +XtScancode["F9"] = 0x0043; +XtScancode["F10"] = 0x0044; +XtScancode["Pause"] = 0xE045; +XtScancode["ScrollLock"] = 0x0046; +XtScancode["Numpad7"] = 0x0047; +XtScancode["Numpad8"] = 0x0048; +XtScancode["Numpad9"] = 0x0049; +XtScancode["NumpadSubtract"] = 0x004A; +XtScancode["Numpad4"] = 0x004B; +XtScancode["Numpad5"] = 0x004C; +XtScancode["Numpad6"] = 0x004D; +XtScancode["NumpadAdd"] = 0x004E; +XtScancode["Numpad1"] = 0x004F; +XtScancode["Numpad2"] = 0x0050; +XtScancode["Numpad3"] = 0x0051; +XtScancode["Numpad0"] = 0x0052; +XtScancode["NumpadDecimal"] = 0x0053; +XtScancode["IntlBackslash"] = 0x0056; +XtScancode["F11"] = 0x0057; +XtScancode["F12"] = 0x0058; +XtScancode["IntlYen"] = 0x007D; +XtScancode["MediaTrackPrevious"] = 0xE010; +XtScancode["MediaTrackNext"] = 0xE019; +XtScancode["NumpadEnter"] = 0xE01C; +XtScancode["ControlRight"] = 0xE01D; +XtScancode["VolumeMute"] = 0xE020; +XtScancode["MediaPlayPause"] = 0xE022; +XtScancode["MediaStop"] = 0xE024; +XtScancode["VolumeDown"] = 0xE02E; +XtScancode["VolumeUp"] = 0xE030; +XtScancode["BrowserHome"] = 0xE032; +XtScancode["NumpadDivide"] = 0xE035; +XtScancode["PrintScreen"] = 0xE037; +XtScancode["AltRight"] = 0xE038; +XtScancode["NumLock"] = 0x0045; +XtScancode["Home"] = 0xE047; +XtScancode["ArrowUp"] = 0xE048; +XtScancode["PageUp"] = 0xE049; +XtScancode["ArrowLeft"] = 0xE04B; +XtScancode["ArrowRight"] = 0xE04D; +XtScancode["End"] = 0xE04F; +XtScancode["ArrowDown"] = 0xE050; +XtScancode["PageDown"] = 0xE051; +XtScancode["Insert"] = 0xE052; +XtScancode["Delete"] = 0xE053; +XtScancode["OSLeft"] = 0xE05B; +XtScancode["OSRight"] = 0xE05C; +XtScancode["ContextMenu"] = 0xE05D; +XtScancode["BrowserSearch"] = 0xE065; +XtScancode["BrowserFavorites"] = 0xE066; +XtScancode["BrowserRefresh"] = 0xE067; +XtScancode["BrowserStop"] = 0xE068; +XtScancode["BrowserForward"] = 0xE069; +XtScancode["BrowserBack"] = 0xE06A; +XtScancode["NumpadComma"] = 0x007E; +XtScancode["NumpadEqual"] = 0x0059; +XtScancode["F13"] = 0x0064; +XtScancode["F14"] = 0x0065; +XtScancode["F15"] = 0x0066; +XtScancode["F16"] = 0x0067; +XtScancode["F17"] = 0x0068; +XtScancode["F18"] = 0x0069; +XtScancode["F19"] = 0x006A; +XtScancode["F20"] = 0x006B; +XtScancode["F21"] = 0x006C; +XtScancode["F22"] = 0x006D; +XtScancode["F23"] = 0x006E; +XtScancode["F24"] = 0x0076; +XtScancode["KanaMode"] = 0x0070; +XtScancode["Lang2"] = 0x0071; +XtScancode["Lang1"] = 0x0072; +XtScancode["IntlRo"] = 0x0073; +XtScancode["Convert"] = 0x0079; +XtScancode["NonConvert"] = 0x007B; +XtScancode["LaunchApp2"] = 0xE021; +XtScancode["Power"] = 0xE05E; +XtScancode["LaunchApp1"] = 0xE06B; +XtScancode["LaunchMail"] = 0xE06C; +XtScancode["MediaSelect"] = 0xE06D; diff --git a/karma.conf.js b/karma.conf.js index 870b8551..2c49ffc7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -115,6 +115,7 @@ module.exports = function(config) { 'include/base64.js', 'include/keysym.js', 'include/keysymdef.js', + 'include/xtscancodes.js', 'include/keyboard.js', 'include/input.js', 'include/websock.js', diff --git a/tests/input.html b/tests/input.html index 8416379b..301a7f8e 100644 --- a/tests/input.html +++ b/tests/input.html @@ -20,16 +20,17 @@ - + - - + + + --> - - - - - - - - - + + + + + + + + + - - + + diff --git a/tests/vnc_playback.html b/tests/vnc_playback.html index c4d2108e..168663db 100644 --- a/tests/vnc_playback.html +++ b/tests/vnc_playback.html @@ -33,24 +33,24 @@ - - + + diff --git a/utils/make-module-transform.js b/utils/make-module-transform.js new file mode 100644 index 00000000..bb48ae50 --- /dev/null +++ b/utils/make-module-transform.js @@ -0,0 +1,25 @@ +var through = require('through2'); + +var singleLineRe = /\/\* \[module\] ((.(?!\*\/))+) \*\//g; +var multiLineRe = /\/\* \[module\]\n(( * .+\n)+) \*\//g; + +var skipAsModule = /\/\* \[begin skip-as-module\] \*\/(.|\n)+\/\* \[end skip-as-module\] \*\//g; + +module.exports = function (file) { + var stream = through(function (buf, enc, next) { + var bufStr = buf.toString('utf8'); + bufStr = bufStr.replace(singleLineRe, "$1"); + bufStr = bufStr.replace(multiLineRe, function (match, mainLines) { + return mainLines.split(" * ").join(""); + }); + + bufStr = bufStr.replace(skipAsModule, ""); + + this.push(bufStr); + next(); + }); + + stream._is_make_module = true; + + return stream; +}; diff --git a/utils/use_require.js b/utils/use_require.js new file mode 100755 index 00000000..0c16db26 --- /dev/null +++ b/utils/use_require.js @@ -0,0 +1,120 @@ +#!/usr/bin/env node + +var path = require('path'); +var program = require('commander'); +var fs = require('fs'); +var fse = require('fs-extra'); +var browserify = require('browserify'); + +var make_modules_transform = require('./make-module-transform'); +var babelify = require("babelify"); + + +program + .option('-b, --browserify', 'create a browserify bundled app') + .option('--as-require', 'output files using "require" instead of ES6 import and export') + .parse(process.argv); + +// the various important paths +var core_path = path.resolve(__dirname, '..', 'core'); +var app_path = path.resolve(__dirname, '..', 'app'); +var out_dir_base = path.resolve(__dirname, '..', 'build'); +var lib_dir_base = path.resolve(__dirname, '..', 'lib'); + +var make_browserify = function (src_files, opts) { + // change to the root noVNC directory + process.chdir(path.resolve(__dirname, '..')); + + var b = browserify(src_files, opts); + + // register the transforms + b.transform(make_modules_transform); + b.transform(babelify, + { plugins: ["add-module-exports", "transform-es2015-modules-commonjs"] }); + + return b; +}; + +var make_full_app = function () { + // make sure the output directory exists + fse.ensureDir(out_dir_base); + + // actually bundle the files into a browserified bundled + var ui_file = path.join(app_path, 'ui.js'); + var b = make_browserify(ui_file, {}); + var app_file = path.join(out_dir_base, 'app.js'); + b.bundle().pipe(fs.createWriteStream(app_file)); + + // copy over app-related resources (images, styles, etc) + var src_dir_app = path.join(__dirname, '..', 'app'); + fs.readdir(src_dir_app, function (err, files) { + if (err) { throw err; } + + files.forEach(function (src_file) { + var src_file_path = path.resolve(src_dir_app, src_file); + var out_file_path = path.resolve(out_dir_base, src_file); + var ext = path.extname(src_file); + if (ext === '.js' || ext === '.html') return; + fse.copy(src_file_path, out_file_path, function (err) { + if (err) { throw err; } + console.log("Copied file(s) from " + src_file_path + " to " + out_file_path); + }); + }); + }); + + // write out the modified vnc.html file that works with the bundle + var src_html_path = path.resolve(__dirname, '..', 'vnc.html'); + var out_html_path = path.resolve(out_dir_base, 'vnc.html'); + fs.readFile(src_html_path, function (err, contents_raw) { + if (err) { throw err; } + + var contents = contents_raw.toString(); + contents = contents.replace(/="app\//g, '="'); + + var start_marker = '\n'; + var end_marker = ''; + var start_ind = contents.indexOf(start_marker) + start_marker.length; + var end_ind = contents.indexOf(end_marker, start_ind); + + contents = contents.slice(0, start_ind) + '\n' + contents.slice(end_ind); + + fs.writeFile(out_html_path, contents, function (err) { + if (err) { throw err; } + console.log("Wrote " + out_html_path); + }); + }); +}; + +var make_lib_files = function (use_require) { + // make sure the output directory exists + fse.ensureDir(lib_dir_base); + + var through = require('through2'); + + var deps = {}; + var rfb_file = path.join(core_path, 'rfb.js'); + var b = make_browserify(rfb_file, {}); + b.on('transform', function (tr, file) { + if (tr._is_make_module) { + var new_path = path.join(lib_dir_base, path.basename(file)); + console.log("Writing " + new_path) + var fileStream = fs.createWriteStream(new_path); + + if (use_require) { + var babelificate = babelify(file, + { plugins: ["add-module-exports", "transform-es2015-modules-commonjs"] }); + tr.pipe(babelificate); + tr = babelificate; + } + tr.pipe(fileStream); + } + }); + + b.bundle(); +}; + +if (program.browserify) { + make_full_app(); +} else { + make_lib_files(program.asRequire); +} diff --git a/vnc.html b/vnc.html index 0b653065..bfc12017 100644 --- a/vnc.html +++ b/vnc.html @@ -27,18 +27,18 @@ - + - + - - - + + +
    -
    - - - - -
    - - - - - - -
    @@ -218,8 +218,10 @@
    - - + + + + diff --git a/vnc_auto.html b/vnc_auto.html index 597028e7..6fa3f253 100644 --- a/vnc_auto.html +++ b/vnc_auto.html @@ -27,22 +27,22 @@ - + - + - + - + @@ -77,10 +77,11 @@ "use strict"; // Load supporting scripts - Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", - "keysymdef.js", "xtscancodes.js", "keyboard.js", - "input.js", "display.js", "inflator.js", "rfb.js", - "keysym.js"]); + Util.load_scripts({ + 'core': ["base64.js", "websock.js", "des.js", "keysymdef.js", + "xtscancodes.js", "keyboard.js", "input.js", "display.js", + "inflator.js", "rfb.js", "keysym.js"], + 'app': ["webutil.js"]}); var rfb; var resizeTimeout; @@ -90,7 +91,7 @@ if (WebUtil.getConfigVar('resize', false)) { var innerW = window.innerWidth; var innerH = window.innerHeight; - var controlbarH = $D('noVNC_status_bar').offsetHeight; + var controlbarH = document.getElementById('noVNC_status_bar').offsetHeight; var padding = 5; if (innerW !== undefined && innerH !== undefined) rfb.requestDesktopSize(innerW, innerH - controlbarH - padding); @@ -107,11 +108,11 @@ msg += 'Password Required: '; msg += ''; msg += '<\/form>'; - $D('noVNC_status_bar').setAttribute("class", "noVNC_status_warn"); - $D('noVNC_status').innerHTML = msg; + document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn"); + document.getElementById('noVNC_status').innerHTML = msg; } function setPassword() { - rfb.sendPassword($D('password_input').value); + rfb.sendPassword(document.getElementById('password_input').value); return false; } function sendCtrlAltDel() { @@ -132,9 +133,9 @@ } function updateState(rfb, state, oldstate, msg) { var s, sb, cad, level; - s = $D('noVNC_status'); - sb = $D('noVNC_status_bar'); - cad = $D('sendCtrlAltDelButton'); + s = document.getElementById('noVNC_status'); + sb = document.getElementById('noVNC_status_bar'); + cad = document.getElementById('sendCtrlAltDelButton'); switch (state) { case 'failed': level = "error"; break; case 'fatal': level = "error"; break; @@ -169,7 +170,7 @@ function xvpInit(ver) { var xvpbuttons; - xvpbuttons = $D('noVNC_xvp_buttons'); + xvpbuttons = document.getElementById('noVNC_xvp_buttons'); if (ver >= 1) { xvpbuttons.style.display = 'inline'; } else { @@ -180,11 +181,11 @@ window.onscriptsload = function () { var host, port, password, path, token; - $D('sendCtrlAltDelButton').style.display = "inline"; - $D('sendCtrlAltDelButton').onclick = sendCtrlAltDel; - $D('xvpShutdownButton').onclick = xvpShutdown; - $D('xvpRebootButton').onclick = xvpReboot; - $D('xvpResetButton').onclick = xvpReset; + document.getElementById('sendCtrlAltDelButton').style.display = "inline"; + document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel; + document.getElementById('xvpShutdownButton').onclick = xvpShutdown; + document.getElementById('xvpRebootButton').onclick = xvpReboot; + document.getElementById('xvpResetButton').onclick = xvpReset; WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn')); document.title = unescape(WebUtil.getConfigVar('title', 'noVNC')); @@ -223,7 +224,7 @@ } try { - rfb = new RFB({'target': $D('noVNC_canvas'), + rfb = new RFB({'target': document.getElementById('noVNC_canvas'), 'encrypt': WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:")), 'repeaterID': WebUtil.getConfigVar('repeaterID', ''), From a62b1b352a976a57354761a229f061b8c462e51c Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Wed, 14 Sep 2016 13:53:13 -0400 Subject: [PATCH 57/65] Clean up unused files in tests There were quite a few old/irrelevant files in `tests/`. This commit removes them. --- tests/arrays.html | 39 ---- tests/arrays.js | 375 -------------------------------------- tests/base64.html | 91 --------- tests/base64.js | 12 -- tests/browser.js | 134 -------------- tests/canvas.html | 148 --------------- tests/cursor.html | 135 -------------- tests/face.png | Bin 2303 -> 0 bytes tests/face.png.js | 1 - tests/keyboard-tests.html | 29 --- tests/stats.js | 53 ------ tests/viewport.css | 43 ----- tests/viewport.html | 203 --------------------- 13 files changed, 1263 deletions(-) delete mode 100644 tests/arrays.html delete mode 100644 tests/arrays.js delete mode 100644 tests/base64.html delete mode 100644 tests/base64.js delete mode 100644 tests/browser.js delete mode 100644 tests/canvas.html delete mode 100644 tests/cursor.html delete mode 100644 tests/face.png delete mode 100644 tests/face.png.js delete mode 100644 tests/keyboard-tests.html delete mode 100644 tests/stats.js delete mode 100644 tests/viewport.css delete mode 100644 tests/viewport.html diff --git a/tests/arrays.html b/tests/arrays.html deleted file mode 100644 index 257df261..00000000 --- a/tests/arrays.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - Javascript Arrays Performance Test - - - - - - - - -

    Javascript Arrays Performance Test

    - Iterations:   - Array Size: *1024  - -   - -

    - Results:
    - -
    - - - - - - diff --git a/tests/arrays.js b/tests/arrays.js deleted file mode 100644 index 69da7fbb..00000000 --- a/tests/arrays.js +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Javascript binary array performance tests - * Copyright (C) 2012 Joel Martin - * Licensed under MPL 2.0 (see LICENSE.txt) - */ - -var ctx, i, j, randlist, - new_normal, new_imageData, new_arrayBuffer, - browser = Browser.browser + " " + - Browser.version + " on " + - Browser.OS, - do_imageData = false, - do_arrayBuffer = false, - conf = { - 'create_cnt' : 2000, - 'read_cnt' : 5000000, - 'write_cnt' : 5000000, - 'iterations' : 0, - 'order_l1' : [browser], - 'order_l2' : ['normal', - 'imageData', - 'arrayBuffer'], - 'order_l3' : ['create', - 'sequentialRead', - 'randomRead', - 'sequentialWrite'] - }, - stats = {}, - testFunc = {}, - iteration, arraySize; - -var newline = "\n"; -if (Util.Engine.trident) { - var newline = "
    \n"; -} -function message(str) { - //console.log(str); - cell = $D('messages'); - cell.innerHTML += str + newline; - cell.scrollTop = cell.scrollHeight; -} - -function vmessage(str) { - if (verbose) { - message(str); - } else { - console.log(str); - } -} - -new_normal = function() { - var arr = [], i; - for (i = 0; i < arraySize; i++) { - arr[i] = 0; - } - return arr; -} - -/* Will be overridden with real function */ -new_imageData = function() { - throw("imageData not supported"); -}; - -new_imageData_createImageData = function() { - var imageData = ctx.createImageData(1024/4, arraySize / 1024); - return imageData.data; -}; - -new_imageData_getImageData = function() { - var imageData = ctx.getImageData(0, 0, 1024/4, arraySize / 1024), - arr = imageData.data; - for (i = 0; i < arraySize; i++) { - arr[i] = 0; - } - return arr; -}; - -new_arrayBuffer = function() { - var arr = new ArrayBuffer(arraySize); - return new Uint8Array(arr); -} - -function init_randlist() { - randlist = []; - for (var i=0; i < arraySize; i++) { - randlist[i] = parseInt(Math.random() * 256, 10); - } -} -function copy_randlist(arr) { - for (var i=0; i < arraySize; i++) { - arr[i] = randlist[i]; - } -} - -function begin() { - var i, j; - conf.iterations = parseInt($D('iterations').value, 10); - arraySize = parseInt($D('arraySize').value, 10) * 1024; - - init_randlist(); - - // TODO: randomize test_list - - stats = {}; - for (i = 0; i < conf.order_l2.length; i++) { - stats[conf.order_l2[i]] = {}; - for (j = 0; j < conf.order_l3.length; j++) { - stats[conf.order_l2[i]][conf.order_l3[j]] = []; - } - } - - $D('startButton').value = "Running"; - $D('startButton').disabled = true; - - message("running " + conf.iterations + " test iterations"); - iteration = 1; - setTimeout(run_next_iteration, 250); -} - -function finish() { - var totalTime, arrayType, testType, times; - message("tests finished"); - - for (j = 0; j < conf.order_l3.length; j++) { - testType = conf.order_l3[j]; - message("Test '" + testType + "'"); - for (i = 0; i < conf.order_l2.length; i++) { - arrayType = conf.order_l2[i]; - message(" Array Type '" + arrayType); - times = stats[arrayType][testType]; - message(" Average : " + times.mean() + "ms" + - " (Total: " + times.sum() + "ms)"); - message(" Min/Max : " + times.min() + "ms/" + - times.max() + "ms"); - message(" StdDev : " + times.stdDev() + "ms"); - } - } - - vmessage("array_chart.py JSON data:"); - chart_data = {'conf' : conf, 'stats' : { } }; - chart_data.stats[browser] = stats; - chart_data.stats['next_browser'] = {}; - vmessage(JSON.stringify(chart_data, null, 2)); - - $D('startButton').disabled = false; - $D('startButton').value = "Run Tests"; -} - -function run_next_iteration() { - var arrayType, testType, deltaTime; - - for (i = 0; i < conf.order_l2.length; i++) { - arrayType = conf.order_l2[i]; - if (arrayType === 'imageData' && (!do_imageData)) { - continue; - } - if (arrayType === 'arrayBuffer' && (!do_arrayBuffer)) { - continue; - } - for (j = 0; j < conf.order_l3.length; j++) { - testType = conf.order_l3[j]; - - deltaTime = testFunc[arrayType + "_" + testType](); - - stats[arrayType][testType].push(deltaTime); - vmessage("test " + (arrayType + "_" + testType) + - " time: " + (deltaTime) + "ms"); - } - } - - message("finished test iteration " + iteration); - if (iteration >= conf.iterations) { - setTimeout(finish, 1); - return; - } - iteration++; - setTimeout(run_next_iteration, 1); -} - -/* - * Test functions - */ - -testFunc["normal_create"] = function() { - var cnt, arrNormal, startTime, endTime; - vmessage("create normal array " + conf.create_cnt + "x, initialized to 0"); - - startTime = (new Date()).getTime(); - for (cnt = 0; cnt < conf.create_cnt; cnt++) { - arrNormal = new_normal(); - } - endTime = (new Date()).getTime(); - - return endTime - startTime; -}; - -testFunc["imageData_create"] = function() { - var cnt, arrImage, startTime, endTime; - vmessage("create imageData array " + conf.create_cnt + "x, initialized to 0"); - - startTime = (new Date()).getTime(); - for (cnt = 0; cnt < conf.create_cnt; cnt++) { - arrImage = new_imageData(); - } - endTime = (new Date()).getTime(); - - if (arrImage[103] !== 0) { - message("Initialization failed, arrImage[103] is: " + arrImage[103]); - throw("Initialization failed, arrImage[103] is: " + arrImage[103]); - } - return endTime - startTime; -}; - -testFunc["arrayBuffer_create"] = function() { - var cnt, arrBuffer, startTime, endTime; - vmessage("create arrayBuffer array " + conf.create_cnt + "x, initialized to 0"); - - startTime = (new Date()).getTime(); - for (cnt = 0; cnt < conf.create_cnt; cnt++) { - arrBuffer = new_arrayBuffer(); - } - endTime = (new Date()).getTime(); - - if (arrBuffer[103] !== 0) { - message("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]); - throw("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]); - } - return endTime - startTime; -}; - -function test_sequentialRead(arr) { - var i, j, cnt, startTime, endTime; - /* Initialize the array */ - copy_randlist(arr); - - startTime = (new Date()).getTime(); - i = 0; - j = 0; - for (cnt = 0; cnt < conf.read_cnt; cnt++) { - j = arr[i]; - i++; - if (i >= arraySize) { - i = 0; - } - } - endTime = (new Date()).getTime(); - - return endTime - startTime; -} - -function test_randomRead(arr) { - var i, cnt, startTime, endTime; - /* Initialize the array */ - copy_randlist(arr); // used as jumplist - - startTime = (new Date()).getTime(); - i = 0; - for (cnt = 0; cnt < conf.read_cnt; cnt++) { - i = (arr[i] + cnt) % arraySize; - } - endTime = (new Date()).getTime(); - - return endTime - startTime; -} - -function test_sequentialWrite(arr) { - var i, cnt, startTime, endTime; - /* Initialize the array */ - copy_randlist(arr); - - startTime = (new Date()).getTime(); - i = 0; - for (cnt = 0; cnt < conf.write_cnt; cnt++) { - arr[i] = (cnt % 256); - i++; - if (i >= arraySize) { - i = 0; - } - } - endTime = (new Date()).getTime(); - - return endTime - startTime; -} - -/* Sequential Read Tests */ -testFunc["normal_sequentialRead"] = function() { - vmessage("read normal array " + conf.read_cnt + "x"); - return test_sequentialRead(new_normal()); -}; - -testFunc["imageData_sequentialRead"] = function() { - vmessage("read imageData array " + conf.read_cnt + "x"); - return test_sequentialRead(new_imageData()); -}; - -testFunc["arrayBuffer_sequentialRead"] = function() { - vmessage("read arrayBuffer array " + conf.read_cnt + "x"); - return test_sequentialRead(new_arrayBuffer()); -}; - - -/* Random Read Tests */ -testFunc["normal_randomRead"] = function() { - vmessage("read normal array " + conf.read_cnt + "x"); - return test_randomRead(new_normal()); -}; - -testFunc["imageData_randomRead"] = function() { - vmessage("read imageData array " + conf.read_cnt + "x"); - return test_randomRead(new_imageData()); -}; - -testFunc["arrayBuffer_randomRead"] = function() { - vmessage("read arrayBuffer array " + conf.read_cnt + "x"); - return test_randomRead(new_arrayBuffer()); -}; - - -/* Sequential Write Tests */ -testFunc["normal_sequentialWrite"] = function() { - vmessage("write normal array " + conf.write_cnt + "x"); - return test_sequentialWrite(new_normal()); -}; - -testFunc["imageData_sequentialWrite"] = function() { - vmessage("write imageData array " + conf.write_cnt + "x"); - return test_sequentialWrite(new_imageData()); -}; - -testFunc["arrayBuffer_sequentialWrite"] = function() { - vmessage("write arrayBuffer array " + conf.write_cnt + "x"); - return test_sequentialWrite(new_arrayBuffer()); -}; - -init = function() { - vmessage(">> init"); - - $D('iterations').value = 10; - $D('arraySize').value = 10; - arraySize = parseInt($D('arraySize').value, 10) * 1024; - - message("Browser: " + browser); - - /* Determine browser binary array support */ - try { - ctx = $D('canvas').getContext('2d'); - new_imageData = new_imageData_createImageData; - new_imageData(); - do_imageData = true; - } catch (exc) { - vmessage("createImageData not supported: " + exc); - try { - ctx = $D('canvas').getContext('2d'); - new_imageData = new_imageData_getImageData; - blah = new_imageData(); - do_imageData = true; - } catch (exc) { - vmessage("getImageData not supported: " + exc); - } - } - if (! do_imageData) { - message("imageData arrays not supported"); - } - - try { - new_arrayBuffer(); - do_arrayBuffer = true; - } catch (exc) { - vmessage("Typed Arrays not supported: " + exc); - } - if (! do_arrayBuffer) { - message("Typed Arrays (ArrayBuffers) not suppoted"); - } - vmessage("<< init"); -} diff --git a/tests/base64.html b/tests/base64.html deleted file mode 100644 index dc45fdd5..00000000 --- a/tests/base64.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - Native Base64 Tests - - - - - -

    Native Base64 Tests

    - -
    - Messages:
    - - -
    - - - diff --git a/tests/base64.js b/tests/base64.js deleted file mode 100644 index 6ade00a3..00000000 --- a/tests/base64.js +++ /dev/null @@ -1,12 +0,0 @@ -// The following results in 'hello [MANGLED]' -// -// Filed as https://github.com/ry/node/issues/issue/402 - -var sys = require("sys"), - buf = new Buffer(1024), len, - str1 = "aGVsbG8g", // 'hello ' - str2 = "d29ybGQ=", // 'world' - -len = buf.write(str1, 0, 'base64'); -len += buf.write(str2, len, 'base64'); -sys.log("decoded result: " + buf.toString('binary', 0, len)); diff --git a/tests/browser.js b/tests/browser.js deleted file mode 100644 index 7cf8279c..00000000 --- a/tests/browser.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - * From: - * http://www.quirksmode.org/js/detect.html - */ - -var Browser = { - init: function () { - this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; - this.version = this.searchVersion(navigator.userAgent) - || this.searchVersion(navigator.appVersion) - || "an unknown version"; - this.majorVersion = this.searchMajorVersion(navigator.userAgent) - || this.searchMajorVersion(navigator.appVersion) - || "an unknown version"; - this.fullVersion = this.searchFullVersion(navigator.userAgent) - || this.searchFullVersion(navigator.appVersion) - || "an unknown version"; - this.OS = this.searchString(this.dataOS) || "an unknown OS"; - }, - searchString: function (data) { - for (var i=0;i - - - Canvas Performance Test - - - - - - - - - Iterations:   - - Width:   - Height:   - -   - -

    - - Canvas (should see three squares and two happy faces):
    - - Canvas not supported. - - -
    - Results:
    - - - - - diff --git a/tests/cursor.html b/tests/cursor.html deleted file mode 100644 index 91e621b3..00000000 --- a/tests/cursor.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - Cursor Change test - - - - - - - - -

    Roll over the buttons to test cursors

    -
    - - - -
    -
    -
    - Debug:
    - -
    -
    - - Canvas not supported. - - - - - diff --git a/tests/face.png b/tests/face.png deleted file mode 100644 index 74c30d82f9736beffef5db259b3e40bb6de4ea2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2303 zcmVDcqz&LP?>7h(O|oIKntKx%ray+TL^a+~)T0!`f>n3cTgh|6ym( z?DyOM%r~>k`rm(L+4(DM%f`8sHkw5f14ij{imA#v*WJ|Q00hwIJr+{BoC65U{pI4W zU}}#{ib*uVz}!qTPqpNmuB>m}lqp;|fAU$yL}^e;Q60pI*t4&1c<9(`|Ju24|G~27 zSu((R_><5N$zql^I-kpZ zxo72fZ~prFbr*Ln>Byv0XOf=!`#-n6^y-54_LC<^95UH_mW+wwC=H*dHC zfI|R*;zVqF>9sA7|5}LTvB!Vsx+y6{6er9w%vO%8vxXRB+;yMd{=%EPb`#NtYp-%s z?wYlidY&JIfvN;VOc`SgrP8T$t8I>iF=`wHvRWC>A@;>qrt&O#}eAoZo%xO_yA}?zTJc5judC%A~baBA-Me zF2r#V1p#RlRD2k9LH8npY{z6l-EsE? zJ*)M-x6P7>0DNonSO2(bMgPIR6|25f_R6QmN2aGrNf?A-XpAvhDJ3hF%3q(|N=QJW z_u;#5z5Rj4=2kbACZn|079&FpaGIK$8|v#zr4qC3d++#8V|^Y(EGZ325m!4aPE3C9 zj=K(ha&*DM#TTvYUcF|0ds|DPPzQin$YwKNxpYlyYrSP@P;68%Q5xC1_e0;CG$w=z zeZMqO9No8n;=O(T)O5J8z46b#-}2SV*VfJxYUio7rST8Frsuldjw8V@1i%;r7+?Wx z_q%&;zU7`rANlE~4QoO2-SaJK*B)rQ8VEl)fRXpq|e(t8a}ZCjpv8Kwdg z0TN(f7QjfIOy?Fe%S4sInz=LoitxsFwRe9T`Xpe1B9KFjgE4@EIS2M1jKXkyYy>cX zIM6o`g~|BnF@Vi}>FNS71{nESOULr^*c<8Y^XGc1DVW+**Senc7*PZh*4hFTNROO6 zas2o(Arg?BHx#p;n?9JD$IWhb?Ac-PSa{b1Ojt@Km6MzDcs>TG+WCTbODIzo9*fB;+kyHn6x>3ss zn^~X)WX~qk097`dv7-bOgOX|yC4ijWPGv|KBLG*4Y3>$k=BM>!r&?7sYNu^b1;msH zoK!PNf$`aBnHf_`KoKY=2#^2?K!Bu@0VpC9gXL8+<)+)_?Gph+)yfqv^NM?6)f2@q zQQyv9Ehj;h+44dD>~aO5h$yP^s?BK?^u4pon9%5mIh}rKI9GpF&D@&*b6eN4Vf@HW zW;KE$qA-(f3MLQ3RA4+9f2PQXslWte0#F1~CB>k`pDLzvd81=vLW?h(939HHY&;|7 zGsQE@lnmp_0JG{rLC30%gZrNIihVP%8AgSuLKJ|i>7QxKE1eiRxPMW1kI@xopO;id zjIw!VNzI&vwW2S7wZO0V?3EN@$R^}`hJft4#4Cx#AecQbX33s>d}?WtU&a>2k+SxsGkmkfP8BAe9nAB#BI-(csv9J=Z>v&Nw6wgXI`s2IqWc zH-qJ2)iG8Fs{k07X);qJPpI(UGI&$P!&dq-sTx21;MM$jTT_{ZsT6lzmpcvs7LLu4 zq>zb_Qp(8xSe1UW>gxM5xh#nfK^m}O6`0)$mIcd!fs9Y8q>}+HhO{mlo!Hq;B5^+b zV29h?l8i7W zHYPGUG&*E_xt(4&J$Crmq5n87zepEWyDqO%T$fvxHA@QoY7mvyQb-}CluAe$hbMID zx9MD}YxPZ;x&=laC3Tc^*_dfE5^xA<<}7A>N$eMo_U}$Y!&`b&*+nkroI5V(+~w6x z0>FZ?{wVNjsjtGMQc^0VlvFAyzhnHrrBd0}&Q2hq_c5KJCYp`m#=aUXamD5ObJf(~_N^7l+Hku681c23KG260j+j4B%vMuhM$(Xxg z&;I|PG0r(STq0xWG!h5^!)YYTVl}{74V}+@QX_)d7PBquiza;mp++)VGluGdoI5eb Z{tpYglKBOBdFlWF002ovPDHLkV1m%%QeprA diff --git a/tests/face.png.js b/tests/face.png.js deleted file mode 100644 index e0b5d6ce..00000000 --- a/tests/face.png.js +++ /dev/null @@ -1 +0,0 @@ -var face64 = 'iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAIAAACRuyQOAAAAA3NCSVQICAjb4U/gAAAAGXRFWHRTb2Z0d2FyZQBnbm9tZS1zY3JlZW5zaG907wO/PgAACJJJREFUSIm1lltsXMUdxr8558zZq9d3OxebJDYhJLhNIAmUWyFKIBUtVaGqSgtUlIJKeahoEahgIZU+VC0oQiVVC60obckDgVIp3KRCQkmhhIhA4oY4wjg2ufmS9drec/bc5vbvw9prJwq85dP/YWfP7Pfb/8w3s8v6339l2fkrbMvGuZQ2mkUTA0bpc4qpyjrX3dTkAATQ5z0WUrqcAwjL/eXirmBqj0yKSTTBwNxMM0+15JuurG/dlClcOH/yWcVEaVBKUR3Eidizr2946Nhr/9q5b//BsudZzDLG5DK4sDt3443XrFm34bkX9x4ZPimkWNBa/+MfrB84+O7rbxz4+JPQD8liljY6n8t9uWfld2/++vp1F3ct6cikU2eSnvr7P7e99OqC9vaTJ0ccMtl8loyJ4igKwzAIK0GglersWv7sM08VCrk4joY/O/rLXz3mTYzmcnnXdZXWcRzHURwEQRCEHUuXdS/vnp4qP/CT2zdvuAKAQwCB4kRse+m1LY//Wojkscd/57opKUQUJ8wyzFaOq7OGGGPcdZ/f/sKbu3YT0YZrr3JT7pq1l3qeH4SBqgRETBljDKXSqXyh/i9PP/W/Q31btz59zVXrUpxb1dYsixUK+c7Fi59/YUdz2yInnbXcLHfTtpu23ZRlu4ZZiRBTp8Z37HjlhW1/evnFZ9/a+VZdLsecFOMpx83ydJanc24q67iuFOr48NC1G6+fKBY7zutIElFNBAC4nN99602XXLzutjvvETqAlcqktVQin0QiLsRxEAUBaRVUfBh1QfcigmzIuw0NTe2LOjNlL07iOArDwA88z0unGWNTk5P1dfkf3XH3BT2r9b23zZKIAHxr81f/uGpF/8G+Fau+VPbKp8ZHpqdKSRiEYWiMMVopJSuVyl+f3UpIQKL34btvvf2BxuZWN5Umo7TWFiNDDHCampob6utLpRKz7Hvv+E5jfR5ELCkNShFXOytOTH7vjrsOfXJ0wcLFF63sXr1mfXtbS6FQB4BZyGYzX7l0TWtrvWVpUGxUMFEa2bv3Q9+bNCaECX2/NFEc3bd/4r19/tR0uLC98c+/3/LVy9fWzhNq56m1pfEPvabnut2OI8EvBMAYAxhgAWz3u3tuvuWeRx/56aYNa0Hy3fc/euiRZx596IZvbF5Dpgw9CdMI0waqaMrEScPgvtdWXH5JzdzC7NElIPQH3GyTk+4ABCgCEpAkMgRGcLb/49WGxqYtTzwNaJDa/tJ7DU1tW558GaYCEwESYGAWwEidTOcWM8tElcGauTP/ivDGd7V3fxv6JGCBIpBDjIMxgIM5B/YfjMJwfGwEMIA40DcQhcn46DGAzX7p6gIwBhj5WUvH8vLYG+nu8+d6qimY2lPXup70GFEEE9baAhRIj5w8cfz4MSESkJw3FLOfnrvSCETqs3xTd2Vyd+1Na/4MmRRt3gBTgfGJKkQhTAQTwgQgv2tpR8X3Vq5YCiiC7lrSXPG9lRe0AmZ2hQxo5jXpspNqEElxPmlOIi5ZThYUgBKYKRgPxgMFMAGM/+D9P2xuLPQ+dBcoAYkHf/bN5sZM74M3gHS1acBUi0gZ4zk8J5NyzdzBGSIJkoANCqsrwgBAg+zN1605Mfw6IIkiUHL9xouODzwBE4ACkKrGBNBkBEgSKSIz39gxRkuRVAduulHLCZtZoARkzybTAFU2m7GjBBSDkmoRJYCc3U5lSBgjAFeJae4Wauan9WSnWlU0aqdtUAXElAicVDNIgfHZaJkZU0pAESgmCJAACUCApJIBKCITg+VVMuWm2+btEwFE1coVLvOKe2HVE8UwUd/OXi0nQZXZ8kH+7HIFoIgoqvKqzWkV9L2zy5jQ6Ig5nX5pOFd/Vc3cmv9zW9eyYfzITmY1giKiMJNtCiYPw1RgPBh/psiHqcAEZAJQBFMlxaDEnyqmc3mjY2NCiy+bHB3Kt2w8I+UzxTPLlAzjygCz6kFBx6qNg/ue84p9M7AZRoWoQhSAqumfacsrnRg6uH9Rd4/RFWafl1RGjLJ5ZknNnIXjh+PQB0BEQkqv9L4sb1t59cMU74GVKxcnhg5sdzN1jQtX5grtqVyj46ZtywIJrUOZeCKYCLxTU+PHkzhZ2vO1XH5MRIfcwvcHP9qRafp5XfN6l3PGGIA5ktJaJEJINXnkvmWrNza0rSBxEFYbnE6veGRq9IPQO54Ep5QItRYAs22Hu1k315QtdDYsuCzf1KHDt0XlbTu3ySuVRo6MNnc/6XLHTbmObc+QotAHIJUSQiSJTKLR4Nh9Pdc+kM44JA+D5RhfBud8ZjeD5WHVMVYHqwAYmGkyUyRPqPDfMnhTxcNW+jKpGj/94NX8eVtTmYWpFHddlzsOABaOzZGkkImQUsrI/1iVfrPq6vszuSyJD0EasGEVmN0KlgXLgYGMT6qkkwEthrQuG53Y2U0icT79YIfb2pup6+Gcp1zOXV4j9VdJxhghpJBSSCmEjL0+XXqsa+0tTYvWQ/aTHJrZW9JEkowwJjYmMjo0OmR8uZ1eNz12+Nih/zgtv0gXVrsur1Jcl1uWNUsK/GoQldZSSCGllEpIGYcndOm36Vyqa/VNmboFRh4ldZR02ZhpMhJwCGnmLGZ8SewXj/bvTkLDW3pT2UUu55w7Lufc5dVNAsCCsf4o8Gqpr8KkUlIqpZRUKim/Y/y/pVLZ1s5V+Zbl3C3Ybp5Iq2RKxhP+xFBxZFAmwi7cmaq/kjuO4zicO9xx5mPOQqrGvYZRWmulldYqGlLBf3X8EfQkSR8A43WMN1nuWid3hZPpcmzbdmzHtmuwarjnkw5FldNIczyljDZKa62NNpoM1QSA1WQx27Jt23Js27It7pzJmLthz/7/nzHOOThcImPoNBIIAMNpJMtiNcBZDZ3PfVIjgtkWsy3riyZ9AaFGMlozhuqCnDsxxv4PC7uS+QV5eeoAAAAASUVORK5CYII='; diff --git a/tests/keyboard-tests.html b/tests/keyboard-tests.html deleted file mode 100644 index a30aa6e0..00000000 --- a/tests/keyboard-tests.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Mocha Tests - - - - -
    - - - - - - - - - - diff --git a/tests/stats.js b/tests/stats.js deleted file mode 100644 index cd3011cb..00000000 --- a/tests/stats.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Define some useful statistical functions on arrays of numbers - */ - -Array.prototype.sum = function() { - var i, sum = 0; - for (i = 0; i < this.length; i++) { - sum += this[i]; - } - return sum; -} - -Array.prototype.max = function() { - return Math.max.apply(null, this); -} - -Array.prototype.min = function() { - return Math.min.apply(null, this); -} - -Array.prototype.mean = function() { - return this.sum() / this.length; -} -Array.prototype.average = Array.prototype.mean; - -Array.prototype.median = function() { - var sorted = this.sort( function(a,b) { return a-b; }), - len = sorted.length; - if (len % 2) { - return sorted[Math.floor(len / 2)]; // Odd - } else { - return (sorted[len/2 - 1] + sorted[len/2]) / 2; // Even - } -} - -Array.prototype.stdDev = function(sample) { - var i, sumSqr = 0, mean = this.mean(), N; - - if (sample) { - // Population correction if this is a sample - N = this.length - 1; - } else { - // Standard deviation of just the array - N = this.length; - } - - for (i = 0; i < this.length; i++) { - sumSqr += Math.pow(this[i] - mean, 2); - } - - return Math.sqrt(sumSqr / N); -} - diff --git a/tests/viewport.css b/tests/viewport.css deleted file mode 100644 index 86f65ff0..00000000 --- a/tests/viewport.css +++ /dev/null @@ -1,43 +0,0 @@ -html,body { - margin: 0px; - padding: 0px; - width: 100%; - height: 100%; -} - -.flex-layout { - width: 100%; - height: 100%; - - display: box; - display: -webkit-box; - display: -moz-box; - display: -ms-box; - - box-orient: vertical; - -webkit-box-orient: vertical; - -moz-box-orient: vertical; - -ms-box-orient: vertical; - - box-align: stretch; - -webkit-box-align: stretch; - -moz-box-align: stretch; - -ms-box-align: stretch; -} -.flex-box { - box-flex: 1; - -webkit-box-flex: 1; - -moz-box-flex: 1; - -ms-box-flex: 1; -} - -.container { - margin: 0px; - padding: 0px; -} - -.canvas { - position: absolute; - border-style: dotted; - border-width: 1px; -} diff --git a/tests/viewport.html b/tests/viewport.html deleted file mode 100644 index 374d8b15..00000000 --- a/tests/viewport.html +++ /dev/null @@ -1,203 +0,0 @@ - - - Viewport Test - - - - - -
    -
    - Canvas: - -
    -
    -
    - - Canvas not supported. - -
    -
    -
    -
    - Results:
    - -
    -
    - - - - - - - - - - - - From 72bdd06ea2d3a2b7f102ac6e068a205433e52a38 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Sat, 3 Sep 2016 13:39:12 -0400 Subject: [PATCH 58/65] Clean up Util This commit removes unused code from Util, and moves the script-loading functionality to WebUtil. --- app/ui.js | 5 +- app/webutil.js | 69 ++++++++++++++++++ core/util.js | 158 ---------------------------------------- tests/input.html | 22 +++--- tests/vnc_perf.html | 2 +- tests/vnc_playback.html | 2 +- vnc.html | 1 + vnc_auto.html | 3 +- 8 files changed, 87 insertions(+), 175 deletions(-) diff --git a/app/ui.js b/app/ui.js index c8251fbe..45aa2ac3 100644 --- a/app/ui.js +++ b/app/ui.js @@ -25,11 +25,10 @@ var UI; /* [begin skip-as-module] */ // Load supporting scripts - Util.load_scripts( + WebUtil.load_scripts( {'core': ["base64.js", "websock.js", "des.js", "keysymdef.js", "xtscancodes.js", "keyboard.js", "input.js", "display.js", - "inflator.js", "rfb.js", "keysym.js"], - '.': ["webutil.js"]}); + "inflator.js", "rfb.js", "keysym.js"]}); window.onscriptsload = function () { UI.load(); }; /* [end skip-as-module] */ diff --git a/app/webutil.js b/app/webutil.js index f5f3077d..7f234dbf 100644 --- a/app/webutil.js +++ b/app/webutil.js @@ -278,4 +278,73 @@ WebUtil.injectParamIfMissing = function (path, param, value) { } }; +// Dynamically load scripts without using document.write() +// Reference: http://unixpapa.com/js/dyna.html +// +// Handles the case where load_scripts is invoked from a script that +// itself is loaded via load_scripts. Once all scripts are loaded the +// window.onscriptsloaded handler is called (if set). +WebUtil.get_include_uri = function (root_dir) { + return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/'; +}; +WebUtil._loading_scripts = []; +WebUtil._pending_scripts = []; +WebUtil.load_scripts = function (files_by_dir) { + "use strict"; + var head = document.getElementsByTagName('head')[0], script, + ls = WebUtil._loading_scripts, ps = WebUtil._pending_scripts; + + var loadFunc = function (e) { + while (ls.length > 0 && (ls[0].readyState === 'loaded' || + ls[0].readyState === 'complete')) { + // For IE, append the script to trigger execution + var s = ls.shift(); + //console.log("loaded script: " + s.src); + head.appendChild(s); + } + if (!this.readyState || + (Util.Engine.presto && this.readyState === 'loaded') || + this.readyState === 'complete') { + if (ps.indexOf(this) >= 0) { + this.onload = this.onreadystatechange = null; + //console.log("completed script: " + this.src); + ps.splice(ps.indexOf(this), 1); + + // Call window.onscriptsload after last script loads + if (ps.length === 0 && window.onscriptsload) { + window.onscriptsload(); + } + } + } + }; + + var root_dirs = Object.keys(files_by_dir); + + for (var d = 0; d < root_dirs.length; d++) { + var root_dir = root_dirs[d]; + var files = files_by_dir[root_dir]; + + for (var f = 0; f < files.length; f++) { + script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = WebUtil.get_include_uri(root_dir) + files[f]; + //console.log("loading script: " + script.src); + script.onload = script.onreadystatechange = loadFunc; + // In-order script execution tricks + if (Util.Engine.trident) { + // For IE wait until readyState is 'loaded' before + // appending it which will trigger execution + // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order + ls.push(script); + } else { + // For webkit and firefox set async=false and append now + // https://developer.mozilla.org/en-US/docs/HTML/Element/script + script.async = false; + head.appendChild(script); + } + ps.push(script); + } + } +}; + /* [module] export default WebUtil; */ diff --git a/core/util.js b/core/util.js index 1b8744ba..3a2d241b 100644 --- a/core/util.js +++ b/core/util.js @@ -41,93 +41,6 @@ addFunc(Array, 'push32', function (num) { num & 0xFF); }); -// IE does not support map (even in IE9) -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Array, 'map', function (fun /*, thisp*/) { - "use strict"; - var len = this.length; - if (typeof fun != "function") { - throw new TypeError(); - } - - var res = new Array(len); - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in this) { - res[i] = fun.call(thisp, this[i], i, this); - } - } - - return res; -}); - -// IE <9 does not support indexOf -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Array, 'indexOf', function (elt /*, from*/) { - "use strict"; - var len = this.length >>> 0; - - var from = Number(arguments[1]) || 0; - from = (from < 0) ? Math.ceil(from) : Math.floor(from); - if (from < 0) { - from += len; - } - - for (; from < len; from++) { - if (from in this && - this[from] === elt) { - return from; - } - } - return -1; -}); - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys -if (!Object.keys) { - Object.keys = (function () { - 'use strict'; - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), - dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ], - dontEnumsLength = dontEnums.length; - - return function (obj) { - if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { - throw new TypeError('Object.keys called on non-object'); - } - - var result = [], prop, i; - - for (prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } - } - - if (hasDontEnumBug) { - for (i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - return result; - }; - })(); -} - // PhantomJS 1.x doesn't support bind, // so leave this in until PhantomJS 2.0 is released //This prototype is provided by the Mozilla foundation and @@ -368,77 +281,6 @@ Util.decodeUTF8 = function (utf8string) { * Cross-browser routines */ - -// Dynamically load scripts without using document.write() -// Reference: http://unixpapa.com/js/dyna.html -// -// Handles the case where load_scripts is invoked from a script that -// itself is loaded via load_scripts. Once all scripts are loaded the -// window.onscriptsloaded handler is called (if set). -Util.get_include_uri = function (root_dir) { - return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/'; -}; -Util._loading_scripts = []; -Util._pending_scripts = []; -Util.load_scripts = function (files_by_dir) { - "use strict"; - var head = document.getElementsByTagName('head')[0], script, - ls = Util._loading_scripts, ps = Util._pending_scripts; - - var loadFunc = function (e) { - while (ls.length > 0 && (ls[0].readyState === 'loaded' || - ls[0].readyState === 'complete')) { - // For IE, append the script to trigger execution - var s = ls.shift(); - //console.log("loaded script: " + s.src); - head.appendChild(s); - } - if (!this.readyState || - (Util.Engine.presto && this.readyState === 'loaded') || - this.readyState === 'complete') { - if (ps.indexOf(this) >= 0) { - this.onload = this.onreadystatechange = null; - //console.log("completed script: " + this.src); - ps.splice(ps.indexOf(this), 1); - - // Call window.onscriptsload after last script loads - if (ps.length === 0 && window.onscriptsload) { - window.onscriptsload(); - } - } - } - }; - - var root_dirs = Object.Keys(files_by_dir); - - for (var d = 0; d < root_dirs.length; d++) { - var root_dir = root_dirs[d]; - var files = files_by_dir[root_dir]; - - for (var f = 0; f < files.length; f++) { - script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = Util.get_include_uri(root_dir) + files[f]; - //console.log("loading script: " + script.src); - script.onload = script.onreadystatechange = loadFunc; - // In-order script execution tricks - if (Util.Engine.trident) { - // For IE wait until readyState is 'loaded' before - // appending it which will trigger execution - // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order - ls.push(script); - } else { - // For webkit and firefox set async=false and append now - // https://developer.mozilla.org/en-US/docs/HTML/Element/script - script.async = false; - head.appendChild(script); - } - ps.push(script); - } - } -}; - - Util.getPosition = function(obj) { "use strict"; // NB(sross): the Mozilla developer reference seems to indicate that diff --git a/tests/input.html b/tests/input.html index ec3aefe6..824a9489 100644 --- a/tests/input.html +++ b/tests/input.html @@ -44,7 +44,7 @@ function message(str) { console.log(str); - cell = $D('messages'); + cell = document.getElementById('messages'); cell.innerHTML += msg_cnt + ": " + str + newline; cell.scrollTop = cell.scrollHeight; msg_cnt++; @@ -94,23 +94,23 @@ for (b = 0; b < blist.length; b++) { if (blist[b] === num) { - $D('button' + blist[b]).style.backgroundColor = "black"; - $D('button' + blist[b]).style.color = "lightgray"; + document.getElementById('button' + blist[b]).style.backgroundColor = "black"; + document.getElementById('button' + blist[b]).style.color = "lightgray"; } else { - $D('button' + blist[b]).style.backgroundColor = ""; - $D('button' + blist[b]).style.color = ""; + document.getElementById('button' + blist[b]).style.backgroundColor = ""; + document.getElementById('button' + blist[b]).style.color = ""; } } } window.onload = function() { - canvas = new Display({'target' : $D('canvas')}); + canvas = new Display({'target' : document.getElementById('canvas')}); keyboard = new Keyboard({'target': document, 'onKeyPress': rfbKeyPress}); Util.addEvent(document, 'keypress', rawKey); Util.addEvent(document, 'keydown', rawKey); Util.addEvent(document, 'keyup', rawKey); - mouse = new Mouse({'target': $D('canvas'), + mouse = new Mouse({'target': document.getElementById('canvas'), 'onMouseButton': mouseButton, 'onMouseMove': mouseMove}); @@ -121,10 +121,10 @@ if ('ontouchstart' in document.documentElement) { message("Touch device detected"); - $D('button-selection').style.display = "inline"; - $D('button1').onclick = function(){ selectButton(1) }; - $D('button2').onclick = function(){ selectButton(2) }; - $D('button4').onclick = function(){ selectButton(4) }; + document.getElementById('button-selection').style.display = "inline"; + document.getElementById('button1').onclick = function(){ selectButton(1) }; + document.getElementById('button2').onclick = function(){ selectButton(2) }; + document.getElementById('button4').onclick = function(){ selectButton(4) }; selectButton(); } diff --git a/tests/vnc_perf.html b/tests/vnc_perf.html index e6eee6eb..021bc4ee 100644 --- a/tests/vnc_perf.html +++ b/tests/vnc_perf.html @@ -49,7 +49,7 @@ msg("Loading " + fname); // Load supporting scripts - Util.load_scripts({ + WebUtil.load_scripts({ 'core': ["base64.js", "websock.js", "des.js", "keysym.js", "keysymdef.js", "xtscancodes.js", "keyboard.js", "input.js", "display.js", "rfb.js", "inflator.js"], diff --git a/tests/vnc_playback.html b/tests/vnc_playback.html index 168663db..611c371d 100644 --- a/tests/vnc_playback.html +++ b/tests/vnc_playback.html @@ -59,7 +59,7 @@ if (fname) { message("Loading " + fname); // Load supporting scripts - Util.load_scripts({ + WebUtil.load_scripts({ 'core': ["base64.js", "websock.js", "des.js", "keysym.js", "keysymdef.js", "xtscancodes.js", "keyboard.js", "input.js", "display.js", "rfb.js", "inflator.js"], diff --git a/vnc.html b/vnc.html index bfc12017..b33b704e 100644 --- a/vnc.html +++ b/vnc.html @@ -220,6 +220,7 @@
    + diff --git a/vnc_auto.html b/vnc_auto.html index 6fa3f253..2bb9013b 100644 --- a/vnc_auto.html +++ b/vnc_auto.html @@ -43,6 +43,7 @@ src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'> --> + @@ -77,7 +78,7 @@ "use strict"; // Load supporting scripts - Util.load_scripts({ + WebUtil.load_scripts({ 'core': ["base64.js", "websock.js", "des.js", "keysymdef.js", "xtscancodes.js", "keyboard.js", "input.js", "display.js", "inflator.js", "rfb.js", "keysym.js"], From 3949a095342153865682d716a7289c5de3e611c2 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Sat, 3 Sep 2016 13:49:55 -0400 Subject: [PATCH 59/65] Don't modify Array prototype This commit removes our modification of the Array prototype. It wasn't actually used much in the main code, anyway, and it's a bad practice to modify built-in prototypes. --- core/util.js | 23 ------- tests/test.rfb.js | 153 +++++++++++++++++++++++++-------------------- tests/test.util.js | 44 ------------- 3 files changed, 86 insertions(+), 134 deletions(-) diff --git a/core/util.js b/core/util.js index 3a2d241b..cbc74dc4 100644 --- a/core/util.js +++ b/core/util.js @@ -12,35 +12,12 @@ var Util = {}; -/* - * Make arrays quack - */ - var addFunc = function (cl, name, func) { if (!cl.prototype[name]) { Object.defineProperty(cl.prototype, name, { enumerable: false, value: func }); } }; -addFunc(Array, 'push8', function (num) { - "use strict"; - this.push(num & 0xFF); -}); - -addFunc(Array, 'push16', function (num) { - "use strict"; - this.push((num >> 8) & 0xFF, - num & 0xFF); -}); - -addFunc(Array, 'push32', function (num) { - "use strict"; - this.push((num >> 24) & 0xFF, - (num >> 16) & 0xFF, - (num >> 8) & 0xFF, - num & 0xFF); -}); - // PhantomJS 1.x doesn't support bind, // so leave this in until PhantomJS 2.0 is released //This prototype is provided by the Mozilla foundation and diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 06eeebe3..86d63787 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -13,6 +13,25 @@ function make_rfb (extra_opts) { return new RFB(extra_opts); } +var push8 = function (arr, num) { + "use strict"; + arr.push(num & 0xFF); +}; + +var push16 = function (arr, num) { + "use strict"; + arr.push((num >> 8) & 0xFF, + num & 0xFF); +}; + +var push32 = function (arr, num) { + "use strict"; + arr.push((num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + num & 0xFF); +}; + describe('Remote Frame Buffer Protocol Client', function() { "use strict"; before(FakeWebSocket.replace); @@ -232,17 +251,17 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should send the request with the given width and height', function () { var expected = [251]; - expected.push8(0); // padding - expected.push16(1); // width - expected.push16(2); // height - expected.push8(1); // number-of-screens - expected.push8(0); // padding before screen array - expected.push32(0); // id - expected.push16(0); // x-position - expected.push16(0); // y-position - expected.push16(1); // width - expected.push16(2); // height - expected.push32(0); // flags + push8(expected, 0); // padding + push16(expected, 1); // width + push16(expected, 2); // height + push8(expected, 1); // number-of-screens + push8(expected, 0); // padding before screen array + push32(expected, 0); // id + push16(expected, 0); // x-position + push16(expected, 0); // y-position + push16(expected, 1); // width + push16(expected, 2); // height + push32(expected, 0); // flags client.requestDesktopSize(1, 2); expect(client._sock).to.have.sent(new Uint8Array(expected)); @@ -662,7 +681,7 @@ describe('Remote Frame Buffer Protocol Client', function() { var err_msg = "Whoopsies"; var data = [0, 0, 0, 0]; var err_len = err_msg.length; - data.push32(err_len); + push32(data, err_len); for (var i = 0; i < err_len; i++) { data.push(err_msg.charCodeAt(i)); } @@ -796,10 +815,10 @@ describe('Remote Frame Buffer Protocol Client', function() { function send_num_str_pairs(pairs, client) { var pairs_len = pairs.length; var data = []; - data.push32(pairs_len); + push32(data, pairs_len); for (var i = 0; i < pairs_len; i++) { - data.push32(pairs[i][0]); + push32(data, pairs[i][0]); var j; for (j = 0; j < 4; j++) { data.push(pairs[i][1].charCodeAt(j)); @@ -948,30 +967,30 @@ describe('Remote Frame Buffer Protocol Client', function() { } var data = []; - data.push16(full_opts.width); - data.push16(full_opts.height); + push16(data, full_opts.width); + push16(data, full_opts.height); data.push(full_opts.bpp); data.push(full_opts.depth); data.push(full_opts.big_endian); data.push(full_opts.true_color); - data.push16(full_opts.red_max); - data.push16(full_opts.green_max); - data.push16(full_opts.blue_max); - data.push8(full_opts.red_shift); - data.push8(full_opts.green_shift); - data.push8(full_opts.blue_shift); + push16(data, full_opts.red_max); + push16(data, full_opts.green_max); + push16(data, full_opts.blue_max); + push8(data, full_opts.red_shift); + push8(data, full_opts.green_shift); + push8(data, full_opts.blue_shift); // padding - data.push8(0); - data.push8(0); - data.push8(0); + push8(data, 0); + push8(data, 0); + push8(data, 0); client._sock._websocket._receive_data(new Uint8Array(data)); var name_data = []; - name_data.push32(full_opts.name.length); + push32(name_data, full_opts.name.length); for (var i = 0; i < full_opts.name.length; i++) { name_data.push(full_opts.name.charCodeAt(i)); } @@ -1003,10 +1022,10 @@ describe('Remote Frame Buffer Protocol Client', function() { send_server_init({}, client); var tight_data = []; - tight_data.push16(1); - tight_data.push16(2); - tight_data.push16(3); - tight_data.push16(0); + push16(tight_data, 1); + push16(tight_data, 2); + push16(tight_data, 3); + push16(tight_data, 0); for (var i = 0; i < 16 + 32 + 48; i++) { tight_data.push(i); } @@ -1136,16 +1155,16 @@ describe('Remote Frame Buffer Protocol Client', function() { // header data.push(0); // msg type data.push(0); // padding - data.push16(rect_cnt || rect_data.length); + push16(data, rect_cnt || rect_data.length); } for (var i = 0; i < rect_data.length; i++) { if (rect_info[i]) { - data.push16(rect_info[i].x); - data.push16(rect_info[i].y); - data.push16(rect_info[i].width); - data.push16(rect_info[i].height); - data.push32(rect_info[i].encoding); + push16(data, rect_info[i].x); + push16(data, rect_info[i].y); + push16(data, rect_info[i].width); + push16(data, rect_info[i].height); + push32(data, rect_info[i].encoding); } data = data.concat(rect_data[i]); } @@ -1339,24 +1358,24 @@ describe('Remote Frame Buffer Protocol Client', function() { it('should handle the RRE encoding', function () { var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x02 }]; var rect = []; - rect.push32(2); // 2 subrects - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 2); // 2 subrects + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color rect.push(0xff); // becomes ff0000ff --> #0000FF color rect.push(0x00); rect.push(0x00); rect.push(0xff); - rect.push16(0); // x: 0 - rect.push16(0); // y: 0 - rect.push16(2); // width: 2 - rect.push16(2); // height: 2 + push16(rect, 0); // x: 0 + push16(rect, 0); // y: 0 + push16(rect, 2); // width: 2 + push16(rect, 2); // height: 2 rect.push(0xff); // becomes ff0000ff --> #0000FF color rect.push(0x00); rect.push(0x00); rect.push(0xff); - rect.push16(2); // x: 2 - rect.push16(2); // y: 2 - rect.push16(2); // width: 2 - rect.push16(2); // height: 2 + push16(rect, 2); // x: 2 + push16(rect, 2); // y: 2 + push16(rect, 2); // width: 2 + push16(rect, 2); // height: 2 send_fbu_msg(info, [rect], client); expect(client._display).to.have.displayed(target_data_check); @@ -1384,7 +1403,7 @@ describe('Remote Frame Buffer Protocol Client', function() { var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }]; var rect = []; rect.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color rect.push(0xff); // becomes ff0000ff --> #0000FF fg color rect.push(0x00); rect.push(0x00); @@ -1416,11 +1435,11 @@ describe('Remote Frame Buffer Protocol Client', function() { var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }]; var rect = []; rect.push(0x02); - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color send_fbu_msg(info, [rect], client); var expected = []; - for (var i = 0; i < 16; i++) { expected.push32(0xff00ff); } + for (var i = 0; i < 16; i++) { push32(expected, 0xff00ff); } expect(client._display).to.have.displayed(new Uint8Array(expected)); }); @@ -1436,7 +1455,7 @@ describe('Remote Frame Buffer Protocol Client', function() { // send a bg frame rect.push(0x02); - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color // send an empty frame rect.push(0x00); @@ -1445,8 +1464,8 @@ describe('Remote Frame Buffer Protocol Client', function() { var expected = []; var i; - for (i = 0; i < 16; i++) { expected.push32(0xff00ff); } // rect 1: solid - for (i = 0; i < 16; i++) { expected.push32(0xff00ff); } // rect 2: same bkground color + for (i = 0; i < 16; i++) { push32(expected, 0xff00ff); } // rect 1: solid + for (i = 0; i < 16; i++) { push32(expected, 0xff00ff); } // rect 2: same bkground color expect(client._display).to.have.displayed(new Uint8Array(expected)); }); @@ -1454,7 +1473,7 @@ describe('Remote Frame Buffer Protocol Client', function() { var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }]; var rect = []; rect.push(0x02 | 0x08 | 0x10); // bg spec, anysubrects, colouredsubrects - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color rect.push(2); // 2 subrects rect.push(0xff); // becomes ff0000ff --> #0000FF fg color rect.push(0x00); @@ -1480,7 +1499,7 @@ describe('Remote Frame Buffer Protocol Client', function() { var info = [{ x: 0, y: 0, width: 4, height: 17, encoding: 0x05}]; var rect = []; rect.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects - rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color + push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color rect.push(0xff); // becomes ff0000ff --> #0000FF fg color rect.push(0x00); rect.push(0x00); @@ -1561,16 +1580,16 @@ describe('Remote Frame Buffer Protocol Client', function() { function make_screen_data (nr_of_screens) { var data = []; - data.push8(nr_of_screens); // number-of-screens - data.push8(0); // padding - data.push16(0); // padding + push8(data, nr_of_screens); // number-of-screens + push8(data, 0); // padding + push16(data, 0); // padding for (var i=0; i Date: Sat, 3 Sep 2016 13:53:47 -0400 Subject: [PATCH 60/65] Switch to PhantomJS 2.x for testing This commit switches over to use PhantomJS 2.x, bringing in a whole host of improvements (including `Function#bind`, so we can remove the `Function#bind` shim in core/util.js). --- core/util.js | 35 -------------------------------- package.json | 5 ++--- tests/run_from_console.casper.js | 2 +- tests/run_from_console.js | 2 +- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/core/util.js b/core/util.js index cbc74dc4..f2e12ae1 100644 --- a/core/util.js +++ b/core/util.js @@ -11,41 +11,6 @@ var Util = {}; - -var addFunc = function (cl, name, func) { - if (!cl.prototype[name]) { - Object.defineProperty(cl.prototype, name, { enumerable: false, value: func }); - } -}; - -// PhantomJS 1.x doesn't support bind, -// so leave this in until PhantomJS 2.0 is released -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Function, 'bind', function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new TypeError("Function.prototype.bind - " + - "what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; -}); - // // requestAnimationFrame shim with setTimeout fallback // diff --git a/package.json b/package.json index 26ee6ff4..c169e922 100644 --- a/package.json +++ b/package.json @@ -41,14 +41,13 @@ "karma-chai": "^0.1.0", "karma-mocha": "^0.1.10", "karma-mocha-reporter": "^1.0.0", - "karma-phantomjs-launcher": "^0.1.4", + "karma-phantomjs-launcher": "^1.0.0", "karma-sauce-launcher": "^0.2.10", "karma-sinon": "^1.0.4", "karma-sinon-chai-latest": "^0.1.0", "mocha": "^2.1.0", "open": "^0.0.5", - "phantom": "^0.7.2", - "phantomjs": "^1.9.15", + "phantomjs-prebuilt": "^2.1.4", "sinon": "^1.12.2", "sinon-chai": "^2.7.0", "spooky": "^0.2.5", diff --git a/tests/run_from_console.casper.js b/tests/run_from_console.casper.js index 6a738a3e..ba8546b9 100644 --- a/tests/run_from_console.casper.js +++ b/tests/run_from_console.casper.js @@ -1,7 +1,7 @@ var Spooky = require('spooky'); var path = require('path'); -var phantom_path = require('phantomjs').path; +var phantom_path = require('phantomjs-prebuilt').path; var casper_path = path.resolve(__dirname, '../node_modules/casperjs/bin/casperjs'); process.env.PHANTOMJS_EXECUTABLE = phantom_path; var casper_opts = { diff --git a/tests/run_from_console.js b/tests/run_from_console.js index d7d13da2..1a2b800a 100755 --- a/tests/run_from_console.js +++ b/tests/run_from_console.js @@ -92,7 +92,7 @@ if (program.autoInject) { var template = { header: "\n\n\n\n\n
    ", script_tag: function(p) { return ""; }, - footer: "\n\n" + footer: "\n\n" }; template.header += "\n" + template.script_tag(get_path('node_modules/chai/chai.js')); From e4fef7be2d21423bae5df5a8bd4ebe3b2088a9aa Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Sat, 3 Sep 2016 13:58:32 -0400 Subject: [PATCH 61/65] Util shouldn't modify window object This commits prevents Util from modifying the window object. - `window.requestAnimFrame` was removed (no polyfill is needed anymore) - the potential redefinition of `console.log` and friends was removed (all supported browsers have `console.xyz` defined anyway) --- core/display.js | 2 +- core/util.js | 63 ++++++++++++------------------------------- tests/test.display.js | 6 ++--- tests/test.util.js | 12 ++++++--- 4 files changed, 30 insertions(+), 53 deletions(-) diff --git a/core/display.js b/core/display.js index 79e1e4f6..e6239f48 100644 --- a/core/display.js +++ b/core/display.js @@ -778,7 +778,7 @@ } if (this._renderQ.length > 0) { - requestAnimFrame(this._scan_renderQ.bind(this)); + requestAnimationFrame(this._scan_renderQ.bind(this)); } }, }; diff --git a/core/util.js b/core/util.js index f2e12ae1..eda4616a 100644 --- a/core/util.js +++ b/core/util.js @@ -11,22 +11,6 @@ var Util = {}; -// -// requestAnimationFrame shim with setTimeout fallback -// - -window.requestAnimFrame = (function () { - "use strict"; - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function (callback) { - window.setTimeout(callback, 1000 / 60); - }; -})(); - /* * ------------------------------------------------------ * Namespaced in Util @@ -45,39 +29,26 @@ Util.init_logging = function (level) { } else { Util._log_level = level; } - if (typeof window.console === "undefined") { - if (typeof window.opera !== "undefined") { - window.console = { - 'log' : window.opera.postError, - 'warn' : window.opera.postError, - 'error': window.opera.postError - }; - } else { - window.console = { - 'log' : function (m) {}, - 'warn' : function (m) {}, - 'error': function (m) {} - }; - } - } Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; - /* jshint -W086 */ - switch (level) { - case 'debug': - Util.Debug = function (msg) { console.log(msg); }; - case 'info': - Util.Info = function (msg) { console.log(msg); }; - case 'warn': - Util.Warn = function (msg) { console.warn(msg); }; - case 'error': - Util.Error = function (msg) { console.error(msg); }; - case 'none': - break; - default: - throw new Error("invalid logging type '" + level + "'"); + if (typeof window.console !== "undefined") { + /* jshint -W086 */ + switch (level) { + case 'debug': + Util.Debug = function (msg) { console.log(msg); }; + case 'info': + Util.Info = function (msg) { console.info(msg); }; + case 'warn': + Util.Warn = function (msg) { console.warn(msg); }; + case 'error': + Util.Error = function (msg) { console.error(msg); }; + case 'none': + break; + default: + throw new Error("invalid logging type '" + level + "'"); + } + /* jshint +W086 */ } - /* jshint +W086 */ }; Util.get_logging = function () { return Util._log_level; diff --git a/tests/test.display.js b/tests/test.display.js index 32a92e22..7c7c693b 100644 --- a/tests/test.display.js +++ b/tests/test.display.js @@ -384,15 +384,15 @@ describe('Display/Canvas Helper', function () { display = new Display({ target: document.createElement('canvas'), prefer_js: false }); display.resize(4, 4); sinon.spy(display, '_scan_renderQ'); - this.old_requestAnimFrame = window.requestAnimFrame; - window.requestAnimFrame = function (cb) { + this.old_requestAnimationFrame = window.requestAnimationFrame; + window.requestAnimationFrame = function (cb) { this.next_frame_cb = cb; }.bind(this); this.next_frame = function () { this.next_frame_cb(); }; }); afterEach(function () { - window.requestAnimFrame = this.old_requestAnimFrame; + window.requestAnimationFrame = this.old_requestAnimationFrame; }); it('should try to process an item when it is pushed on, if nothing else is on the queue', function () { diff --git a/tests/test.util.js b/tests/test.util.js index c4ac403b..c903c745 100644 --- a/tests/test.util.js +++ b/tests/test.util.js @@ -12,12 +12,14 @@ describe('Utils', function() { sinon.spy(console, 'log'); sinon.spy(console, 'warn'); sinon.spy(console, 'error'); + sinon.spy(console, 'info'); }); afterEach(function () { console.log.restore(); console.warn.restore(); console.error.restore(); + console.info.restore(); }); it('should use noop for levels lower than the min level', function () { @@ -27,12 +29,16 @@ describe('Utils', function() { expect(console.log).to.not.have.been.called; }); - it('should use console.log for Debug and Info', function () { + it('should use console.log for Debug', function () { Util.init_logging('debug'); Util.Debug('dbg'); - Util.Info('inf'); expect(console.log).to.have.been.calledWith('dbg'); - expect(console.log).to.have.been.calledWith('inf'); + }); + + it('should use console.info for Info', function () { + Util.init_logging('debug'); + Util.Info('inf'); + expect(console.info).to.have.been.calledWith('inf'); }); it('should use console.warn for Warn', function () { From b4ef49ea36883b0b90bb8c8d9ef97c836f731fd1 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Sat, 3 Sep 2016 14:06:42 -0400 Subject: [PATCH 62/65] Remove unecessary event-related code from Util The event-related wrapper functions in Util existed mainly for backwards-compat. However, all currently supported browsers support the standard functions, so these wrappers are no longer needed. --- app/ui.js | 14 +++++------ core/input.js | 60 ++++++++++++++++++++++++------------------------ core/util.js | 36 ++--------------------------- tests/input.html | 6 ++--- 4 files changed, 42 insertions(+), 74 deletions(-) diff --git a/app/ui.js b/app/ui.js index 45aa2ac3..cb0cc9e9 100644 --- a/app/ui.js +++ b/app/ui.js @@ -142,7 +142,7 @@ var UI; UI.setViewClip(); UI.setBarPosition(); - Util.addEvent(window, 'resize', function () { + window.addEventListener('resize', function () { UI.applyResizeMode(); UI.setViewClip(); UI.updateViewDrag(); @@ -160,17 +160,17 @@ var UI; document.documentElement.webkitRequestFullscreen || document.body.msRequestFullscreen)) { document.getElementById('noVNC_fullscreen_button').style.display = "inline"; - Util.addEvent(window, 'fullscreenchange', UI.updateFullscreenButton); - Util.addEvent(window, 'mozfullscreenchange', UI.updateFullscreenButton); - Util.addEvent(window, 'webkitfullscreenchange', UI.updateFullscreenButton); - Util.addEvent(window, 'msfullscreenchange', UI.updateFullscreenButton); + window.addEventListener('fullscreenchange', UI.updateFullscreenButton); + window.addEventListener('mozfullscreenchange', UI.updateFullscreenButton); + window.addEventListener('webkitfullscreenchange', UI.updateFullscreenButton); + window.addEventListener('msfullscreenchange', UI.updateFullscreenButton); } - Util.addEvent(window, 'load', UI.keyboardinputReset); + window.addEventListener('load', UI.keyboardinputReset); // While connected we want to display a confirmation dialogue // if the user tries to leave the page - Util.addEvent(window, 'beforeunload', function (e) { + window.addEventListener('beforeunload', function (e) { if (UI.rfb && UI.rfb_state === 'normal') { var msg = "You are currently connected."; e.returnValue = msg; diff --git a/core/input.js b/core/input.js index ec5382fd..e1fff1c0 100644 --- a/core/input.js +++ b/core/input.js @@ -122,12 +122,12 @@ //Util.Debug(">> Keyboard.grab"); var c = this._target; - Util.addEvent(c, 'keydown', this._eventHandlers.keydown); - Util.addEvent(c, 'keyup', this._eventHandlers.keyup); - Util.addEvent(c, 'keypress', this._eventHandlers.keypress); + c.addEventListener('keydown', this._eventHandlers.keydown); + c.addEventListener('keyup', this._eventHandlers.keyup); + c.addEventListener('keypress', this._eventHandlers.keypress); // Release (key up) if window loses focus - Util.addEvent(window, 'blur', this._eventHandlers.blur); + window.addEventListener('blur', this._eventHandlers.blur); //Util.Debug("<< Keyboard.grab"); }, @@ -136,10 +136,10 @@ //Util.Debug(">> Keyboard.ungrab"); var c = this._target; - Util.removeEvent(c, 'keydown', this._eventHandlers.keydown); - Util.removeEvent(c, 'keyup', this._eventHandlers.keyup); - Util.removeEvent(c, 'keypress', this._eventHandlers.keypress); - Util.removeEvent(window, 'blur', this._eventHandlers.blur); + c.removeEventListener('keydown', this._eventHandlers.keydown); + c.removeEventListener('keyup', this._eventHandlers.keyup); + c.removeEventListener('keypress', this._eventHandlers.keypress); + window.removeEventListener('blur', this._eventHandlers.blur); // Release (key up) all keys that are in a down state this._allKeysUp(); @@ -347,44 +347,44 @@ var c = this._target; if ('ontouchstart' in document.documentElement) { - Util.addEvent(c, 'touchstart', this._eventHandlers.mousedown); - Util.addEvent(window, 'touchend', this._eventHandlers.mouseup); - Util.addEvent(c, 'touchend', this._eventHandlers.mouseup); - Util.addEvent(c, 'touchmove', this._eventHandlers.mousemove); + c.addEventListener('touchstart', this._eventHandlers.mousedown); + window.addEventListener('touchend', this._eventHandlers.mouseup); + c.addEventListener('touchend', this._eventHandlers.mouseup); + c.addEventListener('touchmove', this._eventHandlers.mousemove); } else { - Util.addEvent(c, 'mousedown', this._eventHandlers.mousedown); - Util.addEvent(window, 'mouseup', this._eventHandlers.mouseup); - Util.addEvent(c, 'mouseup', this._eventHandlers.mouseup); - Util.addEvent(c, 'mousemove', this._eventHandlers.mousemove); - Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + c.addEventListener('mousedown', this._eventHandlers.mousedown); + window.addEventListener('mouseup', this._eventHandlers.mouseup); + c.addEventListener('mouseup', this._eventHandlers.mouseup); + c.addEventListener('mousemove', this._eventHandlers.mousemove); + c.addEventListener((Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', this._eventHandlers.mousewheel); } /* Work around right and middle click browser behaviors */ - Util.addEvent(document, 'click', this._eventHandlers.mousedisable); - Util.addEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable); + document.addEventListener('click', this._eventHandlers.mousedisable); + document.body.addEventListener('contextmenu', this._eventHandlers.mousedisable); }, ungrab: function () { var c = this._target; if ('ontouchstart' in document.documentElement) { - Util.removeEvent(c, 'touchstart', this._eventHandlers.mousedown); - Util.removeEvent(window, 'touchend', this._eventHandlers.mouseup); - Util.removeEvent(c, 'touchend', this._eventHandlers.mouseup); - Util.removeEvent(c, 'touchmove', this._eventHandlers.mousemove); + c.removeEventListener('touchstart', this._eventHandlers.mousedown); + window.removeEventListener('touchend', this._eventHandlers.mouseup); + c.removeEventListener('touchend', this._eventHandlers.mouseup); + c.removeEventListener('touchmove', this._eventHandlers.mousemove); } else { - Util.removeEvent(c, 'mousedown', this._eventHandlers.mousedown); - Util.removeEvent(window, 'mouseup', this._eventHandlers.mouseup); - Util.removeEvent(c, 'mouseup', this._eventHandlers.mouseup); - Util.removeEvent(c, 'mousemove', this._eventHandlers.mousemove); - Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + c.removeEventListener('mousedown', this._eventHandlers.mousedown); + window.removeEventListener('mouseup', this._eventHandlers.mouseup); + c.removeEventListener('mouseup', this._eventHandlers.mouseup); + c.removeEventListener('mousemove', this._eventHandlers.mousemove); + c.removeEventListener((Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', this._eventHandlers.mousewheel); } /* Work around right and middle click browser behaviors */ - Util.removeEvent(document, 'click', this._eventHandlers.mousedisable); - Util.removeEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable); + document.removeEventListener('click', this._eventHandlers.mousedisable); + document.body.removeEventListener('contextmenu', this._eventHandlers.mousedisable); } }; diff --git a/core/util.js b/core/util.js index eda4616a..d6a01932 100644 --- a/core/util.js +++ b/core/util.js @@ -232,41 +232,9 @@ Util.getEventPosition = function (e, obj, scale) { return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale}; }; - -// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events -Util.addEvent = function (obj, evType, fn) { - "use strict"; - if (obj.attachEvent) { - var r = obj.attachEvent("on" + evType, fn); - return r; - } else if (obj.addEventListener) { - obj.addEventListener(evType, fn, false); - return true; - } else { - throw new Error("Handler could not be attached"); - } -}; - -Util.removeEvent = function (obj, evType, fn) { - "use strict"; - if (obj.detachEvent) { - var r = obj.detachEvent("on" + evType, fn); - return r; - } else if (obj.removeEventListener) { - obj.removeEventListener(evType, fn, false); - return true; - } else { - throw new Error("Handler could not be removed"); - } -}; - Util.stopEvent = function (e) { - "use strict"; - if (e.stopPropagation) { e.stopPropagation(); } - else { e.cancelBubble = true; } - - if (e.preventDefault) { e.preventDefault(); } - else { e.returnValue = false; } + e.stopPropagation(); + e.preventDefault(); }; Util._cursor_uris_supported = null; diff --git a/tests/input.html b/tests/input.html index 824a9489..a513645c 100644 --- a/tests/input.html +++ b/tests/input.html @@ -107,9 +107,9 @@ canvas = new Display({'target' : document.getElementById('canvas')}); keyboard = new Keyboard({'target': document, 'onKeyPress': rfbKeyPress}); - Util.addEvent(document, 'keypress', rawKey); - Util.addEvent(document, 'keydown', rawKey); - Util.addEvent(document, 'keyup', rawKey); + document.addEventListener('keypress', rawKey); + document.addEventListener('keydown', rawKey); + document.addEventListener('keyup', rawKey); mouse = new Mouse({'target': document.getElementById('canvas'), 'onMouseButton': mouseButton, 'onMouseMove': mouseMove}); From bd5340c7ee92c28ef01519c1ef9eb456f93a892d Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Wed, 14 Sep 2016 13:45:08 -0400 Subject: [PATCH 63/65] Move input-related files into core/input This commit moves all the input-related files from `core/` to `core/input/`, and renames a couple as relevant (input.js --> input/devices.js, keyboard.js --> input/util.js). --- LICENSE.txt | 6 +++--- app/ui.js | 8 ++++---- core/{input.js => input/devices.js} | 4 ++-- core/{ => input}/keysym.js | 0 core/{ => input}/keysymdef.js | 0 core/{keyboard.js => input/util.js} | 0 core/{ => input}/xtscancodes.js | 0 core/rfb.js | 6 +++--- karma.conf.js | 10 +++++----- tests/input.html | 10 +++++----- tests/test.helper.js | 2 +- tests/test.keyboard.js | 2 +- tests/test.rfb.js | 2 +- tests/vnc_perf.html | 6 +++--- tests/vnc_playback.html | 6 +++--- utils/use_require.js | 3 ++- vnc_auto.html | 6 +++--- 17 files changed, 36 insertions(+), 35 deletions(-) rename core/{input.js => input/devices.js} (99%) rename core/{ => input}/keysym.js (100%) rename core/{ => input}/keysymdef.js (100%) rename core/{keyboard.js => input/util.js} (100%) rename core/{ => input}/xtscancodes.js (100%) diff --git a/LICENSE.txt b/LICENSE.txt index 41b45bb9..7b5de592 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -8,8 +8,8 @@ is not limited to): core/base64.js core/des.js core/display.js - core/input.js - core/keysym.js + core/input/devices.js + core/input/keysym.js core/logo.js core/playback.js core/rfb.js @@ -17,7 +17,7 @@ is not limited to): core/util.js core/websock.js app/webutil.js - core/xtscancodes.js + core/input/xtscancodes.js The HTML, CSS, font and images files that included with the noVNC source distibution (or repository) are not considered part of the diff --git a/app/ui.js b/app/ui.js index cb0cc9e9..78d397d7 100644 --- a/app/ui.js +++ b/app/ui.js @@ -12,7 +12,7 @@ /* [module] * import Util from "../core/util"; - * import KeyTable from "../core/keysym"; + * import KeyTable from "../core/input/keysym"; * import RFB from "../core/rfb"; * import Display from "../core/display"; * import WebUtil from "./webutil"; @@ -26,9 +26,9 @@ var UI; /* [begin skip-as-module] */ // Load supporting scripts WebUtil.load_scripts( - {'core': ["base64.js", "websock.js", "des.js", "keysymdef.js", - "xtscancodes.js", "keyboard.js", "input.js", "display.js", - "inflator.js", "rfb.js", "keysym.js"]}); + {'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js", + "input/xtscancodes.js", "input/util.js", "input/devices.js", + "display.js", "inflator.js", "rfb.js", "input/keysym.js"]}); window.onscriptsload = function () { UI.load(); }; /* [end skip-as-module] */ diff --git a/core/input.js b/core/input/devices.js similarity index 99% rename from core/input.js rename to core/input/devices.js index e1fff1c0..d283fc4e 100644 --- a/core/input.js +++ b/core/input/devices.js @@ -9,8 +9,8 @@ /*global window, Util */ /* [module] - * import Util from "./util"; - * import KeyboardUtil from "./keyboard"; + * import Util from "../util"; + * import KeyboardUtil from "./util"; */ /* [module] export */ var Keyboard; diff --git a/core/keysym.js b/core/input/keysym.js similarity index 100% rename from core/keysym.js rename to core/input/keysym.js diff --git a/core/keysymdef.js b/core/input/keysymdef.js similarity index 100% rename from core/keysymdef.js rename to core/input/keysymdef.js diff --git a/core/keyboard.js b/core/input/util.js similarity index 100% rename from core/keyboard.js rename to core/input/util.js diff --git a/core/xtscancodes.js b/core/input/xtscancodes.js similarity index 100% rename from core/xtscancodes.js rename to core/input/xtscancodes.js diff --git a/core/rfb.js b/core/rfb.js index 0ae96bd4..135d3a75 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -13,12 +13,12 @@ /* [module] * import Util from "./util"; * import Display from "./display"; - * import { Keyboard, Mouse } from "./input" + * import { Keyboard, Mouse } from "./input/devices" * import Websock from "./websock" * import Base64 from "./base64"; * import DES from "./des"; - * import KeyTable from "./keysym"; - * import XtScancode from "./xtscancodes"; + * import KeyTable from "./input/keysym"; + * import XtScancode from "./input/xtscancodes"; * import Inflator from "./inflator.mod"; */ /*jslint white: false, browser: true */ diff --git a/karma.conf.js b/karma.conf.js index f14dc429..5f3c20b9 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -113,11 +113,11 @@ module.exports = function(config) { 'core/util.js', // load first to avoid issues, since methods are called immediately //'../core/*.js', 'core/base64.js', - 'core/keysym.js', - 'core/keysymdef.js', - 'core/xtscancodes.js', - 'core/keyboard.js', - 'core/input.js', + 'core/input/keysym.js', + 'core/input/keysymdef.js', + 'core/input/xtscancodes.js', + 'core/input/util.js', + 'core/input/devices.js', 'core/websock.js', 'core/rfb.js', 'core/des.js', diff --git a/tests/input.html b/tests/input.html index a513645c..a261924b 100644 --- a/tests/input.html +++ b/tests/input.html @@ -26,11 +26,11 @@ - - - - - + + + + +