Use RequireJS module system

Use a standard module system rather than a home grown one, and
RequireJS fits better with browsers than CommonJS.
This commit is contained in:
Pierre Ossman 2017-01-18 16:57:20 +01:00
parent 8ad1347fe3
commit 6bc9cadaef
41 changed files with 2634 additions and 5031 deletions

2
.gitignore vendored
View File

@ -1,5 +1,7 @@
*.pyc *.pyc
*.o *.o
inflator/inflator-merged.js
inflator/pako
tests/data_*.js tests/data_*.js
utils/rebind.so utils/rebind.so
utils/websockify utils/websockify

View File

@ -5,7 +5,10 @@
* DO NOT EDIT! * DO NOT EDIT!
*/ */
Language = { "use strict";
define(function() {
return {
"Connecting...": "Verbunden...", "Connecting...": "Verbunden...",
"Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ", "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ",
"Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ", "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ",
@ -16,3 +19,4 @@ Language = {
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "'Clipping-Modus' aktiviert, Scrollbalken in 'IE-Vollbildmodus' werden nicht unterstützt", "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "'Clipping-Modus' aktiviert, Scrollbalken in 'IE-Vollbildmodus' werden nicht unterstützt",
"Disconnect timeout": "Timeout beim trennen", "Disconnect timeout": "Timeout beim trennen",
}; };
});

View File

@ -5,7 +5,10 @@
* DO NOT EDIT! * DO NOT EDIT!
*/ */
Language = { "use strict";
define(function() {
return {
"Connecting...": "Συνδέεται...", "Connecting...": "Συνδέεται...",
"Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ", "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ",
"Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ", "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ",
@ -72,3 +75,4 @@ Language = {
"Send Password": "Αποστολή Κωδικού Πρόσβασης", "Send Password": "Αποστολή Κωδικού Πρόσβασης",
"Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas", "Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas",
}; };
});

View File

@ -5,7 +5,10 @@
* DO NOT EDIT! * DO NOT EDIT!
*/ */
Language = { "use strict";
define(function() {
return {
"Connecting...": "Verbinden...", "Connecting...": "Verbinden...",
"Connected (encrypted) to ": "Verbonden (versleuteld) met ", "Connected (encrypted) to ": "Verbonden (versleuteld) met ",
"Connected (unencrypted) to ": "Verbonden (onversleuteld) met ", "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ",
@ -16,3 +19,4 @@ Language = {
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "''Clipping mode' ingeschakeld, omdat schuifbalken in volledige-scherm-modus in IE niet worden ondersteund", "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "''Clipping mode' ingeschakeld, omdat schuifbalken in volledige-scherm-modus in IE niet worden ondersteund",
"Disconnect timeout": "Timeout tijdens verbreken van verbinding", "Disconnect timeout": "Timeout tijdens verbreken van verbinding",
}; };
});

View File

@ -5,7 +5,10 @@
* DO NOT EDIT! * DO NOT EDIT!
*/ */
Language = { "use strict";
define(function() {
return {
"Connecting...": "Ansluter...", "Connecting...": "Ansluter...",
"Connected (encrypted) to ": "Ansluten (krypterat) till ", "Connected (encrypted) to ": "Ansluten (krypterat) till ",
"Connected (unencrypted) to ": "Ansluten (okrypterat) till ", "Connected (unencrypted) to ": "Ansluten (okrypterat) till ",
@ -75,3 +78,4 @@ Language = {
"Send Password": "Skicka Lösenord", "Send Password": "Skicka Lösenord",
"Canvas not supported.": "Canvas stöds ej", "Canvas not supported.": "Canvas stöds ej",
}; };
});

22
app/novnc.js Normal file
View File

@ -0,0 +1,22 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
/* jslint white: false, browser: true */
"use strict";
requirejs.config({
baseUrl: '',
});
requirejs(['app/ui', 'core/util'],
function(ui, util) {
// Set up translations, then start the UI
var LINGUAS = ["de", "el", "nl", "sv"];
util.Localisation.setup(LINGUAS, "app/locale", ui.load);
});

5
app/require.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -2,29 +2,19 @@
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2016 Samuel Mannehed for Cendio AB * Copyright (C) 2016 Samuel Mannehed for Cendio AB
* Copyright (C) 2016 Pierre Ossman for Cendio AB * Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
* *
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
/* jslint white: false, browser: true */ /* jslint white: false, browser: true */
/* global window, document.getElementById, Util, WebUtil, RFB, Display */
/* [module]
* import Util from "../core/util";
* import KeyTable from "../core/input/keysym";
* import keysyms from "./keysymdef";
* import RFB from "../core/rfb";
* import Display from "../core/display";
* import WebUtil from "./webutil";
*/
"use strict"; "use strict";
var UI; define(["app/webutil", "core/rfb", "core/util",
"core/input/keysym", "core/input/keysymdef"],
(function () { function (WebUtil, rfb, Util, KeyTable, keysyms) {
// Fallback for all uncought errors // Fallback for all uncought errors
window.addEventListener('error', function(event) { window.addEventListener('error', function(event) {
@ -66,27 +56,9 @@ var UI;
return false; return false;
}); });
// Set up translations
var LINGUAS = ["de", "el", "nl", "sv"];
Util.Localisation.setup(LINGUAS);
if (Util.Localisation.language !== "en") {
WebUtil.load_scripts(
{'app': ["locale/" + Util.Localisation.language + ".js"]});
}
/* [begin skip-as-module] */
// Load supporting scripts
WebUtil.load_scripts(
{'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js",
"input/xtscancodes.js", "input/util.js", "input/devices.js",
"display.js", "inflator.js", "rfb.js", "input/keysym.js"]});
window.onscriptsload = function () { UI.load(); };
/* [end skip-as-module] */
var _ = Util.Localisation.get; var _ = Util.Localisation.get;
UI = { var UI = {
connected: false, connected: false,
desktopName: "", desktopName: "",
@ -390,7 +362,7 @@ var UI;
initRFB: function() { initRFB: function() {
try { try {
UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'), UI.rfb = new rfb.RFB({'target': document.getElementById('noVNC_canvas'),
'onNotification': UI.notification, 'onNotification': UI.notification,
'onUpdateState': UI.updateState, 'onUpdateState': UI.updateState,
'onDisconnected': UI.disconnectFinished, 'onDisconnected': UI.disconnectFinished,
@ -1679,7 +1651,5 @@ var UI;
*/ */
}; };
/* [module] UI.load(); */ return UI;
})(); });
/* [module] export default UI; */

View File

@ -2,42 +2,32 @@
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 NTT corp. * Copyright (C) 2013 NTT corp.
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
* *
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
/*jslint bitwise: false, white: false, browser: true, devel: true */ /*jslint bitwise: false, white: false, browser: true, devel: true */
/*global Util, window, document */
/* [module]
* import Util from "../core/util";
*/
"use strict"; "use strict";
// Globals defined here define(['core/util'],
var WebUtil = {}; function(Util) {
var WebUtil = {};
/* // init log level reading the logging HTTP param
* ------------------------------------------------------ WebUtil.init_logging = function (level) {
* Namespaced in WebUtil if (typeof level === "undefined") {
* ------------------------------------------------------
*/
// init log level reading the logging HTTP param
WebUtil.init_logging = function (level) {
if (typeof level !== "undefined") {
Util._log_level = level;
} else {
var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/); var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/);
Util._log_level = (param || ['', Util._log_level])[1]; if (param !== undefined)
level = param;
} }
Util.init_logging(); Util.init_logging(level);
}; };
WebUtil.dirObj = function (obj, depth, parent) { WebUtil.dirObj = function (obj, depth, parent) {
if (! depth) { depth = 2; } if (! depth) { depth = 2; }
if (! parent) { parent = ""; } if (! parent) { parent = ""; }
@ -62,10 +52,10 @@ WebUtil.dirObj = function (obj, depth, parent) {
} }
} }
return msg; return msg;
}; };
// Read a query string variable // Read a query string variable
WebUtil.getQueryVar = function (name, defVal) { WebUtil.getQueryVar = function (name, defVal) {
var re = new RegExp('.*[?&]' + name + '=([^&#]*)'), var re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
match = document.location.href.match(re); match = document.location.href.match(re);
if (typeof defVal === 'undefined') { defVal = null; } if (typeof defVal === 'undefined') { defVal = null; }
@ -74,10 +64,10 @@ WebUtil.getQueryVar = function (name, defVal) {
} else { } else {
return defVal; return defVal;
} }
}; };
// Read a hash fragment variable // Read a hash fragment variable
WebUtil.getHashVar = function (name, defVal) { WebUtil.getHashVar = function (name, defVal) {
var re = new RegExp('.*[&#]' + name + '=([^&]*)'), var re = new RegExp('.*[&#]' + name + '=([^&]*)'),
match = document.location.hash.match(re); match = document.location.hash.match(re);
if (typeof defVal === 'undefined') { defVal = null; } if (typeof defVal === 'undefined') { defVal = null; }
@ -86,24 +76,24 @@ WebUtil.getHashVar = function (name, defVal) {
} else { } else {
return defVal; return defVal;
} }
}; };
// Read a variable from the fragment or the query string // Read a variable from the fragment or the query string
// Fragment takes precedence // Fragment takes precedence
WebUtil.getConfigVar = function (name, defVal) { WebUtil.getConfigVar = function (name, defVal) {
var val = WebUtil.getHashVar(name); var val = WebUtil.getHashVar(name);
if (val === null) { if (val === null) {
val = WebUtil.getQueryVar(name, defVal); val = WebUtil.getQueryVar(name, defVal);
} }
return val; return val;
}; };
/* /*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
*/ */
// No days means only for this browser session // No days means only for this browser session
WebUtil.createCookie = function (name, value, days) { WebUtil.createCookie = function (name, value, days) {
var date, expires; var date, expires;
if (days) { if (days) {
date = new Date(); date = new Date();
@ -120,9 +110,9 @@ WebUtil.createCookie = function (name, value, days) {
secure = ""; secure = "";
} }
document.cookie = name + "=" + value + expires + "; path=/" + secure; document.cookie = name + "=" + value + expires + "; path=/" + secure;
}; };
WebUtil.readCookie = function (name, defaultValue) { WebUtil.readCookie = function (name, defaultValue) {
var nameEQ = name + "=", var nameEQ = name + "=",
ca = document.cookie.split(';'); ca = document.cookie.split(';');
@ -132,17 +122,17 @@ WebUtil.readCookie = function (name, defaultValue) {
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); } if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); }
} }
return (typeof defaultValue !== 'undefined') ? defaultValue : null; return (typeof defaultValue !== 'undefined') ? defaultValue : null;
}; };
WebUtil.eraseCookie = function (name) { WebUtil.eraseCookie = function (name) {
WebUtil.createCookie(name, "", -1); WebUtil.createCookie(name, "", -1);
}; };
/* /*
* Setting handling. * Setting handling.
*/ */
WebUtil.initSettings = function (callback /*, ...callbackArgs */) { WebUtil.initSettings = function (callback /*, ...callbackArgs */) {
var callbackArgs = Array.prototype.slice.call(arguments, 1); var callbackArgs = Array.prototype.slice.call(arguments, 1);
if (window.chrome && window.chrome.storage) { if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.get(function (cfg) { window.chrome.storage.sync.get(function (cfg) {
@ -158,10 +148,10 @@ WebUtil.initSettings = function (callback /*, ...callbackArgs */) {
callback.apply(this, callbackArgs); callback.apply(this, callbackArgs);
} }
} }
}; };
// No days means only for this browser session // No days means only for this browser session
WebUtil.writeSetting = function (name, value) { WebUtil.writeSetting = function (name, value) {
if (window.chrome && window.chrome.storage) { if (window.chrome && window.chrome.storage) {
//console.log("writeSetting:", name, value); //console.log("writeSetting:", name, value);
if (WebUtil.settings[name] !== value) { if (WebUtil.settings[name] !== value) {
@ -171,9 +161,9 @@ WebUtil.writeSetting = function (name, value) {
} else { } else {
localStorage.setItem(name, value); localStorage.setItem(name, value);
} }
}; };
WebUtil.readSetting = function (name, defaultValue) { WebUtil.readSetting = function (name, defaultValue) {
var value; var value;
if (window.chrome && window.chrome.storage) { if (window.chrome && window.chrome.storage) {
value = WebUtil.settings[name]; value = WebUtil.settings[name];
@ -188,18 +178,18 @@ WebUtil.readSetting = function (name, defaultValue) {
} else { } else {
return value; return value;
} }
}; };
WebUtil.eraseSetting = function (name) { WebUtil.eraseSetting = function (name) {
if (window.chrome && window.chrome.storage) { if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.remove(name); window.chrome.storage.sync.remove(name);
delete WebUtil.settings[name]; delete WebUtil.settings[name];
} else { } else {
localStorage.removeItem(name); localStorage.removeItem(name);
} }
}; };
WebUtil.injectParamIfMissing = function (path, param, value) { WebUtil.injectParamIfMissing = function (path, param, value) {
// force pretend that we're dealing with a relative path // force pretend that we're dealing with a relative path
// (assume that we wanted an extra if we pass one in) // (assume that we wanted an extra if we pass one in)
path = "/" + path; path = "/" + path;
@ -227,29 +217,30 @@ WebUtil.injectParamIfMissing = function (path, param, value) {
} else { } else {
return elem.pathname + elem.search + elem.hash; return elem.pathname + elem.search + elem.hash;
} }
}; };
// Emulate Element.setCapture() when not supported // Emulate Element.setCapture() when not supported
WebUtil._captureRecursion = false; var _captureElem;
WebUtil._captureProxy = function (e) { var _captureRecursion = false;
var _captureProxy = function (e) {
// Recursion protection as we'll see our own event // Recursion protection as we'll see our own event
if (WebUtil._captureRecursion) return; if (_captureRecursion) return;
// Clone the event as we cannot dispatch an already dispatched event // Clone the event as we cannot dispatch an already dispatched event
var newEv = new e.constructor(e.type, e); var newEv = new e.constructor(e.type, e);
WebUtil._captureRecursion = true; _captureRecursion = true;
WebUtil._captureElem.dispatchEvent(newEv); _captureElem.dispatchEvent(newEv);
WebUtil._captureRecursion = false; _captureRecursion = false;
// Implicitly release the capture on button release // Implicitly release the capture on button release
if ((e.type === "mouseup") || (e.type === "touchend")) { if ((e.type === "mouseup") || (e.type === "touchend")) {
WebUtil.releaseCapture(); WebUtil.releaseCapture();
} }
}; };
WebUtil.setCapture = function (elem) { WebUtil.setCapture = function (elem) {
if (elem.setCapture) { if (elem.setCapture) {
elem.setCapture(); elem.setCapture();
@ -284,111 +275,43 @@ WebUtil.setCapture = function (elem) {
captureElem.style.display = "none"; captureElem.style.display = "none";
document.body.appendChild(captureElem); document.body.appendChild(captureElem);
captureElem.addEventListener('mousemove', WebUtil._captureProxy); captureElem.addEventListener('mousemove', _captureProxy);
captureElem.addEventListener('mouseup', WebUtil._captureProxy); captureElem.addEventListener('mouseup', _captureProxy);
captureElem.addEventListener('touchmove', WebUtil._captureProxy); captureElem.addEventListener('touchmove', _captureProxy);
captureElem.addEventListener('touchend', WebUtil._captureProxy); captureElem.addEventListener('touchend', _captureProxy);
} }
WebUtil._captureElem = elem; _captureElem = elem;
captureElem.style.display = null; captureElem.style.display = null;
// We listen to events on window in order to keep tracking if it // We listen to events on window in order to keep tracking if it
// happens to leave the viewport // happens to leave the viewport
window.addEventListener('mousemove', WebUtil._captureProxy); window.addEventListener('mousemove', _captureProxy);
window.addEventListener('mouseup', WebUtil._captureProxy); window.addEventListener('mouseup', _captureProxy);
window.addEventListener('touchmove', WebUtil._captureProxy); window.addEventListener('touchmove', _captureProxy);
window.addEventListener('touchend', WebUtil._captureProxy); window.addEventListener('touchend', _captureProxy);
} }
}; };
WebUtil.releaseCapture = function () { WebUtil.releaseCapture = function () {
if (document.releaseCapture) { if (document.releaseCapture) {
document.releaseCapture(); document.releaseCapture();
} else { } else {
var captureElem = document.getElementById("noVNC_mouse_capture_elem"); var captureElem = document.getElementById("noVNC_mouse_capture_elem");
WebUtil._captureElem = null; _captureElem = null;
captureElem.style.display = "none"; captureElem.style.display = "none";
window.removeEventListener('mousemove', WebUtil._captureProxy); window.removeEventListener('mousemove', _captureProxy);
window.removeEventListener('mouseup', WebUtil._captureProxy); window.removeEventListener('mouseup', _captureProxy);
window.removeEventListener('touchmove', WebUtil._captureProxy); window.removeEventListener('touchmove', _captureProxy);
window.removeEventListener('touchend', WebUtil._captureProxy); window.removeEventListener('touchend', _captureProxy);
}
};
// Dynamically load scripts without using document.write()
// Reference: http://unixpapa.com/js/dyna.html
//
// Handles the case where load_scripts is invoked from a script that
// itself is loaded via load_scripts. Once all scripts are loaded the
// window.onscriptsloaded handler is called (if set).
WebUtil.get_include_uri = function (root_dir) {
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/';
};
WebUtil._loading_scripts = [];
WebUtil._pending_scripts = [];
WebUtil.load_scripts = function (files_by_dir) {
var head = document.getElementsByTagName('head')[0], script,
ls = WebUtil._loading_scripts, ps = WebUtil._pending_scripts;
var loadFunc = function (e) {
while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
ls[0].readyState === 'complete')) {
// For IE, append the script to trigger execution
var s = ls.shift();
//console.log("loaded script: " + s.src);
head.appendChild(s);
}
if (!this.readyState ||
(Util.Engine.presto && this.readyState === 'loaded') ||
this.readyState === 'complete') {
if (ps.indexOf(this) >= 0) {
this.onload = this.onreadystatechange = null;
//console.log("completed script: " + this.src);
ps.splice(ps.indexOf(this), 1);
// Call window.onscriptsload after last script loads
if (ps.length === 0 && window.onscriptsload) {
window.onscriptsload();
}
}
} }
}; };
var root_dirs = Object.keys(files_by_dir); return WebUtil;
});
for (var d = 0; d < root_dirs.length; d++) {
var root_dir = root_dirs[d];
var files = files_by_dir[root_dir];
for (var f = 0; f < files.length; f++) {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = WebUtil.get_include_uri(root_dir) + files[f];
//console.log("loading script: " + script.src);
script.onload = script.onreadystatechange = loadFunc;
// In-order script execution tricks
if (Util.Engine.trident) {
// For IE wait until readyState is 'loaded' before
// appending it which will trigger execution
// http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
ls.push(script);
} else {
// For webkit and firefox set async=false and append now
// https://developer.mozilla.org/en-US/docs/HTML/Element/script
script.async = false;
head.appendChild(script);
}
ps.push(script);
}
}
};
/* [module] export default WebUtil; */

View File

@ -5,11 +5,11 @@
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
/*jslint white: false */ /*jslint white: false */
/*global console */
"use strict"; "use strict";
var Base64 = { define(function () {
var Base64 = {
/* Convert data (an array of integers) to a Base64 string. */ /* Convert data (an array of integers) to a Base64 string. */
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
base64Pad : '=', base64Pad : '=',
@ -112,6 +112,7 @@ var Base64 = {
return result; return result;
} }
}; /* End of Base64 namespace */ };
/* [module] export default Base64; */ return Base64;
});

View File

@ -79,8 +79,8 @@
"use strict"; "use strict";
/* [module] export default */ function DES(passwd) { define(function () {
function DES(passwd) {
// Tables, permutations, S-boxes, etc. // Tables, permutations, S-boxes, etc.
// jshint -W013 // jshint -W013
var PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3, var PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
@ -274,4 +274,7 @@
setKeys(passwd); // Setup keys setKeys(passwd); // Setup keys
return {'encrypt': encrypt}; // Public interface return {'encrypt': encrypt}; // Public interface
}; // function DES }; // function DES
return DES;
});

View File

@ -2,22 +2,27 @@
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2015 Samuel Mannehed for Cendio AB * Copyright (C) 2015 Samuel Mannehed for Cendio AB
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
* *
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
/*jslint browser: true, white: false */ /*jslint browser: true, white: false */
/*global Util, Base64, changeCursor */
/* [module]
* import Util from "./util";
* import Base64 from "./base64";
*/
"use strict"; "use strict";
/* [module] export default */ function Display(defaults) { define(["core/util", "core/base64"],
function (Util, Base64) {
var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try {
new ImageData(new Uint8ClampedArray(4), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
} catch (ex) {
// ignore failure
}
function Display(defaults) {
this._drawCtx = null; this._drawCtx = null;
this._c_forceCanvas = false; this._c_forceCanvas = false;
@ -98,18 +103,7 @@
} }
Util.Debug("<< Display.constructor"); Util.Debug("<< Display.constructor");
}; };
(function () {
var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try {
new ImageData(new Uint8ClampedArray(4), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
} catch (ex) {
// ignore failure
}
Display.prototype = { Display.prototype = {
// Public methods // Public methods
@ -876,4 +870,6 @@
var url = 'data:image/x-icon;base64,' + Base64.encode(cur); var url = 'data:image/x-icon;base64,' + Base64.encode(cur);
target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
}; };
})();
return { Display: Display };
});

File diff suppressed because one or more lines are too long

View File

@ -1,40 +0,0 @@
var zlib = require('pako/lib/zlib/inflate.js');
var ZStream = require('pako/lib/zlib/zstream.js');
function Inflate() {
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 };

View File

@ -2,28 +2,21 @@
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed for Cendio AB * Copyright (C) 2013 Samuel Mannehed for Cendio AB
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 or any later version (see LICENSE.txt) * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/ */
/*jslint browser: true, white: false */ /*jslint browser: true, white: false */
/*global window, Util */
/* [module]
* import Util from "../util";
* import KeyboardUtil from "./util";
*/
"use strict"; "use strict";
/* [module] export */ var Keyboard; define(["core/util", "core/input/util"],
function (Util, KeyboardUtil) {
(function () {
// //
// Keyboard event handler // Keyboard event handler
// //
Keyboard = function (defaults) { function Keyboard(defaults) {
this._keyDownList = []; // List of depressed keys this._keyDownList = []; // List of depressed keys
// (even if they are happy) // (even if they are happy)
@ -159,12 +152,8 @@
['onKeyPress', 'rw', 'func'] // Handler for key press/release ['onKeyPress', 'rw', 'func'] // Handler for key press/release
]); ]);
})();
/* [module] export */ var Mouse; function Mouse(defaults) {
(function () {
Mouse = function (defaults) {
this._mouseCaptured = false; this._mouseCaptured = false;
this._doubleClickTimer = null; this._doubleClickTimer = null;
@ -403,4 +392,7 @@
['onMouseMove', 'rw', 'func'], // Handler for mouse movement ['onMouseMove', 'rw', 'func'], // Handler for mouse movement
['touchButton', 'rw', 'int'] // Button mask (1, 2, 4) for touch devices (0 means ignore clicks) ['touchButton', 'rw', 'int'] // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
]); ]);
})();
return { Keyboard: Keyboard,
Mouse: Mouse };
});

View File

@ -1,6 +1,7 @@
"use strict"; "use strict";
var KeyTable = { define(function () {
var KeyTable = {
XK_VoidSymbol: 0xffffff, /* Void symbol */ XK_VoidSymbol: 0xffffff, /* Void symbol */
XK_BackSpace: 0xff08, /* Back space, back char */ XK_BackSpace: 0xff08, /* Back space, back char */
@ -379,6 +380,7 @@ var KeyTable = {
XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
}; };
/* [module] export default KeyTable; */ return KeyTable;
});

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,17 @@
/* [module] /*
* import KeyTable from "./keysym"; * noVNC: HTML5 VNC client
* import keysyms from "./keysymdef"; * Copyright (C) 2012 Joel Martin
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/ */
/*jslint browser: true, white: false */
"use strict"; "use strict";
var KeyboardUtil = {}; define(["core/input/keysym", "core/input/keysymdef"],
function (KeyTable, keysyms) {
(function() { var KeyboardUtil = {};
function substituteCodepoint(cp) { function substituteCodepoint(cp) {
// Any Unicode code points which do not have corresponding keysym entries // Any Unicode code points which do not have corresponding keysym entries
@ -287,9 +291,8 @@ var KeyboardUtil = {};
KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode; KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode;
KeyboardUtil.nonCharacterKey = nonCharacterKey; KeyboardUtil.nonCharacterKey = nonCharacterKey;
KeyboardUtil.substituteCodepoint = substituteCodepoint; KeyboardUtil.substituteCodepoint = substituteCodepoint;
})();
KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) { KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
function sendAll(evts) { function sendAll(evts) {
for (var i = 0; i < evts.length; ++i) { for (var i = 0; i < evts.length; ++i) {
next(evts[i]); next(evts[i]);
@ -355,9 +358,9 @@ KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
}, },
releaseAll: function() { next({type: 'releaseall'}); } releaseAll: function() { next({type: 'releaseall'}); }
}; };
}; };
KeyboardUtil.TrackQEMUKeyState = function(next) { KeyboardUtil.TrackQEMUKeyState = function(next) {
var state = []; var state = [];
return function (evt) { return function (evt) {
@ -415,16 +418,16 @@ KeyboardUtil.TrackQEMUKeyState = function(next) {
state = []; state = [];
} }
}; };
}; };
// Takes a DOM keyboard event and: // Takes a DOM keyboard event and:
// - determines which keysym it represents // - determines which keysym it represents
// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event) // - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event)
// - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down // - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down
// - marks each event with an 'escape' property if a modifier was down which should be "escaped" // - 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 // - 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) // This information is collected into an object which is passed to the next() function. (one call per event)
KeyboardUtil.KeyEventDecoder = function(modifierState, next) { KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
function sendAll(evts) { function sendAll(evts) {
for (var i = 0; i < evts.length; ++i) { for (var i = 0; i < evts.length; ++i) {
next(evts[i]); next(evts[i]);
@ -502,15 +505,15 @@ KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
}, },
releaseAll: function() { next({type: 'releaseall'}); } releaseAll: function() { next({type: 'releaseall'}); }
}; };
}; };
// Combines keydown and keypress events where necessary to handle char modifiers. // 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. // On some OS'es, a char modifier is sometimes used as a shortcut modifier.
// For example, on Windows, AltGr is synonymous with Ctrl-Alt. On a Danish keyboard layout, AltGr-2 yields a @, but Ctrl-Alt-D does nothing // For example, on Windows, AltGr is synonymous with Ctrl-Alt. On a Danish keyboard layout, AltGr-2 yields a @, but Ctrl-Alt-D does nothing
// 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. // 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 // 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 // When we receive a "stall" event, wait a few ms before processing the next keydown. If a keypress has also arrived, merge the two
KeyboardUtil.VerifyCharModifier = function(next) { KeyboardUtil.VerifyCharModifier = function(next) {
var queue = []; var queue = [];
var timer = null; var timer = null;
function process() { function process() {
@ -559,14 +562,14 @@ KeyboardUtil.VerifyCharModifier = function(next) {
queue.push(evt); queue.push(evt);
process(); process();
}; };
}; };
// Keeps track of which keys we (and the server) believe are down // 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) // 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 // 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. // 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 // Because we can't always identify which entry a keydown or keyup event corresponds to, we sometimes have to guess
KeyboardUtil.TrackKeyState = function(next) { KeyboardUtil.TrackKeyState = function(next) {
var state = []; var state = [];
return function (evt) { return function (evt) {
@ -645,11 +648,11 @@ KeyboardUtil.TrackKeyState = function(next) {
state = []; state = [];
} }
}; };
}; };
// Handles "escaping" of modifiers: if a char modifier is used to produce a keysym (such as AltGr-2 to generate an @), // 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. // then the modifier must be "undone" before sending the @, and "redone" afterwards.
KeyboardUtil.EscapeModifiers = function(next) { KeyboardUtil.EscapeModifiers = function(next) {
return function(evt) { return function(evt) {
if (evt.type !== 'keydown' || evt.escape === undefined) { if (evt.type !== 'keydown' || evt.escape === undefined) {
next(evt); next(evt);
@ -668,6 +671,7 @@ KeyboardUtil.EscapeModifiers = function(next) {
} }
/* jshint shadow: false */ /* jshint shadow: false */
}; };
}; };
/* [module] export default KeyboardUtil; */ return KeyboardUtil;
});

View File

@ -1,6 +1,7 @@
"use strict"; "use strict";
var XtScancode = { define(function () {
var XtScancode = {
"Escape": 0x0001, "Escape": 0x0001,
"Digit1": 0x0002, "Digit1": 0x0002,
"Digit2": 0x0003, "Digit2": 0x0003,
@ -148,6 +149,7 @@ var XtScancode = {
"LaunchApp1": 0xE06B, "LaunchApp1": 0xE06B,
"LaunchMail": 0xE06C, "LaunchMail": 0xE06C,
"MediaSelect": 0xE06D, "MediaSelect": 0xE06D,
}; };
/* [module] export default XtScancode */ return XtScancode;
});

View File

@ -2,6 +2,7 @@
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2016 Samuel Mannehed for Cendio AB * Copyright (C) 2016 Samuel Mannehed for Cendio AB
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
* *
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
@ -10,23 +11,19 @@
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
*/ */
/* [module]
* import Util from "./util";
* import Display from "./display";
* import { Keyboard, Mouse } from "./input/devices"
* import Websock from "./websock"
* import Base64 from "./base64";
* import DES from "./des";
* import KeyTable from "./input/keysym";
* import XtScancode from "./input/xtscancodes";
* import Inflator from "./inflator.mod";
*/
/*jslint white: false, browser: true */ /*jslint white: false, browser: true */
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
"use strict"; "use strict";
/* [module] export default */ function RFB(defaults) { define(["core/util", "core/display", "core/websock",
"core/inflator", "core/des",
"core/input/devices", "core/input/keysym",
"core/input/xtscancodes"],
function (Util, display, websock, Inflator, DES, devices,
KeyTable, XtScancode) {
var _ = Util.Localisation.get;
function RFB(defaults) {
if (!defaults) { if (!defaults) {
defaults = {}; defaults = {};
} }
@ -191,22 +188,22 @@
// NB: nothing that needs explicit teardown should be done // NB: nothing that needs explicit teardown should be done
// before this point, since this can throw an exception // before this point, since this can throw an exception
try { try {
this._display = new Display({target: this._target, this._display = new display.Display({target: this._target,
onFlush: this._onFlush.bind(this)}); onFlush: this._onFlush.bind(this)});
} catch (exc) { } catch (exc) {
Util.Error("Display exception: " + exc); Util.Error("Display exception: " + exc);
throw exc; throw exc;
} }
this._keyboard = new Keyboard({target: this._focusContainer, this._keyboard = new devices.Keyboard({target: this._focusContainer,
onKeyPress: this._handleKeyPress.bind(this)}); onKeyPress: this._handleKeyPress.bind(this)});
this._mouse = new Mouse({target: this._target, this._mouse = new devices.Mouse({target: this._target,
onMouseButton: this._handleMouseButton.bind(this), onMouseButton: this._handleMouseButton.bind(this),
onMouseMove: this._handleMouseMove.bind(this), onMouseMove: this._handleMouseMove.bind(this),
notify: this._keyboard.sync.bind(this._keyboard)}); notify: this._keyboard.sync.bind(this._keyboard)});
this._sock = new Websock(); this._sock = new websock.Websock();
this._sock.on('message', this._handle_message.bind(this)); this._sock.on('message', this._handle_message.bind(this));
this._sock.on('open', function () { this._sock.on('open', function () {
if ((this._rfb_connection_state === 'connecting') && if ((this._rfb_connection_state === 'connecting') &&
@ -261,10 +258,7 @@
Util.Info("Using native WebSockets, render mode: " + rmode); Util.Info("Using native WebSockets, render mode: " + rmode);
Util.Debug("<< RFB.constructor"); Util.Debug("<< RFB.constructor");
}; };
(function() {
var _ = Util.Localisation.get;
RFB.prototype = { RFB.prototype = {
// Public methods // Public methods
@ -2443,4 +2437,6 @@
Util.Error("Server sent compress level pseudo-encoding"); Util.Error("Server sent compress level pseudo-encoding");
} }
}; };
})();
return { RFB: RFB };
});

View File

@ -1,34 +1,29 @@
/* /*
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
* *
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
/* jshint white: false, nonstandard: true */ /* jshint white: false, nonstandard: true */
/*global window, console, document, navigator, ActiveXObject, INCLUDE_URI */
"use strict"; "use strict";
var Util = {}; define(function() {
var Util = {};
/* /*
* ------------------------------------------------------
* Namespaced in Util
* ------------------------------------------------------
*/
/*
* Logging/debug routines * Logging/debug routines
*/ */
Util._log_level = 'warn'; var _log_level = 'warn';
Util.init_logging = function (level) { Util.init_logging = function (level) {
if (typeof level === 'undefined') { if (typeof level === 'undefined') {
level = Util._log_level; level = _log_level;
} else { } else {
Util._log_level = level; _log_level = level;
} }
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
@ -50,14 +45,14 @@ Util.init_logging = function (level) {
} }
/* jshint +W086 */ /* jshint +W086 */
} }
}; };
Util.get_logging = function () { Util.get_logging = function () {
return Util._log_level; return _log_level;
}; };
// Initialize logging level // Initialize logging level
Util.init_logging(); Util.init_logging();
Util.make_property = function (proto, name, mode, type) { Util.make_property = function (proto, name, mode, type) {
var getter; var getter;
if (type === 'arr') { if (type === 'arr') {
@ -147,15 +142,15 @@ Util.make_property = function (proto, name, mode, type) {
setter.call(this, val, idx); setter.call(this, val, idx);
//delete this['_init_set_' + name]; // remove it after use //delete this['_init_set_' + name]; // remove it after use
}; };
}; };
Util.make_properties = function (constructor, arr) { Util.make_properties = function (constructor, arr) {
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
Util.make_property(constructor.prototype, arr[i][0], arr[i][1], arr[i][2]); Util.make_property(constructor.prototype, arr[i][0], arr[i][1], arr[i][2]);
} }
}; };
Util.set_defaults = function (obj, conf, defaults) { Util.set_defaults = function (obj, conf, defaults) {
var defaults_keys = Object.keys(defaults); var defaults_keys = Object.keys(defaults);
var conf_keys = Object.keys(conf); var conf_keys = Object.keys(conf);
var keys_obj = {}; var keys_obj = {};
@ -177,39 +172,39 @@ Util.set_defaults = function (obj, conf, defaults) {
setter.call(obj, defaults[keys[i]]); setter.call(obj, defaults[keys[i]]);
} }
} }
}; };
/* /*
* Decode from UTF-8 * Decode from UTF-8
*/ */
Util.decodeUTF8 = function (utf8string) { Util.decodeUTF8 = function (utf8string) {
return decodeURIComponent(escape(utf8string)); return decodeURIComponent(escape(utf8string));
}; };
/* /*
* Cross-browser routines * Cross-browser routines
*/ */
Util.getPosition = function(obj) { Util.getPosition = function(obj) {
// NB(sross): the Mozilla developer reference seems to indicate that // NB(sross): the Mozilla developer reference seems to indicate that
// getBoundingClientRect includes border and padding, so the canvas // getBoundingClientRect includes border and padding, so the canvas
// style should NOT include either. // style should NOT include either.
var objPosition = obj.getBoundingClientRect(); var objPosition = obj.getBoundingClientRect();
return {'x': objPosition.left + window.pageXOffset, 'y': objPosition.top + window.pageYOffset, return {'x': objPosition.left + window.pageXOffset, 'y': objPosition.top + window.pageYOffset,
'width': objPosition.width, 'height': objPosition.height}; 'width': objPosition.width, 'height': objPosition.height};
}; };
Util.getPointerEvent = function (e) { Util.getPointerEvent = function (e) {
var evt; var evt;
evt = (e ? e : window.event); evt = (e ? e : window.event);
evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt);
return evt; return evt;
}; };
// Get mouse event position in DOM element // Get mouse event position in DOM element
Util.getEventPosition = function (e, obj, scale) { Util.getEventPosition = function (e, obj, scale) {
var evt, docX, docY, pos; var evt, docX, docY, pos;
evt = Util.getPointerEvent(e); evt = Util.getPointerEvent(e);
if (evt.pageX || evt.pageY) { if (evt.pageX || evt.pageY) {
@ -230,53 +225,52 @@ Util.getEventPosition = function (e, obj, scale) {
var x = Math.max(Math.min(realx, pos.width - 1), 0); var x = Math.max(Math.min(realx, pos.width - 1), 0);
var y = Math.max(Math.min(realy, pos.height - 1), 0); var y = Math.max(Math.min(realy, pos.height - 1), 0);
return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale}; return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale};
}; };
Util.stopEvent = function (e) { Util.stopEvent = function (e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}; };
// Touch detection // Touch detection
Util.isTouchDevice = ('ontouchstart' in document.documentElement) || Util.isTouchDevice = ('ontouchstart' in document.documentElement) ||
// requried for Chrome debugger // requried for Chrome debugger
(document.ontouchstart !== undefined) || (document.ontouchstart !== undefined) ||
// required for MS Surface // required for MS Surface
(navigator.maxTouchPoints > 0) || (navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0); (navigator.msMaxTouchPoints > 0);
window.addEventListener('touchstart', function onFirstTouch() { window.addEventListener('touchstart', function onFirstTouch() {
Util.isTouchDevice = true; Util.isTouchDevice = true;
window.removeEventListener('touchstart', onFirstTouch, false); window.removeEventListener('touchstart', onFirstTouch, false);
}, false); }, false);
Util._cursor_uris_supported = null; var _cursor_uris_supported = null;
Util.browserSupportsCursorURIs = function () { Util.browserSupportsCursorURIs = function () {
if (Util._cursor_uris_supported === null) { if (_cursor_uris_supported === null) {
try { try {
var target = document.createElement('canvas'); var target = document.createElement('canvas');
target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default'; target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
if (target.style.cursor) { if (target.style.cursor) {
Util.Info("Data URI scheme cursor supported"); Util.Info("Data URI scheme cursor supported");
Util._cursor_uris_supported = true; _cursor_uris_supported = true;
} else { } else {
Util.Warn("Data URI scheme cursor not supported"); Util.Warn("Data URI scheme cursor not supported");
Util._cursor_uris_supported = false; _cursor_uris_supported = false;
} }
} catch (exc) { } catch (exc) {
Util.Error("Data URI scheme cursor test exception: " + exc); Util.Error("Data URI scheme cursor test exception: " + exc);
Util._cursor_uris_supported = false; _cursor_uris_supported = false;
} }
} }
return Util._cursor_uris_supported; return _cursor_uris_supported;
}; };
// Set browser engine versions. Based on mootools. // Set browser engine versions. Based on mootools.
Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
(function () {
// 'presto': (function () { return (!window.opera) ? false : true; }()), // 'presto': (function () { return (!window.opera) ? false : true; }()),
var detectPresto = function () { var detectPresto = function () {
return !!window.opera; return !!window.opera;
@ -343,9 +337,8 @@ Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !
// Extract actual webkit version if available // Extract actual webkit version if available
Util.Engine.webkit = detectActualWebkit(Util.Engine.webkit); Util.Engine.webkit = detectActualWebkit(Util.Engine.webkit);
} }
})();
Util.Flash = (function () { Util.Flash = (function () {
var v, version; var v, version;
try { try {
v = navigator.plugins['Shockwave Flash'].description; v = navigator.plugins['Shockwave Flash'].description;
@ -358,15 +351,44 @@ Util.Flash = (function () {
} }
version = v.match(/\d+/g); version = v.match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}()); }());
Util.Localisation = { Util.Localisation = {
// Currently configured language // Currently configured language
language: 'en', language: 'en',
// Configure suitable language based on user preferences // Translation data
setup: function (supportedLanguages) { _translations: null,
// Configure and load suitable language based on user preferences
setup: function (supportedLanguages, basedir, callback) {
Util.Localisation._setLanguageCode(supportedLanguages);
if (Util.Localisation.language === 'en') {
if (callback !== undefined) {
callback();
}
return;
}
if (basedir[basedir.length - 1] !== '/') {
basedir = basedir + '/';
}
require([basedir + Util.Localisation.language],
function(lang) {
Util.Localisation._translations = lang;
if (callback !== undefined) {
callback();
}
});
},
// Internal function to figure out the proper language code
_setLanguageCode: function (supportedLanguages) {
var userLanguages; var userLanguages;
Util.Localisation.language = 'en'; // Default: US English Util.Localisation.language = 'en'; // Default: US English
@ -429,11 +451,12 @@ Util.Localisation = {
// Retrieve localised text // Retrieve localised text
get: function (id) { get: function (id) {
if (typeof Language !== 'undefined' && Language[id]) { if ((Util.Localisation._translations === null) ||
return Language[id]; (Util.Localisation._translations[id] === undefined)) {
} else {
return id; return id;
} }
return Util.Localisation._translations[id];
}, },
// Traverses the DOM and translates relevant fields // Traverses the DOM and translates relevant fields
@ -498,7 +521,7 @@ Util.Localisation = {
} }
for (var i = 0;i < elem.childNodes.length;i++) { for (var i = 0;i < elem.childNodes.length;i++) {
node = elem.childNodes[i]; var node = elem.childNodes[i];
if (node.nodeType === node.ELEMENT_NODE) { if (node.nodeType === node.ELEMENT_NODE) {
process(node, enabled); process(node, enabled);
} else if (node.nodeType === node.TEXT_NODE && enabled) { } else if (node.nodeType === node.TEXT_NODE && enabled) {
@ -509,6 +532,7 @@ Util.Localisation = {
process(document.body, true); process(document.body, true);
}, },
}; };
/* [module] export default Util; */ return Util;
});

View File

@ -14,18 +14,14 @@
* read binary data off of the receive queue. * read binary data off of the receive queue.
*/ */
/* [module]
* import Util from "./util";
* import Base64 from "./base64";
*/
/*jslint browser: true, bitwise: true */ /*jslint browser: true, bitwise: true */
/*global Util*/
"use strict"; "use strict";
/* [module] export default */ function Websock() { define(["core/util"],
function (Util) {
function Websock() {
this._websocket = null; // WebSocket object this._websocket = null; // WebSocket object
this._rQi = 0; // Receive queue index this._rQi = 0; // Receive queue index
@ -49,9 +45,8 @@
'close': function () {}, 'close': function () {},
'error': function () {} 'error': function () {}
}; };
}; };
(function () {
// this has performance issues in some versions Chromium, and // this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox // doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future. // at the moment. It may be valuable to turn it on in the future.
@ -423,4 +418,6 @@
} }
} }
}; };
})();
return { Websock: Websock };
});

View File

@ -1,5 +1,5 @@
Rebuilding inflator.js Rebuilding inflator.js
- Download pako from npm - Download pako from npm
- Install browserify using npm - Install requirejs using npm
- browserify core/inflator.mod.js -o core/inflator.js -s Inflator - make -C inflator install

19
inflator/Makefile Normal file
View File

@ -0,0 +1,19 @@
.PHONY: all install clean
all: inflator-merged.js
RJS := r.js
inflator-merged.js: build.js inflator.js pako
r.js -o build.js
pako: ../node_modules/pako
$(RJS) -convert $< pako/
install: all
rm -f ../core/inflator.js
cp inflator-merged.js ../core/inflator.js
clean:
rm -f inflator.js
rm -rf pako

8
inflator/build.js Normal file
View File

@ -0,0 +1,8 @@
({
baseUrl: ".",
name: "core/inflator",
paths: {
"core": ".",
},
out: "inflator-merged.js"
})

52
inflator/inflator.js Normal file
View File

@ -0,0 +1,52 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin
* Copyright (C) 2017 Pierre Ossman for Cendio AB
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/
/*jslint browser: true, white: false */
"use strict";
define(["pako/lib/zlib/inflate.js", "pako/lib/zlib/zstream.js"],
function (zlib, ZStream) {
function Inflate() {
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);
}
};
return { Inflate: Inflate };
});

View File

@ -108,34 +108,15 @@ module.exports = function(config) {
// list of files / patterns to load in the browser (loaded in order) // list of files / patterns to load in the browser (loaded in order)
files: [ files: [
'node_modules/requirejs/require.js',
'tests/test-main.js',
'tests/fake.*.js', 'tests/fake.*.js',
'tests/assertions.js', 'tests/assertions.js',
'core/util.js', // load first to avoid issues, since methods are called immediately 'tests/test.*.js',
//'../core/*.js', // Only packaged, not included in browser as RequireJS will
'core/base64.js', // do the actual loading
'core/input/keysym.js', {pattern: 'core/*.js', included: false},
'core/input/keysymdef.js', {pattern: 'core/input/*.js', included: false},
'core/input/xtscancodes.js',
'core/input/util.js',
'core/input/devices.js',
'core/websock.js',
'core/rfb.js',
'core/des.js',
'core/display.js',
'core/inflator.js',
'tests/test.*.js'
],
client: {
mocha: {
'ui': 'bdd'
}
},
// list of files to exclude
exclude: [
'../tests/playback.js',
'../app/ui.js'
], ],
customLaunchers: customLaunchers, customLaunchers: customLaunchers,

View File

@ -51,6 +51,7 @@
"open": "^0.0.5", "open": "^0.0.5",
"phantomjs-prebuilt": "^2.1.13", "phantomjs-prebuilt": "^2.1.13",
"po2json": "*", "po2json": "*",
"requirejs": "*",
"sinon": "^1.17.6", "sinon": "^1.17.6",
"sinon-chai": "^2.8.0", "sinon-chai": "^2.8.0",
"spooky": "^0.2.5", "spooky": "^0.2.5",

View File

@ -40,7 +40,10 @@ var output =
" * DO NOT EDIT!\n" + " * DO NOT EDIT!\n" +
" */\n" + " */\n" +
"\n" + "\n" +
"Language = {\n"; "\"use strict\";\n" +
"\n" +
"define(function() {\n" +
"return {\n";
for (msgid in data) { for (msgid in data) {
if (msgid === "") if (msgid === "")
@ -52,5 +55,6 @@ for (msgid in data) {
} }
output += "};\n"; output += "};\n";
output += "});\n";
fs.writeFileSync(opt.argv[1], output); fs.writeFileSync(opt.argv[1], output);

View File

@ -99,6 +99,8 @@ if (program.autoInject) {
template.header += "\n" + template.script_tag(get_path('node_modules/mocha/mocha.js')); template.header += "\n" + template.script_tag(get_path('node_modules/mocha/mocha.js'));
template.header += "\n" + template.script_tag(get_path('node_modules/sinon/pkg/sinon.js')); template.header += "\n" + template.script_tag(get_path('node_modules/sinon/pkg/sinon.js'));
template.header += "\n" + template.script_tag(get_path('node_modules/sinon-chai/lib/sinon-chai.js')); template.header += "\n" + template.script_tag(get_path('node_modules/sinon-chai/lib/sinon-chai.js'));
template.header += "\n" + template.script_tag(get_path('node_modules/requirejs/require.js'));
template.header += "\n<script>requirejs.config({ baseUrl: \"" + get_path('.') + "\" });</script>";
template.header += "\n<script>mocha.setup('bdd');</script>"; template.header += "\n<script>mocha.setup('bdd');</script>";

5
tests/test-main.js Normal file
View File

@ -0,0 +1,5 @@
requirejs.config({
// Karma serves files under /base
baseUrl: '/base'
});

View File

@ -1,10 +1,19 @@
// requires local modules: base64
var assert = chai.assert; var assert = chai.assert;
var expect = chai.expect; var expect = chai.expect;
describe('Base64 Tools', function() { describe('Base64 Tools', function(done) {
"use strict"; "use strict";
var Base64;
before(function (done) {
requirejs(["core/base64"],
function (b) {
Base64 = b;
done();
});
});
var BIN_ARR = new Array(256); var BIN_ARR = new Array(256);
for (var i = 0; i < 256; i++) { for (var i = 0; i < 256; i++) {
BIN_ARR[i] = i; BIN_ARR[i] = i;

View File

@ -1,9 +1,22 @@
// requires local modules: util, base64, display
// requires test modules: assertions // requires test modules: assertions
/* jshint expr: true */ /* jshint expr: true */
var expect = chai.expect; var expect = chai.expect;
describe('Display/Canvas Helper', function () { describe('Display/Canvas Helper', function () {
"use strict";
var Util, Base64, Display;
before(function (done) {
requirejs(["core/util", "core/base64", "core/display"],
function (u, b, d) {
Util = u;
Base64 = b;
Display = d.Display;
done();
});
});
var checked_data = [ var checked_data = [
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,

View File

@ -1,10 +1,20 @@
// requires local modules: input/keysym, input/keysymdef, input/util
var assert = chai.assert; var assert = chai.assert;
var expect = chai.expect; var expect = chai.expect;
describe('Helpers', function() { describe('Helpers', function() {
"use strict"; "use strict";
var keysyms, KeyboardUtil;
before(function (done) {
requirejs(["core/input/keysymdef", "core/input/util"],
function (k, u) {
keysyms = k;
KeyboardUtil = u;
done();
});
});
describe('keysymFromKeyCode', function() { describe('keysymFromKeyCode', function() {
it('should map known keycodes to keysyms', function() { it('should map known keycodes to keysyms', function() {
expect(KeyboardUtil.keysymFromKeyCode(0x41, false), 'a').to.be.equal(0x61); expect(KeyboardUtil.keysymFromKeyCode(0x41, false), 'a').to.be.equal(0x61);

View File

@ -1,10 +1,21 @@
// requires local modules: input/devices, input/util, input/keysymdef, input/keysym
var assert = chai.assert; var assert = chai.assert;
var expect = chai.expect; var expect = chai.expect;
/* jshint newcap: false, expr: true */ /* jshint newcap: false, expr: true */
describe('Key Event Pipeline Stages', function() { describe('Key Event Pipeline Stages', function() {
"use strict"; "use strict";
var keysyms, KeyboardUtil;
before(function (done) {
requirejs(["core/input/keysymdef", "core/input/util"],
function (k, u) {
keysyms = k;
KeyboardUtil = u;
done();
});
});
describe('Decode Keyboard Events', function() { describe('Decode Keyboard Events', function() {
it('should pass events to the next stage', function(done) { it('should pass events to the next stage', function(done) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) { KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {

View File

@ -1,9 +1,10 @@
// requires local modules: util, websock, rfb, input/util, input/keysym, input/keysymdef, input/devices, inflator, des, display
// requires test modules: fake.websocket, assertions // requires test modules: fake.websocket, assertions
/* jshint expr: true */ /* jshint expr: true */
var assert = chai.assert; var assert = chai.assert;
var expect = chai.expect; var expect = chai.expect;
var RFB;
function make_rfb (extra_opts) { function make_rfb (extra_opts) {
if (!extra_opts) { if (!extra_opts) {
extra_opts = {}; extra_opts = {};
@ -34,9 +35,21 @@ var push32 = function (arr, num) {
describe('Remote Frame Buffer Protocol Client', function() { describe('Remote Frame Buffer Protocol Client', function() {
"use strict"; "use strict";
before(FakeWebSocket.replace); before(FakeWebSocket.replace);
after(FakeWebSocket.restore); after(FakeWebSocket.restore);
var Websock;
before(function (done) {
requirejs(["core/rfb", "core/websock"],
function (r, w) {
RFB = r.RFB;
Websock = w.Websock;
done();
});
});
before(function () { before(function () {
this.clock = sinon.useFakeTimers(); this.clock = sinon.useFakeTimers();
// Use a single set of buffers instead of reallocating to // Use a single set of buffers instead of reallocating to

View File

@ -1,4 +1,3 @@
// requires local modules: util
/* jshint expr: true */ /* jshint expr: true */
var assert = chai.assert; var assert = chai.assert;
@ -7,6 +6,16 @@ var expect = chai.expect;
describe('Utils', function() { describe('Utils', function() {
"use strict"; "use strict";
var Util;
before(function (done) {
requirejs(["core/util"],
function (u) {
Util = u;
done();
});
});
describe('logging functions', function () { describe('logging functions', function () {
beforeEach(function () { beforeEach(function () {
sinon.spy(console, 'log'); sinon.spy(console, 'log');
@ -57,7 +66,7 @@ describe('Utils', function() {
}); });
describe('language selection', function () { describe('language selection', function () {
var origNavigator; var origNavigator, origRequire;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these
@ -77,8 +86,13 @@ describe('Utils', function() {
} }
window.navigator.languages = []; window.navigator.languages = [];
// Prevent the code from trying to actually load translations
origRequire = require;
require = function (mods, func) { func([]); };
}); });
afterEach(function () { afterEach(function () {
require = origRequire;
Object.defineProperty(window, "navigator", origNavigator); Object.defineProperty(window, "navigator", origNavigator);
}); });
@ -87,37 +101,37 @@ describe('Utils', function() {
}); });
it('should use English if no user language matches', function() { it('should use English if no user language matches', function() {
window.navigator.languages = ["nl", "de"]; window.navigator.languages = ["nl", "de"];
Util.Localisation.setup(["es", "fr"]); Util.Localisation.setup(["es", "fr"], ".");
expect(Util.Localisation.language).to.equal('en'); expect(Util.Localisation.language).to.equal('en');
}); });
it('should use the most preferred user language', function() { it('should use the most preferred user language', function() {
window.navigator.languages = ["nl", "de", "fr"]; window.navigator.languages = ["nl", "de", "fr"];
Util.Localisation.setup(["es", "fr", "de"]); Util.Localisation.setup(["es", "fr", "de"], ".");
expect(Util.Localisation.language).to.equal('de'); expect(Util.Localisation.language).to.equal('de');
}); });
it('should prefer sub-languages languages', function() { it('should prefer sub-languages languages', function() {
window.navigator.languages = ["pt-BR"]; window.navigator.languages = ["pt-BR"];
Util.Localisation.setup(["pt", "pt-BR"]); Util.Localisation.setup(["pt", "pt-BR"], ".");
expect(Util.Localisation.language).to.equal('pt-BR'); expect(Util.Localisation.language).to.equal('pt-BR');
}); });
it('should fall back to language "parents"', function() { it('should fall back to language "parents"', function() {
window.navigator.languages = ["pt-BR"]; window.navigator.languages = ["pt-BR"];
Util.Localisation.setup(["fr", "pt", "de"]); Util.Localisation.setup(["fr", "pt", "de"], ".");
expect(Util.Localisation.language).to.equal('pt'); expect(Util.Localisation.language).to.equal('pt');
}); });
it('should not use specific language when user asks for a generic language', function() { it('should not use specific language when user asks for a generic language', function() {
window.navigator.languages = ["pt", "de"]; window.navigator.languages = ["pt", "de"];
Util.Localisation.setup(["fr", "pt-BR", "de"]); Util.Localisation.setup(["fr", "pt-BR", "de"], ".");
expect(Util.Localisation.language).to.equal('de'); expect(Util.Localisation.language).to.equal('de');
}); });
it('should handle underscore as a separator', function() { it('should handle underscore as a separator', function() {
window.navigator.languages = ["pt-BR"]; window.navigator.languages = ["pt-BR"];
Util.Localisation.setup(["pt_BR"]); Util.Localisation.setup(["pt_BR"], ".");
expect(Util.Localisation.language).to.equal('pt_BR'); expect(Util.Localisation.language).to.equal('pt_BR');
}); });
it('should handle difference in case', function() { it('should handle difference in case', function() {
window.navigator.languages = ["pt-br"]; window.navigator.languages = ["pt-br"];
Util.Localisation.setup(["pt-BR"]); Util.Localisation.setup(["pt-BR"], ".");
expect(Util.Localisation.language).to.equal('pt-BR'); expect(Util.Localisation.language).to.equal('pt-BR');
}); });
}); });

View File

@ -1,4 +1,3 @@
// requires local modules: websock, util
// requires test modules: fake.websocket, assertions // requires test modules: fake.websocket, assertions
/* jshint expr: true */ /* jshint expr: true */
var assert = chai.assert; var assert = chai.assert;
@ -7,6 +6,16 @@ var expect = chai.expect;
describe('Websock', function() { describe('Websock', function() {
"use strict"; "use strict";
var Websock;
before(function (done) {
requirejs(["core/websock"],
function (w) {
Websock = w.Websock;
done();
});
});
describe('Queue methods', function () { describe('Queue methods', function () {
var sock; var sock;
var RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]); var RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);

View File

@ -80,12 +80,15 @@ var out = "// This file describes mappings from Unicode codepoints to the keysym
"// (and optionally, key names) expected by the RFB protocol\n" + "// (and optionally, key names) expected by the RFB protocol\n" +
"// How this file was generated:\n" + "// How this file was generated:\n" +
"// " + process.argv.join(" ") + "\n" + "// " + process.argv.join(" ") + "\n" +
"var keysyms = (function(){\n" + "\n" +
" \"use strict\";\n" + "\"use strict\";\n" +
"\n" +
"define(function () {\n" +
" var keynames = {keysyms};\n" + " var keynames = {keysyms};\n" +
" var codepoints = {codepoints};\n" + " var codepoints = {codepoints};\n" +
"\n" + "\n" +
" function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; }\n" + " function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; }\n" +
"\n" +
" return {\n" + " return {\n" +
" fromUnicode : function(u) {\n" + " fromUnicode : function(u) {\n" +
" var keysym = codepoints[u];\n" + " var keysym = codepoints[u];\n" +
@ -96,7 +99,7 @@ var out = "// This file describes mappings from Unicode codepoints to the keysym
" },\n" + " },\n" +
" lookup : lookup\n" + " lookup : lookup\n" +
" };\n" + " };\n" +
"})();\n"; "});\n";
out = out.replace('{keysyms}', use_keynames ? JSON.stringify(keysyms) : "null"); out = out.replace('{keysyms}', use_keynames ? JSON.stringify(keysyms) : "null");
out = out.replace('{codepoints}', JSON.stringify(codepoints)); out = out.replace('{codepoints}', JSON.stringify(codepoints));

View File

@ -55,10 +55,7 @@
<!-- Stylesheets --> <!-- Stylesheets -->
<link rel="stylesheet" href="app/styles/base.css" /> <link rel="stylesheet" href="app/styles/base.css" />
<!-- <script type='text/javascript' data-main='app/novnc.js' src='app/require.js'></script>
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
</head> </head>
@ -314,12 +311,5 @@
<source src="app/sounds/bell.oga" type="audio/ogg"> <source src="app/sounds/bell.oga" type="audio/ogg">
<source src="app/sounds/bell.mp3" type="audio/mpeg"> <source src="app/sounds/bell.mp3" type="audio/mpeg">
</audio> </audio>
<!-- begin scripts -->
<script src="core/util.js"></script>
<script src="app/webutil.js"></script>
<script src="app/ui.js"></script>
<!-- end scripts -->
</body> </body>
</html> </html>

View File

@ -38,12 +38,7 @@
<!-- Stylesheets --> <!-- Stylesheets -->
<link rel="stylesheet" href="app/styles/auto.css"> <link rel="stylesheet" href="app/styles/auto.css">
<!-- <script src="app/require.js"></script>
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script src="core/util.js"></script>
<script src="app/webutil.js"></script>
</head> </head>
<body style="margin: 0px;"> <body style="margin: 0px;">
@ -74,14 +69,10 @@
<script> <script>
/*jslint white: false */ /*jslint white: false */
/*global window, $, Util, RFB, */
"use strict"; "use strict";
// Load supporting scripts require(["app/webutil", "core/rfb"],
WebUtil.load_scripts({ function(WebUtil, rfbmod) {
'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js",
"input/xtscancodes.js", "input/util.js", "input/devices.js",
"display.js", "inflator.js", "rfb.js", "input/keysym.js"]});
var rfb; var rfb;
var resizeTimeout; var resizeTimeout;
@ -215,7 +206,6 @@
} }
} }
window.onscriptsload = function () {
var host, port, password, path, token; var host, port, password, path, token;
document.getElementById('sendCtrlAltDelButton').style.display = "inline"; document.getElementById('sendCtrlAltDelButton').style.display = "inline";
@ -261,7 +251,7 @@
} }
try { try {
rfb = new RFB({'target': document.getElementById('noVNC_canvas'), rfb = new rfbmod.RFB({'target': document.getElementById('noVNC_canvas'),
'encrypt': WebUtil.getConfigVar('encrypt', 'encrypt': WebUtil.getConfigVar('encrypt',
(window.location.protocol === "https:")), (window.location.protocol === "https:")),
'repeaterID': WebUtil.getConfigVar('repeaterID', ''), 'repeaterID': WebUtil.getConfigVar('repeaterID', ''),
@ -282,7 +272,7 @@
} }
rfb.connect(host, port, password, path); rfb.connect(host, port, password, path);
}; });
</script> </script>
</body> </body>