Add eslint and refactor to ES6

This commit is contained in:
Juanjo Diaz 2018-01-27 20:47:24 -08:00
parent 609a3fac74
commit d737fda1cc
48 changed files with 8970 additions and 2449 deletions

10
.eslintrc Normal file
View File

@ -0,0 +1,10 @@
{
"env": {
"browser": true,
"es6": true
},
"parserOptions": {
"sourceType": "module",
},
"extends": "eslint:recommended"
}

View File

@ -9,14 +9,14 @@
// Fallback for all uncought errors
function handleError (event, err) {
try {
var msg = document.getElementById('noVNC_fallback_errormsg');
const msg = document.getElementById('noVNC_fallback_errormsg');
// Only show the initial error
if (msg.hasChildNodes()) {
return false;
}
var div = document.createElement("div");
let div = document.createElement("div");
div.classList.add('noVNC_message');
div.appendChild(document.createTextNode(event.message));
msg.appendChild(div);
@ -24,7 +24,7 @@
if (event.filename) {
div = document.createElement("div");
div.className = 'noVNC_location';
var text = event.filename;
let text = event.filename;
if (event.lineno !== undefined) {
text += ":" + event.lineno;
if (event.colno !== undefined) {
@ -51,6 +51,6 @@
// from being printed to the browser console.
return false;
}
window.addEventListener('error', function (evt) { handleError(evt, evt.error); });
window.addEventListener('unhandledrejection', function (evt) { handleError(evt.reason, evt.reason); });
window.addEventListener('error', evt => handleError(evt, evt.error));
window.addEventListener('unhandledrejection', evt => handleError(evt.reason, evt.reason));
})();

View File

@ -10,7 +10,8 @@
* Localization Utilities
*/
export function Localizer() {
export class Localizer{
constructor() {
// Currently configured language
this.language = 'en';
@ -18,10 +19,8 @@ export function Localizer() {
this.dictionary = undefined;
}
Localizer.prototype = {
// Configure suitable language based on user preferences
setup: function (supportedLanguages) {
var userLanguages;
setup(supportedLanguages) {
this.language = 'en'; // Default: US English
@ -29,17 +28,16 @@ Localizer.prototype = {
* Navigator.languages only available in Chrome (32+) and FireFox (32+)
* Fall back to navigator.language for other browsers
*/
if (typeof window.navigator.languages == 'object') {
userLanguages = window.navigator.languages;
} else {
userLanguages = [navigator.language || navigator.userLanguage];
}
for (var i = 0;i < userLanguages.length;i++) {
var userLang = userLanguages[i];
userLang = userLang.toLowerCase();
userLang = userLang.replace("_", "-");
userLang = userLang.split("-");
const userLanguages = (typeof window.navigator.languages == 'object')
? window.navigator.languages
: [navigator.language || navigator.userLanguage];
for (let i = 0;i < userLanguages.length;i++) {
const userLang = userLanguages[i]
.toLowerCase()
.replace("_", "-")
.split("-");
// Built-in default?
if ((userLang[0] === 'en') &&
@ -48,11 +46,11 @@ Localizer.prototype = {
}
// First pass: perfect match
for (var j = 0;j < supportedLanguages.length;j++) {
var supLang = supportedLanguages[j];
supLang = supLang.toLowerCase();
supLang = supLang.replace("_", "-");
supLang = supLang.split("-");
for (let j = 0;j < supportedLanguages.length;j++) {
const supLang = supportedLanguages[j]
.toLowerCase()
.replace("_", "-")
.split("-");
if (userLang[0] !== supLang[0])
continue;
@ -64,11 +62,11 @@ Localizer.prototype = {
}
// Second pass: fallback
for (var j = 0;j < supportedLanguages.length;j++) {
supLang = supportedLanguages[j];
supLang = supLang.toLowerCase();
supLang = supLang.replace("_", "-");
supLang = supLang.split("-");
for (let j = 0; j < supportedLanguages.length; j++) {
const supLang = supportedLanguages[j]
.toLowerCase()
.replace("_", "-")
.split("-");
if (userLang[0] !== supLang[0])
continue;
@ -79,36 +77,31 @@ Localizer.prototype = {
return;
}
}
},
}
// Retrieve localised text
get: function (id) {
get(id) {
if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
return this.dictionary[id];
} else {
return id;
}
},
}
// Traverses the DOM and translates relevant fields
// See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
translateDOM: function () {
var self = this;
translateDOM() {
function process(elem, enabled) {
function isAnyOf(searchElement, items) {
return items.indexOf(searchElement) !== -1;
}
function translateAttribute(elem, attr) {
var str = elem.getAttribute(attr);
str = self.get(str);
elem.setAttribute(attr, str);
elem.setAttribute(attr, this.get(elem.getAttribute(attr)));
}
function translateTextNode(node) {
var str = node.data.trim();
str = self.get(str);
node.data = str;
node.data = this.get(node.data.trim());
}
if (elem.hasAttribute("translate")) {
@ -152,19 +145,18 @@ Localizer.prototype = {
}
}
for (var i = 0;i < elem.childNodes.length;i++) {
var node = elem.childNodes[i];
elem.childNodes.forEach((node) => {
if (node.nodeType === node.ELEMENT_NODE) {
process(node, enabled);
} else if (node.nodeType === node.TEXT_NODE && enabled) {
translateTextNode(node);
}
}
});
}
process(document.body, true);
},
};
}
}
export var l10n = new Localizer();
export let l10n = new Localizer();
export default l10n.get.bind(l10n);

445
app/ui.js

File diff suppressed because it is too large Load Diff

View File

@ -7,26 +7,21 @@
* See README.md for usage and integration instructions.
*/
/*jslint bitwise: false, white: false, browser: true, devel: true */
/*global Util, window, document */
import { init_logging as main_init_logging } from '../core/util/logging.js';
// init log level reading the logging HTTP param
export function init_logging (level) {
"use strict";
if (typeof level !== "undefined") {
main_init_logging(level);
} else {
var param = document.location.href.match(/logging=([A-Za-z0-9\._\-]*)/);
const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
main_init_logging(param || undefined);
}
};
}
// Read a query string variable
export function getQueryVar (name, defVal) {
"use strict";
var re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
match = document.location.href.match(re);
if (typeof defVal === 'undefined') { defVal = null; }
if (match) {
@ -34,12 +29,11 @@ export function getQueryVar (name, defVal) {
} else {
return defVal;
}
};
}
// Read a hash fragment variable
export function getHashVar (name, defVal) {
"use strict";
var re = new RegExp('.*[&#]' + name + '=([^&]*)'),
const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
match = document.location.hash.match(re);
if (typeof defVal === 'undefined') { defVal = null; }
if (match) {
@ -47,18 +41,17 @@ export function getHashVar (name, defVal) {
} else {
return defVal;
}
};
}
// Read a variable from the fragment or the query string
// Fragment takes precedence
export function getConfigVar (name, defVal) {
"use strict";
var val = getHashVar(name);
let val = getHashVar(name);
if (val === null) {
val = getQueryVar(name, defVal);
}
return val;
};
}
/*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
@ -66,8 +59,7 @@ export function getConfigVar (name, defVal) {
// No days means only for this browser session
export function createCookie (name, value, days) {
"use strict";
var date, expires;
let date, expires;
if (days) {
date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
@ -76,46 +68,41 @@ export function createCookie (name, value, days) {
expires = "";
}
var secure;
if (document.location.protocol === "https:") {
secure = "; secure";
} else {
secure = "";
}
const secure = (document.location.protocol === "https:")
? "; secure"
: "";
document.cookie = name + "=" + value + expires + "; path=/" + secure;
};
}
export function readCookie (name, defaultValue) {
"use strict";
var nameEQ = name + "=",
const nameEQ = name + "=",
ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i += 1) {
var c = ca[i];
for (let i = 0; i < ca.length; i += 1) {
let c = ca[i];
while (c.charAt(0) === ' ') { c = c.substring(1, c.length); }
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); }
}
return (typeof defaultValue !== 'undefined') ? defaultValue : null;
};
}
export function eraseCookie (name) {
"use strict";
createCookie(name, "", -1);
};
}
/*
* Setting handling.
*/
var settings = {};
let settings = {};
export function initSettings (callback /*, ...callbackArgs */) {
"use strict";
var callbackArgs = Array.prototype.slice.call(arguments, 1);
const callbackArgs = Array.prototype.slice.call(arguments, 1);
if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.get(function (cfg) {
window.chrome.storage.sync.get((cfg) => {
settings = cfg;
console.log(settings);
if (callback) {
callback.apply(this, callbackArgs);
}
@ -126,11 +113,10 @@ export function initSettings (callback /*, ...callbackArgs */) {
callback.apply(this, callbackArgs);
}
}
};
}
// No days means only for this browser session
export function writeSetting (name, value) {
"use strict";
if (window.chrome && window.chrome.storage) {
//console.log("writeSetting:", name, value);
if (settings[name] !== value) {
@ -140,11 +126,10 @@ export function writeSetting (name, value) {
} else {
localStorage.setItem(name, value);
}
};
}
export function readSetting (name, defaultValue) {
"use strict";
var value;
let value;
if (window.chrome && window.chrome.storage) {
value = settings[name];
} else {
@ -158,33 +143,29 @@ export function readSetting (name, defaultValue) {
} else {
return value;
}
};
}
export function eraseSetting (name) {
"use strict";
if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.remove(name);
delete settings[name];
} else {
localStorage.removeItem(name);
}
};
}
export function injectParamIfMissing (path, param, value) {
// force pretend that we're dealing with a relative path
// (assume that we wanted an extra if we pass one in)
path = "/" + path;
var elem = document.createElement('a');
const elem = document.createElement('a');
elem.href = path;
var param_eq = encodeURIComponent(param) + "=";
var query;
if (elem.search) {
query = elem.search.slice(1).split('&');
} else {
query = [];
}
const param_eq = encodeURIComponent(param) + "=";
const query = elem.search
? elem.search.slice(1).split('&')
: [];
if (!query.some(function (v) { return v.startsWith(param_eq); })) {
query.push(param_eq + encodeURIComponent(value));
@ -195,10 +176,10 @@ export function injectParamIfMissing (path, param, value) {
// in the elem.pathname string. Handle that case gracefully.
if (elem.pathname.charAt(0) == "/") {
return elem.pathname.slice(1) + elem.search + elem.hash;
} else {
}
return elem.pathname + elem.search + elem.hash;
}
};
// sadly, we can't use the Fetch API until we decide to drop
// IE11 support or polyfill promises and fetch in IE11.
@ -206,28 +187,26 @@ export function injectParamIfMissing (path, param, value) {
// will receive either an event or an error on failure.
export function fetchJSON(path, resolve, reject) {
// NB: IE11 doesn't support JSON as a responseType
var req = new XMLHttpRequest();
const req = new XMLHttpRequest();
req.open('GET', path);
req.onload = function () {
req.onload = () => {
if (req.status === 200) {
try {
var resObj = JSON.parse(req.responseText);
resolve(JSON.parse(req.responseText));
} catch (err) {
reject(err);
return;
}
resolve(resObj);
} else {
reject(new Error("XHR got non-200 status while trying to load '" + path + "': " + req.status));
}
};
req.onerror = function (evt) {
req.onerror = (evt) => {
reject(new Error("XHR encountered an error while trying to load '" + path + "': " + evt.message));
};
req.ontimeout = function (evt) {
req.ontimeout = () => {
reject(new Error("XHR timed out while trying to load '" + path + "'"));
};

View File

@ -4,50 +4,44 @@
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
/*jslint white: false */
/*global console */
import * as Log from './util/logging.js';
export default {
/* Convert data (an array of integers) to a Base64 string. */
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
base64Pad : '=',
encode: function (data) {
"use strict";
var result = '';
var toBase64Table = this.toBase64Table;
var length = data.length;
var lengthpad = (length % 3);
encode(data) {
let result = '';
const length = data.length;
const lengthpad = (length % 3);
// Convert every three bytes to 4 ascii characters.
for (var i = 0; i < (length - 2); i += 3) {
result += toBase64Table[data[i] >> 2];
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
result += toBase64Table[data[i + 2] & 0x3f];
for (let i = 0; i < (length - 2); i += 3) {
result += this.toBase64Table[data[i] >> 2];
result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
result += this.toBase64Table[data[i + 2] & 0x3f];
}
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
var j = 0;
let j = length - lengthpad;
if (lengthpad === 2) {
j = length - lengthpad;
result += toBase64Table[data[j] >> 2];
result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
result += toBase64Table[(data[j + 1] & 0x0f) << 2];
result += toBase64Table[64];
result += this.toBase64Table[data[j] >> 2];
result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
result += this.toBase64Table[64];
} else if (lengthpad === 1) {
j = length - lengthpad;
result += toBase64Table[data[j] >> 2];
result += toBase64Table[(data[j] & 0x03) << 4];
result += toBase64Table[64];
result += toBase64Table[64];
result += this.toBase64Table[data[j] >> 2];
result += this.toBase64Table[(data[j] & 0x03) << 4];
result += this.toBase64Table[64];
result += this.toBase64Table[64];
}
return result;
},
/* Convert Base64 data to a string */
/* jshint -W013 */
toBinaryTable : [
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
@ -58,31 +52,25 @@ export default {
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
],
/* jshint +W013 */
decode: function (data, offset) {
"use strict";
decode(data, offset) {
offset = typeof(offset) !== 'undefined' ? offset : 0;
var toBinaryTable = this.toBinaryTable;
var base64Pad = this.base64Pad;
var result, result_length;
var leftbits = 0; // number of bits decoded, but yet to be appended
var leftdata = 0; // bits decoded, but yet to be appended
var data_length = data.indexOf('=') - offset;
let leftbits = 0; // number of bits decoded, but yet to be appended
let leftdata = 0; // bits decoded, but yet to be appended
let data_length = data.indexOf('=') - offset;
if (data_length < 0) { data_length = data.length - offset; }
/* Every four characters is 3 resulting numbers */
result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
result = new Array(result_length);
const result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
const result = new Array(result_length);
// Convert one by one.
for (var idx = 0, i = offset; i < data.length; i++) {
var c = toBinaryTable[data.charCodeAt(i) & 0x7f];
var padding = (data.charAt(i) === base64Pad);
for (let idx = 0, i = offset; i < data.length; i++) {
const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
// Skip illegal characters and whitespace
if (c === -1) {
console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
continue;
}
@ -94,7 +82,7 @@ export default {
if (leftbits >= 8) {
leftbits -= 8;
// Append if not padding.
if (!padding) {
if (data.charAt(i) !== this.base64Pad) {
result[idx++] = (leftdata >> leftbits) & 0xff;
}
leftdata &= (1 << leftbits) - 1;
@ -103,7 +91,7 @@ export default {
// If there are any bits left, the base64 string was corrupted
if (leftbits) {
err = new Error('Corrupted base64 string');
const err = new Error('Corrupted base64 string');
err.name = 'Base64-Error';
throw err;
}

View File

@ -75,89 +75,79 @@
* fine Java utilities: http://www.acme.com/java/
*/
/* jslint white: false */
export default function DES(passwd) {
"use strict";
// Tables, permutations, S-boxes, etc.
// jshint -W013
var PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
const PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ],
totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28],
z = 0x0, a,b,c,d,e,f, SP1,SP2,SP3,SP4,SP5,SP6,SP7,SP8,
keys = [];
50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ];
const totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28];
const keys = [];
const z = 0x0;
let a,b,c,d,e,f;
// jshint -W015
a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e;
SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d,
const SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d,
z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z,
a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f,
c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d];
a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e;
SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d,
const SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d,
a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f,
z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z,
z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e];
a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e;
SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f,
const SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f,
b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z,
c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d,
b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e];
a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e;
SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d,
const SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d,
z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f,
b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e,
c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e];
a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e;
SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z,
const SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z,
a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f,
z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e,
c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d];
a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e;
SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f,
const SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f,
z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z,
b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z,
a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f];
a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e;
SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f,
const SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f,
b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e,
b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e,
z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d];
a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e;
SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d,
const SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d,
c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z,
a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f,
z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e];
// jshint +W013,+W015
// Set the key.
function setKeys(keyBlock) {
var i, j, l, m, n, o, pc1m = [], pcr = [], kn = [],
raw0, raw1, rawi, KnLi;
const pc1m = [], pcr = [], kn = [];
let l, m, n;
for (j = 0, l = 56; j < 56; ++j, l -= 8) {
for (let j = 0, l = 56; j < 56; ++j, l -= 8) {
l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
m = l & 0x7;
pc1m[j] = ((keyBlock[l >>> 3] & (1<<m)) !== 0) ? 1: 0;
}
for (i = 0; i < 16; ++i) {
for (let i = 0; i < 16; ++i) {
m = i << 1;
n = m + 1;
kn[m] = kn[n] = 0;
for (o = 28; o < 59; o += 28) {
for (j = o - 28; j < o; ++j) {
for (let o = 28; o < 59; o += 28) {
for (let j = o - 28; j < o; ++j) {
l = j + totrot[i];
if (l < o) {
pcr[j] = pc1m[l];
} else {
pcr[j] = pc1m[l - 28];
pcr[j] = (l < o) ? pc1m[l] : pc1m[l - 28];
}
}
}
for (j = 0; j < 24; ++j) {
for (let j = 0; j < 24; ++j) {
if (pcr[PC2[j]] !== 0) {
kn[m] |= 1 << (23 - j);
}
@ -168,9 +158,9 @@ export default function DES(passwd) {
}
// cookey
for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
raw0 = kn[rawi++];
raw1 = kn[rawi++];
for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
const raw0 = kn[rawi++];
const raw1 = kn[rawi++];
keys[KnLi] = (raw0 & 0x00fc0000) << 6;
keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
@ -186,7 +176,8 @@ export default function DES(passwd) {
// Encrypt 8 bytes of text
function enc8(text) {
var i = 0, b = text.slice(), fval, keysi = 0,
const b = text.slice();
let i = 0, fval, keysi = 0,
l, r, x; // left, right, accumulator
// Squash 8 bytes to 2 ints
@ -271,6 +262,5 @@ export default function DES(passwd) {
}
setKeys(passwd); // Setup keys
return {'encrypt': encrypt}; // Public interface
}; // function DES
return { encrypt }; // Public interface
}

View File

@ -7,13 +7,19 @@
* See README.md for usage and integration instructions.
*/
/*jslint browser: true, white: false */
/*global Util, Base64, changeCursor */
import * as Log from './util/logging.js';
import Base64 from "./base64.js";
export default function Display(target) {
let SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try {
new ImageData(new Uint8ClampedArray(4), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
} catch (ex) {
// ignore failure
}
export default class Display {
constructor(target) {
this._drawCtx = null;
this._c_forceCanvas = false;
@ -70,53 +76,48 @@ export default function Display(target) {
}
this._tile16x16 = this._drawCtx.createImageData(16, 16);
Log.Debug("<< Display.constructor");
};
var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try {
new ImageData(new Uint8ClampedArray(4), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
} catch (ex) {
// ignore failure
}
Display.prototype = {
// ===== PROPERTIES =====
_scale: 1.0,
get scale() { return this._scale; },
this._scale = 1.0;
this._clipViewport = false;
this.logo = null;
Log.Debug("<< Display.constructor");
}
// ===== PROPERTIES =====
get scale() { return this._scale; }
set scale(scale) {
this._rescale(scale);
},
}
_clipViewport: false,
get clipViewport() { return this._clipViewport; },
get clipViewport() { return this._clipViewport; }
set clipViewport(viewport) {
this._clipViewport = viewport;
// May need to readjust the viewport dimensions
var vp = this._viewportLoc;
const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0);
},
}
get width() {
return this._fb_width;
},
}
get height() {
return this._fb_height;
},
logo: null,
}
// ===== EVENT HANDLERS =====
onflush: function () {}, // A flush request has finished
onflush() {} // A flush request has finished
// ===== PUBLIC METHODS =====
viewportChangePos: function (deltaX, deltaY) {
var vp = this._viewportLoc;
viewportChangePos(deltaX, deltaY) {
const vp = this._viewportLoc;
deltaX = Math.floor(deltaX);
deltaY = Math.floor(deltaY);
@ -125,8 +126,8 @@ Display.prototype = {
deltaY = -vp.h;
}
var vx2 = vp.x + vp.w - 1;
var vy2 = vp.y + vp.h - 1;
const vx2 = vp.x + vp.w - 1;
const vy2 = vp.y + vp.h - 1;
// Position change
@ -155,10 +156,9 @@ Display.prototype = {
this._damage(vp.x, vp.y, vp.w, vp.h);
this.flip();
},
viewportChangeSize: function(width, height) {
}
viewportChangeSize(width, height) {
if (!this._clipViewport ||
typeof(width) === "undefined" ||
typeof(height) === "undefined") {
@ -175,12 +175,12 @@ Display.prototype = {
height = this._fb_height;
}
var vp = this._viewportLoc;
const vp = this._viewportLoc;
if (vp.w !== width || vp.h !== height) {
vp.w = width;
vp.h = height;
var canvas = this._target;
const canvas = this._target;
canvas.width = width;
canvas.height = height;
@ -193,27 +193,27 @@ Display.prototype = {
// Update the visible size of the target canvas
this._rescale(this._scale);
}
},
}
absX: function (x) {
absX(x) {
return x / this._scale + this._viewportLoc.x;
},
}
absY: function (y) {
absY(y) {
return y / this._scale + this._viewportLoc.y;
},
}
resize: function (width, height) {
resize(width, height) {
this._prevDrawStyle = "";
this._fb_width = width;
this._fb_height = height;
var canvas = this._backbuffer;
const canvas = this._backbuffer;
if (canvas.width !== width || canvas.height !== height) {
// We have to save the canvas data since changing the size will clear it
var saveImg = null;
let saveImg = null;
if (canvas.width > 0 && canvas.height > 0) {
saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
}
@ -232,13 +232,13 @@ Display.prototype = {
// Readjust the viewport as it may be incorrectly sized
// and positioned
var vp = this._viewportLoc;
const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0);
},
}
// Track what parts of the visible canvas that need updating
_damage: function(x, y, w, h) {
_damage(x, y, w, h) {
if (x < this._damageBounds.left) {
this._damageBounds.left = x;
}
@ -251,25 +251,25 @@ Display.prototype = {
if ((y + h) > this._damageBounds.bottom) {
this._damageBounds.bottom = y + h;
}
},
}
// Update the visible canvas with the contents of the
// rendering canvas
flip: function(from_queue) {
flip(from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'flip'
});
} else {
var x, y, vx, vy, w, h;
return;
}
x = this._damageBounds.left;
y = this._damageBounds.top;
w = this._damageBounds.right - x;
h = this._damageBounds.bottom - y;
let x = this._damageBounds.left;
let y = this._damageBounds.top;
let w = this._damageBounds.right - x;
let h = this._damageBounds.bottom - y;
vx = x - this._viewportLoc.x;
vy = y - this._viewportLoc.y;
let vx = x - this._viewportLoc.x;
let vy = y - this._viewportLoc.y;
if (vx < 0) {
w += vx;
@ -301,9 +301,8 @@ Display.prototype = {
this._damageBounds.left = this._damageBounds.top = 65535;
this._damageBounds.right = this._damageBounds.bottom = 0;
}
},
clear: function () {
clear() {
if (this._logo) {
this.resize(this._logo.width, this._logo.height);
this.imageRect(0, 0, this._logo.type, this._logo.data);
@ -312,21 +311,21 @@ Display.prototype = {
this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
}
this.flip();
},
}
pending: function() {
pending() {
return this._renderQ.length > 0;
},
}
flush: function() {
flush() {
if (this._renderQ.length === 0) {
this.onflush();
} else {
this._flushing = true;
}
},
}
fillRect: function (x, y, width, height, color, from_queue) {
fillRect(x, y, width, height, color, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'fill',
@ -341,9 +340,9 @@ Display.prototype = {
this._drawCtx.fillRect(x, y, width, height);
this._damage(x, y, width, height);
}
},
}
copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) {
copyImage(old_x, old_y, new_x, new_y, w, h, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
this._renderQ_push({
'type': 'copy',
@ -372,10 +371,10 @@ Display.prototype = {
new_x, new_y, w, h);
this._damage(new_x, new_y, w, h);
}
},
}
imageRect: function(x, y, mime, arr) {
var img = new Image();
imageRect(x, y, mime, arr) {
const img = new Image();
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
this._renderQ_push({
'type': 'img',
@ -383,10 +382,10 @@ Display.prototype = {
'x': x,
'y': y
});
},
}
// start updating a tile
startTile: function (x, y, width, height, color) {
startTile(x, y, width, height, color) {
this._tile_x = x;
this._tile_y = y;
if (width === 16 && height === 16) {
@ -395,53 +394,57 @@ Display.prototype = {
this._tile = this._drawCtx.createImageData(width, height);
}
var red = color[2];
var green = color[1];
var blue = color[0];
const red = color[2];
const green = color[1];
const blue = color[0];
var data = this._tile.data;
for (var i = 0; i < width * height * 4; i += 4) {
const data = this._tile.data;
for (let i = 0; i < width * height * 4; i += 4) {
data[i] = red;
data[i + 1] = green;
data[i + 2] = blue;
data[i + 3] = 255;
}
},
}
// update sub-rectangle of the current tile
subTile: function (x, y, w, h, color) {
var red = color[2];
var green = color[1];
var blue = color[0];
var xend = x + w;
var yend = y + h;
subTile(x, y, w, h, color) {
const red = color[2];
const green = color[1];
const blue = color[0];
const xend = x + w;
const yend = y + h;
var data = this._tile.data;
var width = this._tile.width;
for (var j = y; j < yend; j++) {
for (var i = x; i < xend; i++) {
var p = (i + (j * width)) * 4;
const data = this._tile.data;
const width = this._tile.width;
for (let j = y; j < yend; j++) {
for (let i = x; i < xend; i++) {
const p = (i + (j * width)) * 4;
data[p] = red;
data[p + 1] = green;
data[p + 2] = blue;
data[p + 3] = 255;
}
}
},
}
// draw the current tile to the screen
finishTile: function () {
finishTile() {
this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y);
this._damage(this._tile_x, this._tile_y,
this._tile.width, this._tile.height);
},
}
blitImage(x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length === 0 || from_queue) {
this._bgrxImageData(x, y, width, height, arr, offset);
return;
}
blitImage: function (x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much
var new_arr = new Uint8Array(width * height * 4);
const new_arr = new Uint8Array(width * height * 4);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({
'type': 'blit',
@ -451,17 +454,18 @@ Display.prototype = {
'width': width,
'height': height,
});
} else {
this._bgrxImageData(x, y, width, height, arr, offset);
}
},
blitRgbImage: function (x, y , width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
blitRgbImage(x, y , width, height, arr, offset, from_queue) {
if (this._renderQ.length === 0 || from_queue) {
this._rgbImageData(x, y, width, height, arr, offset);
return;
}
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much
var new_arr = new Uint8Array(width * height * 3);
const new_arr = new Uint8Array(width * height * 3);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({
'type': 'blitRgb',
@ -471,17 +475,19 @@ Display.prototype = {
'width': width,
'height': height,
});
} else {
this._rgbImageData(x, y, width, height, arr, offset);
}
},
blitRgbxImage: function (x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length !== 0 && !from_queue) {
blitRgbxImage(x, y, width, height, arr, offset, from_queue) {
if (this._renderQ.length === 0 || from_queue) {
this._rgbxImageData(x, y, width, height, arr, offset);
return;
}
// NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much
var new_arr = new Uint8Array(width * height * 4);
const new_arr = new Uint8Array(width * height * 4);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({
'type': 'blitRgbx',
@ -491,75 +497,69 @@ Display.prototype = {
'width': width,
'height': height,
});
} else {
this._rgbxImageData(x, y, width, height, arr, offset);
}
},
drawImage: function (img, x, y) {
drawImage(img, x, y) {
this._drawCtx.drawImage(img, x, y);
this._damage(x, y, img.width, img.height);
},
changeCursor: function (pixels, mask, hotx, hoty, w, h) {
Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h);
},
defaultCursor: function () {
this._target.style.cursor = "default";
},
disableLocalCursor: function () {
this._target.style.cursor = "none";
},
autoscale: function (containerWidth, containerHeight) {
var vp = this._viewportLoc;
var targetAspectRatio = containerWidth / containerHeight;
var fbAspectRatio = vp.w / vp.h;
var scaleRatio;
if (fbAspectRatio >= targetAspectRatio) {
scaleRatio = containerWidth / vp.w;
} else {
scaleRatio = containerHeight / vp.h;
}
changeCursor(pixels, mask, hotx, hoty, w, h) {
Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h);
}
defaultCursor() {
this._target.style.cursor = "default";
}
disableLocalCursor() {
this._target.style.cursor = "none";
}
autoscale(containerWidth, containerHeight) {
const vp = this._viewportLoc;
const targetAspectRatio = containerWidth / containerHeight;
const fbAspectRatio = vp.w / vp.h;
const scaleRatio = (fbAspectRatio >= targetAspectRatio)
? containerWidth / vp.w
: containerHeight / vp.h;
this._rescale(scaleRatio);
},
}
// ===== PRIVATE METHODS =====
_rescale: function (factor) {
_rescale(factor) {
this._scale = factor;
var vp = this._viewportLoc;
const vp = this._viewportLoc;
// NB(directxman12): If you set the width directly, or set the
// style width to a number, the canvas is cleared.
// However, if you set the style width to a string
// ('NNNpx'), the canvas is scaled without clearing.
var width = Math.round(factor * vp.w) + 'px';
var height = Math.round(factor * vp.h) + 'px';
const width = Math.round(factor * vp.w) + 'px';
const height = Math.round(factor * vp.h) + 'px';
if ((this._target.style.width !== width) ||
(this._target.style.height !== height)) {
this._target.style.width = width;
this._target.style.height = height;
}
},
}
_setFillColor: function (color) {
var newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
_setFillColor(color) {
const newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
if (newStyle !== this._prevDrawStyle) {
this._drawCtx.fillStyle = newStyle;
this._prevDrawStyle = newStyle;
}
},
}
_rgbImageData: function (x, y, width, height, arr, offset) {
var img = this._drawCtx.createImageData(width, height);
var data = img.data;
for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
_rgbImageData(x, y, width, height, arr, offset) {
const img = this._drawCtx.createImageData(width, height);
const data = img.data;
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
data[i] = arr[j];
data[i + 1] = arr[j + 1];
data[i + 2] = arr[j + 2];
@ -567,12 +567,12 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
},
}
_bgrxImageData: function (x, y, width, height, arr, offset) {
var img = this._drawCtx.createImageData(width, height);
var data = img.data;
for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
_bgrxImageData(x, y, width, height, arr, offset) {
const img = this._drawCtx.createImageData(width, height);
const data = img.data;
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
data[i] = arr[j + 2];
data[i + 1] = arr[j + 1];
data[i + 2] = arr[j];
@ -580,11 +580,11 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
},
}
_rgbxImageData: function (x, y, width, height, arr, offset) {
_rgbxImageData(x, y, width, height, arr) {
// NB(directxman12): arr must be an Type Array view
var img;
let img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
} else {
@ -593,28 +593,28 @@ Display.prototype = {
}
this._drawCtx.putImageData(img, x, y);
this._damage(x, y, img.width, img.height);
},
}
_renderQ_push: function (action) {
_renderQ_push(action) {
this._renderQ.push(action);
if (this._renderQ.length === 1) {
// If this can be rendered immediately it will be, otherwise
// the scanner will wait for the relevant event
this._scan_renderQ();
}
},
}
_resume_renderQ: function() {
_resume_renderQ() {
// "this" is the object that is ready, not the
// display object
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
this._noVNC_display._scan_renderQ();
},
}
_scan_renderQ: function () {
var ready = true;
_scan_renderQ() {
let ready = true;
while (ready && this._renderQ.length > 0) {
var a = this._renderQ[0];
const a = this._renderQ[0];
switch (a.type) {
case 'flip':
this.flip(true);
@ -656,22 +656,21 @@ Display.prototype = {
this._flushing = false;
this.onflush();
}
},
};
}
}
// Class Methods
Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
Display.changeCursor = (target, pixels, mask, hotx, hoty, w, h) => {
if ((w === 0) || (h === 0)) {
target.style.cursor = 'none';
return;
}
var cur = []
var y, x;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
var idx = y * Math.ceil(w / 8) + Math.floor(x / 8);
var alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
const cur = [];
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
let idx = y * Math.ceil(w / 8) + Math.floor(x / 8);
const alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
idx = ((w * y) + x) * 4;
cur.push(pixels[idx + 2]); // red
cur.push(pixels[idx + 1]); // green
@ -680,13 +679,13 @@ Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
}
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = w;
canvas.height = h;
var img;
let img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
img = new ImageData(new Uint8ClampedArray(cur), w, h);
} else {
@ -696,6 +695,6 @@ Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
ctx.clearRect(0, 0, w, h);
ctx.putImageData(img, 0, 0);
var url = canvas.toDataURL();
const url = canvas.toDataURL();
target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
};

View File

@ -6,7 +6,7 @@
* See README.md for usage and integration instructions.
*/
export var encodings = {
export let encodings = {
encodingRaw: 0,
encodingCopyRect: 1,
encodingRRE: 2,

View File

@ -1,8 +1,17 @@
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
Inflate.prototype = {
inflate: function (data, flush, expected) {
export default class Inflate {
constructor() {
this.strm = new ZStream();
this.chunkSize = 1024 * 10 * 10;
this.strm.output = new Uint8Array(this.chunkSize);
this.windowBits = 5;
inflateInit(this.strm, this.windowBits);
}
inflate(data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
@ -21,18 +30,9 @@ Inflate.prototype = {
inflate(this.strm, flush);
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
},
}
reset: function () {
reset() {
inflateReset(this.strm);
}
};
export default function Inflate() {
this.strm = new ZStream();
this.chunkSize = 1024 * 10 * 10;
this.strm.output = new Uint8Array(this.chunkSize);
this.windowBits = 5;
inflateInit(this.strm, this.windowBits);
};
}

View File

@ -13,7 +13,7 @@ import KeyTable from "./keysym.js";
* See https://www.w3.org/TR/uievents-key/ for possible values.
*/
var DOMKeyTable = {};
const DOMKeyTable = {};
function addStandard(key, standard)
{

View File

@ -5,19 +5,18 @@
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/
/*jslint browser: true, white: false */
/*global window, Util */
import * as Log from '../util/logging.js';
import { stopEvent } from '../util/events.js';
import * as KeyboardUtil from "./util.js";
import KeyTable from "./keysym.js";
import * as browserUtils from "../util/browsers.js";
//
// Keyboard event handler
//
export default function Keyboard(target) {
export default class Keyboard {
constructor(target) {
this._target = target || null;
this._keyDownList = {}; // List of depressed keys
@ -31,35 +30,15 @@ export default function Keyboard(target) {
'keypress': this._handleKeyPress.bind(this),
'blur': this._allKeysUp.bind(this)
};
};
function isMac() {
return navigator && !!(/mac/i).exec(navigator.platform);
}
function isWindows() {
return navigator && !!(/win/i).exec(navigator.platform);
}
function isIOS() {
return navigator &&
(!!(/ipad/i).exec(navigator.platform) ||
!!(/iphone/i).exec(navigator.platform) ||
!!(/ipod/i).exec(navigator.platform));
}
function isIE() {
return navigator && !!(/trident/i).exec(navigator.userAgent);
}
function isEdge() {
return navigator && !!(/edge/i).exec(navigator.userAgent);
}
Keyboard.prototype = {
// ===== EVENT HANDLERS =====
onkeyevent: function () {}, // Handler for key press/release
onkeyevent() {} // Handler for key press/release
// ===== PRIVATE METHODS =====
_sendKeyEvent: function (keysym, code, down) {
_sendKeyEvent(keysym, code, down) {
Log.Debug("onkeyevent " + (down ? "down" : "up") +
", keysym: " + keysym, ", code: " + code);
@ -67,8 +46,8 @@ Keyboard.prototype = {
// AltGraph, which tends to confuse the hell out of
// remote systems. Fake a release of these keys until
// there is a way to detect AltGraph properly.
var fakeAltGraph = false;
if (down && isWindows()) {
let fakeAltGraph = false;
if (down && browserUtils.isWindows()) {
if ((code !== 'ControlLeft') &&
(code !== 'AltRight') &&
('ControlLeft' in this._keyDownList) &&
@ -89,10 +68,10 @@ Keyboard.prototype = {
this.onkeyevent(this._keyDownList['AltRight'],
'AltRight', true);
}
},
}
_getKeyCode: function (e) {
var code = KeyboardUtil.getKeycode(e);
_getKeyCode(e) {
const code = KeyboardUtil.getKeycode(e);
if (code !== 'Unidentified') {
return code;
}
@ -115,26 +94,26 @@ Keyboard.prototype = {
return e.keyIdentifier;
}
var codepoint = parseInt(e.keyIdentifier.substr(2), 16);
var char = String.fromCharCode(codepoint);
const codepoint = parseInt(e.keyIdentifier.substr(2), 16);
// Some implementations fail to uppercase the symbols
char = char.toUpperCase();
const char = String.fromCharCode(codepoint).toUpperCase();
return 'Platform' + char.charCodeAt();
}
return 'Unidentified';
},
}
_handleKeyDown: function (e) {
var code = this._getKeyCode(e);
var keysym = KeyboardUtil.getKeysym(e);
_handleKeyDown(e) {
let code = this._getKeyCode(e);
let keysym = KeyboardUtil.getKeysym(e);
// We cannot handle keys we cannot track, but we also need
// to deal with virtual keyboards which omit key info
// (iOS omits tracking info on keyup events, which forces us to
// special treat that platform here)
if ((code === 'Unidentified') || isIOS()) {
if ((code === 'Unidentified') || browserUtils.isIOS()) {
if (keysym) {
// If it's a virtual keyboard then it should be
// sufficient to just send press and release right
@ -151,7 +130,7 @@ Keyboard.prototype = {
// keys around a bit to make things more sane for the remote
// server. This method is used by RealVNC and TigerVNC (and
// possibly others).
if (isMac()) {
if (browserUtils.isMac()) {
switch (keysym) {
case KeyTable.XK_Super_L:
keysym = KeyTable.XK_Alt_L;
@ -178,7 +157,7 @@ Keyboard.prototype = {
// state change events. That gets extra confusing for CapsLock
// which toggles on each press, but not on release. So pretend
// it was a quick press and release of the button.
if (isMac() && (code === 'CapsLock')) {
if (browserUtils.isMac() && (code === 'CapsLock')) {
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
stopEvent(e);
@ -189,7 +168,8 @@ Keyboard.prototype = {
// a keypress event as well
// (IE and Edge has a broken KeyboardEvent.key, so we can't
// just check for the presence of that field)
if (!keysym && (!e.key || isIE() || isEdge())) {
if (!keysym
&& (!e.key || browserUtils.isIE() || browserUtils.isEdge())) {
this._pendingKey = code;
// However we might not get a keypress event if the key
// is non-printable, which needs some special fallback
@ -204,10 +184,10 @@ Keyboard.prototype = {
this._keyDownList[code] = keysym;
this._sendKeyEvent(keysym, code, true);
},
}
// Legacy event for browsers without code/key
_handleKeyPress: function (e) {
_handleKeyPress(e) {
stopEvent(e);
// Are we expecting a keypress?
@ -215,8 +195,8 @@ Keyboard.prototype = {
return;
}
var code = this._getKeyCode(e);
var keysym = KeyboardUtil.getKeysym(e);
let code = this._getKeyCode(e);
const keysym = KeyboardUtil.getKeysym(e);
// The key we were waiting for?
if ((code !== 'Unidentified') && (code != this._pendingKey)) {
@ -227,23 +207,24 @@ Keyboard.prototype = {
this._pendingKey = null;
if (!keysym) {
console.log('keypress with no keysym:', e);
Log.Debug('keypress with no keysym:', e);
return;
}
this._keyDownList[code] = keysym;
this._sendKeyEvent(keysym, code, true);
},
_handleKeyPressTimeout: function (e) {
}
_handleKeyPressTimeout(e) {
// Did someone manage to sort out the key already?
if (this._pendingKey === null) {
return;
}
var code, keysym;
let keysym;
code = this._pendingKey;
const code = this._pendingKey;
this._pendingKey = null;
// We have no way of knowing the proper keysym with the
@ -254,12 +235,11 @@ Keyboard.prototype = {
keysym = e.keyCode;
} else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) {
// Character (A-Z)
var char = String.fromCharCode(e.keyCode);
let char = String.fromCharCode(e.keyCode);
// A feeble attempt at the correct case
if (e.shiftKey)
char = char.toUpperCase();
else
char = char.toLowerCase();
char = e.shiftKey
? char.toUpperCase()
: char.toLowerCase();
keysym = char.charCodeAt();
} else {
// Unknown, give up
@ -269,15 +249,15 @@ Keyboard.prototype = {
this._keyDownList[code] = keysym;
this._sendKeyEvent(keysym, code, true);
},
}
_handleKeyUp: function (e) {
_handleKeyUp(e) {
stopEvent(e);
var code = this._getKeyCode(e);
const code = this._getKeyCode(e);
// See comment in _handleKeyDown()
if (isMac() && (code === 'CapsLock')) {
if (browserUtils.isMac() && (code === 'CapsLock')) {
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
return;
@ -291,22 +271,22 @@ Keyboard.prototype = {
this._sendKeyEvent(this._keyDownList[code], code, false);
delete this._keyDownList[code];
},
}
_allKeysUp: function () {
_allKeysUp() {
Log.Debug(">> Keyboard.allKeysUp");
for (var code in this._keyDownList) {
for (let code in this._keyDownList) {
this._sendKeyEvent(this._keyDownList[code], code, false);
};
}
this._keyDownList = {};
Log.Debug("<< Keyboard.allKeysUp");
},
}
// ===== PUBLIC METHODS =====
grab: function () {
grab() {
//Log.Debug(">> Keyboard.grab");
var c = this._target;
const c = this._target;
c.addEventListener('keydown', this._eventHandlers.keydown);
c.addEventListener('keyup', this._eventHandlers.keyup);
@ -316,11 +296,11 @@ Keyboard.prototype = {
window.addEventListener('blur', this._eventHandlers.blur);
//Log.Debug("<< Keyboard.grab");
},
}
ungrab: function () {
ungrab () {
//Log.Debug(">> Keyboard.ungrab");
var c = this._target;
const c = this._target;
c.removeEventListener('keydown', this._eventHandlers.keydown);
c.removeEventListener('keyup', this._eventHandlers.keyup);
@ -331,5 +311,5 @@ Keyboard.prototype = {
this._allKeysUp();
//Log.Debug(">> Keyboard.ungrab");
},
};
}
}

View File

@ -7,7 +7,7 @@
/* Functions at the bottom */
var codepoints = {
const codepoints = {
0x0100: 0x03c0, // XK_Amacron
0x0101: 0x03e0, // XK_amacron
0x0102: 0x01c3, // XK_Abreve
@ -670,14 +670,14 @@ var codepoints = {
};
export default {
lookup : function(u) {
lookup(u) {
// Latin-1 is one-to-one mapping
if ((u >= 0x20) && (u <= 0xff)) {
return u;
}
// Lookup table (fairly random)
var keysym = codepoints[u];
const keysym = codepoints[u];
if (keysym !== undefined) {
return keysym;
}

View File

@ -5,18 +5,16 @@
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/
/*jslint browser: true, white: false */
/*global window, Util */
import * as Log from '../util/logging.js';
import { isTouchDevice } from '../util/browsers.js';
import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
var WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
var WHEEL_STEP_TIMEOUT = 50; // ms
var WHEEL_LINE_HEIGHT = 19;
const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
const WHEEL_STEP_TIMEOUT = 50; // ms
const WHEEL_LINE_HEIGHT = 19;
export default function Mouse(target) {
export default class Mouse {
constructor(target) {
this._target = target || document;
this._doubleClickTimer = null;
@ -35,29 +33,29 @@ export default function Mouse(target) {
'mousewheel': this._handleMouseWheel.bind(this),
'mousedisable': this._handleMouseDisable.bind(this)
};
};
Mouse.prototype = {
// ===== PROPERTIES =====
touchButton: 1, // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
this.touchButton = 1; // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
}
// ===== EVENT HANDLERS =====
onmousebutton: function () {}, // Handler for mouse button click/release
onmousemove: function () {}, // Handler for mouse movement
onmousebutton() {} // Handler for mouse button click/release
onmousemove() {} // Handler for mouse movement
// ===== PRIVATE METHODS =====
_resetDoubleClickTimer: function () {
_resetDoubleClickTimer() {
this._doubleClickTimer = null;
},
}
_handleMouseButton: function (e, down) {
_handleMouseButton(e, down) {
this._updateMousePosition(e);
var pos = this._pos;
let pos = this._pos;
var bmask;
let bmask;
if (e.touches || e.changedTouches) {
// Touch device
@ -73,13 +71,13 @@ Mouse.prototype = {
// force the position of the latter touch to the position of
// the first.
var xs = this._lastTouchPos.x - pos.x;
var ys = this._lastTouchPos.y - pos.y;
var d = Math.sqrt((xs * xs) + (ys * ys));
const xs = this._lastTouchPos.x - pos.x;
const ys = this._lastTouchPos.y - pos.y;
const d = Math.sqrt((xs * xs) + (ys * ys));
// The goal is to trigger on a certain physical width, the
// devicePixelRatio brings us a bit closer but is not optimal.
var threshold = 20 * (window.devicePixelRatio || 1);
const threshold = 20 * (window.devicePixelRatio || 1);
if (d < threshold) {
pos = this._lastTouchPos;
}
@ -103,25 +101,25 @@ Mouse.prototype = {
this.onmousebutton(pos.x, pos.y, down, bmask);
stopEvent(e);
},
}
_handleMouseDown: function (e) {
_handleMouseDown(e) {
// Touch events have implicit capture
if (e.type === "mousedown") {
setCapture(this._target);
}
this._handleMouseButton(e, 1);
},
}
_handleMouseUp: function (e) {
_handleMouseUp(e) {
this._handleMouseButton(e, 0);
},
}
// Mouse wheel events are sent in steps over VNC. This means that the VNC
// protocol can't handle a wheel event with specific distance or speed.
// Therefor, if we get a lot of small mouse wheel events we combine them.
_generateWheelStepX: function () {
_generateWheelStepX() {
if (this._accumulatedWheelDeltaX < 0) {
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
@ -132,9 +130,9 @@ Mouse.prototype = {
}
this._accumulatedWheelDeltaX = 0;
},
}
_generateWheelStepY: function () {
_generateWheelStepY() {
if (this._accumulatedWheelDeltaY < 0) {
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
@ -145,22 +143,22 @@ Mouse.prototype = {
}
this._accumulatedWheelDeltaY = 0;
},
}
_resetWheelStepTimers: function () {
_resetWheelStepTimers() {
window.clearTimeout(this._wheelStepXTimer);
window.clearTimeout(this._wheelStepYTimer);
this._wheelStepXTimer = null;
this._wheelStepYTimer = null;
},
}
_handleMouseWheel: function (e) {
_handleMouseWheel(e) {
this._resetWheelStepTimers();
this._updateMousePosition(e);
var dX = e.deltaX;
var dY = e.deltaY;
let dX = e.deltaX;
let dY = e.deltaY;
// Pixel units unless it's non-zero.
// Note that if deltamode is line or page won't matter since we aren't
@ -186,6 +184,7 @@ Mouse.prototype = {
window.setTimeout(this._generateWheelStepX.bind(this),
WHEEL_STEP_TIMEOUT);
}
if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
this._generateWheelStepY();
} else {
@ -195,15 +194,15 @@ Mouse.prototype = {
}
stopEvent(e);
},
}
_handleMouseMove: function (e) {
_handleMouseMove(e) {
this._updateMousePosition(e);
this.onmousemove(this._pos.x, this._pos.y);
stopEvent(e);
},
}
_handleMouseDisable: function (e) {
_handleMouseDisable(e) {
/*
* Stop propagation if inside canvas area
* Note: This is only needed for the 'click' event as it fails
@ -213,13 +212,13 @@ Mouse.prototype = {
if (e.target == this._target) {
stopEvent(e);
}
},
}
// Update coordinates relative to target
_updateMousePosition: function(e) {
_updateMousePosition(e) {
e = getPointerEvent(e);
var bounds = this._target.getBoundingClientRect();
var x, y;
const bounds = this._target.getBoundingClientRect();
let x, y;
// Clip to target bounds
if (e.clientX < bounds.left) {
x = 0;
@ -235,19 +234,20 @@ Mouse.prototype = {
} else {
y = e.clientY - bounds.top;
}
this._pos = {x:x, y:y};
},
this._pos = { x, y };
}
// ===== PUBLIC METHODS =====
grab: function () {
var c = this._target;
grab() {
const c = this._target;
if (isTouchDevice) {
c.addEventListener('touchstart', this._eventHandlers.mousedown);
c.addEventListener('touchend', this._eventHandlers.mouseup);
c.addEventListener('touchmove', this._eventHandlers.mousemove);
}
c.addEventListener('mousedown', this._eventHandlers.mousedown);
c.addEventListener('mouseup', this._eventHandlers.mouseup);
c.addEventListener('mousemove', this._eventHandlers.mousemove);
@ -259,10 +259,10 @@ Mouse.prototype = {
/* preventDefault() on mousedown doesn't stop this event for some
reason so we have to explicitly block it */
c.addEventListener('contextmenu', this._eventHandlers.mousedisable);
},
}
ungrab: function () {
var c = this._target;
ungrab() {
const c = this._target;
this._resetWheelStepTimers();
@ -271,6 +271,7 @@ Mouse.prototype = {
c.removeEventListener('touchend', this._eventHandlers.mouseup);
c.removeEventListener('touchmove', this._eventHandlers.mousemove);
}
c.removeEventListener('mousedown', this._eventHandlers.mousedown);
c.removeEventListener('mouseup', this._eventHandlers.mouseup);
c.removeEventListener('mousemove', this._eventHandlers.mousemove);
@ -280,4 +281,4 @@ Mouse.prototype = {
c.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
}
};
}

View File

@ -1,18 +1,8 @@
import KeyTable from "./keysym.js";
import keysyms from "./keysymdef.js";
import vkeys from "./vkeys.js";
import fixedkeys from "./fixedkeys.js";
import DOMKeyTable from "./domkeytable.js";
function isMac() {
return navigator && !!(/mac/i).exec(navigator.platform);
}
function isIE() {
return navigator && !!(/trident/i).exec(navigator.userAgent);
}
function isEdge() {
return navigator && !!(/edge/i).exec(navigator.userAgent);
}
import * as browserUtils from "../util/browsers.js";
// Get 'KeyboardEvent.code', handling legacy browsers
export function getKeycode(evt){
@ -34,10 +24,10 @@ export function getKeycode(evt){
// in the 'keyCode' field for non-printable characters. However
// Webkit sets it to the same as charCode in 'keypress' events.
if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) {
var code = vkeys[evt.keyCode];
let code = vkeys[evt.keyCode];
// macOS has messed up this code for some reason
if (isMac() && (code === 'ContextMenu')) {
if (browserUtils.isMac() && (code === 'ContextMenu')) {
code = 'MetaRight';
}
@ -114,13 +104,14 @@ export function getKey(evt) {
// IE and Edge have broken handling of AltGraph so we cannot
// trust them for printable characters
if ((evt.key.length !== 1) || (!isIE() && !isEdge())) {
if ((evt.key.length !== 1)
|| (!browserUtils.isIE() && !browserUtils.isEdge())) {
return evt.key;
}
}
// Try to deduce it based on the physical key
var code = getKeycode(evt);
let code = getKeycode(evt);
if (code in fixedkeys) {
return fixedkeys[code];
}
@ -136,7 +127,7 @@ export function getKey(evt) {
// Get the most reliable keysym value we can get from a key event
export function getKeysym(evt){
var key = getKey(evt);
const key = getKey(evt);
if (key === 'Unidentified') {
return null;
@ -144,7 +135,7 @@ export function getKeysym(evt){
// First look up special keys
if (key in DOMKeyTable) {
var location = evt.location;
let location = evt.location;
// Safari screws up location for the right cmd key
if ((key === 'Meta') && (location === 0)) {
@ -159,15 +150,12 @@ export function getKeysym(evt){
}
// Now we need to look at the Unicode symbol instead
var codepoint;
// Special key? (FIXME: Should have been caught earlier)
if (key.length !== 1) {
return null;
}
codepoint = key.charCodeAt();
const codepoint = key.charCodeAt();
if (codepoint) {
return keysyms.lookup(codepoint);
}

File diff suppressed because it is too large Load Diff

View File

@ -8,24 +8,48 @@
import * as Log from './logging.js';
export function isMac() {
return navigator && !!(/mac/i).exec(navigator.platform);
}
export function isIE() {
return navigator && !!(/trident/i).exec(navigator.userAgent);
}
export function isEdge() {
return navigator && !!(/edge/i).exec(navigator.userAgent);
}
export function isWindows() {
return navigator && !!(/win/i).exec(navigator.platform);
}
export function isIOS() {
return navigator &&
(!!(/ipad/i).exec(navigator.platform) ||
!!(/iphone/i).exec(navigator.platform) ||
!!(/ipod/i).exec(navigator.platform));
}
// Touch detection
export var isTouchDevice = ('ontouchstart' in document.documentElement) ||
export let isTouchDevice = ('ontouchstart' in document.documentElement) ||
// requried for Chrome debugger
(document.ontouchstart !== undefined) ||
// required for MS Surface
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0);
window.addEventListener('touchstart', function onFirstTouch() {
isTouchDevice = true;
window.removeEventListener('touchstart', onFirstTouch, false);
}, false);
var _cursor_uris_supported = null;
let _cursor_uris_supported = null;
export function browserSupportsCursorURIs () {
if (_cursor_uris_supported === null) {
if (_cursor_uris_supported !== null) {
try {
var target = document.createElement('canvas');
const target = document.createElement('canvas');
target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
if (target.style.cursor) {
@ -42,4 +66,4 @@ export function browserSupportsCursorURIs () {
}
return _cursor_uris_supported;
};
}

View File

@ -10,26 +10,24 @@
* Cross-browser event and position routines
*/
import * as Log from './logging.js';
export function getPointerEvent (e) {
return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
};
}
export function stopEvent (e) {
e.stopPropagation();
e.preventDefault();
};
}
// Emulate Element.setCapture() when not supported
var _captureRecursion = false;
var _captureElem = null;
let _captureRecursion = false;
let _captureElem = null;
function _captureProxy(e) {
// Recursion protection as we'll see our own event
if (_captureRecursion) return;
// Clone the event as we cannot dispatch an already dispatched event
var newEv = new e.constructor(e.type, e);
const newEv = new e.constructor(e.type, e);
_captureRecursion = true;
_captureElem.dispatchEvent(newEv);
@ -47,16 +45,17 @@ function _captureProxy(e) {
if (e.type === "mouseup") {
releaseCapture();
}
};
}
// Follow cursor style of target element
function _captureElemChanged() {
var captureElem = document.getElementById("noVNC_mouse_capture_elem");
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
captureElem.style.cursor = window.getComputedStyle(_captureElem).cursor;
};
var _captureObserver = new MutationObserver(_captureElemChanged);
}
var _captureIndex = 0;
let _captureObserver = new MutationObserver(_captureElemChanged);
let _captureIndex = 0;
export function setCapture (elem) {
if (elem.setCapture) {
@ -71,7 +70,7 @@ export function setCapture (elem) {
// called multiple times without coordination
releaseCapture();
var captureElem = document.getElementById("noVNC_mouse_capture_elem");
let captureElem = document.getElementById("noVNC_mouse_capture_elem");
if (captureElem === null) {
captureElem = document.createElement("div");
@ -107,13 +106,11 @@ export function setCapture (elem) {
window.addEventListener('mousemove', _captureProxy);
window.addEventListener('mouseup', _captureProxy);
}
};
}
export function releaseCapture () {
if (document.releaseCapture) {
document.releaseCapture();
} else {
if (!_captureElem) {
return;
@ -121,7 +118,7 @@ export function releaseCapture () {
// There might be events already queued, so we need to wait for
// them to flush. E.g. contextmenu in Microsoft Edge
window.setTimeout(function(expected) {
window.setTimeout((expected) => {
// Only clear it if it's the expected grab (i.e. no one
// else has initiated a new grab)
if (_captureIndex === expected) {
@ -131,10 +128,10 @@ export function releaseCapture () {
_captureObserver.disconnect();
var captureElem = document.getElementById("noVNC_mouse_capture_elem");
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
captureElem.style.display = "none";
window.removeEventListener('mousemove', _captureProxy);
window.removeEventListener('mouseup', _captureProxy);
}
};
}

View File

@ -6,10 +6,12 @@
* See README.md for usage and integration instructions.
*/
var EventTargetMixin = {
_listeners: null,
export default class EventTargetMixin {
constructor() {
this._listeners = null;
}
addEventListener: function(type, callback) {
addEventListener(type, callback) {
if (!this._listeners) {
this._listeners = new Map();
}
@ -17,24 +19,22 @@ var EventTargetMixin = {
this._listeners.set(type, new Set());
}
this._listeners.get(type).add(callback);
},
}
removeEventListener: function(type, callback) {
removeEventListener(type, callback) {
if (!this._listeners || !this._listeners.has(type)) {
return;
}
this._listeners.get(type).delete(callback);
},
}
dispatchEvent: function(event) {
dispatchEvent(event) {
if (!this._listeners || !this._listeners.has(event.type)) {
return true;
}
this._listeners.get(event.type).forEach(function (callback) {
this._listeners.get(event.type).forEach((callback) => {
callback.call(this, event);
}, this);
return !event.defaultPrevented;
},
};
export default EventTargetMixin;
}
}

View File

@ -10,12 +10,12 @@
* Logging/debug routines
*/
var _log_level = 'warn';
let _log_level = 'warn';
var Debug = function (msg) {};
var Info = function (msg) {};
var Warn = function (msg) {};
var Error = function (msg) {};
let Debug = () => {};
let Info = () => {};
let Warn = () => {};
let Error = () => {};
export function init_logging (level) {
if (typeof level === 'undefined') {
@ -24,9 +24,9 @@ export function init_logging (level) {
_log_level = level;
}
Debug = Info = Warn = Error = function (msg) {};
Debug = Info = Warn = Error = () => {};
if (typeof window.console !== "undefined") {
/* jshint -W086 */
/* eslint-disable no-fallthrough, no-console */
switch (level) {
case 'debug':
Debug = console.debug.bind(window.console);
@ -41,12 +41,14 @@ export function init_logging (level) {
default:
throw new Error("invalid logging type '" + level + "'");
}
/* jshint +W086 */
/* eslint-enable no-fallthrough, no-console */
}
};
}
export function get_logging () {
return _log_level;
};
}
export { Debug, Info, Warn, Error };
// Initialize logging level

View File

@ -10,19 +10,18 @@
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
value(target) { // .length of function is 2
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
const to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
for (let index = 1; index < arguments.length; index++) {
const nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
for (let nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
@ -38,17 +37,17 @@ if (typeof Object.assign != 'function') {
}
/* CustomEvent constructor (taken from MDN) */
(function () {
(() => {
function CustomEvent( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
const evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
if (typeof window.CustomEvent !== "function") {
if (typeof window.CustomEvent !== 'function') {
window.CustomEvent = CustomEvent;
}
})();

View File

@ -10,6 +10,5 @@
* Decode from UTF-8
*/
export function decodeUTF8 (utf8string) {
"use strict";
return decodeURIComponent(escape(utf8string));
};
}

View File

@ -14,12 +14,29 @@
import * as Log from './util/logging.js';
/*jslint browser: true, bitwise: true */
/*global Util*/
// this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future.
const ENABLE_COPYWITHIN = false;
export default function Websock() {
"use strict";
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
const typedArrayToString = (() => {
// This is only for PhantomJS, which doesn't like apply-ing
// with Typed Arrays
try {
const arr = new Uint8Array([1, 2, 3]);
String.fromCharCode.apply(null, arr);
return (a) => String.fromCharCode.apply(null, a);
} catch (ex) {
return (a) =>
String.fromCharCode.apply(
null, Array.prototype.slice.call(a));
}
})();
export default class Websock {
constructor() {
this._websocket = null; // WebSocket object
this._rQi = 0; // Receive queue index
@ -35,125 +52,105 @@ export default function Websock() {
this._sQ = null; // Send queue
this._eventHandlers = {
'message': function () {},
'open': function () {},
'close': function () {},
'error': function () {}
};
};
// this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future.
var ENABLE_COPYWITHIN = false;
var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
var typedArrayToString = (function () {
// This is only for PhantomJS, which doesn't like apply-ing
// with Typed Arrays
try {
var arr = new Uint8Array([1, 2, 3]);
String.fromCharCode.apply(null, arr);
return function (a) { return String.fromCharCode.apply(null, a); };
} catch (ex) {
return function (a) {
return String.fromCharCode.apply(
null, Array.prototype.slice.call(a));
'message'() {},
'open'() {},
'close'() {},
'error'() {}
};
}
})();
Websock.prototype = {
// Getters and Setters
get_sQ: function () {
get_sQ() {
return this._sQ;
},
}
get_rQ: function () {
get_rQ() {
return this._rQ;
},
}
get_rQi: function () {
get_rQi() {
return this._rQi;
},
}
set_rQi: function (val) {
set_rQi(val) {
this._rQi = val;
},
}
// Receive Queue
rQlen: function () {
rQlen() {
return this._rQlen - this._rQi;
},
}
rQpeek8: function () {
rQpeek8() {
return this._rQ[this._rQi];
},
}
rQshift8: function () {
rQshift8() {
return this._rQ[this._rQi++];
},
}
rQskip8: function () {
rQskip8() {
this._rQi++;
},
}
rQskipBytes: function (num) {
rQskipBytes(num) {
this._rQi += num;
},
}
// TODO(directxman12): test performance with these vs a DataView
rQshift16: function () {
rQshift16() {
return (this._rQ[this._rQi++] << 8) +
this._rQ[this._rQi++];
},
}
rQshift32: function () {
rQshift32() {
return (this._rQ[this._rQi++] << 24) +
(this._rQ[this._rQi++] << 16) +
(this._rQ[this._rQi++] << 8) +
this._rQ[this._rQi++];
},
}
rQshiftStr: function (len) {
rQshiftStr(len) {
if (typeof(len) === 'undefined') { len = this.rQlen(); }
var arr = new Uint8Array(this._rQ.buffer, this._rQi, len);
const arr = new Uint8Array(this._rQ.buffer, this._rQi, len);
this._rQi += len;
return typedArrayToString(arr);
},
}
rQshiftBytes: function (len) {
rQshiftBytes(len) {
if (typeof(len) === 'undefined') { len = this.rQlen(); }
this._rQi += len;
return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
},
}
rQshiftTo: function (target, len) {
rQshiftTo(target, len) {
if (len === undefined) { len = this.rQlen(); }
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ
target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
this._rQi += len;
},
}
rQwhole: function () {
rQwhole() {
return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
},
}
rQslice: function (start, end) {
rQslice(start, end) {
if (end) {
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
} else {
return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
}
},
}
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
// to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false.
rQwait: function (msg, num, goback) {
var rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
if (rQlen < num) {
rQwait(msg, num, goback) {
const rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
if (rQlen >= num) {
return false;
}
if (goback) {
if (this._rQi < goback) {
throw new Error("rQwait cannot backup " + goback + " bytes");
@ -162,59 +159,54 @@ Websock.prototype = {
}
return true; // true means need more data
}
return false;
},
// Send Queue
flush: function () {
flush() {
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
this._websocket.send(this._encode_message());
this._sQlen = 0;
}
},
}
send: function (arr) {
send(arr) {
this._sQ.set(arr, this._sQlen);
this._sQlen += arr.length;
this.flush();
},
}
send_string: function (str) {
this.send(str.split('').map(function (chr) {
return chr.charCodeAt(0);
}));
},
send_string(str) {
this.send(str.split('').map(chr => chr.charCodeAt(0)));
}
// Event Handlers
off: function (evt) {
this._eventHandlers[evt] = function () {};
},
off(evt) {
this._eventHandlers[evt] = () => {};
}
on: function (evt, handler) {
on(evt, handler) {
this._eventHandlers[evt] = handler;
},
}
_allocate_buffers: function () {
_allocate_buffers() {
this._rQ = new Uint8Array(this._rQbufferSize);
this._sQ = new Uint8Array(this._sQbufferSize);
},
}
init: function () {
init() {
this._allocate_buffers();
this._rQi = 0;
this._websocket = null;
},
}
open: function (uri, protocols) {
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
open(uri, protocols) {
this.init();
this._websocket = new WebSocket(uri, protocols);
this._websocket.binaryType = 'arraybuffer';
this._websocket.onmessage = this._recv_message.bind(this);
this._websocket.onopen = (function () {
this._websocket.onopen = () => {
Log.Debug('>> WebSock.onopen');
if (this._websocket.protocol) {
Log.Info("Server choose sub-protocol: " + this._websocket.protocol);
@ -222,20 +214,20 @@ Websock.prototype = {
this._eventHandlers.open();
Log.Debug("<< WebSock.onopen");
}).bind(this);
this._websocket.onclose = (function (e) {
};
this._websocket.onclose = (e) => {
Log.Debug(">> WebSock.onclose");
this._eventHandlers.close(e);
Log.Debug("<< WebSock.onclose");
}).bind(this);
this._websocket.onerror = (function (e) {
};
this._websocket.onerror = (e) => {
Log.Debug(">> WebSock.onerror: " + e);
this._eventHandlers.error(e);
Log.Debug("<< WebSock.onerror: " + e);
}).bind(this);
},
};
}
close: function () {
close() {
if (this._websocket) {
if ((this._websocket.readyState === WebSocket.OPEN) ||
(this._websocket.readyState === WebSocket.CONNECTING)) {
@ -243,19 +235,19 @@ Websock.prototype = {
this._websocket.close();
}
this._websocket.onmessage = function (e) { return; };
this._websocket.onmessage = () => {};
}
}
},
// private methods
_encode_message: function () {
_encode_message() {
// Put in a binary arraybuffer
// according to the spec, you can send ArrayBufferViews with the send method
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
},
}
_expand_compact_rQ: function (min_fit) {
var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
_expand_compact_rQ(min_fit) {
const resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
if (resizeNeeded) {
if (!min_fit) {
// just double the size if we need to do compaction
@ -270,12 +262,12 @@ Websock.prototype = {
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
this._rQbufferSize = MAX_RQ_GROW_SIZE;
if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) {
throw new Exception("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
}
}
if (resizeNeeded) {
var old_rQbuffer = this._rQ.buffer;
const old_rQbuffer = this._rQ.buffer;
this._rQmax = this._rQbufferSize / 8;
this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
@ -289,21 +281,25 @@ Websock.prototype = {
this._rQlen = this._rQlen - this._rQi;
this._rQi = 0;
},
}
_decode_message: function (data) {
_decode_message(data) {
// push arraybuffer values onto the end
var u8 = new Uint8Array(data);
const u8 = new Uint8Array(data);
if (u8.length > this._rQbufferSize - this._rQlen) {
this._expand_compact_rQ(u8.length);
}
this._rQ.set(u8, this._rQlen);
this._rQlen += u8.length;
},
}
_recv_message: function (e) {
_recv_message(e) {
this._decode_message(e.data);
if (this.rQlen() > 0) {
if (this.rQlen() <= 0) {
Log.Debug("Ignoring empty message");
return;
}
this._eventHandlers.message();
// Compact the receive queue
if (this._rQlen == this._rQi) {
@ -312,8 +308,5 @@ Websock.prototype = {
} else if (this._rQlen > this._rQmax) {
this._expand_compact_rQ();
}
} else {
Log.Debug("Ignoring empty message");
}
}
};

View File

@ -137,7 +137,7 @@ connection to a specified VNC server.
##### Syntax
var rfb = new RFB( target, url [, options] );
const rfb = new RFB( target, url [, options] );
###### Parameters

View File

@ -1,9 +1,9 @@
// Karma configuration
module.exports = function(config) {
var customLaunchers = {};
var browsers = [];
var useSauce = false;
const customLaunchers = {};
let browsers = [];
let useSauce = false;
// use Sauce when running on Travis
if (process.env.TRAVIS_JOB_NUMBER) {
@ -11,22 +11,18 @@ module.exports = function(config) {
}
if (useSauce && process.env.TEST_BROWSER_NAME && process.env.TEST_BROWSER_NAME != 'PhantomJS') {
var names = process.env.TEST_BROWSER_NAME.split(',');
var platforms = process.env.TEST_BROWSER_OS.split(',');
var versions = [];
if (process.env.TEST_BROWSER_VERSION) {
versions = process.env.TEST_BROWSER_VERSION.split(',');
} else {
versions = [null];
}
const names = process.env.TEST_BROWSER_NAME.split(',');
const platforms = process.env.TEST_BROWSER_OS.split(',');
const versions = process.env.TEST_BROWSER_VERSION
? process.env.TEST_BROWSER_VERSION.split(',')
: [null];
for (var i = 0; i < names.length; i++) {
for (var j = 0; j < platforms.length; j++) {
for (var k = 0; k < versions.length; k++) {
var launcher_name = 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i];
if (versions[k]) {
launcher_name += '_' + versions[k];
}
for (let i = 0; i < names.length; i++) {
for (let j = 0; j < platforms.length; j++) {
for (let k = 0; k < versions.length; k++) {
const launcher_name = versions[k]
? '_' + versions[k]
: 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i];
customLaunchers[launcher_name] = {
base: 'SauceLabs',
@ -48,7 +44,7 @@ module.exports = function(config) {
browsers = [];
}
var my_conf = {
const my_conf = {
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',

6634
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,8 @@
"test": "tests"
},
"scripts": {
"test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js",
"lint": "eslint app core tests utils",
"test": "karma start karma.conf.js",
"prepare": "node ./utils/use_require.js --as commonjs --clean"
},
"repository": {
@ -40,6 +41,7 @@
"chai": "^3.5.0",
"commander": "^2.9.0",
"es-module-loader": "^2.1.0",
"eslint": "^4.16.0",
"fs-extra": "^1.0.0",
"jsdom": "*",
"karma": "^1.3.0",

9
tests/.eslintrc Normal file
View File

@ -0,0 +1,9 @@
{
"env": {
"node": true,
"mocha": true
},
"globals": {
"chai": true
}
}

View File

@ -5,23 +5,21 @@ chai.use(sinonChai);
// noVNC specific assertions
chai.use(function (_chai, utils) {
_chai.Assertion.addMethod('displayed', function (target_data) {
var obj = this._obj;
var ctx = obj._target.getContext('2d');
var data_cl = ctx.getImageData(0, 0, obj._target.width, obj._target.height).data;
const obj = this._obj;
const ctx = obj._target.getContext('2d');
const data_cl = ctx.getImageData(0, 0, obj._target.width, obj._target.height).data;
// NB(directxman12): PhantomJS 1.x doesn't implement Uint8ClampedArray, so work around that
var data = new Uint8Array(data_cl);
var len = data_cl.length;
const data = new Uint8Array(data_cl);
const len = data_cl.length;
new chai.Assertion(len).to.be.equal(target_data.length, "unexpected display size");
var same = true;
for (var i = 0; i < len; i++) {
let same = true;
for (let i = 0; i < len; i++) {
if (data[i] != target_data[i]) {
same = false;
break;
}
}
if (!same) {
console.log("expected data: %o, actual data: %o", target_data, data);
}
this.assert(same,
"expected #{this} to have displayed the image #{exp}, but instead it displayed #{act}",
"expected #{this} not to have displayed the image #{act}",
@ -30,28 +28,26 @@ chai.use(function (_chai, utils) {
});
_chai.Assertion.addMethod('sent', function (target_data) {
var obj = this._obj;
obj.inspect = function () {
var res = { _websocket: obj._websocket, rQi: obj._rQi, _rQ: new Uint8Array(obj._rQ.buffer, 0, obj._rQlen),
const obj = this._obj;
obj.inspect = () => {
const res = { _websocket: obj._websocket, rQi: obj._rQi, _rQ: new Uint8Array(obj._rQ.buffer, 0, obj._rQlen),
_sQ: new Uint8Array(obj._sQ.buffer, 0, obj._sQlen) };
res.prototype = obj;
return res;
};
var data = obj._websocket._get_sent_data();
var same = true;
const data = obj._websocket._get_sent_data();
let same = true;
if (data.length != target_data.length) {
same = false;
} else {
for (var i = 0; i < data.length; i++) {
for (let i = 0; i < data.length; i++) {
if (data[i] != target_data[i]) {
same = false;
break;
}
}
}
if (!same) {
console.log("expected data: %o, actual data: %o", target_data, data);
}
this.assert(same,
"expected #{this} to have sent the data #{exp}, but it actually sent #{act}",
"expected #{this} not to have sent the data #{act}",
@ -66,13 +62,11 @@ chai.use(function (_chai, utils) {
_chai.Assertion.overwriteMethod('equal', function (_super) {
return function assertArrayEqual(target) {
if (utils.flag(this, 'array')) {
var obj = this._obj;
var i;
var same = true;
const obj = this._obj;
let same = true;
if (utils.flag(this, 'deep')) {
for (i = 0; i < obj.length; i++) {
for (let i = 0; i < obj.length; i++) {
if (!utils.eql(obj[i], target[i])) {
same = false;
break;
@ -84,7 +78,7 @@ chai.use(function (_chai, utils) {
"expected #{this} not to have elements deeply equal to #{exp}",
Array.prototype.slice.call(target));
} else {
for (i = 0; i < obj.length; i++) {
for (let i = 0; i < obj.length; i++) {
if (obj[i] != target[i]) {
same = false;
break;

View File

@ -1,16 +1,19 @@
import Base64 from '../core/base64.js';
// PhantomJS can't create Event objects directly, so we need to use this
function make_event(name, props) {
var evt = document.createEvent('Event');
const evt = document.createEvent('Event');
evt.initEvent(name, true, true);
if (props) {
for (var prop in props) {
for (let prop in props) {
evt[prop] = props[prop];
}
}
return evt;
}
export default function FakeWebSocket (uri, protocols) {
export default class FakeWebSocket {
constructor(uri, protocols) {
this.url = uri;
this.binaryType = "arraybuffer";
this.extensions = "";
@ -27,17 +30,16 @@ export default function FakeWebSocket (uri, protocols) {
this.bufferedAmount = 0;
this.__is_fake = true;
};
}
FakeWebSocket.prototype = {
close: function (code, reason) {
close(code, reason) {
this.readyState = FakeWebSocket.CLOSED;
if (this.onclose) {
this.onclose(make_event("close", { 'code': code, 'reason': reason, 'wasClean': true }));
}
},
}
send: function (data) {
send(data) {
if (this.protocol == 'base64') {
data = Base64.decode(data);
} else {
@ -45,25 +47,25 @@ FakeWebSocket.prototype = {
}
this._send_queue.set(data, this.bufferedAmount);
this.bufferedAmount += data.length;
},
}
_get_sent_data: function () {
var res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount);
_get_sent_data() {
const res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount);
this.bufferedAmount = 0;
return res;
},
}
_open: function (data) {
_open() {
this.readyState = FakeWebSocket.OPEN;
if (this.onopen) {
this.onopen(make_event('open'));
}
},
}
_receive_data: function (data) {
_receive_data(data) {
this.onmessage(make_event("message", { 'data': data }));
}
};
}
FakeWebSocket.OPEN = WebSocket.OPEN;
FakeWebSocket.CONNECTING = WebSocket.CONNECTING;
@ -72,16 +74,18 @@ FakeWebSocket.CLOSED = WebSocket.CLOSED;
FakeWebSocket.__is_fake = true;
FakeWebSocket.replace = function () {
FakeWebSocket.replace = () => {
if (!WebSocket.__is_fake) {
var real_version = WebSocket;
const real_version = WebSocket;
// eslint-disable-next-line no-global-assign
WebSocket = FakeWebSocket;
FakeWebSocket.__real_version = real_version;
}
};
FakeWebSocket.restore = function () {
FakeWebSocket.restore = () => {
if (WebSocket.__is_fake) {
// eslint-disable-next-line no-global-assign
WebSocket = WebSocket.__real_version;
}
};

View File

@ -1,8 +1,8 @@
var TEST_REGEXP = /test\..*\.js/;
var allTestFiles = [];
var extraFiles = ['/base/tests/assertions.js'];
const TEST_REGEXP = /test\..*\.js/;
const allTestFiles = [];
const extraFiles = ['/base/tests/assertions.js'];
Object.keys(window.__karma__.files).forEach(function (file) {
Object.keys(window.__karma__.files).forEach((file) => {
if (TEST_REGEXP.test(file)) {
// TODO: normalize?
allTestFiles.push(file);

View File

@ -1,18 +1,19 @@
/* global VNC_frame_data, VNC_frame_encoding */
import * as WebUtil from '../app/webutil.js';
import RecordingPlayer from './playback.js';
var frames = null;
var encoding = null;
let frames = null;
let encoding = null;
function message(str) {
console.log(str);
var cell = document.getElementById('messages');
const cell = document.getElementById('messages');
cell.textContent += str + "\n";
cell.scrollTop = cell.scrollHeight;
}
function loadFile() {
const fname = WebUtil.getQueryVar('data', null);
const fname = WebUtil.getQueryconst('data', null);
if (!fname) {
return Promise.reject("Must specify data=FOO in query string.");
@ -21,7 +22,7 @@ function loadFile() {
message("Loading " + fname);
return new Promise(function (resolve, reject) {
var script = document.createElement("script");
const script = document.createElement("script");
script.onload = resolve;
script.onerror = reject;
document.body.appendChild(script);
@ -30,10 +31,10 @@ function loadFile() {
}
function enableUI() {
var iterations = WebUtil.getQueryVar('iterations', 3);
const iterations = WebUtil.getQueryconst('iterations', 3);
document.getElementById('iterations').value = iterations;
var mode = WebUtil.getQueryVar('mode', 3);
const mode = WebUtil.getQueryconst('mode', 3);
if (mode === 'realtime') {
document.getElementById('mode2').checked = true;
} else {
@ -120,7 +121,7 @@ IterationPlayer.prototype = {
this._state = 'failed';
}
var evt = new Event('rfbdisconnected');
const evt = new Event('rfbdisconnected');
evt.clean = clean;
evt.frame = frame;
evt.iteration = this._iteration;
@ -135,7 +136,7 @@ function start() {
const iterations = document.getElementById('iterations').value;
var mode;
let mode;
if (document.getElementById('mode1').checked) {
message(`Starting performance playback (fullspeed) [${iterations} iteration(s)]`);

View File

@ -10,11 +10,12 @@ import Base64 from '../core/base64.js';
// Immediate polyfill
if (setImmediate === undefined) {
var _immediateIdCounter = 1;
var _immediateFuncs = {};
let _immediateIdCounter = 1;
const _immediateFuncs = {};
var setImmediate = function (func) {
var index = _immediateIdCounter++;
// eslint-disable-next-line no-unused-vars
const setImmediate = function (func) {
const index = _immediateIdCounter++;
_immediateFuncs[index] = func;
window.postMessage("noVNC immediate trigger:" + index, "*");
return index;
@ -24,15 +25,15 @@ if (setImmediate === undefined) {
_immediateFuncs[id];
};
var _onMessage = function (event) {
const _onMessage = function (event) {
if ((typeof event.data !== "string") ||
(event.data.indexOf("noVNC immediate trigger:") !== 0)) {
return;
}
var index = event.data.slice("noVNC immediate trigger:".length);
const index = event.data.slice("noVNC immediate trigger:".length);
var callback = _immediateFuncs[index];
const callback = _immediateFuncs[index];
if (callback === undefined) {
return;
}
@ -70,11 +71,11 @@ export default function RecordingPlayer (frames, encoding, disconnected) {
this._running = false;
this.onfinish = function () {};
this.onfinish = () => {};
}
RecordingPlayer.prototype = {
run: function (realtime, trafficManagement) {
run(realtime, trafficManagement) {
// initialize a new RFB
this._rfb = new RFB(document.getElementById('VNC_screen'), 'wss://test');
this._rfb.viewOnly = true;
@ -95,20 +96,20 @@ RecordingPlayer.prototype = {
},
// _enablePlaybackMode mocks out things not required for running playback
_enablePlaybackMode: function () {
this._rfb._sock.send = function (arr) {};
this._rfb._sock.close = function () {};
this._rfb._sock.flush = function () {};
this._rfb._sock.open = function () {
_enablePlaybackMode() {
this._rfb._sock.send = () => {};
this._rfb._sock.close = () => {};
this._rfb._sock.flush = () => {};
this._rfb._sock.open = () => {
this.init();
this._eventHandlers.open();
};
},
_queueNextPacket: function () {
_queueNextPacket() {
if (!this._running) { return; }
var frame = this._frames[this._frame_index];
let frame = this._frames[this._frame_index];
// skip send frames
while (this._frame_index < this._frame_length && frame.charAt(0) === "}") {
@ -140,7 +141,7 @@ RecordingPlayer.prototype = {
}
},
_doPacket: function () {
_doPacket() {
// Avoid having excessive queue buildup in non-realtime mode
if (this._trafficManagement && this._rfb._flushing) {
let player = this;
@ -154,12 +155,13 @@ RecordingPlayer.prototype = {
}
const frame = this._frames[this._frame_index];
var start = frame.indexOf('{', 1) + 1;
let start = frame.indexOf('{', 1) + 1;
let u8;
if (this._encoding === 'base64') {
var u8 = Base64.decode(frame.slice(start));
u8 = Base64.decode(frame.slice(start));
start = 0;
} else {
var u8 = new Uint8Array(frame.length - start);
u8 = new Uint8Array(frame.length - start);
for (let i = 0; i < frame.length - start; i++) {
u8[i] = frame.charCodeAt(start + i);
}
@ -173,7 +175,7 @@ RecordingPlayer.prototype = {
_finish() {
if (this._rfb._display.pending()) {
var player = this;
const player = this;
this._rfb._display.onflush = function () {
if (player._rfb._flushing) {
player._rfb._onFlush();

View File

@ -1,29 +1,26 @@
var assert = chai.assert;
var expect = chai.expect;
const expect = chai.expect;
import Base64 from '../core/base64.js';
describe('Base64 Tools', function() {
"use strict";
var BIN_ARR = new Array(256);
for (var i = 0; i < 256; i++) {
const BIN_ARR = new Array(256);
for (let i = 0; i < 256; i++) {
BIN_ARR[i] = i;
}
var B64_STR = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==";
const B64_STR = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==";
describe('encode', function() {
it('should encode a binary string into Base64', function() {
var encoded = Base64.encode(BIN_ARR);
const encoded = Base64.encode(BIN_ARR);
expect(encoded).to.equal(B64_STR);
});
});
describe('decode', function() {
it('should decode a Base64 string into a normal string', function() {
var decoded = Base64.decode(B64_STR);
const decoded = Base64.decode(B64_STR);
expect(decoded).to.deep.equal(BIN_ARR);
});

View File

@ -1,5 +1,4 @@
/* jshint expr: true */
var expect = chai.expect;
const expect = chai.expect;
import Base64 from '../core/base64.js';
import Display from '../core/display.js';
@ -7,37 +6,35 @@ import Display from '../core/display.js';
import sinon from '../vendor/sinon.js';
describe('Display/Canvas Helper', function () {
var checked_data = [
const checked_data = new Uint8Array([
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, 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
];
checked_data = new Uint8Array(checked_data);
]);
var basic_data = [0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255];
basic_data = new Uint8Array(basic_data);
const basic_data = new Uint8Array([0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255]);
function make_image_canvas (input_data) {
var canvas = document.createElement('canvas');
const canvas = document.createElement('canvas');
canvas.width = 4;
canvas.height = 4;
var ctx = canvas.getContext('2d');
var data = ctx.createImageData(4, 4);
for (var i = 0; i < checked_data.length; i++) { data.data[i] = input_data[i]; }
const ctx = canvas.getContext('2d');
const data = ctx.createImageData(4, 4);
for (let i = 0; i < checked_data.length; i++) { data.data[i] = input_data[i]; }
ctx.putImageData(data, 0, 0);
return canvas;
}
function make_image_png (input_data) {
var canvas = make_image_canvas(input_data);
var url = canvas.toDataURL();
var data = url.split(",")[1];
const canvas = make_image_canvas(input_data);
const url = canvas.toDataURL();
const data = url.split(",")[1];
return Base64.decode(data);
}
describe('viewport handling', function () {
var display;
let display;
beforeEach(function () {
display = new Display(document.createElement('canvas'));
display.clipViewport = true;
@ -52,10 +49,9 @@ describe('Display/Canvas Helper', function () {
display.drawImage(make_image_canvas(basic_data), 1, 1);
display.flip();
var expected = new Uint8Array(16);
var i;
for (i = 0; i < 8; i++) { expected[i] = basic_data[i]; }
for (i = 8; i < 16; i++) { expected[i] = 0; }
const expected = new Uint8Array(16);
for (let i = 0; i < 8; i++) { expected[i] = basic_data[i]; }
for (let i = 8; i < 16; i++) { expected[i] = 0; }
expect(display).to.have.displayed(expected);
});
@ -120,7 +116,7 @@ describe('Display/Canvas Helper', function () {
});
describe('resizing', function () {
var display;
let display;
beforeEach(function () {
display = new Display(document.createElement('canvas'));
display.clipViewport = false;
@ -137,8 +133,8 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 4, 4, [0, 0, 0xff]);
display.resize(2, 2);
display.flip();
var expected = [];
for (var i = 0; i < 4 * 2*2; i += 4) {
const expected = [];
for (let i = 0; i < 4 * 2*2; i += 4) {
expected[i] = 0xff;
expected[i+1] = expected[i+2] = 0;
expected[i+3] = 0xff;
@ -180,8 +176,8 @@ describe('Display/Canvas Helper', function () {
});
describe('rescaling', function () {
var display;
var canvas;
let display;
let canvas;
beforeEach(function () {
canvas = document.createElement('canvas');
@ -221,8 +217,8 @@ describe('Display/Canvas Helper', function () {
});
describe('autoscaling', function () {
var display;
var canvas;
let display;
let canvas;
beforeEach(function () {
canvas = document.createElement('canvas');
@ -269,7 +265,7 @@ describe('Display/Canvas Helper', function () {
// TODO(directxman12): improve the tests for each of the drawing functions to cover more than just the
// basic cases
var display;
let display;
beforeEach(function () {
display = new Display(document.createElement('canvas'));
display.resize(4, 4);
@ -280,15 +276,15 @@ describe('Display/Canvas Helper', function () {
display._logo = null;
display.clear();
display.resize(4, 4);
var empty = [];
for (var i = 0; i < 4 * display._fb_width * display._fb_height; i++) { empty[i] = 0; }
const empty = [];
for (let i = 0; i < 4 * display._fb_width * display._fb_height; i++) { empty[i] = 0; }
expect(display).to.have.displayed(new Uint8Array(empty));
});
it('should draw the logo on #clear with a logo set', function (done) {
display._logo = { width: 4, height: 4, type: "image/png", data: make_image_png(checked_data) };
display.clear();
display.onflush = function () {
display.onflush = () => {
expect(display).to.have.displayed(checked_data);
expect(display._fb_width).to.equal(4);
expect(display._fb_height).to.equal(4);
@ -301,8 +297,8 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 4, 4, [0, 0, 0xff]);
display.flip();
display.fillRect(0, 0, 4, 4, [0, 0xff, 0]);
var expected = [];
for (var i = 0; i < 4 * display._fb_width * display._fb_height; i += 4) {
const expected = [];
for (let i = 0; i < 4 * display._fb_width * display._fb_height; i += 4) {
expected[i] = 0xff;
expected[i+1] = expected[i+2] = 0;
expected[i+3] = 0xff;
@ -329,7 +325,7 @@ describe('Display/Canvas Helper', function () {
it('should support drawing images via #imageRect', function (done) {
display.imageRect(0, 0, "image/png", make_image_png(checked_data));
display.flip();
display.onflush = function () {
display.onflush = () => {
expect(display).to.have.displayed(checked_data);
done();
};
@ -372,8 +368,8 @@ describe('Display/Canvas Helper', function () {
});
it('should support drawing BGRX blit images with true color via #blitImage', function () {
var data = [];
for (var i = 0; i < 16; i++) {
const data = [];
for (let i = 0; i < 16; i++) {
data[i * 4] = checked_data[i * 4 + 2];
data[i * 4 + 1] = checked_data[i * 4 + 1];
data[i * 4 + 2] = checked_data[i * 4];
@ -385,8 +381,8 @@ describe('Display/Canvas Helper', function () {
});
it('should support drawing RGB blit images with true color via #blitRgbImage', function () {
var data = [];
for (var i = 0; i < 16; i++) {
const data = [];
for (let i = 0; i < 16; i++) {
data[i * 3] = checked_data[i * 4];
data[i * 3 + 1] = checked_data[i * 4 + 1];
data[i * 3 + 2] = checked_data[i * 4 + 2];
@ -397,7 +393,7 @@ describe('Display/Canvas Helper', function () {
});
it('should support drawing an image object via #drawImage', function () {
var img = make_image_canvas(checked_data);
const img = make_image_canvas(checked_data);
display.drawImage(img, 0, 0);
display.flip();
expect(display).to.have.displayed(checked_data);
@ -405,7 +401,7 @@ describe('Display/Canvas Helper', function () {
});
describe('the render queue processor', function () {
var display;
let display;
beforeEach(function () {
display = new Display(document.createElement('canvas'));
display.resize(4, 4);
@ -428,7 +424,7 @@ describe('Display/Canvas Helper', function () {
});
it('should wait until an image is loaded to attempt to draw it and the rest of the queue', function () {
var img = { complete: false, addEventListener: sinon.spy() }
const img = { complete: false, addEventListener: sinon.spy() }
display._renderQ = [{ type: 'img', x: 3, y: 4, img: img },
{ type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }];
display.drawImage = sinon.spy();

View File

@ -1,5 +1,4 @@
var assert = chai.assert;
var expect = chai.expect;
const expect = chai.expect;
import keysyms from '../core/input/keysymdef.js';
import * as KeyboardUtil from "../core/input/util.js";
@ -12,8 +11,6 @@ function isEdge() {
}
describe('Helpers', function() {
"use strict";
describe('keysyms.lookup', function() {
it('should map ASCII characters to keysyms', function() {
expect(keysyms.lookup('a'.charCodeAt())).to.be.equal(0x61);
@ -71,7 +68,7 @@ describe('Helpers', function() {
});
describe('Fix Meta on macOS', function() {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
@ -134,7 +131,7 @@ describe('Helpers', function() {
});
describe('Broken key AltGraph on IE/Edge', function() {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these

View File

@ -1,5 +1,4 @@
var assert = chai.assert;
var expect = chai.expect;
const expect = chai.expect;
import sinon from '../vendor/sinon.js';
@ -12,27 +11,24 @@ function isEdge() {
return navigator && !!(/edge/i).exec(navigator.userAgent);
}
/* jshint newcap: false, expr: true */
describe('Key Event Handling', function() {
"use strict";
// The real KeyboardEvent constructor might not work everywhere we
// want to run these tests
function keyevent(typeArg, KeyboardEventInit) {
var e = { type: typeArg };
for (var key in KeyboardEventInit) {
const e = { type: typeArg };
for (let key in KeyboardEventInit) {
e[key] = KeyboardEventInit[key];
}
e.stopPropagation = sinon.spy();
e.preventDefault = sinon.spy();
return e;
};
}
describe('Decode Keyboard Events', function() {
it('should decode keydown events', function(done) {
if (isIE() || isEdge()) this.skip();
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -42,9 +38,9 @@ describe('Key Event Handling', function() {
});
it('should decode keyup events', function(done) {
if (isIE() || isEdge()) this.skip();
var calls = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let calls = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
if (calls++ === 1) {
@ -58,14 +54,14 @@ describe('Key Event Handling', function() {
describe('Legacy keypress Events', function() {
it('should wait for keypress when needed', function() {
var kbd = new Keyboard(document);
const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
expect(kbd.onkeyevent).to.not.have.been.called;
});
it('should decode keypress events', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -75,15 +71,15 @@ describe('Key Event Handling', function() {
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyA', charCode: 0x61}));
});
it('should ignore keypress with different code', function() {
var kbd = new Keyboard(document);
const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61}));
expect(kbd.onkeyevent).to.not.have.been.called;
});
it('should handle keypress with missing code', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -93,8 +89,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61}));
});
it('should guess key if no keypress and numeric key', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x32);
expect(code).to.be.equal('Digit2');
expect(down).to.be.equal(true);
@ -103,8 +99,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32}));
});
it('should guess key if no keypress and alpha key', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -113,8 +109,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false}));
});
it('should guess key if no keypress and alpha key (with shift)', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x41);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -123,8 +119,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true}));
});
it('should not guess key if no keypress and unknown key', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -139,27 +135,27 @@ describe('Key Event Handling', function() {
if (isIE() || isEdge()) this.skip();
});
it('should suppress anything with a valid key', function() {
var kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', key: 'a'});
kbd._handleKeyDown(evt);
expect(evt.preventDefault).to.have.been.called;
evt = keyevent('keyup', {code: 'KeyA', key: 'a'});
kbd._handleKeyUp(evt);
expect(evt.preventDefault).to.have.been.called;
const kbd = new Keyboard(document, {});
const evt1 = keyevent('keydown', {code: 'KeyA', key: 'a'});
kbd._handleKeyDown(evt1);
expect(evt1.preventDefault).to.have.been.called;
const evt2 = keyevent('keyup', {code: 'KeyA', key: 'a'});
kbd._handleKeyUp(evt2);
expect(evt2.preventDefault).to.have.been.called;
});
it('should not suppress keys without key', function() {
var kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
const kbd = new Keyboard(document, {});
const evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
kbd._handleKeyDown(evt);
expect(evt.preventDefault).to.not.have.been.called;
});
it('should suppress the following keypress event', function() {
var kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
kbd._handleKeyDown(evt);
var evt = keyevent('keypress', {code: 'KeyA', charCode: 0x41});
kbd._handleKeyPress(evt);
expect(evt.preventDefault).to.have.been.called;
const kbd = new Keyboard(document, {});
const evt1 = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
kbd._handleKeyDown(evt1);
const evt2 = keyevent('keypress', {code: 'KeyA', charCode: 0x41});
kbd._handleKeyPress(evt2);
expect(evt2.preventDefault).to.have.been.called;
});
});
});
@ -167,9 +163,9 @@ describe('Key Event Handling', function() {
describe('Fake keyup', function() {
it('should fake keyup events for virtual keyboards', function(done) {
if (isIE() || isEdge()) this.skip();
var count = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let count = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
switch (count++) {
case 0:
expect(keysym).to.be.equal(0x61);
@ -187,7 +183,7 @@ describe('Key Event Handling', function() {
});
describe('iOS', function() {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
@ -214,9 +210,9 @@ describe('Key Event Handling', function() {
it('should fake keyup events on iOS', function(done) {
if (isIE() || isEdge()) this.skip();
var count = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let count = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
switch (count++) {
case 0:
expect(keysym).to.be.equal(0x61);
@ -240,8 +236,8 @@ describe('Key Event Handling', function() {
if (isIE() || isEdge()) this.skip();
});
it('should send release using the same keysym as the press', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
if (!down) {
@ -252,9 +248,9 @@ describe('Key Event Handling', function() {
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'b'}));
});
it('should send the same keysym for multiple presses', function() {
var count = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let count = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
@ -265,7 +261,7 @@ describe('Key Event Handling', function() {
expect(count).to.be.equal(2);
});
it('should do nothing on keyup events if no keys are down', function() {
var kbd = new Keyboard(document);
const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy();
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
expect(kbd.onkeyevent).to.not.have.been.called;
@ -273,8 +269,8 @@ describe('Key Event Handling', function() {
describe('Legacy Events', function() {
it('should track keys using keyCode if no code', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Platform65');
if (!down) {
@ -285,16 +281,16 @@ describe('Key Event Handling', function() {
kbd._handleKeyUp(keyevent('keyup', {keyCode: 65, key: 'b'}));
});
it('should ignore compositing code', function() {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Unidentified');
};
kbd._handleKeyDown(keyevent('keydown', {keyCode: 229, key: 'a'}));
});
it('should track keys using keyIdentifier if no code', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Platform65');
if (!down) {
@ -308,7 +304,7 @@ describe('Key Event Handling', function() {
});
describe('Shuffle modifiers on macOS', function() {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
@ -334,9 +330,9 @@ describe('Key Event Handling', function() {
});
it('should change Alt to AltGraph', function() {
var count = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let count = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code) => {
switch (count++) {
case 0:
expect(keysym).to.be.equal(0xFF7E);
@ -353,8 +349,8 @@ describe('Key Event Handling', function() {
expect(count).to.be.equal(2);
});
it('should change left Super to Alt', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code) => {
expect(keysym).to.be.equal(0xFFE9);
expect(code).to.be.equal('MetaLeft');
done();
@ -362,8 +358,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1}));
});
it('should change right Super to left Super', function(done) {
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code) => {
expect(keysym).to.be.equal(0xFFEB);
expect(code).to.be.equal('MetaRight');
done();
@ -373,7 +369,7 @@ describe('Key Event Handling', function() {
});
describe('Escape AltGraph on Windows', function() {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
@ -399,9 +395,9 @@ describe('Key Event Handling', function() {
});
it('should generate fake undo/redo events on press when AltGraph is down', function() {
var times_called = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let times_called = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
switch(times_called++) {
case 0:
expect(keysym).to.be.equal(0xFFE3);
@ -448,9 +444,9 @@ describe('Key Event Handling', function() {
expect(times_called).to.be.equal(7);
});
it('should no do anything on key release', function() {
var times_called = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let times_called = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
switch(times_called++) {
case 7:
expect(keysym).to.be.equal(0x61);
@ -468,9 +464,9 @@ describe('Key Event Handling', function() {
expect(times_called).to.be.equal(8);
});
it('should not consider a char modifier to be down on the modifier key itself', function() {
var times_called = 0;
var kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) {
let times_called = 0;
const kbd = new Keyboard(document);
kbd.onkeyevent = (keysym, code, down) => {
switch(times_called++) {
case 0:
expect(keysym).to.be.equal(0xFFE3);

View File

@ -1,15 +1,10 @@
/* jshint expr: true */
const expect = chai.expect;
var assert = chai.assert;
var expect = chai.expect;
import l10nGet, { l10n } from '../app/localization.js';
import { l10n } from '../app/localization.js';
describe('Localization', function() {
"use strict";
describe('language selection', function () {
var origNavigator;
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
@ -35,7 +30,8 @@ describe('Localization', function() {
});
it('should use English by default', function() {
expect(l10n.language).to.equal('en');
const a = l10n.language;
expect(a).to.equal('en');
});
it('should use English if no user language matches', function() {
window.navigator.languages = ["nl", "de"];

View File

@ -1,40 +1,36 @@
var assert = chai.assert;
var expect = chai.expect;
const expect = chai.expect;
import sinon from '../vendor/sinon.js';
import Mouse from '../core/input/mouse.js';
import * as eventUtils from '../core/util/events.js';
/* jshint newcap: false, expr: true */
describe('Mouse Event Handling', function() {
"use strict";
sinon.stub(eventUtils, 'setCapture');
// This function is only used on target (the canvas)
// and for these tests we can assume that the canvas is 100x100
// located at coordinates 10x10
sinon.stub(Element.prototype, 'getBoundingClientRect').returns(
{left: 10, right: 110, top: 10, bottom: 110, width: 100, height: 100});
var target = document.createElement('canvas');
const target = document.createElement('canvas');
// The real constructors might not work everywhere we
// want to run these tests
var mouseevent, touchevent;
mouseevent = touchevent = function(typeArg, MouseEventInit) {
var e = { type: typeArg };
for (var key in MouseEventInit) {
const touchevent = (typeArg, MouseEventInit) => {
const e = { type: typeArg };
for (let key in MouseEventInit) {
e[key] = MouseEventInit[key];
}
e.stopPropagation = sinon.spy();
e.preventDefault = sinon.spy();
return e;
};
const mouseevent = touchevent;
describe('Decode Mouse Events', function() {
it('should decode mousedown events', function(done) {
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down, bmask) => {
expect(bmask).to.be.equal(0x01);
expect(down).to.be.equal(1);
done();
@ -42,9 +38,9 @@ describe('Mouse Event Handling', function() {
mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' }));
});
it('should decode mouseup events', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down, bmask) => {
expect(bmask).to.be.equal(0x01);
if (calls++ === 1) {
expect(down).to.not.be.equal(1);
@ -55,8 +51,8 @@ describe('Mouse Event Handling', function() {
mouse._handleMouseUp(mouseevent('mouseup', { button: '0x01' }));
});
it('should decode mousemove events', function(done) {
var mouse = new Mouse(target);
mouse.onmousemove = function(x, y) {
const mouse = new Mouse(target);
mouse.onmousemove = (x, y) => {
// Note that target relative coordinates are sent
expect(x).to.be.equal(40);
expect(y).to.be.equal(10);
@ -66,9 +62,9 @@ describe('Mouse Event Handling', function() {
{ clientX: 50, clientY: 20 }));
});
it('should decode mousewheel events', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down, bmask) => {
calls++;
expect(bmask).to.be.equal(1<<6);
if (calls === 1) {
@ -90,9 +86,9 @@ describe('Mouse Event Handling', function() {
afterEach(function () { this.clock.restore(); });
it('should use same pos for 2nd tap if close enough', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down) => {
calls++;
if (calls === 1) {
expect(down).to.be.equal(1);
@ -121,9 +117,9 @@ describe('Mouse Event Handling', function() {
});
it('should not modify 2nd tap pos if far apart', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down) => {
calls++;
if (calls === 1) {
expect(down).to.be.equal(1);
@ -150,9 +146,9 @@ describe('Mouse Event Handling', function() {
});
it('should not modify 2nd tap pos if not soon enough', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down) => {
calls++;
if (calls === 1) {
expect(down).to.be.equal(1);
@ -179,9 +175,9 @@ describe('Mouse Event Handling', function() {
});
it('should not modify 2nd tap pos if not touch', function(done) {
var calls = 0;
var mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) {
let calls = 0;
const mouse = new Mouse(target);
mouse.onmousebutton = (x, y, down) => {
calls++;
if (calls === 1) {
expect(down).to.be.equal(1);
@ -215,7 +211,7 @@ describe('Mouse Event Handling', function() {
afterEach(function () { this.clock.restore(); });
it('should accumulate wheel events if small enough', function () {
var mouse = new Mouse(target);
const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent(
@ -248,7 +244,7 @@ describe('Mouse Event Handling', function() {
});
it('should not accumulate large wheel events', function () {
var mouse = new Mouse(target);
const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent(
@ -267,7 +263,7 @@ describe('Mouse Event Handling', function() {
});
it('should send even small wheel events after a timeout', function () {
var mouse = new Mouse(target);
const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent(
@ -279,7 +275,7 @@ describe('Mouse Event Handling', function() {
});
it('should account for non-zero deltaMode', function () {
var mouse = new Mouse(target);
const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent(

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,5 @@
/* jshint expr: true */
var assert = chai.assert;
var expect = chai.expect;
/* eslint-disable no-console */
const expect = chai.expect;
import * as Log from '../core/util/logging.js';
@ -70,3 +68,4 @@ describe('Utils', function() {
// (we can't really test them against the browsers, except for Gecko
// via PhantomJS, the default test driver)
});
/* eslint-enable no-console */

View File

@ -1,6 +1,4 @@
/* jshint expr: true */
var assert = chai.assert;
var expect = chai.expect;
const expect = chai.expect;
import Websock from '../core/websock.js';
import FakeWebSocket from './fake.websocket.js';
@ -11,8 +9,8 @@ describe('Websock', function() {
"use strict";
describe('Queue methods', function () {
var sock;
var RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);
let sock;
const RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);
beforeEach(function () {
sock = new Websock();
@ -37,8 +35,8 @@ describe('Websock', function() {
describe('rQpeek8', function () {
it('should peek at the next byte without poping it off the queue', function () {
var bef_len = sock.rQlen();
var peek = sock.rQpeek8();
const bef_len = sock.rQlen();
const peek = sock.rQpeek8();
expect(sock.rQpeek8()).to.equal(peek);
expect(sock.rQlen()).to.equal(bef_len);
});
@ -46,8 +44,8 @@ describe('Websock', function() {
describe('rQshift8', function () {
it('should pop a single byte from the receive queue', function () {
var peek = sock.rQpeek8();
var bef_len = sock.rQlen();
const peek = sock.rQpeek8();
const bef_len = sock.rQlen();
expect(sock.rQshift8()).to.equal(peek);
expect(sock.rQlen()).to.equal(bef_len - 1);
});
@ -55,8 +53,8 @@ describe('Websock', function() {
describe('rQshift16', function () {
it('should pop two bytes from the receive queue and return a single number', function () {
var bef_len = sock.rQlen();
var expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1];
const bef_len = sock.rQlen();
const expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1];
expect(sock.rQshift16()).to.equal(expected);
expect(sock.rQlen()).to.equal(bef_len - 2);
});
@ -64,8 +62,8 @@ describe('Websock', function() {
describe('rQshift32', function () {
it('should pop four bytes from the receive queue and return a single number', function () {
var bef_len = sock.rQlen();
var expected = (RQ_TEMPLATE[0] << 24) +
const bef_len = sock.rQlen();
const expected = (RQ_TEMPLATE[0] << 24) +
(RQ_TEMPLATE[1] << 16) +
(RQ_TEMPLATE[2] << 8) +
RQ_TEMPLATE[3];
@ -76,9 +74,9 @@ describe('Websock', function() {
describe('rQshiftStr', function () {
it('should shift the given number of bytes off of the receive queue and return a string', function () {
var bef_len = sock.rQlen();
var bef_rQi = sock.get_rQi();
var shifted = sock.rQshiftStr(3);
const bef_len = sock.rQlen();
const bef_rQi = sock.get_rQi();
const shifted = sock.rQshiftStr(3);
expect(shifted).to.be.a('string');
expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3))));
expect(sock.rQlen()).to.equal(bef_len - 3);
@ -92,9 +90,9 @@ describe('Websock', function() {
describe('rQshiftBytes', function () {
it('should shift the given number of bytes of the receive queue and return an array', function () {
var bef_len = sock.rQlen();
var bef_rQi = sock.get_rQi();
var shifted = sock.rQshiftBytes(3);
const bef_len = sock.rQlen();
const bef_rQi = sock.get_rQi();
const shifted = sock.rQshiftBytes(3);
expect(shifted).to.be.an.instanceof(Uint8Array);
expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3));
expect(sock.rQlen()).to.equal(bef_len - 3);
@ -112,19 +110,19 @@ describe('Websock', function() {
});
it('should not modify the receive queue', function () {
var bef_len = sock.rQlen();
const bef_len = sock.rQlen();
sock.rQslice(0, 2);
expect(sock.rQlen()).to.equal(bef_len);
});
it('should return an array containing the given slice of the receive queue', function () {
var sl = sock.rQslice(0, 2);
const sl = sock.rQslice(0, 2);
expect(sl).to.be.an.instanceof(Uint8Array);
expect(sl).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 0, 2));
});
it('should use the rest of the receive queue if no end is given', function () {
var sl = sock.rQslice(1);
const sl = sock.rQslice(1);
expect(sl).to.have.length(RQ_TEMPLATE.length - 1);
expect(sl).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 1));
});
@ -178,7 +176,7 @@ describe('Websock', function() {
sock._websocket.readyState = WebSocket.OPEN
sock._sQ = new Uint8Array([1, 2, 3]);
sock._sQlen = 3;
var encoded = sock._encode_message();
const encoded = sock._encode_message();
sock.flush();
expect(sock._websocket.send).to.have.been.calledOnce;
@ -202,7 +200,7 @@ describe('Websock', function() {
it('should add to the send queue', function () {
sock.send([1, 2, 3]);
var sq = sock.get_sQ();
const sq = sock.get_sQ();
expect(new Uint8Array(sq.buffer, sock._sQlen - 3, 3)).to.array.equal(new Uint8Array([1, 2, 3]));
});
@ -225,14 +223,15 @@ describe('Websock', function() {
});
describe('lifecycle methods', function () {
var old_WS;
let old_WS;
before(function () {
old_WS = WebSocket;
});
var sock;
let sock;
beforeEach(function () {
sock = new Websock();
// eslint-disable-next-line no-global-assign
WebSocket = sinon.spy();
WebSocket.OPEN = old_WS.OPEN;
WebSocket.CONNECTING = old_WS.CONNECTING;
@ -328,19 +327,20 @@ describe('Websock', function() {
});
after(function () {
// eslint-disable-next-line no-global-assign
WebSocket = old_WS;
});
});
describe('WebSocket Receiving', function () {
var sock;
let sock;
beforeEach(function () {
sock = new Websock();
sock._allocate_buffers();
});
it('should support adding binary Uint8Array data to the receive queue', function () {
var msg = { data: new Uint8Array([1, 2, 3]) };
const msg = { data: new Uint8Array([1, 2, 3]) };
sock._mode = 'binary';
sock._recv_message(msg);
expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03');
@ -348,7 +348,7 @@ describe('Websock', function() {
it('should call the message event handler if present', function () {
sock._eventHandlers.message = sinon.spy();
var msg = { data: new Uint8Array([1, 2, 3]).buffer };
const msg = { data: new Uint8Array([1, 2, 3]).buffer };
sock._mode = 'binary';
sock._recv_message(msg);
expect(sock._eventHandlers.message).to.have.been.calledOnce;
@ -356,7 +356,7 @@ describe('Websock', function() {
it('should not call the message event handler if there is nothing in the receive queue', function () {
sock._eventHandlers.message = sinon.spy();
var msg = { data: new Uint8Array([]).buffer };
const msg = { data: new Uint8Array([]).buffer };
sock._mode = 'binary';
sock._recv_message(msg);
expect(sock._eventHandlers.message).not.to.have.been.called;
@ -369,7 +369,7 @@ describe('Websock', function() {
sock._rQlen = 6;
sock.set_rQi(6);
sock._rQmax = 3;
var msg = { data: new Uint8Array([1, 2, 3]).buffer };
const msg = { data: new Uint8Array([1, 2, 3]).buffer };
sock._mode = 'binary';
sock._recv_message(msg);
expect(sock._rQlen).to.equal(3);
@ -382,12 +382,12 @@ describe('Websock', function() {
sock.set_rQi(0);
sock._rQbufferSize = 20;
sock._rQmax = 2;
var msg = { data: new Uint8Array(30).buffer };
const msg = { data: new Uint8Array(30).buffer };
sock._mode = 'binary';
sock._recv_message(msg);
expect(sock._rQlen).to.equal(30);
expect(sock.get_rQi()).to.equal(0);
expect(sock._rQ.length).to.equal(240); // keep the invariant that rQbufferSize / 8 >= rQlen
expect(sock._rQ.length).to.equal(240); // keep the inconstiant that rQbufferSize / 8 >= rQlen
});
});
@ -396,7 +396,7 @@ describe('Websock', function() {
after(function () { FakeWebSocket.restore(); });
describe('as binary data', function () {
var sock;
let sock;
beforeEach(function () {
sock = new Websock();
sock.open('ws://', 'binary');
@ -406,7 +406,7 @@ describe('Websock', function() {
it('should only send the send queue up to the send queue length', function () {
sock._sQ = new Uint8Array([1, 2, 3, 4, 5]);
sock._sQlen = 3;
var res = sock._encode_message();
const res = sock._encode_message();
expect(res).to.array.equal(new Uint8Array([1, 2, 3]));
});

8
utils/.eslintrc Normal file
View File

@ -0,0 +1,8 @@
{
"env": {
"node": true
},
"rules": {
"no-console": 0
}
}

View File

@ -8,12 +8,12 @@
"use strict";
var fs = require('fs');
const fs = require('fs');
var show_help = process.argv.length === 2;
var filename;
let show_help = process.argv.length === 2;
let filename;
for (var i = 2; i < process.argv.length; ++i) {
for (let i = 2; i < process.argv.length; ++i) {
switch (process.argv[i]) {
case "--help":
case "-h":
@ -36,37 +36,37 @@ if (show_help) {
console.log("Usage: node parse.js [options] filename:");
console.log(" -h [ --help ] Produce this help message");
console.log(" filename The keysymdef.h file to parse");
return;
process.exit(0);
}
var buf = fs.readFileSync(filename);
var str = buf.toString('utf8');
const buf = fs.readFileSync(filename);
const str = buf.toString('utf8');
var re = /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/m;
const re = /^#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/m;
var arr = str.split('\n');
const arr = str.split('\n');
var codepoints = {};
const codepoints = {};
for (var i = 0; i < arr.length; ++i) {
var result = re.exec(arr[i]);
for (let i = 0; i < arr.length; ++i) {
const result = re.exec(arr[i]);
if (result){
var keyname = result[1];
var keysym = parseInt(result[2], 16);
var remainder = result[3];
const name = result[1];
const keysym = parseInt(result[2], 16);
const remainder = result[3];
var unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder);
const unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder);
if (unicodeRes) {
var unicode = parseInt(unicodeRes[1], 16);
const unicode = parseInt(unicodeRes[1], 16);
// The first entry is the preferred one
if (!codepoints[unicode]){
codepoints[unicode] = { keysym: keysym, name: keyname };
codepoints[unicode] = { keysym, name };
}
}
}
}
var out =
let out =
"/*\n" +
" * Mapping from Unicode codepoints to X11/RFB keysyms\n" +
" *\n" +
@ -79,14 +79,14 @@ var out =
"var codepoints = {\n";
function toHex(num) {
var s = num.toString(16);
let s = num.toString(16);
if (s.length < 4) {
s = ("0000" + s).slice(-4);
}
return "0x" + s;
};
}
for (var codepoint in codepoints) {
for (let codepoint in codepoints) {
codepoint = parseInt(codepoint);
// Latin-1?

View File

@ -1,9 +1,9 @@
#!/usr/bin/env node
var path = require('path');
var program = require('commander');
var fs = require('fs');
var fse = require('fs-extra');
const path = require('path');
const program = require('commander');
const fs = require('fs');
const fse = require('fs-extra');
const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']);
@ -40,7 +40,7 @@ no_copy_files.forEach((file) => no_transform_files.add(file));
// walkDir *recursively* walks directories trees,
// calling the callback for all normal files found.
var walkDir = function (base_path, cb, filter) {
function walkDir(base_path, cb, filter) {
fs.readdir(base_path, (err, files) => {
if (err) throw err;
@ -56,26 +56,26 @@ var walkDir = function (base_path, cb, filter) {
});
});
});
};
}
var transform_html = function (new_script) {
function transform_html(new_script) {
// 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(paths.out_dir_base, 'vnc.html');
const src_html_path = path.resolve(__dirname, '..', 'vnc.html');
const out_html_path = path.resolve(paths.out_dir_base, 'vnc.html');
fs.readFile(src_html_path, (err, contents_raw) => {
if (err) { throw err; }
var contents = contents_raw.toString();
let contents = contents_raw.toString();
var start_marker = '<!-- begin scripts -->\n';
var end_marker = '<!-- end scripts -->';
var start_ind = contents.indexOf(start_marker) + start_marker.length;
var end_ind = contents.indexOf(end_marker, start_ind);
const start_marker = '<!-- begin scripts -->\n';
const end_marker = '<!-- end scripts -->';
const start_ind = contents.indexOf(start_marker) + start_marker.length;
const end_ind = contents.indexOf(end_marker, start_ind);
contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind);
console.log(`Writing ${out_html_path}`);
fs.writeFile(out_html_path, contents, function (err) {
fs.writeFile(out_html_path, contents, (err) => {
if (err) { throw err; }
});
});
@ -96,12 +96,13 @@ var make_lib_files = function (import_format, source_maps, with_app_dir) {
});
const babel = require('babel-core');
var in_path;
let in_path;
let out_path_base;
if (with_app_dir) {
var out_path_base = paths.out_dir_base;
out_path_base = paths.out_dir_base;
in_path = paths.main;
} else {
var out_path_base = paths.lib_dir_base;
out_path_base = paths.lib_dir_base;
}
fse.ensureDirSync(out_path_base);
@ -109,7 +110,7 @@ var make_lib_files = function (import_format, source_maps, with_app_dir) {
const helpers = require('./use_require_helpers');
const helper = helpers[import_format];
var handleDir = (js_only, vendor_rewrite, in_path_base, filename) => {
const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => {
if (no_copy_files.has(filename)) return;
const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
@ -143,7 +144,7 @@ var make_lib_files = function (import_format, source_maps, with_app_dir) {
babel.transformFile(filename, opts, (err, res) => {
console.log(`Writing ${out_path}`);
if (err) throw err;
var {code, map, ast} = res;
let {code, map} = res;
if (source_maps === true) {
// append URL for external source map
code += `\n//# sourceMappingURL=${path.basename(out_path)}.map\n`;
@ -161,11 +162,11 @@ var make_lib_files = function (import_format, source_maps, with_app_dir) {
helper.noCopyOverride(paths, no_copy_files);
}
walkDir(paths.vendor, handleDir.bind(null, true, false, in_path || paths.main), (filename, stats) => !no_copy_files.has(filename));
walkDir(paths.core, handleDir.bind(null, true, !in_path, in_path || paths.core), (filename, stats) => !no_copy_files.has(filename));
walkDir(paths.vendor, handleDir.bind(null, true, false, in_path || paths.main), filename => !no_copy_files.has(filename));
walkDir(paths.core, handleDir.bind(null, true, !in_path, in_path || paths.core), filename => !no_copy_files.has(filename));
if (with_app_dir) {
walkDir(paths.app, handleDir.bind(null, false, false, in_path), (filename, stats) => !no_copy_files.has(filename));
walkDir(paths.app, handleDir.bind(null, false, false, in_path), filename => !no_copy_files.has(filename));
const out_app_path = path.join(out_path_base, 'app.js');
if (helper && helper.appWriter) {

View File

@ -1,7 +1,6 @@
// writes helpers require for vnc.html (they should output app.js)
var fs = require('fs');
var fse = require('fs-extra');
var path = require('path');
const fs = require('fs');
const path = require('path');
module.exports = {
'amd': {
@ -19,8 +18,8 @@ module.exports = {
opts.plugins.unshift("add-module-exports");
},
appWriter: (base_out_path, out_path) => {
var browserify = require('browserify');
var b = browserify(path.join(base_out_path, 'app/ui.js'), {});
const browserify = require('browserify');
const b = browserify(path.join(base_out_path, 'app/ui.js'), {});
b.bundle().pipe(fs.createWriteStream(out_path));
return `<script src="${path.relative(base_out_path, out_path)}"></script>`;
},

View File

@ -280,7 +280,7 @@ function longest_match(s, cur_match) {
* the 256th check will be made at strstart+258.
*/
do {
/*jshint noempty:false*/
// Do nothing
} while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
@ -892,7 +892,7 @@ function deflate_rle(s, flush) {
if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
strend = s.strstart + MAX_MATCH;
do {
/*jshint noempty:false*/
// Do nothing
} while (prev === _win[++scan] && prev === _win[++scan] &&
prev === _win[++scan] && prev === _win[++scan] &&
prev === _win[++scan] && prev === _win[++scan] &&