From ae510306b5094b55aa08a2a0d15a151704f70993 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Wed, 14 Sep 2016 13:52:53 -0400 Subject: [PATCH] Enable noVNC to become Browserifiable This commit restructures noVNC, splitting it into the core directory and the app directory, with the former containing core noVNC parts, and the latter containing parts specific to the application. --- .gitignore | 3 + .npmignore | 21 + LICENSE.txt | 46 +- {images => app/images}/alt.png | Bin {images => app/images}/clipboard.png | Bin {images => app/images}/connect.png | Bin {images => app/images}/ctrl.png | Bin {images => app/images}/ctrlaltdel.png | Bin {images => app/images}/disconnect.png | Bin {images => app/images}/drag.png | Bin {images => app/images}/esc.png | Bin {images => app/images}/favicon.ico | Bin {images => app/images}/favicon.png | Bin {images => app/images}/fullscreen.png | Bin {images => app/images}/keyboard.png | Bin {images => app/images}/mouse_left.png | Bin {images => app/images}/mouse_middle.png | Bin {images => app/images}/mouse_none.png | Bin {images => app/images}/mouse_right.png | Bin {images => app/images}/power.png | Bin {images => app/images}/screen_320x460.png | Bin {images => app/images}/screen_57x57.png | Bin {images => app/images}/screen_700x700.png | Bin {images => app/images}/settings.png | Bin {images => app/images}/tab.png | Bin {images => app/images}/toggleextrakeys.png | Bin {include => app/styles}/Orbitron700.ttf | Bin {include => app/styles}/Orbitron700.woff | Bin {include => app/styles}/base.css | 2 +- {include => app/styles}/black.css | 0 {include => app/styles}/blue.css | 0 {include => app}/ui.js | 376 ++++++++------- {include => app}/webutil.js | 23 +- {include => core}/base64.js | 4 +- {include => core}/des.js | 12 +- {include => core}/display.js | 146 +++--- {include => core}/inflator.js | 213 +++++---- .../inflator.mod.js | 8 +- {include => core}/input.js | 25 +- {include => core}/keyboard.js | 184 +++---- core/keysym.js | 382 +++++++++++++++ {include => core}/keysymdef.js | 3 + {include => core}/rfb.js | 450 +++++++++--------- {include => core}/util.js | 52 +- {include => core}/websock.js | 28 +- core/xtscancodes.js | 149 ++++++ docs/notes | 2 +- favicon.ico | 2 +- include/chrome-app/tcp-client.js | 321 ------------- include/keysym.js | 378 --------------- include/logo.js | 1 - include/xtscancodes.js | 146 ------ karma.conf.js | 30 +- package.json | 17 +- tests/input.html | 18 +- {include => tests}/playback.js | 2 +- tests/run_from_console.js | 2 +- tests/test.helper.js | 96 ++-- tests/test.keyboard.js | 114 ++--- tests/test.util.js | 1 - tests/vnc_perf.html | 38 +- tests/vnc_playback.html | 42 +- utils/make-module-transform.js | 25 + utils/use_require.js | 120 +++++ vnc.html | 54 ++- vnc_auto.html | 47 +- 66 files changed, 1754 insertions(+), 1829 deletions(-) create mode 100644 .npmignore rename {images => app/images}/alt.png (100%) rename {images => app/images}/clipboard.png (100%) rename {images => app/images}/connect.png (100%) rename {images => app/images}/ctrl.png (100%) rename {images => app/images}/ctrlaltdel.png (100%) rename {images => app/images}/disconnect.png (100%) rename {images => app/images}/drag.png (100%) rename {images => app/images}/esc.png (100%) rename {images => app/images}/favicon.ico (100%) rename {images => app/images}/favicon.png (100%) rename {images => app/images}/fullscreen.png (100%) rename {images => app/images}/keyboard.png (100%) rename {images => app/images}/mouse_left.png (100%) rename {images => app/images}/mouse_middle.png (100%) rename {images => app/images}/mouse_none.png (100%) rename {images => app/images}/mouse_right.png (100%) rename {images => app/images}/power.png (100%) rename {images => app/images}/screen_320x460.png (100%) rename {images => app/images}/screen_57x57.png (100%) rename {images => app/images}/screen_700x700.png (100%) rename {images => app/images}/settings.png (100%) rename {images => app/images}/tab.png (100%) rename {images => app/images}/toggleextrakeys.png (100%) rename {include => app/styles}/Orbitron700.ttf (100%) rename {include => app/styles}/Orbitron700.woff (100%) rename {include => app/styles}/base.css (99%) rename {include => app/styles}/black.css (100%) rename {include => app/styles}/blue.css (100%) rename {include => app}/ui.js (71%) rename {include => app}/webutil.js (95%) rename {include => core}/base64.js (99%) rename {include => core}/des.js (99%) rename {include => core}/display.js (92%) rename {include => core}/inflator.js (95%) rename utils/inflator.partial.js => core/inflator.mod.js (83%) rename {include => core}/input.js (95%) rename {include => core}/keyboard.js (81%) create mode 100644 core/keysym.js rename {include => core}/keysymdef.js (99%) rename {include => core}/rfb.js (89%) rename {include => core}/util.js (93%) rename {include => core}/websock.js (96%) create mode 100644 core/xtscancodes.js delete mode 100644 include/chrome-app/tcp-client.js delete mode 100644 include/keysym.js delete mode 100644 include/logo.js delete mode 100644 include/xtscancodes.js rename {include => tests}/playback.js (97%) create mode 100644 utils/make-module-transform.js create mode 100755 utils/use_require.js diff --git a/.gitignore b/.gitignore index a707ba7..da1b8c2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ tests/data_*.js utils/rebind.so utils/websockify node_modules +build +lib +recordings diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..69a33a5 --- /dev/null +++ b/.npmignore @@ -0,0 +1,21 @@ +app +core +favicon.ico +.gitmodules +node_modules +.* +*~ +*.swp +*.swo +tests +.travis.yml +utils +docs/notes +docs/links +docs/release.txt +docs/rfb_notes +docs/*.pdf +vnc.html +vnc_auto.html +karma.conf.js +docs/flash_policy.txt diff --git a/LICENSE.txt b/LICENSE.txt index 2ec4a64..41b45bb 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -5,19 +5,19 @@ Public License 2.0). The noVNC core library is composed of the Javascript code necessary for full noVNC operation. This includes (but is not limited to): - include/base64.js - include/des.js - include/display.js - include/input.js - include/keysym.js - include/logo.js - include/playback.js - include/rfb.js - include/ui.js - include/util.js - include/websock.js - include/webutil.js - include/xtscancodes.js + core/base64.js + core/des.js + core/display.js + core/input.js + core/keysym.js + core/logo.js + core/playback.js + core/rfb.js + app/ui.js + core/util.js + core/websock.js + app/webutil.js + core/xtscancodes.js The HTML, CSS, font and images files that included with the noVNC source distibution (or repository) are not considered part of the @@ -29,12 +29,12 @@ The HTML, CSS, font and image files are licensed as follows: *.html : 2-Clause BSD license - include/*.css : 2-Clause BSD license + app/styles/*.css : 2-Clause BSD license - include/Orbitron* : SIL Open Font License 1.1 + app/styles/Orbitron* : SIL Open Font License 1.1 (Copyright 2009 Matt McInerney) - images/ : Creative Commons Attribution-ShareAlike + app/images/ : Creative Commons Attribution-ShareAlike http://creativecommons.org/licenses/by-sa/3.0/ Some portions of noVNC are copyright to their individual authors. @@ -45,18 +45,12 @@ The are several files and projects that have been incorporated into 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 + core/base64.js : MPL 2.0 - include/des.js : Various BSD style licenses + core/des.js : Various BSD style licenses - include/chrome-app/tcp-stream.js - : Apache 2.0 license - - utils/websockify - utils/websocket.py : LGPL 3 - - utils/inflator.partial.js - include/inflator.js : MIT (for pako) + utils/inflator.mod.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 diff --git a/images/alt.png b/app/images/alt.png similarity index 100% rename from images/alt.png rename to app/images/alt.png diff --git a/images/clipboard.png b/app/images/clipboard.png similarity index 100% rename from images/clipboard.png rename to app/images/clipboard.png diff --git a/images/connect.png b/app/images/connect.png similarity index 100% rename from images/connect.png rename to app/images/connect.png diff --git a/images/ctrl.png b/app/images/ctrl.png similarity index 100% rename from images/ctrl.png rename to app/images/ctrl.png diff --git a/images/ctrlaltdel.png b/app/images/ctrlaltdel.png similarity index 100% rename from images/ctrlaltdel.png rename to app/images/ctrlaltdel.png diff --git a/images/disconnect.png b/app/images/disconnect.png similarity index 100% rename from images/disconnect.png rename to app/images/disconnect.png diff --git a/images/drag.png b/app/images/drag.png similarity index 100% rename from images/drag.png rename to app/images/drag.png diff --git a/images/esc.png b/app/images/esc.png similarity index 100% rename from images/esc.png rename to app/images/esc.png diff --git a/images/favicon.ico b/app/images/favicon.ico similarity index 100% rename from images/favicon.ico rename to app/images/favicon.ico diff --git a/images/favicon.png b/app/images/favicon.png similarity index 100% rename from images/favicon.png rename to app/images/favicon.png diff --git a/images/fullscreen.png b/app/images/fullscreen.png similarity index 100% rename from images/fullscreen.png rename to app/images/fullscreen.png diff --git a/images/keyboard.png b/app/images/keyboard.png similarity index 100% rename from images/keyboard.png rename to app/images/keyboard.png diff --git a/images/mouse_left.png b/app/images/mouse_left.png similarity index 100% rename from images/mouse_left.png rename to app/images/mouse_left.png diff --git a/images/mouse_middle.png b/app/images/mouse_middle.png similarity index 100% rename from images/mouse_middle.png rename to app/images/mouse_middle.png diff --git a/images/mouse_none.png b/app/images/mouse_none.png similarity index 100% rename from images/mouse_none.png rename to app/images/mouse_none.png diff --git a/images/mouse_right.png b/app/images/mouse_right.png similarity index 100% rename from images/mouse_right.png rename to app/images/mouse_right.png diff --git a/images/power.png b/app/images/power.png similarity index 100% rename from images/power.png rename to app/images/power.png diff --git a/images/screen_320x460.png b/app/images/screen_320x460.png similarity index 100% rename from images/screen_320x460.png rename to app/images/screen_320x460.png diff --git a/images/screen_57x57.png b/app/images/screen_57x57.png similarity index 100% rename from images/screen_57x57.png rename to app/images/screen_57x57.png diff --git a/images/screen_700x700.png b/app/images/screen_700x700.png similarity index 100% rename from images/screen_700x700.png rename to app/images/screen_700x700.png diff --git a/images/settings.png b/app/images/settings.png similarity index 100% rename from images/settings.png rename to app/images/settings.png diff --git a/images/tab.png b/app/images/tab.png similarity index 100% rename from images/tab.png rename to app/images/tab.png diff --git a/images/toggleextrakeys.png b/app/images/toggleextrakeys.png similarity index 100% rename from images/toggleextrakeys.png rename to app/images/toggleextrakeys.png diff --git a/include/Orbitron700.ttf b/app/styles/Orbitron700.ttf similarity index 100% rename from include/Orbitron700.ttf rename to app/styles/Orbitron700.ttf diff --git a/include/Orbitron700.woff b/app/styles/Orbitron700.woff similarity index 100% rename from include/Orbitron700.woff rename to app/styles/Orbitron700.woff diff --git a/include/base.css b/app/styles/base.css similarity index 99% rename from include/base.css rename to app/styles/base.css index 8d88c0f..382234e 100644 --- a/include/base.css +++ b/app/styles/base.css @@ -280,7 +280,7 @@ html { /* Control bar */ #noVNC_control_bar { position:fixed; - + display:block; height:36px; left:0; diff --git a/include/black.css b/app/styles/black.css similarity index 100% rename from include/black.css rename to app/styles/black.css diff --git a/include/blue.css b/app/styles/blue.css similarity index 100% rename from include/blue.css rename to app/styles/blue.css diff --git a/include/ui.js b/app/ui.js similarity index 71% rename from include/ui.js rename to app/ui.js index d69a4f6..c8251fb 100644 --- a/include/ui.js +++ b/app/ui.js @@ -8,19 +8,31 @@ */ /* jslint white: false, browser: true */ -/* global window, $D, Util, WebUtil, RFB, Display */ +/* global window, document.getElementById, Util, WebUtil, RFB, Display */ + +/* [module] + * import Util from "../core/util"; + * import KeyTable from "../core/keysym"; + * import RFB from "../core/rfb"; + * import Display from "../core/display"; + * import WebUtil from "./webutil"; + */ var UI; (function () { "use strict"; + /* [begin skip-as-module] */ // Load supporting scripts + 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"], + '.': ["webutil.js"]}); + window.onscriptsload = function () { UI.load(); }; - Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", - "keysymdef.js", "xtscancodes.js", "keyboard.js", - "input.js", "display.js", "rfb.js", "keysym.js", - "inflator.js"]); + /* [end skip-as-module] */ UI = { @@ -60,13 +72,13 @@ var UI; var sheets = WebUtil.getStylesheets(); var i; for (i = 0; i < sheets.length; i += 1) { - UI.addOption($D('noVNC_setting_stylesheet'),sheets[i].title, sheets[i].title); + UI.addOption(document.getElementById('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_setting_logging'),llevels[i], llevels[i]); + UI.addOption(document.getElementById('noVNC_setting_logging'),llevels[i], llevels[i]); } // Settings with immediate effects @@ -114,12 +126,12 @@ var UI; UI.updateVisualState(); - $D('noVNC_setting_host').focus(); + document.getElementById('noVNC_setting_host').focus(); // Show mouse selector buttons on touch screen devices if (UI.isTouchDevice) { // Show mobile buttons - $D('noVNC_mobile_buttons').style.display = "inline"; + document.getElementById('noVNC_mobile_buttons').style.display = "inline"; UI.setMouseButton(); // Remove the address bar setTimeout(function() { window.scrollTo(0, 1); }, 100); @@ -148,7 +160,7 @@ var UI; document.documentElement.mozRequestFullScreen || document.documentElement.webkitRequestFullscreen || document.body.msRequestFullscreen)) { - $D('noVNC_fullscreen_button').style.display = "inline"; + 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); @@ -172,7 +184,7 @@ var UI; // Show description by default when hosted at for kanaka.github.com if (location.host === "kanaka.github.io") { // Open the description dialog - $D('noVNC_description').style.display = "block"; + document.getElementById('noVNC_description').style.display = "block"; } else { // Show the connect panel on first load unless autoconnecting if (autoconnect === UI.connSettingsOpen) { @@ -190,7 +202,7 @@ var UI; initRFB: function() { try { - UI.rfb = new RFB({'target': $D('noVNC_canvas'), + UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'), 'onUpdateState': UI.updateState, 'onXvpInit': UI.updateXvpButton, 'onClipboard': UI.clipboardReceive, @@ -206,49 +218,49 @@ var UI; addMouseHandlers: function() { // Setup interface handlers that can't be inline - $D("noVNC_view_drag_button").onclick = UI.toggleViewDrag; - $D("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); }; - $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("noVNC_keyboard_button").onclick = UI.showKeyboard; - - $D("noVNC_keyboardinput").oninput = UI.keyInput; - $D("noVNC_keyboardinput").onblur = UI.hideKeyboard; - $D("noVNC_keyboardinput").onsubmit = function () { return false; }; - - $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("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("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; - $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; - $D("noVNC_settings_apply").onclick = UI.settingsApply; - - $D("noVNC_connect_button").onclick = UI.connect; - - $D("noVNC_setting_resize").onchange = UI.enableDisableViewClip; + document.getElementById("noVNC_view_drag_button").onclick = UI.toggleViewDrag; + document.getElementById("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); }; + document.getElementById("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); }; + document.getElementById("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); }; + document.getElementById("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); }; + document.getElementById("noVNC_keyboard_button").onclick = UI.showKeyboard; + + document.getElementById("noVNC_keyboardinput").oninput = UI.keyInput; + document.getElementById("noVNC_keyboardinput").onblur = UI.hideKeyboard; + document.getElementById("noVNC_keyboardinput").onsubmit = function () { return false; }; + + document.getElementById("noVNC_toggleExtraKeys_button").onclick = UI.toggleExtraKeys; + document.getElementById("noVNC_toggleCtrl_button").onclick = UI.toggleCtrl; + document.getElementById("noVNC_toggleAlt_button").onclick = UI.toggleAlt; + document.getElementById("noVNC_sendTab_button").onclick = UI.sendTab; + document.getElementById("noVNC_sendEsc_button").onclick = UI.sendEsc; + + document.getElementById("noVNC_sendCtrlAltDel_button").onclick = UI.sendCtrlAltDel; + document.getElementById("noVNC_xvpShutdown_button").onclick = function() { UI.rfb.xvpShutdown(); }, + document.getElementById("noVNC_xvpReboot_button").onclick = function() { UI.rfb.xvpReboot(); }, + document.getElementById("noVNC_xvpReset_button").onclick = function() { UI.rfb.xvpReset(); }, + document.getElementById("noVNC_status").onclick = UI.popupStatus; + document.getElementById("noVNC_popup_status").onclick = UI.closePopup; + document.getElementById("noVNC_toggleXvp_button").onclick = UI.toggleXvpPanel; + document.getElementById("noVNC_clipboard_button").onclick = UI.toggleClipboardPanel; + document.getElementById("noVNC_fullscreen_button").onclick = UI.toggleFullscreen; + document.getElementById("noVNC_settings_button").onclick = UI.toggleSettingsPanel; + document.getElementById("noVNC_connectPanel_button").onclick = UI.toggleConnectPanel; + document.getElementById("noVNC_disconnect_button").onclick = UI.disconnect; + document.getElementById("noVNC_description_button").onclick = UI.toggleConnectPanel; + + document.getElementById("noVNC_clipboard_text").onfocus = UI.displayBlur; + document.getElementById("noVNC_clipboard_text").onblur = UI.displayFocus; + document.getElementById("noVNC_clipboard_text").onchange = UI.clipboardSend; + document.getElementById("noVNC_clipboard_clear_button").onclick = UI.clipboardClear; + + document.getElementById("noVNC_settings_menu").onmouseover = UI.displayBlur; + document.getElementById("noVNC_settings_menu").onmouseover = UI.displayFocus; + document.getElementById("noVNC_settings_apply").onclick = UI.settingsApply; + + document.getElementById("noVNC_connect_button").onclick = UI.connect; + + document.getElementById("noVNC_setting_resize").onchange = UI.enableDisableViewClip; }, /* ------^------- @@ -269,8 +281,8 @@ var UI; klass = "noVNC_status_normal"; break; case 'disconnected': - $D('noVNC_logo').style.display = "block"; - $D('noVNC_screen').style.display = "none"; + document.getElementById('noVNC_logo').style.display = "block"; + document.getElementById('noVNC_screen').style.display = "none"; /* falls through */ case 'loaded': klass = "noVNC_status_normal"; @@ -278,9 +290,9 @@ var UI; case 'password': UI.toggleConnectPanel(); - $D('noVNC_connect_button').value = "Send Password"; - $D('noVNC_connect_button').onclick = UI.setPassword; - $D('noVNC_setting_password').focus(); + document.getElementById('noVNC_connect_button').value = "Send Password"; + document.getElementById('noVNC_connect_button').onclick = UI.setPassword; + document.getElementById('noVNC_setting_password').focus(); klass = "noVNC_status_warn"; break; @@ -290,8 +302,8 @@ var UI; } if (typeof(msg) !== 'undefined') { - $D('noVNC_control_bar').setAttribute("class", klass); - $D('noVNC_status').innerHTML = msg; + document.getElementById('noVNC_control_bar').setAttribute("class", klass); + document.getElementById('noVNC_status').innerHTML = msg; } UI.updateVisualState(); @@ -302,35 +314,35 @@ var UI; var connected = UI.rfb && UI.rfb_state === 'normal'; //Util.Debug(">> updateVisualState"); - $D('noVNC_setting_encrypt').disabled = connected; - $D('noVNC_setting_true_color').disabled = connected; + document.getElementById('noVNC_setting_encrypt').disabled = connected; + document.getElementById('noVNC_setting_true_color').disabled = connected; if (Util.browserSupportsCursorURIs()) { - $D('noVNC_setting_cursor').disabled = connected; + document.getElementById('noVNC_setting_cursor').disabled = connected; } else { UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_setting_cursor').disabled = true; + document.getElementById('noVNC_setting_cursor').disabled = true; } UI.enableDisableViewClip(); - $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; + document.getElementById('noVNC_setting_resize').disabled = connected; + document.getElementById('noVNC_setting_shared').disabled = connected; + document.getElementById('noVNC_setting_view_only').disabled = connected; + document.getElementById('noVNC_setting_path').disabled = connected; + document.getElementById('noVNC_setting_repeaterID').disabled = connected; if (connected) { UI.setViewClip(); UI.setMouseButton(1); - $D('noVNC_clipboard_button').style.display = "inline"; - $D('noVNC_keyboard_button').style.display = "inline"; - $D('noVNC_extra_keys').style.display = ""; - $D('noVNC_sendCtrlAltDel_button').style.display = "inline"; + document.getElementById('noVNC_clipboard_button').style.display = "inline"; + document.getElementById('noVNC_keyboard_button').style.display = "inline"; + document.getElementById('noVNC_extra_keys').style.display = ""; + document.getElementById('noVNC_sendCtrlAltDel_button').style.display = "inline"; } else { UI.setMouseButton(); - $D('noVNC_clipboard_button').style.display = "none"; - $D('noVNC_keyboard_button').style.display = "none"; - $D('noVNC_extra_keys').style.display = "none"; - $D('noVNC_sendCtrlAltDel_button').style.display = "none"; + document.getElementById('noVNC_clipboard_button').style.display = "none"; + document.getElementById('noVNC_keyboard_button').style.display = "none"; + document.getElementById('noVNC_extra_keys').style.display = "none"; + document.getElementById('noVNC_sendCtrlAltDel_button').style.display = "none"; UI.updateXvpButton(0); } @@ -342,18 +354,18 @@ var UI; case 'fatal': case 'failed': case 'disconnected': - $D('noVNC_connectPanel_button').style.display = ""; - $D('noVNC_disconnect_button').style.display = "none"; + document.getElementById('noVNC_connectPanel_button').style.display = ""; + document.getElementById('noVNC_disconnect_button').style.display = "none"; UI.connSettingsOpen = false; UI.toggleConnectPanel(); break; case 'loaded': - $D('noVNC_connectPanel_button').style.display = ""; - $D('noVNC_disconnect_button').style.display = "none"; + document.getElementById('noVNC_connectPanel_button').style.display = ""; + document.getElementById('noVNC_disconnect_button').style.display = "none"; break; default: - $D('noVNC_connectPanel_button').style.display = "none"; - $D('noVNC_disconnect_button').style.display = ""; + document.getElementById('noVNC_connectPanel_button').style.display = "none"; + document.getElementById('noVNC_disconnect_button').style.display = ""; break; } @@ -361,14 +373,14 @@ var UI; }, popupStatus: function(text) { - var psp = $D('noVNC_popup_status'); + var psp = document.getElementById('noVNC_popup_status'); clearTimeout(UI.popupStatusTimeout); if (typeof text === 'string') { psp.innerHTML = text; } else { - psp.innerHTML = $D('noVNC_status').innerHTML; + psp.innerHTML = document.getElementById('noVNC_status').innerHTML; } psp.style.display = "block"; psp.style.left = window.innerWidth/2 - @@ -380,7 +392,7 @@ var UI; closePopup: function() { clearTimeout(UI.popupStatusTimeout); - $D('noVNC_popup_status').style.display = "none"; + document.getElementById('noVNC_popup_status').style.display = "none"; }, /* ------^------- @@ -412,7 +424,7 @@ var UI; // Update the settings control value = UI.getSetting(name); - var ctrl = $D('noVNC_setting_' + name); + var ctrl = document.getElementById('noVNC_setting_' + name); if (ctrl.type === 'checkbox') { ctrl.checked = value; @@ -435,7 +447,7 @@ var UI; // Save control setting to cookie saveSetting: function(name) { - var val, ctrl = $D('noVNC_setting_' + name); + var val, ctrl = document.getElementById('noVNC_setting_' + name); if (ctrl.type === 'checkbox') { val = ctrl.checked; } else if (typeof ctrl.options !== 'undefined') { @@ -456,7 +468,7 @@ var UI; // Read form control compatible setting from cookie getSetting: function(name) { - var ctrl = $D('noVNC_setting_' + name); + var ctrl = document.getElementById('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}) { @@ -502,7 +514,7 @@ var UI; // Open menu openSettingsMenu: function() { // Close the description panel - $D('noVNC_description').style.display = "none"; + document.getElementById('noVNC_description').style.display = "none"; // Close clipboard panel if open if (UI.clipboardOpen === true) { UI.toggleClipboardPanel(); @@ -515,15 +527,15 @@ var UI; if (UI.xvpOpen === true) { UI.toggleXvpPanel(); } - $D('noVNC_settings').style.display = "block"; - $D('noVNC_settings_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_settings').style.display = "block"; + document.getElementById('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('noVNC_settings_button').className = "noVNC_status_button"; + document.getElementById('noVNC_settings').style.display = "none"; + document.getElementById('noVNC_settings_button').className = "noVNC_status_button"; UI.settingsOpen = false; }, @@ -532,7 +544,7 @@ var UI; // On close, settings are applied toggleSettingsPanel: function() { // Close the description panel - $D('noVNC_description').style.display = "none"; + document.getElementById('noVNC_description').style.display = "none"; if (UI.settingsOpen) { UI.settingsApply(); UI.closeSettingsMenu(); @@ -543,7 +555,7 @@ var UI; UI.updateSetting('cursor'); } else { UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_setting_cursor').disabled = true; + document.getElementById('noVNC_setting_cursor').disabled = true; } UI.updateSetting('clip'); UI.updateSetting('resize'); @@ -567,7 +579,7 @@ var UI; // Show the XVP panel toggleXvpPanel: function() { // Close the description panel - $D('noVNC_description').style.display = "none"; + document.getElementById('noVNC_description').style.display = "none"; // Close settings if open if (UI.settingsOpen === true) { UI.settingsApply(); @@ -583,12 +595,12 @@ var UI; } // Toggle XVP panel if (UI.xvpOpen === true) { - $D('noVNC_xvp').style.display = "none"; - $D('noVNC_toggleXvp_button').className = "noVNC_status_button"; + document.getElementById('noVNC_xvp').style.display = "none"; + document.getElementById('noVNC_toggleXvp_button').className = "noVNC_status_button"; UI.xvpOpen = false; } else { - $D('noVNC_xvp').style.display = "block"; - $D('noVNC_toggleXvp_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_xvp').style.display = "block"; + document.getElementById('noVNC_toggleXvp_button').className = "noVNC_status_button_selected"; UI.xvpOpen = true; } }, @@ -596,9 +608,9 @@ var UI; // Disable/enable XVP button updateXvpButton: function(ver) { if (ver >= 1) { - $D('noVNC_toggleXvp_button').style.display = 'inline'; + document.getElementById('noVNC_toggleXvp_button').style.display = 'inline'; } else { - $D('noVNC_toggleXvp_button').style.display = 'none'; + document.getElementById('noVNC_toggleXvp_button').style.display = 'none'; // Close XVP panel if open if (UI.xvpOpen === true) { UI.toggleXvpPanel(); @@ -615,7 +627,7 @@ var UI; // Show the clipboard panel toggleClipboardPanel: function() { // Close the description panel - $D('noVNC_description').style.display = "none"; + document.getElementById('noVNC_description').style.display = "none"; // Close settings if open if (UI.settingsOpen === true) { UI.settingsApply(); @@ -631,29 +643,29 @@ var UI; } // Toggle Clipboard Panel if (UI.clipboardOpen === true) { - $D('noVNC_clipboard').style.display = "none"; - $D('noVNC_clipboard_button').className = "noVNC_status_button"; + document.getElementById('noVNC_clipboard').style.display = "none"; + document.getElementById('noVNC_clipboard_button').className = "noVNC_status_button"; UI.clipboardOpen = false; } else { - $D('noVNC_clipboard').style.display = "block"; - $D('noVNC_clipboard_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_clipboard').style.display = "block"; + document.getElementById('noVNC_clipboard_button').className = "noVNC_status_button_selected"; UI.clipboardOpen = true; } }, clipboardReceive: function(rfb, text) { Util.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "..."); - $D('noVNC_clipboard_text').value = text; + document.getElementById('noVNC_clipboard_text').value = text; Util.Debug("<< UI.clipboardReceive"); }, clipboardClear: function() { - $D('noVNC_clipboard_text').value = ""; + document.getElementById('noVNC_clipboard_text').value = ""; UI.rfb.clipboardPasteFrom(""); }, clipboardSend: function() { - var text = $D('noVNC_clipboard_text').value; + var text = document.getElementById('noVNC_clipboard_text').value; Util.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "..."); UI.rfb.clipboardPasteFrom(text); Util.Debug("<< UI.clipboardSend"); @@ -668,12 +680,12 @@ var UI; // Show the connection settings panel/menu toggleConnectPanel: function() { // Close the description panel - $D('noVNC_description').style.display = "none"; + document.getElementById('noVNC_description').style.display = "none"; // Close connection settings if open if (UI.settingsOpen === true) { UI.settingsApply(); UI.closeSettingsMenu(); - $D('noVNC_connectPanel_button').className = "noVNC_status_button"; + document.getElementById('noVNC_connectPanel_button').className = "noVNC_status_button"; } // Close clipboard panel if open if (UI.clipboardOpen === true) { @@ -686,18 +698,18 @@ var UI; // Toggle Connection Panel if (UI.connSettingsOpen === true) { - $D('noVNC_controls').style.display = "none"; - $D('noVNC_connectPanel_button').className = "noVNC_status_button"; + document.getElementById('noVNC_controls').style.display = "none"; + document.getElementById('noVNC_connectPanel_button').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('noVNC_connectPanel_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_controls').style.display = "block"; + document.getElementById('noVNC_connectPanel_button').className = "noVNC_status_button_selected"; UI.connSettingsOpen = true; - $D('noVNC_setting_host').focus(); + document.getElementById('noVNC_setting_host').focus(); } }, @@ -705,11 +717,11 @@ var UI; UI.closeSettingsMenu(); UI.toggleConnectPanel(); - 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; + var host = document.getElementById('noVNC_setting_host').value; + var port = document.getElementById('noVNC_setting_port').value; + var password = document.getElementById('noVNC_setting_password').value; + var token = document.getElementById('noVNC_setting_token').value; + var path = document.getElementById('noVNC_setting_path').value; //if token is in path then ignore the new token variable if (token) { @@ -733,8 +745,8 @@ var UI; //Close dialog. setTimeout(UI.setBarPosition, 100); - $D('noVNC_logo').style.display = "none"; - $D('noVNC_screen').style.display = "inline"; + document.getElementById('noVNC_logo').style.display = "none"; + document.getElementById('noVNC_screen').style.display = "inline"; }, disconnect: function() { @@ -744,17 +756,17 @@ var UI; // 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"; + document.getElementById('noVNC_logo').style.display = "block"; + document.getElementById('noVNC_screen').style.display = "none"; // Don't display the connection settings until we're actually disconnected }, setPassword: function() { - UI.rfb.sendPassword($D('noVNC_setting_password').value); + UI.rfb.sendPassword(document.getElementById('noVNC_setting_password').value); //Reset connect button. - $D('noVNC_connect_button').value = "Connect"; - $D('noVNC_connect_button').onclick = UI.connect; + document.getElementById('noVNC_connect_button').value = "Connect"; + document.getElementById('noVNC_connect_button').onclick = UI.connect; //Hide connection panel. UI.toggleConnectPanel(); return false; @@ -800,9 +812,9 @@ var UI; document.mozFullScreenElement || // currently working methods document.webkitFullscreenElement || document.msFullscreenElement ) { - $D('noVNC_fullscreen_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_fullscreen_button').className = "noVNC_status_button_selected"; } else { - $D('noVNC_fullscreen_button').className = "noVNC_status_button"; + document.getElementById('noVNC_fullscreen_button').className = "noVNC_status_button"; } }, @@ -856,7 +868,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() { - var screen = $D('noVNC_screen'); + var screen = document.getElementById('noVNC_screen'); // Hide the scrollbars until the size is calculated screen.style.overflow = "hidden"; @@ -931,13 +943,13 @@ var UI; display.set_maxHeight(size.h); // Hide potential scrollbars that can skew the position - $D('noVNC_screen').style.overflow = "hidden"; + document.getElementById('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); + var new_w = size.w - (2 * Util.getPosition(document.getElementById('noVNC_canvas')).x); - $D('noVNC_screen').style.overflow = "visible"; + document.getElementById('noVNC_screen').style.overflow = "visible"; display.viewportChangeSize(new_w, size.h); } @@ -946,18 +958,18 @@ var UI; // Handle special cases where clipping is forced on/off or locked enableDisableViewClip: function() { - var resizeSetting = $D('noVNC_setting_resize'); + var resizeSetting = document.getElementById('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_setting_clip').disabled = true; + document.getElementById('noVNC_setting_clip').disabled = true; } else if (resizeSetting.value === 'downscale' || resizeSetting.value === 'scale') { // Disable clipping if we are scaling UI.setViewClip(false); - $D('noVNC_setting_clip').disabled = true; + document.getElementById('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 @@ -965,13 +977,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_setting_clip').disabled = true; + document.getElementById('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_setting_clip').disabled = connected || UI.isTouchDevice; + document.getElementById('noVNC_setting_clip').disabled = connected || UI.isTouchDevice; } else { - $D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice; + document.getElementById('noVNC_setting_clip').disabled = connected || UI.isTouchDevice; if (UI.isTouchDevice) { UI.setViewClip(true); } @@ -988,7 +1000,7 @@ var UI; updateViewDrag: function(drag) { if (!UI.rfb) return; - var viewDragButton = $D('noVNC_view_drag_button'); + var viewDragButton = document.getElementById('noVNC_view_drag_button'); // Check if viewport drag is possible. It is only possible // if the remote display is clipping the client display. @@ -1033,7 +1045,7 @@ var UI; toggleViewDrag: function() { if (!UI.rfb) return; - var viewDragButton = $D('noVNC_view_drag_button'); + var viewDragButton = document.getElementById('noVNC_view_drag_button'); if (UI.rfb.get_viewportDrag()) { viewDragButton.className = "noVNC_status_button"; UI.rfb.set_viewportDrag(false); @@ -1051,8 +1063,8 @@ var UI; // On touch devices, show the OS keyboard showKeyboard: function() { - var kbi = $D('noVNC_keyboardinput'); - var skb = $D('noVNC_keyboard_button'); + var kbi = document.getElementById('noVNC_keyboardinput'); + var skb = document.getElementById('noVNC_keyboard_button'); var l = kbi.value.length; if(UI.keyboardVisible === false) { kbi.focus(); @@ -1068,7 +1080,7 @@ var UI; }, hideKeyboard: function() { - $D('noVNC_keyboard_button').className = "noVNC_status_button"; + document.getElementById('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. @@ -1080,16 +1092,16 @@ var UI; keepKeyboard: function() { clearTimeout(UI.hideKeyboardTimeout); if(UI.keyboardVisible === true) { - $D('noVNC_keyboardinput').focus(); - $D('noVNC_keyboard_button').className = "noVNC_status_button_selected"; + document.getElementById('noVNC_keyboardinput').focus(); + document.getElementById('noVNC_keyboard_button').className = "noVNC_status_button_selected"; } else if(UI.keyboardVisible === false) { - $D('noVNC_keyboardinput').blur(); - $D('noVNC_keyboard_button').className = "noVNC_status_button"; + document.getElementById('noVNC_keyboardinput').blur(); + document.getElementById('noVNC_keyboard_button').className = "noVNC_status_button"; } }, keyboardinputReset: function() { - var kbi = $D('noVNC_keyboardinput'); + var kbi = document.getElementById('noVNC_keyboardinput'); kbi.value = new Array(UI.defaultKeyboardinputLen).join("_"); UI.lastKeyboardinput = kbi.value; }, @@ -1141,7 +1153,7 @@ var UI; // Send the key events for (i = 0; i < backspaces; i++) { - UI.rfb.sendKey(XK_BackSpace); + UI.rfb.sendKey(KeyTable.XK_BackSpace); } for (i = newLen - inputs; i < newLen; i++) { UI.rfb.sendKey(newValue.charCodeAt(i)); @@ -1168,41 +1180,41 @@ var UI; toggleExtraKeys: function() { UI.keepKeyboard(); if(UI.extraKeysVisible === false) { - $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"; + document.getElementById('noVNC_toggleCtrl_button').style.display = "inline"; + document.getElementById('noVNC_toggleAlt_button').style.display = "inline"; + document.getElementById('noVNC_sendTab_button').style.display = "inline"; + document.getElementById('noVNC_sendEsc_button').style.display = "inline"; + document.getElementById('noVNC_toggleExtraKeys_button').className = "noVNC_status_button_selected"; UI.extraKeysVisible = true; } else if(UI.extraKeysVisible === true) { - $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"; + document.getElementById('noVNC_toggleCtrl_button').style.display = ""; + document.getElementById('noVNC_toggleAlt_button').style.display = ""; + document.getElementById('noVNC_sendTab_button').style.display = ""; + document.getElementById('noVNC_sendEsc_button').style.display = ""; + document.getElementById('noVNC_toggleExtraKeys_button').className = "noVNC_status_button"; UI.extraKeysVisible = false; } }, sendEsc: function() { UI.keepKeyboard(); - UI.rfb.sendKey(XK_Escape); + UI.rfb.sendKey(KeyTable.XK_Escape); }, sendTab: function() { UI.keepKeyboard(); - UI.rfb.sendKey(XK_Tab); + UI.rfb.sendKey(KeyTable.XK_Tab); }, toggleCtrl: function() { UI.keepKeyboard(); if(UI.ctrlOn === false) { - UI.rfb.sendKey(XK_Control_L, true); - $D('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected"; + UI.rfb.sendKey(KeyTable.XK_Control_L, true); + document.getElementById('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected"; UI.ctrlOn = true; } else if(UI.ctrlOn === true) { - UI.rfb.sendKey(XK_Control_L, false); - $D('noVNC_toggleCtrl_button').className = "noVNC_status_button"; + UI.rfb.sendKey(KeyTable.XK_Control_L, false); + document.getElementById('noVNC_toggleCtrl_button').className = "noVNC_status_button"; UI.ctrlOn = false; } }, @@ -1210,12 +1222,12 @@ var UI; toggleAlt: function() { UI.keepKeyboard(); if(UI.altOn === false) { - UI.rfb.sendKey(XK_Alt_L, true); - $D('noVNC_toggleAlt_button').className = "noVNC_status_button_selected"; + UI.rfb.sendKey(KeyTable.XK_Alt_L, true); + document.getElementById('noVNC_toggleAlt_button').className = "noVNC_status_button_selected"; UI.altOn = true; } else if(UI.altOn === true) { - UI.rfb.sendKey(XK_Alt_L, false); - $D('noVNC_toggleAlt_button').className = "noVNC_status_button"; + UI.rfb.sendKey(KeyTable.XK_Alt_L, false); + document.getElementById('noVNC_toggleAlt_button').className = "noVNC_status_button"; UI.altOn = false; } }, @@ -1241,7 +1253,7 @@ var UI; var blist = [0, 1,2,4]; for (var b = 0; b < blist.length; b++) { - var button = $D('noVNC_mouse_button' + blist[b]); + var button = document.getElementById('noVNC_mouse_button' + blist[b]); if (blist[b] === num) { button.style.display = ""; } else { @@ -1278,11 +1290,11 @@ var UI; }, setBarPosition: function() { - $D('noVNC_control_bar').style.top = (window.pageYOffset) + 'px'; - $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; + document.getElementById('noVNC_control_bar').style.top = (window.pageYOffset) + 'px'; + document.getElementById('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; - var vncwidth = $D('noVNC_container').style.offsetWidth; - $D('noVNC_control_bar').style.width = vncwidth + 'px'; + var vncwidth = document.getElementById('noVNC_container').style.offsetWidth; + document.getElementById('noVNC_control_bar').style.width = vncwidth + 'px'; } /* ------^------- @@ -1290,4 +1302,8 @@ var UI; * ============== */ }; + + /* [module] UI.load(); */ })(); + +/* [module] export default UI; */ diff --git a/include/webutil.js b/app/webutil.js similarity index 95% rename from include/webutil.js rename to app/webutil.js index 9ee3473..f5f3077 100644 --- a/include/webutil.js +++ b/app/webutil.js @@ -10,25 +10,12 @@ /*jslint bitwise: false, white: false, browser: true, devel: true */ /*global Util, window, document */ -// Globals defined here -var WebUtil = {}, $D; - -/* - * Simple DOM selector by ID +/* [module] + * import Util from "../core/util"; */ -if (!window.$D) { - window.$D = function (id) { - if (document.getElementById) { - return document.getElementById(id); - } else if (document.all) { - return document.all[id]; - } else if (document.layers) { - return document.layers[id]; - } - return undefined; - }; -} +// Globals defined here +var WebUtil = {}; /* * ------------------------------------------------------ @@ -290,3 +277,5 @@ WebUtil.injectParamIfMissing = function (path, param, value) { return elem.pathname + elem.search + elem.hash; } }; + +/* [module] export default WebUtil; */ diff --git a/include/base64.js b/core/base64.js similarity index 99% rename from include/base64.js rename to core/base64.js index 651fbad..2b4f948 100644 --- a/include/base64.js +++ b/core/base64.js @@ -85,7 +85,7 @@ var Base64 = { console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i); continue; } - + // Collect data into leftdata, update bitcount leftdata = (leftdata << 6) | c; leftbits += 6; @@ -111,3 +111,5 @@ var Base64 = { return result; } }; /* End of Base64 namespace */ + +/* [module] export default Base64; */ diff --git a/include/des.js b/core/des.js similarity index 99% rename from include/des.js rename to core/des.js index ecbc819..c9a4753 100644 --- a/include/des.js +++ b/core/des.js @@ -25,16 +25,16 @@ * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and - * without fee is hereby granted, provided that this copyright notice is kept - * intact. - * + * without fee is hereby granted, provided that this copyright notice is kept + * intact. + * * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. - * + * * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT @@ -77,7 +77,7 @@ /* jslint white: false */ -function DES(passwd) { +/* [module] export default */ function DES(passwd) { "use strict"; // Tables, permutations, S-boxes, etc. @@ -273,4 +273,4 @@ function DES(passwd) { setKeys(passwd); // Setup keys return {'encrypt': encrypt}; // Public interface -} // function DES +}; // function DES diff --git a/include/display.js b/core/display.js similarity index 92% rename from include/display.js rename to core/display.js index ade0451..79e1e4f 100644 --- a/include/display.js +++ b/core/display.js @@ -10,97 +10,101 @@ /*jslint browser: true, white: false */ /*global Util, Base64, changeCursor */ -var Display; +/* [module] + * import Util from "./util"; + * import Base64 from "./base64"; + */ -(function () { - "use strict"; +/* [module] export default */ function Display(defaults) { + this._drawCtx = null; + this._c_forceCanvas = false; - var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false; - try { - new ImageData(new Uint8ClampedArray(4), 1, 1); - SUPPORTS_IMAGEDATA_CONSTRUCTOR = true; - } catch (ex) { - // ignore failure - } + this._renderQ = []; // queue drawing actions for in-oder rendering - Display = function (defaults) { - this._drawCtx = null; - this._c_forceCanvas = false; + // the full frame buffer (logical canvas) size + this._fb_width = 0; + this._fb_height = 0; - this._renderQ = []; // queue drawing actions for in-oder rendering + // the size limit of the viewport (start disabled) + this._maxWidth = 0; + this._maxHeight = 0; - // the full frame buffer (logical canvas) size - this._fb_width = 0; - this._fb_height = 0; + // the visible "physical canvas" viewport + this._viewportLoc = { 'x': 0, 'y': 0, 'w': 0, 'h': 0 }; + this._cleanRect = { 'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1 }; - // the size limit of the viewport (start disabled) - this._maxWidth = 0; - this._maxHeight = 0; + this._prevDrawStyle = ""; + this._tile = null; + this._tile16x16 = null; + this._tile_x = 0; + this._tile_y = 0; - // the visible "physical canvas" viewport - this._viewportLoc = { 'x': 0, 'y': 0, 'w': 0, 'h': 0 }; - this._cleanRect = { 'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1 }; + Util.set_defaults(this, defaults, { + 'true_color': true, + 'colourMap': [], + 'scale': 1.0, + 'viewport': false, + 'render_mode': '' + }); - this._prevDrawStyle = ""; - this._tile = null; - this._tile16x16 = null; - this._tile_x = 0; - this._tile_y = 0; + Util.Debug(">> Display.constructor"); - Util.set_defaults(this, defaults, { - 'true_color': true, - 'colourMap': [], - 'scale': 1.0, - 'viewport': false, - 'render_mode': '' - }); + if (!this._target) { + throw new Error("Target must be set"); + } - Util.Debug(">> Display.constructor"); + if (typeof this._target === 'string') { + throw new Error('target must be a DOM element'); + } - if (!this._target) { - throw new Error("Target must be set"); - } + if (!this._target.getContext) { + throw new Error("no getContext method"); + } - if (typeof this._target === 'string') { - throw new Error('target must be a DOM element'); - } + if (!this._drawCtx) { + this._drawCtx = this._target.getContext('2d'); + } - if (!this._target.getContext) { - throw new Error("no getContext method"); - } + Util.Debug("User Agent: " + navigator.userAgent); + if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); } + if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); } + if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); } + if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); } - if (!this._drawCtx) { - this._drawCtx = this._target.getContext('2d'); - } + this.clear(); - Util.Debug("User Agent: " + navigator.userAgent); - if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); } - if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); } - if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); } - if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); } + // Check canvas features + if ('createImageData' in this._drawCtx) { + this._render_mode = 'canvas rendering'; + } else { + throw new Error("Canvas does not support createImageData"); + } - this.clear(); + if (this._prefer_js === null) { + Util.Info("Prefering javascript operations"); + this._prefer_js = true; + } - // Check canvas features - if ('createImageData' in this._drawCtx) { - this._render_mode = 'canvas rendering'; - } else { - throw new Error("Canvas does not support createImageData"); - } + // Determine browser support for setting the cursor via data URI scheme + if (this._cursor_uri || this._cursor_uri === null || + this._cursor_uri === undefined) { + this._cursor_uri = Util.browserSupportsCursorURIs(); + } - if (this._prefer_js === null) { - Util.Info("Prefering javascript operations"); - this._prefer_js = true; - } + Util.Debug("<< Display.constructor"); +}; - // Determine browser support for setting the cursor via data URI scheme - if (this._cursor_uri || this._cursor_uri === null || - this._cursor_uri === undefined) { - this._cursor_uri = Util.browserSupportsCursorURIs(); - } +(function () { + "use strict"; + + var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false; + try { + new ImageData(new Uint8ClampedArray(4), 1, 1); + SUPPORTS_IMAGEDATA_CONSTRUCTOR = true; + } catch (ex) { + // ignore failure + } - Util.Debug("<< Display.constructor"); - }; Display.prototype = { // Public methods diff --git a/include/inflator.js b/core/inflator.js similarity index 95% rename from include/inflator.js rename to core/inflator.js index 48ede20..973836d 100644 --- a/include/inflator.js +++ b/core/inflator.js @@ -1,4 +1,46 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.inflator = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o this.chunkSize) { + this.chunkSize = expected; + this.strm.output = new Uint8Array(this.chunkSize); + } + + this.strm.avail_out = this.chunkSize; + + zlib.inflate(this.strm, flush); + + return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); + }, + + reset: function () { + zlib.inflateReset(this.strm); + } +}; + +module.exports = { Inflate: Inflate }; + +},{"pako/lib/zlib/inflate.js":6,"pako/lib/zlib/zstream.js":8}],2:[function(require,module,exports){ 'use strict'; @@ -40,28 +82,28 @@ exports.shrinkBuf = function (buf, size) { var fnTyped = { arraySet: function (dest, src, src_offs, len, dest_offs) { if (src.subarray && dest.subarray) { - dest.set(src.subarray(src_offs, src_offs+len), dest_offs); + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); return; } // Fallback to ordinary array - for (var i=0; i>> 1)) : (c >>> 1)); + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); } table[n] = c; } @@ -167,7 +209,7 @@ function crc32(crc, buf, len, pos) { var t = crcTable, end = pos + len; - crc = crc ^ (-1); + crc ^= -1; for (var i = pos; i < end; i++) { crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; @@ -179,7 +221,7 @@ function crc32(crc, buf, len, pos) { module.exports = crc32; -},{}],4:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ 'use strict'; // See state defs from inflate.js @@ -507,14 +549,14 @@ module.exports = function inflate_fast(strm, start) { return; }; -},{}],5:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ 'use strict'; -var utils = require('../utils/common'); -var adler32 = require('./adler32'); -var crc32 = require('./crc32'); -var inflate_fast = require('./inffast'); +var utils = require('../utils/common'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var inflate_fast = require('./inffast'); var inflate_table = require('./inftrees'); var CODES = 0; @@ -602,7 +644,7 @@ var MAX_WBITS = 15; var DEF_WBITS = MAX_WBITS; -function ZSWAP32(q) { +function zswap32(q) { return (((q >>> 24) & 0xff) + ((q >>> 8) & 0xff00) + ((q & 0xff00) << 8) + @@ -795,13 +837,13 @@ function fixedtables(state) { while (sym < 280) { state.lens[sym++] = 7; } while (sym < 288) { state.lens[sym++] = 8; } - inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); /* distance table */ sym = 0; while (sym < 32) { state.lens[sym++] = 5; } - inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); /* do this just once */ virgin = false; @@ -843,7 +885,7 @@ function updatewindow(strm, src, end, copy) { /* copy state->wsize or less output bytes into the circular window */ if (copy >= state.wsize) { - utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); + utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); state.wnext = 0; state.whave = state.wsize; } @@ -853,11 +895,11 @@ function updatewindow(strm, src, end, copy) { dist = copy; } //zmemcpy(state->window + state->wnext, end - copy, dist); - utils.arraySet(state.window,src, end - copy, dist, state.wnext); + utils.arraySet(state.window, src, end - copy, dist, state.wnext); copy -= dist; if (copy) { //zmemcpy(state->window, end - copy, copy); - utils.arraySet(state.window,src, end - copy, copy, 0); + utils.arraySet(state.window, src, end - copy, copy, 0); state.wnext = copy; state.whave = state.wsize; } @@ -894,7 +936,7 @@ function inflate(strm, flush) { var n; // temporary var for NEED_BITS var order = /* permutation of code lengths */ - [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; if (!strm || !strm.state || !strm.output || @@ -1221,7 +1263,7 @@ function inflate(strm, flush) { state.head.hcrc = ((state.flags >> 9) & 1); state.head.done = true; } - strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; + strm.adler = state.check = 0; state.mode = TYPE; break; case DICTID: @@ -1233,7 +1275,7 @@ function inflate(strm, flush) { bits += 8; } //===// - strm.adler = state.check = ZSWAP32(hold); + strm.adler = state.check = zswap32(hold); //=== INITBITS(); hold = 0; bits = 0; @@ -1425,7 +1467,7 @@ function inflate(strm, flush) { state.lencode = state.lendyn; state.lenbits = 7; - opts = {bits: state.lenbits}; + opts = { bits: state.lenbits }; ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); state.lenbits = opts.bits; @@ -1556,7 +1598,7 @@ function inflate(strm, flush) { concerning the ENOUGH constants, which depend on those values */ state.lenbits = 9; - opts = {bits: state.lenbits}; + opts = { bits: state.lenbits }; ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); // We have separate tables & no pointers. 2 commented lines below not needed. // state.next_index = opts.table_index; @@ -1573,7 +1615,7 @@ function inflate(strm, flush) { //state.distcode.copy(state.codes); // Switch to use dynamic table state.distcode = state.distdyn; - opts = {bits: state.distbits}; + opts = { bits: state.distbits }; ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); // We have separate tables & no pointers. 2 commented lines below not needed. // state.next_index = opts.table_index; @@ -1621,7 +1663,7 @@ function inflate(strm, flush) { } state.back = 0; for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; @@ -1640,7 +1682,7 @@ function inflate(strm, flush) { last_val = here_val; for (;;) { here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; @@ -1697,7 +1739,7 @@ function inflate(strm, flush) { bits += 8; } //===// - state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; //--- DROPBITS(state.extra) ---// hold >>>= state.extra; bits -= state.extra; @@ -1710,7 +1752,7 @@ function inflate(strm, flush) { /* falls through */ case DIST: for (;;) { - here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; @@ -1729,7 +1771,7 @@ function inflate(strm, flush) { last_val = here_val; for (;;) { here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; @@ -1773,7 +1815,7 @@ function inflate(strm, flush) { bits += 8; } //===// - state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; //--- DROPBITS(state.extra) ---// hold >>>= state.extra; bits -= state.extra; @@ -1867,8 +1909,8 @@ function inflate(strm, flush) { } _out = left; - // NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too - if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.flags ? hold : zswap32(hold)) !== state.check) { strm.msg = 'incorrect data check'; state.mode = BAD; break; @@ -1990,6 +2032,41 @@ function inflateGetHeader(strm, head) { return Z_OK; } +function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var state; + var dictid; + var ret; + + /* check state */ + if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} exports.inflateReset = inflateReset; exports.inflateReset2 = inflateReset2; @@ -1999,6 +2076,7 @@ exports.inflateInit2 = inflateInit2; exports.inflate = inflate; exports.inflateEnd = inflateEnd; exports.inflateGetHeader = inflateGetHeader; +exports.inflateSetDictionary = inflateSetDictionary; exports.inflateInfo = 'pako inflate (from Nodeca project)'; /* Not implemented @@ -2006,13 +2084,12 @@ exports.inflateCopy = inflateCopy; exports.inflateGetDictionary = inflateGetDictionary; exports.inflateMark = inflateMark; exports.inflatePrime = inflatePrime; -exports.inflateSetDictionary = inflateSetDictionary; exports.inflateSync = inflateSync; exports.inflateSyncPoint = inflateSyncPoint; exports.inflateUndermine = inflateUndermine; */ -},{"../utils/common":1,"./adler32":2,"./crc32":3,"./inffast":4,"./inftrees":6}],6:[function(require,module,exports){ +},{"../utils/common":2,"./adler32":3,"./crc32":4,"./inffast":5,"./inftrees":7}],7:[function(require,module,exports){ 'use strict'; @@ -2072,8 +2149,8 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta var base_index = 0; // var shoextra; /* extra bits table to use */ var end; /* use base and extra for symbol > end */ - var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ - var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ + var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ var extra = null; var extra_index = 0; @@ -2242,7 +2319,7 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta return 1; } - var i=0; + var i = 0; /* process all codes and make table entries */ for (;;) { i++; @@ -2341,7 +2418,7 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta return 0; }; -},{"../utils/common":1}],7:[function(require,module,exports){ +},{"../utils/common":2}],8:[function(require,module,exports){ 'use strict'; @@ -2372,47 +2449,5 @@ function ZStream() { module.exports = ZStream; -},{}],8:[function(require,module,exports){ -var zlib = require('../node_modules/pako/lib/zlib/inflate.js'); -var ZStream = require('../node_modules/pako/lib/zlib/zstream.js'); - -var Inflate = function () { - this.strm = new ZStream(); - this.chunkSize = 1024 * 10 * 10; - this.strm.output = new Uint8Array(this.chunkSize); - this.windowBits = 5; - - zlib.inflateInit(this.strm, this.windowBits); -}; - -Inflate.prototype = { - inflate: function (data, flush, expected) { - this.strm.input = data; - this.strm.avail_in = this.strm.input.length; - this.strm.next_in = 0; - this.strm.next_out = 0; - - // resize our output buffer if it's too small - // (we could just use multiple chunks, but that would cause an extra - // allocation each time to flatten the chunks) - if (expected > this.chunkSize) { - this.chunkSize = expected; - this.strm.output = new Uint8Array(this.chunkSize); - } - - this.strm.avail_out = this.chunkSize; - - zlib.inflate(this.strm, flush); - - return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); - }, - - reset: function () { - zlib.inflateReset(this.strm); - } -}; - -module.exports = {Inflate: Inflate}; - -},{"../node_modules/pako/lib/zlib/inflate.js":5,"../node_modules/pako/lib/zlib/zstream.js":7}]},{},[8])(8) +},{}]},{},[1])(1) }); \ No newline at end of file diff --git a/utils/inflator.partial.js b/core/inflator.mod.js similarity index 83% rename from utils/inflator.partial.js rename to core/inflator.mod.js index 8b6d109..26e6441 100644 --- a/utils/inflator.partial.js +++ b/core/inflator.mod.js @@ -1,7 +1,7 @@ -var zlib = require('../node_modules/pako/lib/zlib/inflate.js'); -var ZStream = require('../node_modules/pako/lib/zlib/zstream.js'); +var zlib = require('pako/lib/zlib/inflate.js'); +var ZStream = require('pako/lib/zlib/zstream.js'); -var Inflate = function () { +function Inflate() { this.strm = new ZStream(); this.chunkSize = 1024 * 10 * 10; this.strm.output = new Uint8Array(this.chunkSize); @@ -37,4 +37,4 @@ Inflate.prototype = { } }; -module.exports = {Inflate: Inflate}; +module.exports = { Inflate: Inflate }; diff --git a/include/input.js b/core/input.js similarity index 95% rename from include/input.js rename to core/input.js index eb4d18a..ec5382f 100644 --- a/include/input.js +++ b/core/input.js @@ -8,7 +8,12 @@ /*jslint browser: true, white: false */ /*global window, Util */ -var Keyboard, Mouse; +/* [module] + * import Util from "./util"; + * import KeyboardUtil from "./keyboard"; + */ + +/* [module] export */ var Keyboard; (function () { "use strict"; @@ -27,10 +32,10 @@ var Keyboard, Mouse; }); // create the keyboard handler - this._handler = new KeyEventDecoder(kbdUtil.ModifierSync(), - VerifyCharModifier( /* jshint newcap: false */ - TrackKeyState( - EscapeModifiers(this._handleRfbEvent.bind(this)) + this._handler = new KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.VerifyCharModifier( /* jshint newcap: false */ + KeyboardUtil.TrackKeyState( + KeyboardUtil.EscapeModifiers(this._handleRfbEvent.bind(this)) ) ) ); /* jshint newcap: true */ @@ -56,8 +61,8 @@ var Keyboard, Mouse; }, setQEMUVNCKeyboardHandler: function () { - this._handler = new QEMUKeyEventDecoder(kbdUtil.ModifierSync(), - TrackQEMUKeyState( + this._handler = new KeyboardUtil.QEMUKeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.TrackQEMUKeyState( this._handleRfbEvent.bind(this) ) ); @@ -153,11 +158,11 @@ var Keyboard, Mouse; ['onKeyPress', 'rw', 'func'] // Handler for key press/release ]); +})(); - // - // Mouse event handler - // +/* [module] export */ var Mouse; +(function () { Mouse = function (defaults) { this._mouseCaptured = false; diff --git a/include/keyboard.js b/core/keyboard.js similarity index 81% rename from include/keyboard.js rename to core/keyboard.js index 26543db..efdcced 100644 --- a/include/keyboard.js +++ b/core/keyboard.js @@ -1,4 +1,11 @@ -var kbdUtil = (function() { +/* [module] + * import KeyTable from "./keysym"; + * import keysyms from "./keysymdef"; + */ + +var KeyboardUtil = {}; + +(function() { "use strict"; function substituteCodepoint(cp) { @@ -31,7 +38,7 @@ var kbdUtil = (function() { function hasShortcutModifier(charModifier, currentModifiers) { var mods = {}; for (var key in currentModifiers) { - if (parseInt(key) !== XK_Shift_L) { + if (parseInt(key) !== KeyTable.XK_Shift_L) { mods[key] = currentModifiers[key]; } } @@ -68,15 +75,15 @@ var kbdUtil = (function() { if (!charModifier) { if (isMac()) { // on Mac, Option (AKA Alt) is used as a char modifier - charModifier = [XK_Alt_L]; + charModifier = [KeyTable.XK_Alt_L]; } else if (isWindows()) { // on Windows, Ctrl+Alt is used as a char modifier - charModifier = [XK_Alt_L, XK_Control_L]; + charModifier = [KeyTable.XK_Alt_L, KeyTable.XK_Control_L]; } else if (isLinux()) { // on Linux, ISO Level 3 Shift (AltGr) is used as a char modifier - charModifier = [XK_ISO_Level3_Shift]; + charModifier = [KeyTable.XK_ISO_Level3_Shift]; } else { charModifier = []; @@ -84,11 +91,11 @@ var kbdUtil = (function() { } var state = {}; - state[XK_Control_L] = false; - state[XK_Alt_L] = false; - state[XK_ISO_Level3_Shift] = false; - state[XK_Shift_L] = false; - state[XK_Meta_L] = false; + state[KeyTable.XK_Control_L] = false; + state[KeyTable.XK_Alt_L] = false; + state[KeyTable.XK_ISO_Level3_Shift] = false; + state[KeyTable.XK_Shift_L] = false; + state[KeyTable.XK_Meta_L] = false; function sync(evt, keysym) { var result = []; @@ -97,29 +104,29 @@ var kbdUtil = (function() { } if (evt.ctrlKey !== undefined && - evt.ctrlKey !== state[XK_Control_L] && keysym !== XK_Control_L) { - state[XK_Control_L] = evt.ctrlKey; - result.push(syncKey(XK_Control_L)); + evt.ctrlKey !== state[KeyTable.XK_Control_L] && keysym !== KeyTable.XK_Control_L) { + state[KeyTable.XK_Control_L] = evt.ctrlKey; + result.push(syncKey(KeyTable.XK_Control_L)); } if (evt.altKey !== undefined && - evt.altKey !== state[XK_Alt_L] && keysym !== XK_Alt_L) { - state[XK_Alt_L] = evt.altKey; - result.push(syncKey(XK_Alt_L)); + evt.altKey !== state[KeyTable.XK_Alt_L] && keysym !== KeyTable.XK_Alt_L) { + state[KeyTable.XK_Alt_L] = evt.altKey; + result.push(syncKey(KeyTable.XK_Alt_L)); } if (evt.altGraphKey !== undefined && - evt.altGraphKey !== state[XK_ISO_Level3_Shift] && keysym !== XK_ISO_Level3_Shift) { - state[XK_ISO_Level3_Shift] = evt.altGraphKey; - result.push(syncKey(XK_ISO_Level3_Shift)); + evt.altGraphKey !== state[KeyTable.XK_ISO_Level3_Shift] && keysym !== KeyTable.XK_ISO_Level3_Shift) { + state[KeyTable.XK_ISO_Level3_Shift] = evt.altGraphKey; + result.push(syncKey(KeyTable.XK_ISO_Level3_Shift)); } if (evt.shiftKey !== undefined && - evt.shiftKey !== state[XK_Shift_L] && keysym !== XK_Shift_L) { - state[XK_Shift_L] = evt.shiftKey; - result.push(syncKey(XK_Shift_L)); + evt.shiftKey !== state[KeyTable.XK_Shift_L] && keysym !== KeyTable.XK_Shift_L) { + state[KeyTable.XK_Shift_L] = evt.shiftKey; + result.push(syncKey(KeyTable.XK_Shift_L)); } if (evt.metaKey !== undefined && - evt.metaKey !== state[XK_Meta_L] && keysym !== XK_Meta_L) { - state[XK_Meta_L] = evt.metaKey; - result.push(syncKey(XK_Meta_L)); + evt.metaKey !== state[KeyTable.XK_Meta_L] && keysym !== KeyTable.XK_Meta_L) { + state[KeyTable.XK_Meta_L] = evt.metaKey; + result.push(syncKey(KeyTable.XK_Meta_L)); } return result; } @@ -210,21 +217,21 @@ var kbdUtil = (function() { return shiftPressed ? keycode : keycode + 32; // A-Z } if (keycode >= 0x60 && keycode <= 0x69) { - return XK_KP_0 + (keycode - 0x60); // numpad 0-9 + return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9 } switch(keycode) { - case 0x20: return XK_space; - case 0x6a: return XK_KP_Multiply; - case 0x6b: return XK_KP_Add; - case 0x6c: return XK_KP_Separator; - case 0x6d: return XK_KP_Subtract; - case 0x6e: return XK_KP_Decimal; - case 0x6f: return XK_KP_Divide; - case 0xbb: return XK_plus; - case 0xbc: return XK_comma; - case 0xbd: return XK_minus; - case 0xbe: return XK_period; + case 0x20: return KeyTable.XK_space; + case 0x6a: return KeyTable.XK_KP_Multiply; + case 0x6b: return KeyTable.XK_KP_Add; + case 0x6c: return KeyTable.XK_KP_Separator; + case 0x6d: return KeyTable.XK_KP_Subtract; + case 0x6e: return KeyTable.XK_KP_Decimal; + case 0x6f: return KeyTable.XK_KP_Divide; + case 0xbb: return KeyTable.XK_plus; + case 0xbc: return KeyTable.XK_comma; + case 0xbd: return KeyTable.XK_minus; + case 0xbe: return KeyTable.XK_period; } return nonCharacterKey({keyCode: keycode}); @@ -238,54 +245,53 @@ var kbdUtil = (function() { var keycode = evt.keyCode; if (keycode >= 0x70 && keycode <= 0x87) { - return XK_F1 + keycode - 0x70; // F1-F24 + return KeyTable.XK_F1 + keycode - 0x70; // F1-F24 } switch (keycode) { - case 8 : return XK_BackSpace; - case 13 : return XK_Return; + case 8 : return KeyTable.XK_BackSpace; + case 13 : return KeyTable.XK_Return; - case 9 : return XK_Tab; + case 9 : return KeyTable.XK_Tab; - case 27 : return XK_Escape; - case 46 : return XK_Delete; + case 27 : return KeyTable.XK_Escape; + case 46 : return KeyTable.XK_Delete; - case 36 : return XK_Home; - case 35 : return XK_End; - case 33 : return XK_Page_Up; - case 34 : return XK_Page_Down; - case 45 : return XK_Insert; + case 36 : return KeyTable.XK_Home; + case 35 : return KeyTable.XK_End; + case 33 : return KeyTable.XK_Page_Up; + case 34 : return KeyTable.XK_Page_Down; + case 45 : return KeyTable.XK_Insert; - case 37 : return XK_Left; - case 38 : return XK_Up; - case 39 : return XK_Right; - case 40 : return XK_Down; + case 37 : return KeyTable.XK_Left; + case 38 : return KeyTable.XK_Up; + case 39 : return KeyTable.XK_Right; + case 40 : return KeyTable.XK_Down; - case 16 : return XK_Shift_L; - case 17 : return XK_Control_L; - case 18 : return XK_Alt_L; // also: Option-key on Mac + case 16 : return KeyTable.XK_Shift_L; + case 17 : return KeyTable.XK_Control_L; + case 18 : return KeyTable.XK_Alt_L; // also: Option-key on Mac - case 224 : return XK_Meta_L; - case 225 : return XK_ISO_Level3_Shift; // AltGr - case 91 : return XK_Super_L; // also: Windows-key - case 92 : return XK_Super_R; // also: Windows-key - case 93 : return XK_Menu; // also: Windows-Menu, Command on Mac + case 224 : return KeyTable.XK_Meta_L; + case 225 : return KeyTable.XK_ISO_Level3_Shift; // AltGr + case 91 : return KeyTable.XK_Super_L; // also: Windows-key + case 92 : return KeyTable.XK_Super_R; // also: Windows-key + case 93 : return KeyTable.XK_Menu; // also: Windows-Menu, Command on Mac default: return null; } } - return { - hasShortcutModifier : hasShortcutModifier, - hasCharModifier : hasCharModifier, - ModifierSync : ModifierSync, - getKey : getKey, - getKeysym : getKeysym, - keysymFromKeyCode : keysymFromKeyCode, - nonCharacterKey : nonCharacterKey, - substituteCodepoint : substituteCodepoint - }; + + KeyboardUtil.hasShortcutModifier = hasShortcutModifier; + KeyboardUtil.hasCharModifier = hasCharModifier; + KeyboardUtil.ModifierSync = ModifierSync; + KeyboardUtil.getKey = getKey; + KeyboardUtil.getKeysym = getKeysym; + KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode; + KeyboardUtil.nonCharacterKey = nonCharacterKey; + KeyboardUtil.substituteCodepoint = substituteCodepoint; })(); -function QEMUKeyEventDecoder(modifierState, next) { +KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) { "use strict"; function sendAll(evts) { @@ -331,7 +337,7 @@ function QEMUKeyEventDecoder(modifierState, next) { var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; - var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt)); + var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); next(result); return suppress; @@ -353,9 +359,9 @@ function QEMUKeyEventDecoder(modifierState, next) { }, releaseAll: function() { next({type: 'releaseall'}); } }; -} +}; -function TrackQEMUKeyState(next) { +KeyboardUtil.TrackQEMUKeyState = function(next) { "use strict"; var state = []; @@ -414,7 +420,7 @@ function TrackQEMUKeyState(next) { state = []; } }; -} +}; // Takes a DOM keyboard event and: // - determines which keysym it represents @@ -423,7 +429,7 @@ function TrackQEMUKeyState(next) { // - marks each event with an 'escape' property if a modifier was down which should be "escaped" // - generates a "stall" event in cases where it might be necessary to wait and see if a keypress event follows a keydown // This information is collected into an object which is passed to the next() function. (one call per event) -function KeyEventDecoder(modifierState, next) { +KeyboardUtil.KeyEventDecoder = function(modifierState, next) { "use strict"; function sendAll(evts) { for (var i = 0; i < evts.length; ++i) { @@ -432,18 +438,18 @@ function KeyEventDecoder(modifierState, next) { } function process(evt, type) { var result = {type: type}; - var keyId = kbdUtil.getKey(evt); + var keyId = KeyboardUtil.getKey(evt); if (keyId) { result.keyId = keyId; } - var keysym = kbdUtil.getKeysym(evt); + var keysym = KeyboardUtil.getKeysym(evt); var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); // Is this a case where we have to decide on the keysym right away, rather than waiting for the keypress? // "special" keys like enter, tab or backspace don't send keypress events, // and some browsers don't send keypresses at all if a modifier is down - if (keysym && (type !== 'keydown' || kbdUtil.nonCharacterKey(evt) || hasModifier)) { + if (keysym && (type !== 'keydown' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) { result.keysym = keysym; } @@ -452,11 +458,11 @@ function KeyEventDecoder(modifierState, next) { // Should we prevent the browser from handling the event? // Doing so on a keydown (in most browsers) prevents keypress from being generated // so only do that if we have to. - var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt)); + var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); // If a char modifier is down on a keydown, we need to insert a stall, // so VerifyCharModifier knows to wait and see if a keypress is comnig - var stall = type === 'keydown' && modifierState.activeCharModifier() && !kbdUtil.nonCharacterKey(evt); + var stall = type === 'keydown' && modifierState.activeCharModifier() && !KeyboardUtil.nonCharacterKey(evt); // if a char modifier is pressed, get the keys it consists of (on Windows, AltGr is equivalent to Ctrl+Alt) var active = modifierState.activeCharModifier(); @@ -502,7 +508,7 @@ function KeyEventDecoder(modifierState, next) { }, releaseAll: function() { next({type: 'releaseall'}); } }; -} +}; // Combines keydown and keypress events where necessary to handle char modifiers. // On some OS'es, a char modifier is sometimes used as a shortcut modifier. @@ -510,7 +516,7 @@ function KeyEventDecoder(modifierState, next) { // so when used with the '2' key, Ctrl-Alt counts as a char modifier (and should be escaped), but when used with 'D', it does not. // The only way we can distinguish these cases is to wait and see if a keypress event arrives // When we receive a "stall" event, wait a few ms before processing the next keydown. If a keypress has also arrived, merge the two -function VerifyCharModifier(next) { +KeyboardUtil.VerifyCharModifier = function(next) { "use strict"; var queue = []; var timer = null; @@ -560,14 +566,14 @@ function VerifyCharModifier(next) { queue.push(evt); process(); }; -} +}; // Keeps track of which keys we (and the server) believe are down // When a keyup is received, match it against this list, to determine the corresponding keysym(s) // in some cases, a single key may produce multiple keysyms, so the corresponding keyup event must release all of these chars // key repeat events should be merged into a single entry. // Because we can't always identify which entry a keydown or keyup event corresponds to, we sometimes have to guess -function TrackKeyState(next) { +KeyboardUtil.TrackKeyState = function(next) { "use strict"; var state = []; @@ -647,11 +653,11 @@ function TrackKeyState(next) { state = []; } }; -} +}; // Handles "escaping" of modifiers: if a char modifier is used to produce a keysym (such as AltGr-2 to generate an @), // then the modifier must be "undone" before sending the @, and "redone" afterwards. -function EscapeModifiers(next) { +KeyboardUtil.EscapeModifiers = function(next) { "use strict"; return function(evt) { if (evt.type !== 'keydown' || evt.escape === undefined) { @@ -671,4 +677,6 @@ function EscapeModifiers(next) { } /* jshint shadow: false */ }; -} +}; + +/* [module] export default KeyboardUtil; */ diff --git a/core/keysym.js b/core/keysym.js new file mode 100644 index 0000000..5983c38 --- /dev/null +++ b/core/keysym.js @@ -0,0 +1,382 @@ +var KeyTable = { + XK_VoidSymbol: 0xffffff, /* Void symbol */ + + XK_BackSpace: 0xff08, /* Back space, back char */ + XK_Tab: 0xff09, + XK_Linefeed: 0xff0a, /* Linefeed, LF */ + XK_Clear: 0xff0b, + XK_Return: 0xff0d, /* Return, enter */ + XK_Pause: 0xff13, /* Pause, hold */ + XK_Scroll_Lock: 0xff14, + XK_Sys_Req: 0xff15, + XK_Escape: 0xff1b, + XK_Delete: 0xffff, /* Delete, rubout */ + + /* Cursor control & motion */ + + XK_Home: 0xff50, + XK_Left: 0xff51, /* Move left, left arrow */ + XK_Up: 0xff52, /* Move up, up arrow */ + XK_Right: 0xff53, /* Move right, right arrow */ + XK_Down: 0xff54, /* Move down, down arrow */ + XK_Prior: 0xff55, /* Prior, previous */ + XK_Page_Up: 0xff55, + XK_Next: 0xff56, /* Next */ + XK_Page_Down: 0xff56, + XK_End: 0xff57, /* EOL */ + XK_Begin: 0xff58, /* BOL */ + + + /* Misc functions */ + + XK_Select: 0xff60, /* Select, mark */ + XK_Print: 0xff61, + XK_Execute: 0xff62, /* Execute, run, do */ + XK_Insert: 0xff63, /* Insert, insert here */ + XK_Undo: 0xff65, + XK_Redo: 0xff66, /* Redo, again */ + XK_Menu: 0xff67, + XK_Find: 0xff68, /* Find, search */ + XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */ + XK_Help: 0xff6a, /* Help */ + XK_Break: 0xff6b, + XK_Mode_switch: 0xff7e, /* Character set switch */ + XK_script_switch: 0xff7e, /* Alias for mode_switch */ + XK_Num_Lock: 0xff7f, + + /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + + XK_KP_Space: 0xff80, /* Space */ + XK_KP_Tab: 0xff89, + XK_KP_Enter: 0xff8d, /* Enter */ + XK_KP_F1: 0xff91, /* PF1, KP_A, ... */ + XK_KP_F2: 0xff92, + XK_KP_F3: 0xff93, + XK_KP_F4: 0xff94, + XK_KP_Home: 0xff95, + XK_KP_Left: 0xff96, + XK_KP_Up: 0xff97, + XK_KP_Right: 0xff98, + XK_KP_Down: 0xff99, + XK_KP_Prior: 0xff9a, + XK_KP_Page_Up: 0xff9a, + XK_KP_Next: 0xff9b, + XK_KP_Page_Down: 0xff9b, + XK_KP_End: 0xff9c, + XK_KP_Begin: 0xff9d, + XK_KP_Insert: 0xff9e, + XK_KP_Delete: 0xff9f, + XK_KP_Equal: 0xffbd, /* Equals */ + XK_KP_Multiply: 0xffaa, + XK_KP_Add: 0xffab, + XK_KP_Separator: 0xffac, /* Separator, often comma */ + XK_KP_Subtract: 0xffad, + XK_KP_Decimal: 0xffae, + XK_KP_Divide: 0xffaf, + + XK_KP_0: 0xffb0, + XK_KP_1: 0xffb1, + XK_KP_2: 0xffb2, + XK_KP_3: 0xffb3, + XK_KP_4: 0xffb4, + XK_KP_5: 0xffb5, + XK_KP_6: 0xffb6, + XK_KP_7: 0xffb7, + XK_KP_8: 0xffb8, + XK_KP_9: 0xffb9, + + /* + * Auxiliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufacturers have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + + XK_F1: 0xffbe, + XK_F2: 0xffbf, + XK_F3: 0xffc0, + XK_F4: 0xffc1, + XK_F5: 0xffc2, + XK_F6: 0xffc3, + XK_F7: 0xffc4, + XK_F8: 0xffc5, + XK_F9: 0xffc6, + XK_F10: 0xffc7, + XK_F11: 0xffc8, + XK_L1: 0xffc8, + XK_F12: 0xffc9, + XK_L2: 0xffc9, + XK_F13: 0xffca, + XK_L3: 0xffca, + XK_F14: 0xffcb, + XK_L4: 0xffcb, + XK_F15: 0xffcc, + XK_L5: 0xffcc, + XK_F16: 0xffcd, + XK_L6: 0xffcd, + XK_F17: 0xffce, + XK_L7: 0xffce, + XK_F18: 0xffcf, + XK_L8: 0xffcf, + XK_F19: 0xffd0, + XK_L9: 0xffd0, + XK_F20: 0xffd1, + XK_L10: 0xffd1, + XK_F21: 0xffd2, + XK_R1: 0xffd2, + XK_F22: 0xffd3, + XK_R2: 0xffd3, + XK_F23: 0xffd4, + XK_R3: 0xffd4, + XK_F24: 0xffd5, + XK_R4: 0xffd5, + XK_F25: 0xffd6, + XK_R5: 0xffd6, + XK_F26: 0xffd7, + XK_R6: 0xffd7, + XK_F27: 0xffd8, + XK_R7: 0xffd8, + XK_F28: 0xffd9, + XK_R8: 0xffd9, + XK_F29: 0xffda, + XK_R9: 0xffda, + XK_F30: 0xffdb, + XK_R10: 0xffdb, + XK_F31: 0xffdc, + XK_R11: 0xffdc, + XK_F32: 0xffdd, + XK_R12: 0xffdd, + XK_F33: 0xffde, + XK_R13: 0xffde, + XK_F34: 0xffdf, + XK_R14: 0xffdf, + XK_F35: 0xffe0, + XK_R15: 0xffe0, + + /* Modifiers */ + + XK_Shift_L: 0xffe1, /* Left shift */ + XK_Shift_R: 0xffe2, /* Right shift */ + XK_Control_L: 0xffe3, /* Left control */ + XK_Control_R: 0xffe4, /* Right control */ + XK_Caps_Lock: 0xffe5, /* Caps lock */ + XK_Shift_Lock: 0xffe6, /* Shift lock */ + + XK_Meta_L: 0xffe7, /* Left meta */ + XK_Meta_R: 0xffe8, /* Right meta */ + XK_Alt_L: 0xffe9, /* Left alt */ + XK_Alt_R: 0xffea, /* Right alt */ + XK_Super_L: 0xffeb, /* Left super */ + XK_Super_R: 0xffec, /* Right super */ + XK_Hyper_L: 0xffed, /* Left hyper */ + XK_Hyper_R: 0xffee, /* Right hyper */ + + XK_ISO_Level3_Shift: 0xfe03, /* AltGr */ + + /* + * Latin 1 + * (ISO/IEC 8859-1: Unicode U+0020..U+00FF) + * Byte 3: 0 + */ + + XK_space: 0x0020, /* U+0020 SPACE */ + XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */ + XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */ + XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */ + XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */ + XK_percent: 0x0025, /* U+0025 PERCENT SIGN */ + XK_ampersand: 0x0026, /* U+0026 AMPERSAND */ + XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */ + XK_quoteright: 0x0027, /* deprecated */ + XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */ + XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */ + XK_asterisk: 0x002a, /* U+002A ASTERISK */ + XK_plus: 0x002b, /* U+002B PLUS SIGN */ + XK_comma: 0x002c, /* U+002C COMMA */ + XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */ + XK_period: 0x002e, /* U+002E FULL STOP */ + XK_slash: 0x002f, /* U+002F SOLIDUS */ + XK_0: 0x0030, /* U+0030 DIGIT ZERO */ + XK_1: 0x0031, /* U+0031 DIGIT ONE */ + XK_2: 0x0032, /* U+0032 DIGIT TWO */ + XK_3: 0x0033, /* U+0033 DIGIT THREE */ + XK_4: 0x0034, /* U+0034 DIGIT FOUR */ + XK_5: 0x0035, /* U+0035 DIGIT FIVE */ + XK_6: 0x0036, /* U+0036 DIGIT SIX */ + XK_7: 0x0037, /* U+0037 DIGIT SEVEN */ + XK_8: 0x0038, /* U+0038 DIGIT EIGHT */ + XK_9: 0x0039, /* U+0039 DIGIT NINE */ + XK_colon: 0x003a, /* U+003A COLON */ + XK_semicolon: 0x003b, /* U+003B SEMICOLON */ + XK_less: 0x003c, /* U+003C LESS-THAN SIGN */ + XK_equal: 0x003d, /* U+003D EQUALS SIGN */ + XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */ + XK_question: 0x003f, /* U+003F QUESTION MARK */ + XK_at: 0x0040, /* U+0040 COMMERCIAL AT */ + XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ + XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ + XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ + XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ + XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ + XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ + XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ + XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ + XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ + XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */ + XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */ + XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */ + XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */ + XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */ + XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */ + XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ + XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ + XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ + XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ + XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ + XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ + XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ + XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ + XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ + XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ + XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ + XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */ + XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */ + XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */ + XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */ + XK_underscore: 0x005f, /* U+005F LOW LINE */ + XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */ + XK_quoteleft: 0x0060, /* deprecated */ + XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */ + XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */ + XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */ + XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */ + XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */ + XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */ + XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */ + XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */ + XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */ + XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */ + XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */ + XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */ + XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */ + XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */ + XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */ + XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */ + XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */ + XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */ + XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */ + XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */ + XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */ + XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */ + XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */ + XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */ + XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */ + XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */ + XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */ + XK_bar: 0x007c, /* U+007C VERTICAL LINE */ + XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */ + XK_asciitilde: 0x007e, /* U+007E TILDE */ + + XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */ + XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */ + XK_cent: 0x00a2, /* U+00A2 CENT SIGN */ + XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */ + XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */ + XK_yen: 0x00a5, /* U+00A5 YEN SIGN */ + XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */ + XK_section: 0x00a7, /* U+00A7 SECTION SIGN */ + XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */ + XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */ + XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */ + XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + XK_notsign: 0x00ac, /* U+00AC NOT SIGN */ + XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */ + XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */ + XK_macron: 0x00af, /* U+00AF MACRON */ + XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */ + XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */ + XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */ + XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */ + XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */ + XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */ + XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */ + XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */ + XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */ + XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */ + XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */ + XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */ + XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */ + XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */ + XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */ + XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ + XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ + XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ + XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ + XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ + XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */ + XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ + XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ + XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ + XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ + XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ + XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ + XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ + XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */ + XK_Eth: 0x00d0, /* deprecated */ + XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ + XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ + XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ + XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ + XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ + XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */ + XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ + XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ + XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ + XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ + XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */ + XK_Thorn: 0x00de, /* deprecated */ + XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */ + XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ + XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ + XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ + XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ + XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ + XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ + XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */ + XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ + XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ + XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ + XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ + XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ + XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ + XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ + XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ + XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ + XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */ + XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ + XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ + XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ + XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ + XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ + XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ + XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */ + XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ + XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ + XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ + XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ + XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ + XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ + XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ +}; + +/* [module] export default KeyTable; */ diff --git a/include/keysymdef.js b/core/keysymdef.js similarity index 99% rename from include/keysymdef.js rename to core/keysymdef.js index f94445c..f45d9d9 100644 --- a/include/keysymdef.js +++ b/core/keysymdef.js @@ -2,6 +2,7 @@ // (and optionally, key names) expected by the RFB protocol // How this file was generated: // node /Users/jalf/dev/mi/novnc/utils/parse.js /opt/X11/include/X11/keysymdef.h + var keysyms = (function(){ "use strict"; var keynames = null; @@ -13,3 +14,5 @@ var keysyms = (function(){ lookup : lookup }; })(); + +/* [module] export default keysyms */ diff --git a/include/rfb.js b/core/rfb.js similarity index 89% rename from include/rfb.js rename to core/rfb.js index ec2fd84..0ae96bd 100644 --- a/include/rfb.js +++ b/core/rfb.js @@ -10,236 +10,240 @@ * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) */ +/* [module] + * import Util from "./util"; + * import Display from "./display"; + * import { Keyboard, Mouse } from "./input" + * import Websock from "./websock" + * import Base64 from "./base64"; + * import DES from "./des"; + * import KeyTable from "./keysym"; + * import XtScancode from "./xtscancodes"; + * import Inflator from "./inflator.mod"; + */ /*jslint white: false, browser: true */ -/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES */ - -var RFB; +/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */ -(function () { +/* [module] export default */ function RFB(defaults) { "use strict"; - RFB = function (defaults) { - if (!defaults) { - defaults = {}; - } + if (!defaults) { + defaults = {}; + } + + this._rfb_host = ''; + this._rfb_port = 5900; + this._rfb_password = ''; + this._rfb_path = ''; + + this._rfb_state = 'disconnected'; + this._rfb_version = 0; + this._rfb_max_version = 3.8; + this._rfb_auth_scheme = ''; + + this._rfb_tightvnc = false; + this._rfb_xvp_ver = 0; + + // In preference order + this._encodings = [ + ['COPYRECT', 0x01 ], + ['TIGHT', 0x07 ], + ['TIGHT_PNG', -260 ], + ['HEXTILE', 0x05 ], + ['RRE', 0x02 ], + ['RAW', 0x00 ], + + // 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 ], + ['Cursor', -239 ], + ['QEMUExtendedKeyEvent', -258 ], + ['ExtendedDesktopSize', -308 ], + ['xvp', -309 ], + ['Fence', -312 ], + ['ContinuousUpdates', -313 ] + ]; + + this._encHandlers = {}; + this._encNames = {}; + this._encStats = {}; + + this._sock = null; // Websock object + this._display = null; // Display object + this._keyboard = null; // Keyboard input handler object + this._mouse = null; // Mouse input handler object + this._disconnTimer = null; // disconnection timer + this._msgTimer = null; // queued handle_msg timer + + this._supportsFence = false; + + this._supportsContinuousUpdates = false; + this._enabledContinuousUpdates = false; + + // Frame buffer update state + this._FBU = { + rects: 0, + subrects: 0, // RRE + lines: 0, // RAW + tiles: 0, // HEXTILE + bytes: 0, + x: 0, + y: 0, + width: 0, + height: 0, + encoding: 0, + subencoding: -1, + background: null, + zlib: [] // TIGHT zlib streams + }; - this._rfb_host = ''; - this._rfb_port = 5900; - this._rfb_password = ''; - this._rfb_path = ''; - - this._rfb_state = 'disconnected'; - this._rfb_version = 0; - this._rfb_max_version = 3.8; - this._rfb_auth_scheme = ''; - - this._rfb_tightvnc = false; - this._rfb_xvp_ver = 0; - - // In preference order - this._encodings = [ - ['COPYRECT', 0x01 ], - ['TIGHT', 0x07 ], - ['TIGHT_PNG', -260 ], - ['HEXTILE', 0x05 ], - ['RRE', 0x02 ], - ['RAW', 0x00 ], - - // 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 ], - ['Cursor', -239 ], - ['QEMUExtendedKeyEvent', -258 ], - ['ExtendedDesktopSize', -308 ], - ['xvp', -309 ], - ['Fence', -312 ], - ['ContinuousUpdates', -313 ] - ]; - - this._encHandlers = {}; - this._encNames = {}; - this._encStats = {}; - - this._sock = null; // Websock object - this._display = null; // Display object - this._keyboard = null; // Keyboard input handler object - this._mouse = null; // Mouse input handler object - this._disconnTimer = null; // disconnection timer - this._msgTimer = null; // queued handle_msg timer - - this._supportsFence = false; - - this._supportsContinuousUpdates = false; - this._enabledContinuousUpdates = false; - - // Frame buffer update state - this._FBU = { - rects: 0, - subrects: 0, // RRE - lines: 0, // RAW - tiles: 0, // HEXTILE - bytes: 0, - x: 0, - y: 0, - width: 0, - height: 0, - encoding: 0, - subencoding: -1, - background: null, - zlib: [] // TIGHT zlib streams - }; - - this._fb_Bpp = 4; - this._fb_depth = 3; - this._fb_width = 0; - this._fb_height = 0; - this._fb_name = ""; - - this._destBuff = null; - this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) - - this._rre_chunk_sz = 100; - - this._timing = { - last_fbu: 0, - fbu_total: 0, - fbu_total_cnt: 0, - full_fbu_total: 0, - full_fbu_cnt: 0, - - fbu_rt_start: 0, - fbu_rt_total: 0, - fbu_rt_cnt: 0, - pixels: 0 - }; - - this._supportsSetDesktopSize = false; - this._screen_id = 0; - this._screen_flags = 0; - - // Mouse state - this._mouse_buttonMask = 0; - this._mouse_arr = []; - this._viewportDragging = false; - this._viewportDragPos = {}; - this._viewportHasMoved = false; - - // QEMU Extended Key Event support - default to false - this._qemuExtKeyEventSupported = false; - - // set the default value on user-facing properties - Util.set_defaults(this, defaults, { - 'target': 'null', // VNC display rendering Canvas object - 'focusContainer': document, // DOM element that captures keyboard input - 'encrypt': false, // Use TLS/SSL/wss encryption - 'true_color': true, // Request true color pixel data - 'local_cursor': false, // Request locally rendered cursor - 'shared': true, // Request shared mode - 'view_only': false, // Disable client mouse/keyboard - 'xvp_password_sep': '@', // Separator for XVP password fields - 'disconnectTimeout': 3, // Time (s) to wait for disconnection - 'wsProtocols': ['binary'], // Protocols to use in the WebSocket connection - 'repeaterID': '', // [UltraVNC] RepeaterID to connect to - 'viewportDrag': false, // Move the viewport on mouse drags - - // Callback functions - 'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change - 'onPasswordRequired': function () { }, // onPasswordRequired(rfb): VNC password is required - 'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received - 'onBell': function () { }, // onBell(rfb): RFB Bell message received - 'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed - '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 - }); - - // main setup - Util.Debug(">> RFB.constructor"); - - // populate encHandlers with bound versions - Object.keys(RFB.encodingHandlers).forEach(function (encName) { - this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this); - }.bind(this)); - - // Create lookup tables based on encoding number - for (var i = 0; i < this._encodings.length; i++) { - this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]]; - this._encNames[this._encodings[i][1]] = this._encodings[i][0]; - this._encStats[this._encodings[i][1]] = [0, 0]; - } + this._fb_Bpp = 4; + this._fb_depth = 3; + this._fb_width = 0; + this._fb_height = 0; + this._fb_name = ""; - // NB: nothing that needs explicit teardown should be done - // before this point, since this can throw an exception - try { - this._display = new Display({target: this._target}); - } catch (exc) { - Util.Error("Display exception: " + exc); - throw exc; - } + this._destBuff = null; + this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) - this._keyboard = new Keyboard({target: this._focusContainer, - onKeyPress: this._handleKeyPress.bind(this)}); + this._rre_chunk_sz = 100; - this._mouse = new Mouse({target: this._target, - onMouseButton: this._handleMouseButton.bind(this), - onMouseMove: this._handleMouseMove.bind(this), - notify: this._keyboard.sync.bind(this._keyboard)}); + this._timing = { + last_fbu: 0, + fbu_total: 0, + fbu_total_cnt: 0, + full_fbu_total: 0, + full_fbu_cnt: 0, - this._sock = new Websock(); - this._sock.on('message', this._handle_message.bind(this)); - this._sock.on('open', function () { - if (this._rfb_state === 'connect') { - this._updateState('ProtocolVersion', "Starting VNC handshake"); - } else { - this._fail("Got unexpected WebSocket connection"); - } - }.bind(this)); - this._sock.on('close', function (e) { - Util.Warn("WebSocket on-close event"); - var msg = ""; - if (e.code) { - msg = " (code: " + e.code; - if (e.reason) { - msg += ", reason: " + e.reason; - } - msg += ")"; - } - if (this._rfb_state === 'disconnect') { - this._updateState('disconnected', 'VNC disconnected' + msg); - } else if (this._rfb_state === 'ProtocolVersion') { - this._fail('Failed to connect to server' + msg); - } else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) { - Util.Error("Received onclose while disconnected" + msg); - } else { - this._fail("Server disconnected" + msg); - } - this._sock.off('close'); - }.bind(this)); - this._sock.on('error', function (e) { - Util.Warn("WebSocket on-error event"); - }); + fbu_rt_start: 0, + fbu_rt_total: 0, + fbu_rt_cnt: 0, + pixels: 0 + }; - this._init_vars(); + this._supportsSetDesktopSize = false; + this._screen_id = 0; + this._screen_flags = 0; + + // Mouse state + this._mouse_buttonMask = 0; + this._mouse_arr = []; + this._viewportDragging = false; + this._viewportDragPos = {}; + this._viewportHasMoved = false; + + // QEMU Extended Key Event support - default to false + this._qemuExtKeyEventSupported = false; + + // set the default value on user-facing properties + Util.set_defaults(this, defaults, { + 'target': 'null', // VNC display rendering Canvas object + 'focusContainer': document, // DOM element that captures keyboard input + 'encrypt': false, // Use TLS/SSL/wss encryption + 'true_color': true, // Request true color pixel data + 'local_cursor': false, // Request locally rendered cursor + 'shared': true, // Request shared mode + 'view_only': false, // Disable client mouse/keyboard + 'xvp_password_sep': '@', // Separator for XVP password fields + 'disconnectTimeout': 3, // Time (s) to wait for disconnection + 'wsProtocols': ['binary'], // Protocols to use in the WebSocket connection + 'repeaterID': '', // [UltraVNC] RepeaterID to connect to + 'viewportDrag': false, // Move the viewport on mouse drags - var rmode = this._display.get_render_mode(); - if (Websock_native) { - Util.Info("Using native WebSockets"); - this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode); + // Callback functions + 'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change + 'onPasswordRequired': function () { }, // onPasswordRequired(rfb): VNC password is required + 'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received + 'onBell': function () { }, // onBell(rfb): RFB Bell message received + 'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed + '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 + }); + + // main setup + Util.Debug(">> RFB.constructor"); + + // populate encHandlers with bound versions + Object.keys(RFB.encodingHandlers).forEach(function (encName) { + this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this); + }.bind(this)); + + // Create lookup tables based on encoding number + for (var i = 0; i < this._encodings.length; i++) { + this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]]; + this._encNames[this._encodings[i][1]] = this._encodings[i][0]; + this._encStats[this._encodings[i][1]] = [0, 0]; + } + + // NB: nothing that needs explicit teardown should be done + // before this point, since this can throw an exception + try { + this._display = new Display({target: this._target}); + } catch (exc) { + Util.Error("Display exception: " + exc); + throw exc; + } + + this._keyboard = new Keyboard({target: this._focusContainer, + onKeyPress: this._handleKeyPress.bind(this)}); + + this._mouse = new Mouse({target: this._target, + onMouseButton: this._handleMouseButton.bind(this), + onMouseMove: this._handleMouseMove.bind(this), + notify: this._keyboard.sync.bind(this._keyboard)}); + + this._sock = new Websock(); + this._sock.on('message', this._handle_message.bind(this)); + this._sock.on('open', function () { + if (this._rfb_state === 'connect') { + this._updateState('ProtocolVersion', "Starting VNC handshake"); } else { - this._cleanupSocket('fatal'); - throw new Error("WebSocket support is required to use noVNC"); + this._fail("Got unexpected WebSocket connection"); } + }.bind(this)); + this._sock.on('close', function (e) { + Util.Warn("WebSocket on-close event"); + var msg = ""; + if (e.code) { + msg = " (code: " + e.code; + if (e.reason) { + msg += ", reason: " + e.reason; + } + msg += ")"; + } + if (this._rfb_state === 'disconnect') { + this._updateState('disconnected', 'VNC disconnected' + msg); + } else if (this._rfb_state === 'ProtocolVersion') { + this._fail('Failed to connect to server' + msg); + } else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) { + Util.Error("Received onclose while disconnected" + msg); + } else { + this._fail("Server disconnected" + msg); + } + this._sock.off('close'); + }.bind(this)); + this._sock.on('error', function (e) { + Util.Warn("WebSocket on-error event"); + }); - Util.Debug("<< RFB.constructor"); - }; + this._init_vars(); + + var rmode = this._display.get_render_mode(); + Util.Info("Using native WebSockets"); + this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode); + + Util.Debug("<< RFB.constructor"); +}; +(function() { RFB.prototype = { // Public methods connect: function (host, port, password, path) { @@ -273,12 +277,12 @@ var RFB; if (this._rfb_state !== 'normal' || this._view_only) { return false; } Util.Info("Sending Ctrl-Alt-Del"); - RFB.messages.keyEvent(this._sock, XK_Control_L, 1); - RFB.messages.keyEvent(this._sock, XK_Alt_L, 1); - RFB.messages.keyEvent(this._sock, XK_Delete, 1); - 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); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 0); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 0); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 0); return true; }, @@ -372,7 +376,7 @@ var RFB; } for (i = 0; i < 4; i++) { - this._FBU.zlibs[i] = new inflator.Inflate(); + this._FBU.zlibs[i] = new Inflator.Inflate(); } }, diff --git a/include/util.js b/core/util.js similarity index 93% rename from include/util.js rename to core/util.js index ed0e3cd..1b8744b 100644 --- a/include/util.js +++ b/core/util.js @@ -9,7 +9,6 @@ /* jshint white: false, nonstandard: true */ /*global window, console, document, navigator, ActiveXObject, INCLUDE_URI */ -// Globals defined here var Util = {}; @@ -376,12 +375,12 @@ Util.decodeUTF8 = function (utf8string) { // 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 () { - return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/"; +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) { +Util.load_scripts = function (files_by_dir) { "use strict"; var head = document.getElementsByTagName('head')[0], script, ls = Util._loading_scripts, ps = Util._pending_scripts; @@ -410,25 +409,32 @@ Util.load_scripts = function (files) { } }; - for (var f = 0; f < files.length; f++) { - script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = Util.get_include_uri() + 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); + 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); } - ps.push(script); } }; @@ -620,3 +626,5 @@ Util.Flash = (function () { version = v.match(/\d+/g); return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; }()); + +/* [module] export default Util; */ diff --git a/include/websock.js b/core/websock.js similarity index 96% rename from include/websock.js rename to core/websock.js index 4d7a4f9..1271d2f 100644 --- a/include/websock.js +++ b/core/websock.js @@ -14,29 +14,15 @@ * read binary data off of the receive queue. */ +/* [module] + * import Util from "./util"; + * import Base64 from "./base64"; + */ + /*jslint browser: true, bitwise: true */ /*global Util*/ - -// Load Flash WebSocket emulator if needed - -// To force WebSocket emulator even when native WebSocket available -//window.WEB_SOCKET_FORCE_FLASH = true; -// To enable WebSocket emulator debug: -//window.WEB_SOCKET_DEBUG=1; - -if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) { - Websock_native = true; -} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) { - Websock_native = true; - window.WebSocket = window.MozWebSocket; -} else { - /* no builtin WebSocket so load web_socket.js */ - - Websock_native = false; -} - -function Websock() { +/* [module] export default */ function Websock() { "use strict"; this._websocket = null; // WebSocket object @@ -62,7 +48,7 @@ function Websock() { 'close': function () {}, 'error': function () {} }; -} +}; (function () { "use strict"; diff --git a/core/xtscancodes.js b/core/xtscancodes.js new file mode 100644 index 0000000..89d824c --- /dev/null +++ b/core/xtscancodes.js @@ -0,0 +1,149 @@ +var XtScancode = { + "Escape": 0x0001, + "Digit1": 0x0002, + "Digit2": 0x0003, + "Digit3": 0x0004, + "Digit4": 0x0005, + "Digit5": 0x0006, + "Digit6": 0x0007, + "Digit7": 0x0008, + "Digit8": 0x0009, + "Digit9": 0x000A, + "Digit0": 0x000B, + "Minus": 0x000C, + "Equal": 0x000D, + "Backspace": 0x000E, + "Tab": 0x000F, + "KeyQ": 0x0010, + "KeyW": 0x0011, + "KeyE": 0x0012, + "KeyR": 0x0013, + "KeyT": 0x0014, + "KeyY": 0x0015, + "KeyU": 0x0016, + "KeyI": 0x0017, + "KeyO": 0x0018, + "KeyP": 0x0019, + "BracketLeft": 0x001A, + "BracketRight": 0x001B, + "Enter": 0x001C, + "ControlLeft": 0x001D, + "KeyA": 0x001E, + "KeyS": 0x001F, + "KeyD": 0x0020, + "KeyF": 0x0021, + "KeyG": 0x0022, + "KeyH": 0x0023, + "KeyJ": 0x0024, + "KeyK": 0x0025, + "KeyL": 0x0026, + "Semicolon": 0x0027, + "Quote": 0x0028, + "Backquote": 0x0029, + "ShiftLeft": 0x002A, + "Backslash": 0x002B, + "KeyZ": 0x002C, + "KeyX": 0x002D, + "KeyC": 0x002E, + "KeyV": 0x002F, + "KeyB": 0x0030, + "KeyN": 0x0031, + "KeyM": 0x0032, + "Comma": 0x0033, + "Period": 0x0034, + "Slash": 0x0035, + "ShiftRight": 0x0036, + "NumpadMultiply": 0x0037, + "AltLeft": 0x0038, + "Space": 0x0039, + "CapsLock": 0x003A, + "F1": 0x003B, + "F2": 0x003C, + "F3": 0x003D, + "F4": 0x003E, + "F5": 0x003F, + "F6": 0x0040, + "F7": 0x0041, + "F8": 0x0042, + "F9": 0x0043, + "F10": 0x0044, + "Pause": 0xE045, + "ScrollLock": 0x0046, + "Numpad7": 0x0047, + "Numpad8": 0x0048, + "Numpad9": 0x0049, + "NumpadSubtract": 0x004A, + "Numpad4": 0x004B, + "Numpad5": 0x004C, + "Numpad6": 0x004D, + "NumpadAdd": 0x004E, + "Numpad1": 0x004F, + "Numpad2": 0x0050, + "Numpad3": 0x0051, + "Numpad0": 0x0052, + "NumpadDecimal": 0x0053, + "IntlBackslash": 0x0056, + "F11": 0x0057, + "F12": 0x0058, + "IntlYen": 0x007D, + "MediaTrackPrevious": 0xE010, + "MediaTrackNext": 0xE019, + "NumpadEnter": 0xE01C, + "ControlRight": 0xE01D, + "VolumeMute": 0xE020, + "MediaPlayPause": 0xE022, + "MediaStop": 0xE024, + "VolumeDown": 0xE02E, + "VolumeUp": 0xE030, + "BrowserHome": 0xE032, + "NumpadDivide": 0xE035, + "PrintScreen": 0xE037, + "AltRight": 0xE038, + "NumLock": 0x0045, + "Home": 0xE047, + "ArrowUp": 0xE048, + "PageUp": 0xE049, + "ArrowLeft": 0xE04B, + "ArrowRight": 0xE04D, + "End": 0xE04F, + "ArrowDown": 0xE050, + "PageDown": 0xE051, + "Insert": 0xE052, + "Delete": 0xE053, + "OSLeft": 0xE05B, + "OSRight": 0xE05C, + "ContextMenu": 0xE05D, + "BrowserSearch": 0xE065, + "BrowserFavorites": 0xE066, + "BrowserRefresh": 0xE067, + "BrowserStop": 0xE068, + "BrowserForward": 0xE069, + "BrowserBack": 0xE06A, + "NumpadComma": 0x007E, + "NumpadEqual": 0x0059, + "F13": 0x0064, + "F14": 0x0065, + "F15": 0x0066, + "F16": 0x0067, + "F17": 0x0068, + "F18": 0x0069, + "F19": 0x006A, + "F20": 0x006B, + "F21": 0x006C, + "F22": 0x006D, + "F23": 0x006E, + "F24": 0x0076, + "KanaMode": 0x0070, + "Lang2": 0x0071, + "Lang1": 0x0072, + "IntlRo": 0x0073, + "Convert": 0x0079, + "NonConvert": 0x007B, + "LaunchApp2": 0xE021, + "Power": 0xE05E, + "LaunchApp1": 0xE06B, + "LaunchMail": 0xE06C, + "MediaSelect": 0xE06D, +}; + +/* [module] export default XtScancode */ diff --git a/docs/notes b/docs/notes index 036cd51..dfef0bd 100644 --- a/docs/notes +++ b/docs/notes @@ -2,4 +2,4 @@ Rebuilding inflator.js - Download pako from npm - Install browserify using npm -- browserify utils/inflator.partial.js -o include/inflator.js -s inflator +- browserify core/inflator.mod.js -o core/inflator.js -s Inflator diff --git a/favicon.ico b/favicon.ico index 45399c8..af26b7b 120000 --- a/favicon.ico +++ b/favicon.ico @@ -1 +1 @@ -images/favicon.ico \ No newline at end of file +app/images/favicon.ico \ No newline at end of file diff --git a/include/chrome-app/tcp-client.js b/include/chrome-app/tcp-client.js deleted file mode 100644 index b8c125f..0000000 --- a/include/chrome-app/tcp-client.js +++ /dev/null @@ -1,321 +0,0 @@ -/* -Copyright 2012 Google Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -Author: Boris Smus (smus@chromium.org) -*/ - -(function(exports) { - - // Define some local variables here. - var socket = chrome.socket || chrome.experimental.socket; - var dns = chrome.experimental.dns; - - /** - * Creates an instance of the client - * - * @param {String} host The remote host to connect to - * @param {Number} port The port to connect to at the remote host - */ - function TcpClient(host, port, pollInterval) { - this.host = host; - this.port = port; - this.pollInterval = pollInterval || 15; - - // Callback functions. - this.callbacks = { - connect: null, // Called when socket is connected. - disconnect: null, // Called when socket is disconnected. - recvBuffer: null, // Called (as ArrayBuffer) when client receives data from server. - recvString: null, // Called (as string) when client receives data from server. - sent: null // Called when client sends data to server. - }; - - // Socket. - this.socketId = null; - this.isConnected = false; - - log('initialized tcp client'); - } - - /** - * Connects to the TCP socket, and creates an open socket. - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-create - * @param {Function} callback The function to call on connection - */ - TcpClient.prototype.connect = function(callback) { - // First resolve the hostname to an IP. - dns.resolve(this.host, function(result) { - this.addr = result.address; - socket.create('tcp', {}, this._onCreate.bind(this)); - - // Register connect callback. - this.callbacks.connect = callback; - }.bind(this)); - }; - - /** - * Sends an arraybuffer/view down the wire to the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-write - * @param {String} msg The arraybuffer/view to send - * @param {Function} callback The function to call when the message has sent - */ - TcpClient.prototype.sendBuffer = function(buf, callback) { - if (buf.buffer) { - buf = buf.buffer; - } - - /* - // Debug - var bytes = [], u8 = new Uint8Array(buf); - for (var i = 0; i < u8.length; i++) { - bytes.push(u8[i]); - } - log("sending bytes: " + (bytes.join(','))); - */ - - socket.write(this.socketId, buf, this._onWriteComplete.bind(this)); - - // Register sent callback. - this.callbacks.sent = callback; - }; - - /** - * Sends a string down the wire to the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-write - * @param {String} msg The string to send - * @param {Function} callback The function to call when the message has sent - */ - TcpClient.prototype.sendString = function(msg, callback) { - /* - // Debug - log("sending string: " + msg); - */ - - this._stringToArrayBuffer(msg, function(arrayBuffer) { - socket.write(this.socketId, arrayBuffer, this._onWriteComplete.bind(this)); - }.bind(this)); - - // Register sent callback. - this.callbacks.sent = callback; - }; - - /** - * Sets the callback for when a message is received - * - * @param {Function} callback The function to call when a message has arrived - * @param {String} type The callback argument type: "arraybuffer" or "string" - */ - TcpClient.prototype.addResponseListener = function(callback, type) { - if (typeof type === "undefined") { - type = "arraybuffer"; - } - // Register received callback. - if (type === "string") { - this.callbacks.recvString = callback; - } else { - this.callbacks.recvBuffer = callback; - } - }; - - /** - * Sets the callback for when the socket disconnects - * - * @param {Function} callback The function to call when the socket disconnects - * @param {String} type The callback argument type: "arraybuffer" or "string" - */ - TcpClient.prototype.addDisconnectListener = function(callback) { - // Register disconnect callback. - this.callbacks.disconnect = callback; - }; - - /** - * Disconnects from the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-disconnect - */ - TcpClient.prototype.disconnect = function() { - if (this.isConnected) { - this.isConnected = false; - socket.disconnect(this.socketId); - if (this.callbacks.disconnect) { - this.callbacks.disconnect(); - } - log('socket disconnected'); - } - }; - - /** - * The callback function used for when we attempt to have Chrome - * create a socket. If the socket is successfully created - * we go ahead and connect to the remote side. - * - * @private - * @see http://developer.chrome.com/trunk/apps/socket.html#method-connect - * @param {Object} createInfo The socket details - */ - TcpClient.prototype._onCreate = function(createInfo) { - this.socketId = createInfo.socketId; - if (this.socketId > 0) { - socket.connect(this.socketId, this.addr, this.port, this._onConnectComplete.bind(this)); - } else { - error('Unable to create socket'); - } - }; - - /** - * The callback function used for when we attempt to have Chrome - * connect to the remote side. If a successful connection is - * made then polling starts to check for data to read - * - * @private - * @param {Number} resultCode Indicates whether the connection was successful - */ - TcpClient.prototype._onConnectComplete = function(resultCode) { - // Start polling for reads. - this.isConnected = true; - setTimeout(this._periodicallyRead.bind(this), this.pollInterval); - - if (this.callbacks.connect) { - log('connect complete'); - this.callbacks.connect(); - } - log('onConnectComplete'); - }; - - /** - * Checks for new data to read from the socket - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-read - */ - TcpClient.prototype._periodicallyRead = function() { - var that = this; - socket.getInfo(this.socketId, function (info) { - if (info.connected) { - setTimeout(that._periodicallyRead.bind(that), that.pollInterval); - socket.read(that.socketId, null, that._onDataRead.bind(that)); - } else if (that.isConnected) { - log('socket disconnect detected'); - that.disconnect(); - } - }); - }; - - /** - * Callback function for when data has been read from the socket. - * Converts the array buffer that is read in to a string - * and sends it on for further processing by passing it to - * the previously assigned callback function. - * - * @private - * @see TcpClient.prototype.addResponseListener - * @param {Object} readInfo The incoming message - */ - TcpClient.prototype._onDataRead = function(readInfo) { - // Call received callback if there's data in the response. - if (readInfo.resultCode > 0) { - log('onDataRead'); - - /* - // Debug - var bytes = [], u8 = new Uint8Array(readInfo.data); - for (var i = 0; i < u8.length; i++) { - bytes.push(u8[i]); - } - log("received bytes: " + (bytes.join(','))); - */ - - if (this.callbacks.recvBuffer) { - // Return raw ArrayBuffer directly. - this.callbacks.recvBuffer(readInfo.data); - } - if (this.callbacks.recvString) { - // Convert ArrayBuffer to string. - this._arrayBufferToString(readInfo.data, function(str) { - this.callbacks.recvString(str); - }.bind(this)); - } - - // Trigger another read right away - setTimeout(this._periodicallyRead.bind(this), 0); - } - }; - - /** - * Callback for when data has been successfully - * written to the socket. - * - * @private - * @param {Object} writeInfo The outgoing message - */ - TcpClient.prototype._onWriteComplete = function(writeInfo) { - log('onWriteComplete'); - // Call sent callback. - if (this.callbacks.sent) { - this.callbacks.sent(writeInfo); - } - }; - - /** - * Converts an array buffer to a string - * - * @private - * @param {ArrayBuffer} buf The buffer to convert - * @param {Function} callback The function to call when conversion is complete - */ - TcpClient.prototype._arrayBufferToString = function(buf, callback) { - var bb = new Blob([new Uint8Array(buf)]); - var f = new FileReader(); - f.onload = function(e) { - callback(e.target.result); - }; - f.readAsText(bb); - }; - - /** - * Converts a string to an array buffer - * - * @private - * @param {String} str The string to convert - * @param {Function} callback The function to call when conversion is complete - */ - TcpClient.prototype._stringToArrayBuffer = function(str, callback) { - var bb = new Blob([str]); - var f = new FileReader(); - f.onload = function(e) { - callback(e.target.result); - }; - f.readAsArrayBuffer(bb); - }; - - /** - * Wrapper function for logging - */ - function log(msg) { - console.log(msg); - } - - /** - * Wrapper function for error logging - */ - function error(msg) { - console.error(msg); - } - - exports.TcpClient = TcpClient; - -})(window); diff --git a/include/keysym.js b/include/keysym.js deleted file mode 100644 index 58b107c..0000000 --- a/include/keysym.js +++ /dev/null @@ -1,378 +0,0 @@ -var XK_VoidSymbol = 0xffffff, /* Void symbol */ - -XK_BackSpace = 0xff08, /* Back space, back char */ -XK_Tab = 0xff09, -XK_Linefeed = 0xff0a, /* Linefeed, LF */ -XK_Clear = 0xff0b, -XK_Return = 0xff0d, /* Return, enter */ -XK_Pause = 0xff13, /* Pause, hold */ -XK_Scroll_Lock = 0xff14, -XK_Sys_Req = 0xff15, -XK_Escape = 0xff1b, -XK_Delete = 0xffff, /* Delete, rubout */ - -/* Cursor control & motion */ - -XK_Home = 0xff50, -XK_Left = 0xff51, /* Move left, left arrow */ -XK_Up = 0xff52, /* Move up, up arrow */ -XK_Right = 0xff53, /* Move right, right arrow */ -XK_Down = 0xff54, /* Move down, down arrow */ -XK_Prior = 0xff55, /* Prior, previous */ -XK_Page_Up = 0xff55, -XK_Next = 0xff56, /* Next */ -XK_Page_Down = 0xff56, -XK_End = 0xff57, /* EOL */ -XK_Begin = 0xff58, /* BOL */ - - -/* Misc functions */ - -XK_Select = 0xff60, /* Select, mark */ -XK_Print = 0xff61, -XK_Execute = 0xff62, /* Execute, run, do */ -XK_Insert = 0xff63, /* Insert, insert here */ -XK_Undo = 0xff65, -XK_Redo = 0xff66, /* Redo, again */ -XK_Menu = 0xff67, -XK_Find = 0xff68, /* Find, search */ -XK_Cancel = 0xff69, /* Cancel, stop, abort, exit */ -XK_Help = 0xff6a, /* Help */ -XK_Break = 0xff6b, -XK_Mode_switch = 0xff7e, /* Character set switch */ -XK_script_switch = 0xff7e, /* Alias for mode_switch */ -XK_Num_Lock = 0xff7f, - -/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ - -XK_KP_Space = 0xff80, /* Space */ -XK_KP_Tab = 0xff89, -XK_KP_Enter = 0xff8d, /* Enter */ -XK_KP_F1 = 0xff91, /* PF1, KP_A, ... */ -XK_KP_F2 = 0xff92, -XK_KP_F3 = 0xff93, -XK_KP_F4 = 0xff94, -XK_KP_Home = 0xff95, -XK_KP_Left = 0xff96, -XK_KP_Up = 0xff97, -XK_KP_Right = 0xff98, -XK_KP_Down = 0xff99, -XK_KP_Prior = 0xff9a, -XK_KP_Page_Up = 0xff9a, -XK_KP_Next = 0xff9b, -XK_KP_Page_Down = 0xff9b, -XK_KP_End = 0xff9c, -XK_KP_Begin = 0xff9d, -XK_KP_Insert = 0xff9e, -XK_KP_Delete = 0xff9f, -XK_KP_Equal = 0xffbd, /* Equals */ -XK_KP_Multiply = 0xffaa, -XK_KP_Add = 0xffab, -XK_KP_Separator = 0xffac, /* Separator, often comma */ -XK_KP_Subtract = 0xffad, -XK_KP_Decimal = 0xffae, -XK_KP_Divide = 0xffaf, - -XK_KP_0 = 0xffb0, -XK_KP_1 = 0xffb1, -XK_KP_2 = 0xffb2, -XK_KP_3 = 0xffb3, -XK_KP_4 = 0xffb4, -XK_KP_5 = 0xffb5, -XK_KP_6 = 0xffb6, -XK_KP_7 = 0xffb7, -XK_KP_8 = 0xffb8, -XK_KP_9 = 0xffb9, - -/* - * Auxiliary functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufacturers have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -XK_F1 = 0xffbe, -XK_F2 = 0xffbf, -XK_F3 = 0xffc0, -XK_F4 = 0xffc1, -XK_F5 = 0xffc2, -XK_F6 = 0xffc3, -XK_F7 = 0xffc4, -XK_F8 = 0xffc5, -XK_F9 = 0xffc6, -XK_F10 = 0xffc7, -XK_F11 = 0xffc8, -XK_L1 = 0xffc8, -XK_F12 = 0xffc9, -XK_L2 = 0xffc9, -XK_F13 = 0xffca, -XK_L3 = 0xffca, -XK_F14 = 0xffcb, -XK_L4 = 0xffcb, -XK_F15 = 0xffcc, -XK_L5 = 0xffcc, -XK_F16 = 0xffcd, -XK_L6 = 0xffcd, -XK_F17 = 0xffce, -XK_L7 = 0xffce, -XK_F18 = 0xffcf, -XK_L8 = 0xffcf, -XK_F19 = 0xffd0, -XK_L9 = 0xffd0, -XK_F20 = 0xffd1, -XK_L10 = 0xffd1, -XK_F21 = 0xffd2, -XK_R1 = 0xffd2, -XK_F22 = 0xffd3, -XK_R2 = 0xffd3, -XK_F23 = 0xffd4, -XK_R3 = 0xffd4, -XK_F24 = 0xffd5, -XK_R4 = 0xffd5, -XK_F25 = 0xffd6, -XK_R5 = 0xffd6, -XK_F26 = 0xffd7, -XK_R6 = 0xffd7, -XK_F27 = 0xffd8, -XK_R7 = 0xffd8, -XK_F28 = 0xffd9, -XK_R8 = 0xffd9, -XK_F29 = 0xffda, -XK_R9 = 0xffda, -XK_F30 = 0xffdb, -XK_R10 = 0xffdb, -XK_F31 = 0xffdc, -XK_R11 = 0xffdc, -XK_F32 = 0xffdd, -XK_R12 = 0xffdd, -XK_F33 = 0xffde, -XK_R13 = 0xffde, -XK_F34 = 0xffdf, -XK_R14 = 0xffdf, -XK_F35 = 0xffe0, -XK_R15 = 0xffe0, - -/* Modifiers */ - -XK_Shift_L = 0xffe1, /* Left shift */ -XK_Shift_R = 0xffe2, /* Right shift */ -XK_Control_L = 0xffe3, /* Left control */ -XK_Control_R = 0xffe4, /* Right control */ -XK_Caps_Lock = 0xffe5, /* Caps lock */ -XK_Shift_Lock = 0xffe6, /* Shift lock */ - -XK_Meta_L = 0xffe7, /* Left meta */ -XK_Meta_R = 0xffe8, /* Right meta */ -XK_Alt_L = 0xffe9, /* Left alt */ -XK_Alt_R = 0xffea, /* Right alt */ -XK_Super_L = 0xffeb, /* Left super */ -XK_Super_R = 0xffec, /* Right super */ -XK_Hyper_L = 0xffed, /* Left hyper */ -XK_Hyper_R = 0xffee, /* Right hyper */ - -XK_ISO_Level3_Shift = 0xfe03, /* AltGr */ - -/* - * Latin 1 - * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) - * Byte 3 = 0 - */ - -XK_space = 0x0020, /* U+0020 SPACE */ -XK_exclam = 0x0021, /* U+0021 EXCLAMATION MARK */ -XK_quotedbl = 0x0022, /* U+0022 QUOTATION MARK */ -XK_numbersign = 0x0023, /* U+0023 NUMBER SIGN */ -XK_dollar = 0x0024, /* U+0024 DOLLAR SIGN */ -XK_percent = 0x0025, /* U+0025 PERCENT SIGN */ -XK_ampersand = 0x0026, /* U+0026 AMPERSAND */ -XK_apostrophe = 0x0027, /* U+0027 APOSTROPHE */ -XK_quoteright = 0x0027, /* deprecated */ -XK_parenleft = 0x0028, /* U+0028 LEFT PARENTHESIS */ -XK_parenright = 0x0029, /* U+0029 RIGHT PARENTHESIS */ -XK_asterisk = 0x002a, /* U+002A ASTERISK */ -XK_plus = 0x002b, /* U+002B PLUS SIGN */ -XK_comma = 0x002c, /* U+002C COMMA */ -XK_minus = 0x002d, /* U+002D HYPHEN-MINUS */ -XK_period = 0x002e, /* U+002E FULL STOP */ -XK_slash = 0x002f, /* U+002F SOLIDUS */ -XK_0 = 0x0030, /* U+0030 DIGIT ZERO */ -XK_1 = 0x0031, /* U+0031 DIGIT ONE */ -XK_2 = 0x0032, /* U+0032 DIGIT TWO */ -XK_3 = 0x0033, /* U+0033 DIGIT THREE */ -XK_4 = 0x0034, /* U+0034 DIGIT FOUR */ -XK_5 = 0x0035, /* U+0035 DIGIT FIVE */ -XK_6 = 0x0036, /* U+0036 DIGIT SIX */ -XK_7 = 0x0037, /* U+0037 DIGIT SEVEN */ -XK_8 = 0x0038, /* U+0038 DIGIT EIGHT */ -XK_9 = 0x0039, /* U+0039 DIGIT NINE */ -XK_colon = 0x003a, /* U+003A COLON */ -XK_semicolon = 0x003b, /* U+003B SEMICOLON */ -XK_less = 0x003c, /* U+003C LESS-THAN SIGN */ -XK_equal = 0x003d, /* U+003D EQUALS SIGN */ -XK_greater = 0x003e, /* U+003E GREATER-THAN SIGN */ -XK_question = 0x003f, /* U+003F QUESTION MARK */ -XK_at = 0x0040, /* U+0040 COMMERCIAL AT */ -XK_A = 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ -XK_B = 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ -XK_C = 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ -XK_D = 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ -XK_E = 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ -XK_F = 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ -XK_G = 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ -XK_H = 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ -XK_I = 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ -XK_J = 0x004a, /* U+004A LATIN CAPITAL LETTER J */ -XK_K = 0x004b, /* U+004B LATIN CAPITAL LETTER K */ -XK_L = 0x004c, /* U+004C LATIN CAPITAL LETTER L */ -XK_M = 0x004d, /* U+004D LATIN CAPITAL LETTER M */ -XK_N = 0x004e, /* U+004E LATIN CAPITAL LETTER N */ -XK_O = 0x004f, /* U+004F LATIN CAPITAL LETTER O */ -XK_P = 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ -XK_Q = 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ -XK_R = 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ -XK_S = 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ -XK_T = 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ -XK_U = 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ -XK_V = 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ -XK_W = 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ -XK_X = 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ -XK_Y = 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ -XK_Z = 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ -XK_bracketleft = 0x005b, /* U+005B LEFT SQUARE BRACKET */ -XK_backslash = 0x005c, /* U+005C REVERSE SOLIDUS */ -XK_bracketright = 0x005d, /* U+005D RIGHT SQUARE BRACKET */ -XK_asciicircum = 0x005e, /* U+005E CIRCUMFLEX ACCENT */ -XK_underscore = 0x005f, /* U+005F LOW LINE */ -XK_grave = 0x0060, /* U+0060 GRAVE ACCENT */ -XK_quoteleft = 0x0060, /* deprecated */ -XK_a = 0x0061, /* U+0061 LATIN SMALL LETTER A */ -XK_b = 0x0062, /* U+0062 LATIN SMALL LETTER B */ -XK_c = 0x0063, /* U+0063 LATIN SMALL LETTER C */ -XK_d = 0x0064, /* U+0064 LATIN SMALL LETTER D */ -XK_e = 0x0065, /* U+0065 LATIN SMALL LETTER E */ -XK_f = 0x0066, /* U+0066 LATIN SMALL LETTER F */ -XK_g = 0x0067, /* U+0067 LATIN SMALL LETTER G */ -XK_h = 0x0068, /* U+0068 LATIN SMALL LETTER H */ -XK_i = 0x0069, /* U+0069 LATIN SMALL LETTER I */ -XK_j = 0x006a, /* U+006A LATIN SMALL LETTER J */ -XK_k = 0x006b, /* U+006B LATIN SMALL LETTER K */ -XK_l = 0x006c, /* U+006C LATIN SMALL LETTER L */ -XK_m = 0x006d, /* U+006D LATIN SMALL LETTER M */ -XK_n = 0x006e, /* U+006E LATIN SMALL LETTER N */ -XK_o = 0x006f, /* U+006F LATIN SMALL LETTER O */ -XK_p = 0x0070, /* U+0070 LATIN SMALL LETTER P */ -XK_q = 0x0071, /* U+0071 LATIN SMALL LETTER Q */ -XK_r = 0x0072, /* U+0072 LATIN SMALL LETTER R */ -XK_s = 0x0073, /* U+0073 LATIN SMALL LETTER S */ -XK_t = 0x0074, /* U+0074 LATIN SMALL LETTER T */ -XK_u = 0x0075, /* U+0075 LATIN SMALL LETTER U */ -XK_v = 0x0076, /* U+0076 LATIN SMALL LETTER V */ -XK_w = 0x0077, /* U+0077 LATIN SMALL LETTER W */ -XK_x = 0x0078, /* U+0078 LATIN SMALL LETTER X */ -XK_y = 0x0079, /* U+0079 LATIN SMALL LETTER Y */ -XK_z = 0x007a, /* U+007A LATIN SMALL LETTER Z */ -XK_braceleft = 0x007b, /* U+007B LEFT CURLY BRACKET */ -XK_bar = 0x007c, /* U+007C VERTICAL LINE */ -XK_braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */ -XK_asciitilde = 0x007e, /* U+007E TILDE */ - -XK_nobreakspace = 0x00a0, /* U+00A0 NO-BREAK SPACE */ -XK_exclamdown = 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */ -XK_cent = 0x00a2, /* U+00A2 CENT SIGN */ -XK_sterling = 0x00a3, /* U+00A3 POUND SIGN */ -XK_currency = 0x00a4, /* U+00A4 CURRENCY SIGN */ -XK_yen = 0x00a5, /* U+00A5 YEN SIGN */ -XK_brokenbar = 0x00a6, /* U+00A6 BROKEN BAR */ -XK_section = 0x00a7, /* U+00A7 SECTION SIGN */ -XK_diaeresis = 0x00a8, /* U+00A8 DIAERESIS */ -XK_copyright = 0x00a9, /* U+00A9 COPYRIGHT SIGN */ -XK_ordfeminine = 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */ -XK_guillemotleft = 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ -XK_notsign = 0x00ac, /* U+00AC NOT SIGN */ -XK_hyphen = 0x00ad, /* U+00AD SOFT HYPHEN */ -XK_registered = 0x00ae, /* U+00AE REGISTERED SIGN */ -XK_macron = 0x00af, /* U+00AF MACRON */ -XK_degree = 0x00b0, /* U+00B0 DEGREE SIGN */ -XK_plusminus = 0x00b1, /* U+00B1 PLUS-MINUS SIGN */ -XK_twosuperior = 0x00b2, /* U+00B2 SUPERSCRIPT TWO */ -XK_threesuperior = 0x00b3, /* U+00B3 SUPERSCRIPT THREE */ -XK_acute = 0x00b4, /* U+00B4 ACUTE ACCENT */ -XK_mu = 0x00b5, /* U+00B5 MICRO SIGN */ -XK_paragraph = 0x00b6, /* U+00B6 PILCROW SIGN */ -XK_periodcentered = 0x00b7, /* U+00B7 MIDDLE DOT */ -XK_cedilla = 0x00b8, /* U+00B8 CEDILLA */ -XK_onesuperior = 0x00b9, /* U+00B9 SUPERSCRIPT ONE */ -XK_masculine = 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */ -XK_guillemotright = 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ -XK_onequarter = 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */ -XK_onehalf = 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */ -XK_threequarters = 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */ -XK_questiondown = 0x00bf, /* U+00BF INVERTED QUESTION MARK */ -XK_Agrave = 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ -XK_Aacute = 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ -XK_Acircumflex = 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ -XK_Atilde = 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ -XK_Adiaeresis = 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ -XK_Aring = 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ -XK_AE = 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */ -XK_Ccedilla = 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ -XK_Egrave = 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ -XK_Eacute = 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ -XK_Ecircumflex = 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ -XK_Ediaeresis = 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ -XK_Igrave = 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ -XK_Iacute = 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ -XK_Icircumflex = 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ -XK_Idiaeresis = 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ -XK_ETH = 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */ -XK_Eth = 0x00d0, /* deprecated */ -XK_Ntilde = 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ -XK_Ograve = 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ -XK_Oacute = 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ -XK_Ocircumflex = 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ -XK_Otilde = 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ -XK_Odiaeresis = 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ -XK_multiply = 0x00d7, /* U+00D7 MULTIPLICATION SIGN */ -XK_Oslash = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -XK_Ooblique = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -XK_Ugrave = 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ -XK_Uacute = 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ -XK_Ucircumflex = 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ -XK_Udiaeresis = 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ -XK_Yacute = 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ -XK_THORN = 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */ -XK_Thorn = 0x00de, /* deprecated */ -XK_ssharp = 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */ -XK_agrave = 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ -XK_aacute = 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ -XK_acircumflex = 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ -XK_atilde = 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ -XK_adiaeresis = 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ -XK_aring = 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ -XK_ae = 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */ -XK_ccedilla = 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ -XK_egrave = 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ -XK_eacute = 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ -XK_ecircumflex = 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ -XK_ediaeresis = 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ -XK_igrave = 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ -XK_iacute = 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ -XK_icircumflex = 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ -XK_idiaeresis = 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ -XK_eth = 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */ -XK_ntilde = 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ -XK_ograve = 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ -XK_oacute = 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ -XK_ocircumflex = 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ -XK_otilde = 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ -XK_odiaeresis = 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ -XK_division = 0x00f7, /* U+00F7 DIVISION SIGN */ -XK_oslash = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -XK_ooblique = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -XK_ugrave = 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ -XK_uacute = 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ -XK_ucircumflex = 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ -XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ -XK_yacute = 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ -XK_thorn = 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ -XK_ydiaeresis = 0x00ff; /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ diff --git a/include/logo.js b/include/logo.js deleted file mode 100644 index befa598..0000000 --- a/include/logo.js +++ /dev/null @@ -1 +0,0 @@ -noVNC_logo = {"width": 640, "height": 435, "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAGzCAYAAAC/y6a9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAStAAAErQBBHTWggAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13fBvlwQfw3522ZMm2vPdIGCFkA4GyoYyGsCmjk+7dQksHL2/H2/dtC4W2tLTlfelu2VA2lEILFCgQIHEGJCQkdjzkLdmWZGvfvX8oOkmJEy/pNO73/Xz44DtLzz2RT7qfnnXC8uXLZUxDlqfdnUYQhIP+bjbPn+5xhypzrmUf6rGzOc5cjzVduXN9/nTPyfRrMt/jzOcY05U5n3L2f95s/34LPW4m/p6FbLp/73xe+5nKnWuZs/07ZOOcnusx5nucbJU727LneuxslDmdTBxn/2NmusyEuZS7kHMxG/XP5Gf3TOVmQzY+u/PhPMnkMcSsH5WIiIiI8goDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHG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"}; diff --git a/include/xtscancodes.js b/include/xtscancodes.js deleted file mode 100644 index d19a017..0000000 --- a/include/xtscancodes.js +++ /dev/null @@ -1,146 +0,0 @@ -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 2c49ffc..f14dc42 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -110,19 +110,19 @@ module.exports = function(config) { files: [ 'tests/fake.*.js', 'tests/assertions.js', - 'include/util.js', // load first to avoid issues, since methods are called immediately - //'../include/*.js', - 'include/base64.js', - 'include/keysym.js', - 'include/keysymdef.js', - 'include/xtscancodes.js', - 'include/keyboard.js', - 'include/input.js', - 'include/websock.js', - 'include/rfb.js', - 'include/des.js', - 'include/display.js', - 'include/inflator.js', + '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/websock.js', + 'core/rfb.js', + 'core/des.js', + 'core/display.js', + 'core/inflator.js', 'tests/test.*.js' ], @@ -134,8 +134,8 @@ module.exports = function(config) { // list of files to exclude exclude: [ - '../include/playback.js', - '../include/ui.js' + '../tests/playback.js', + '../app/ui.js' ], customLaunchers: customLaunchers, diff --git a/package.json b/package.json index 3db93eb..26ee6ff 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "test": "tests" }, "scripts": { - "test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js" + "test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js", + "prepublish": "node ./utils/use_require.js --as-require", + "build-es6": "node ./utils/use_require.js" }, "repository": { "type": "git", @@ -27,9 +29,14 @@ "homepage": "https://github.com/kanaka/noVNC", "devDependencies": { "ansi": "^0.3.0", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.14.0", + "babelify": "^7.3.0", + "browserify": "^13.1.0", "casperjs": "^1.1.0-beta3", "chai": "^2.1.0", - "commander": "^2.6.0", + "commander": "^2.8.1", + "fs-extra": "^0.30.0", "karma": "^0.12.31", "karma-chai": "^0.1.0", "karma-mocha": "^0.1.10", @@ -45,6 +52,10 @@ "sinon": "^1.12.2", "sinon-chai": "^2.7.0", "spooky": "^0.2.5", - "temp": "^0.8.1" + "temp": "^0.8.1", + "through2": "^2.0.1" + }, + "dependencies": { + "pako": "^1.0.3" } } diff --git a/tests/input.html b/tests/input.html index 301a7f8..ec3aefe 100644 --- a/tests/input.html +++ b/tests/input.html @@ -23,15 +23,15 @@ --> - - - - - - - - - + + + + + + + + + - - + + diff --git a/tests/vnc_playback.html b/tests/vnc_playback.html index c4d2108..168663d 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 0000000..bb48ae5 --- /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 0000000..0c16db2 --- /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 0b65306..bfc1201 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 597028e..6fa3f25 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', ''), -- 2.39.5