Merge pull request #1013 from juanjoDiaz/es6_refactor_2

Add eslint and update noVNC to ES6
This commit is contained in:
Samuel Mannehed 2018-05-25 10:22:36 +02:00 committed by GitHub
commit fe70a1d51f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 14993 additions and 3226 deletions

15
.eslintrc Normal file
View File

@ -0,0 +1,15 @@
{
"env": {
"browser": true,
"es6": true
},
"parserOptions": {
"sourceType": "module"
},
"extends": "eslint:recommended",
"rules": {
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
"no-constant-condition": ["error", { "checkLoops": false }],
"no-var": "error"
}
}

View File

@ -2,21 +2,20 @@
// native support in the browsers, so that our error handler // native support in the browsers, so that our error handler
// can catch script-loading errors. // can catch script-loading errors.
(function(){ (function(){
"use strict"; "use strict";
// Fallback for all uncought errors // Fallback for all uncought errors
function handleError (event, err) { function handleError (event, err) {
try { try {
var msg = document.getElementById('noVNC_fallback_errormsg'); const msg = document.getElementById('noVNC_fallback_errormsg');
// Only show the initial error // Only show the initial error
if (msg.hasChildNodes()) { if (msg.hasChildNodes()) {
return false; return false;
} }
var div = document.createElement("div"); let div = document.createElement("div");
div.classList.add('noVNC_message'); div.classList.add('noVNC_message');
div.appendChild(document.createTextNode(event.message)); div.appendChild(document.createTextNode(event.message));
msg.appendChild(div); msg.appendChild(div);
@ -24,7 +23,7 @@
if (event.filename) { if (event.filename) {
div = document.createElement("div"); div = document.createElement("div");
div.className = 'noVNC_location'; div.className = 'noVNC_location';
var text = event.filename; let text = event.filename;
if (event.lineno !== undefined) { if (event.lineno !== undefined) {
text += ":" + event.lineno; text += ":" + event.lineno;
if (event.colno !== undefined) { if (event.colno !== undefined) {

View File

@ -21,25 +21,24 @@ export function Localizer() {
Localizer.prototype = { Localizer.prototype = {
// Configure suitable language based on user preferences // Configure suitable language based on user preferences
setup: function (supportedLanguages) { setup: function (supportedLanguages) {
var userLanguages;
this.language = 'en'; // Default: US English this.language = 'en'; // Default: US English
/* /*
* Navigator.languages only available in Chrome (32+) and FireFox (32+) * Navigator.languages only available in Chrome (32+) and FireFox (32+)
* Fall back to navigator.language for other browsers * Fall back to navigator.language for other browsers
*/ */
let userLanguages;
if (typeof window.navigator.languages == 'object') { if (typeof window.navigator.languages == 'object') {
userLanguages = window.navigator.languages; userLanguages = window.navigator.languages;
} else { } else {
userLanguages = [navigator.language || navigator.userLanguage]; userLanguages = [navigator.language || navigator.userLanguage];
} }
for (var i = 0;i < userLanguages.length;i++) { for (let i = 0;i < userLanguages.length;i++) {
var userLang = userLanguages[i]; const userLang = userLanguages[i]
userLang = userLang.toLowerCase(); .toLowerCase()
userLang = userLang.replace("_", "-"); .replace("_", "-")
userLang = userLang.split("-"); .split("-");
// Built-in default? // Built-in default?
if ((userLang[0] === 'en') && if ((userLang[0] === 'en') &&
@ -48,11 +47,11 @@ Localizer.prototype = {
} }
// First pass: perfect match // First pass: perfect match
for (var j = 0;j < supportedLanguages.length;j++) { for (let j = 0; j < supportedLanguages.length; j++) {
var supLang = supportedLanguages[j]; const supLang = supportedLanguages[j]
supLang = supLang.toLowerCase(); .toLowerCase()
supLang = supLang.replace("_", "-"); .replace("_", "-")
supLang = supLang.split("-"); .split("-");
if (userLang[0] !== supLang[0]) if (userLang[0] !== supLang[0])
continue; continue;
@ -64,11 +63,11 @@ Localizer.prototype = {
} }
// Second pass: fallback // Second pass: fallback
for (var j = 0;j < supportedLanguages.length;j++) { for (let j = 0;j < supportedLanguages.length;j++) {
supLang = supportedLanguages[j]; const supLang = supportedLanguages[j]
supLang = supLang.toLowerCase(); .toLowerCase()
supLang = supLang.replace("_", "-"); .replace("_", "-")
supLang = supLang.split("-"); .split("-");
if (userLang[0] !== supLang[0]) if (userLang[0] !== supLang[0])
continue; continue;
@ -93,21 +92,19 @@ Localizer.prototype = {
// Traverses the DOM and translates relevant fields // Traverses the DOM and translates relevant fields
// See https://html.spec.whatwg.org/multipage/dom.html#attr-translate // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
translateDOM: function () { translateDOM: function () {
var self = this; const self = this;
function process(elem, enabled) { function process(elem, enabled) {
function isAnyOf(searchElement, items) { function isAnyOf(searchElement, items) {
return items.indexOf(searchElement) !== -1; return items.indexOf(searchElement) !== -1;
} }
function translateAttribute(elem, attr) { function translateAttribute(elem, attr) {
var str = elem.getAttribute(attr); const str = self.get(elem.getAttribute(attr));
str = self.get(str);
elem.setAttribute(attr, str); elem.setAttribute(attr, str);
} }
function translateTextNode(node) { function translateTextNode(node) {
var str = node.data.trim(); const str = self.get(node.data.trim());
str = self.get(str);
node.data = str; node.data = str;
} }
@ -152,8 +149,8 @@ Localizer.prototype = {
} }
} }
for (var i = 0;i < elem.childNodes.length;i++) { for (let i = 0; i < elem.childNodes.length; i++) {
var node = elem.childNodes[i]; const node = elem.childNodes[i];
if (node.nodeType === node.ELEMENT_NODE) { if (node.nodeType === node.ELEMENT_NODE) {
process(node, enabled); process(node, enabled);
} else if (node.nodeType === node.TEXT_NODE && enabled) { } else if (node.nodeType === node.TEXT_NODE && enabled) {
@ -166,5 +163,5 @@ Localizer.prototype = {
}, },
}; };
export var l10n = new Localizer(); export const l10n = new Localizer();
export default l10n.get.bind(l10n); export default l10n.get.bind(l10n);

180
app/ui.js
View File

@ -16,10 +16,9 @@ import KeyTable from "../core/input/keysym.js";
import keysyms from "../core/input/keysymdef.js"; import keysyms from "../core/input/keysymdef.js";
import Keyboard from "../core/input/keyboard.js"; import Keyboard from "../core/input/keyboard.js";
import RFB from "../core/rfb.js"; import RFB from "../core/rfb.js";
import Display from "../core/display.js";
import * as WebUtil from "./webutil.js"; import * as WebUtil from "./webutil.js";
var UI = { const UI = {
connected: false, connected: false,
desktopName: "", desktopName: "",
@ -102,7 +101,7 @@ var UI = {
document.documentElement.classList.remove("noVNC_loading"); document.documentElement.classList.remove("noVNC_loading");
var autoconnect = WebUtil.getConfigVar('autoconnect', false); let autoconnect = WebUtil.getConfigVar('autoconnect', false);
if (autoconnect === 'true' || autoconnect == '1') { if (autoconnect === 'true' || autoconnect == '1') {
autoconnect = true; autoconnect = true;
UI.connect(); UI.connect();
@ -132,12 +131,10 @@ var UI = {
}, },
initSettings: function() { initSettings: function() {
var i;
// Logging selection dropdown // Logging selection dropdown
var llevels = ['error', 'warn', 'info', 'debug']; const llevels = ['error', 'warn', 'info', 'debug'];
for (i = 0; i < llevels.length; i += 1) { for (let i = 0; i < llevels.length; i += 1) {
UI.addOption(document.getElementById('noVNC_setting_logging'),llevels[i], llevels[i]); UI.addOption(document.getElementById('noVNC_setting_logging'), llevels[i], llevels[i]);
} }
// Settings with immediate effects // Settings with immediate effects
@ -146,7 +143,7 @@ var UI = {
// if port == 80 (or 443) then it won't be present and should be // if port == 80 (or 443) then it won't be present and should be
// set manually // set manually
var port = window.location.port; let port = window.location.port;
if (!port) { if (!port) {
if (window.location.protocol.substring(0,5) == 'https') { if (window.location.protocol.substring(0,5) == 'https') {
port = 443; port = 443;
@ -173,16 +170,16 @@ var UI = {
}, },
// Adds a link to the label elements on the corresponding input elements // Adds a link to the label elements on the corresponding input elements
setupSettingLabels: function() { setupSettingLabels: function() {
var labels = document.getElementsByTagName('LABEL'); const labels = document.getElementsByTagName('LABEL');
for (var i = 0; i < labels.length; i++) { for (let i = 0; i < labels.length; i++) {
var htmlFor = labels[i].htmlFor; const htmlFor = labels[i].htmlFor;
if (htmlFor != '') { if (htmlFor != '') {
var elem = document.getElementById(htmlFor); const elem = document.getElementById(htmlFor);
if (elem) elem.label = labels[i]; if (elem) elem.label = labels[i];
} else { } else {
// If 'for' isn't set, use the first input element child // If 'for' isn't set, use the first input element child
var children = labels[i].children; const children = labels[i].children;
for (var j = 0; j < children.length; j++) { for (let j = 0; j < children.length; j++) {
if (children[j].form !== undefined) { if (children[j].form !== undefined) {
children[j].label = labels[i]; children[j].label = labels[i];
break; break;
@ -225,8 +222,8 @@ var UI = {
// resize events aren't available for elements // resize events aren't available for elements
window.addEventListener('resize', UI.updateControlbarHandle); window.addEventListener('resize', UI.updateControlbarHandle);
var exps = document.getElementsByClassName("noVNC_expander"); const exps = document.getElementsByClassName("noVNC_expander");
for (var i = 0;i < exps.length;i++) { for (let i = 0;i < exps.length;i++) {
exps[i].addEventListener('click', UI.toggleExpander); exps[i].addEventListener('click', UI.toggleExpander);
} }
}, },
@ -330,7 +327,7 @@ var UI = {
// Add a call to save settings when the element changes, // Add a call to save settings when the element changes,
// unless the optional parameter changeFunc is used instead. // unless the optional parameter changeFunc is used instead.
addSettingChangeHandler: function(name, changeFunc) { addSettingChangeHandler: function(name, changeFunc) {
var settingElem = document.getElementById("noVNC_setting_" + name); const settingElem = document.getElementById("noVNC_setting_" + name);
if (changeFunc === undefined) { if (changeFunc === undefined) {
changeFunc = function () { UI.saveSetting(name); }; changeFunc = function () { UI.saveSetting(name); };
} }
@ -384,7 +381,7 @@ var UI = {
document.documentElement.classList.remove("noVNC_disconnecting"); document.documentElement.classList.remove("noVNC_disconnecting");
document.documentElement.classList.remove("noVNC_reconnecting"); document.documentElement.classList.remove("noVNC_reconnecting");
let transition_elem = document.getElementById("noVNC_transition_text"); const transition_elem = document.getElementById("noVNC_transition_text");
switch (state) { switch (state) {
case 'init': case 'init':
break; break;
@ -445,7 +442,7 @@ var UI = {
}, },
showStatus: function(text, status_type, time) { showStatus: function(text, status_type, time) {
var statusElem = document.getElementById('noVNC_status'); const statusElem = document.getElementById('noVNC_status');
clearTimeout(UI.statusTimeout); clearTimeout(UI.statusTimeout);
@ -551,15 +548,15 @@ var UI = {
toggleControlbarSide: function () { toggleControlbarSide: function () {
// Temporarily disable animation, if bar is displayed, to avoid weird // Temporarily disable animation, if bar is displayed, to avoid weird
// movement. The transitionend-event will not fire when display=none. // movement. The transitionend-event will not fire when display=none.
var bar = document.getElementById('noVNC_control_bar'); const bar = document.getElementById('noVNC_control_bar');
var barDisplayStyle = window.getComputedStyle(bar).display; const barDisplayStyle = window.getComputedStyle(bar).display;
if (barDisplayStyle !== 'none') { if (barDisplayStyle !== 'none') {
bar.style.transitionDuration = '0s'; bar.style.transitionDuration = '0s';
bar.addEventListener('transitionend', function () { bar.addEventListener('transitionend', function () {
this.style.transitionDuration = ""; }); this.style.transitionDuration = ""; });
} }
var anchor = document.getElementById('noVNC_control_bar_anchor'); const anchor = document.getElementById('noVNC_control_bar_anchor');
if (anchor.classList.contains("noVNC_right")) { if (anchor.classList.contains("noVNC_right")) {
WebUtil.writeSetting('controlbar_pos', 'left'); WebUtil.writeSetting('controlbar_pos', 'left');
anchor.classList.remove("noVNC_right"); anchor.classList.remove("noVNC_right");
@ -573,7 +570,7 @@ var UI = {
}, },
showControlbarHint: function (show) { showControlbarHint: function (show) {
var hint = document.getElementById('noVNC_control_bar_hint'); const hint = document.getElementById('noVNC_control_bar_hint');
if (show) { if (show) {
hint.classList.add("noVNC_active"); hint.classList.add("noVNC_active");
} else { } else {
@ -584,9 +581,9 @@ var UI = {
dragControlbarHandle: function (e) { dragControlbarHandle: function (e) {
if (!UI.controlbarGrabbed) return; if (!UI.controlbarGrabbed) return;
var ptr = getPointerEvent(e); const ptr = getPointerEvent(e);
var anchor = document.getElementById('noVNC_control_bar_anchor'); const anchor = document.getElementById('noVNC_control_bar_anchor');
if (ptr.clientX < (window.innerWidth * 0.1)) { if (ptr.clientX < (window.innerWidth * 0.1)) {
if (anchor.classList.contains("noVNC_right")) { if (anchor.classList.contains("noVNC_right")) {
UI.toggleControlbarSide(); UI.toggleControlbarSide();
@ -600,15 +597,15 @@ var UI = {
if (!UI.controlbarDrag) { if (!UI.controlbarDrag) {
// The goal is to trigger on a certain physical width, the // The goal is to trigger on a certain physical width, the
// devicePixelRatio brings us a bit closer but is not optimal. // devicePixelRatio brings us a bit closer but is not optimal.
var dragThreshold = 10 * (window.devicePixelRatio || 1); const dragThreshold = 10 * (window.devicePixelRatio || 1);
var dragDistance = Math.abs(ptr.clientY - UI.controlbarMouseDownClientY); const dragDistance = Math.abs(ptr.clientY - UI.controlbarMouseDownClientY);
if (dragDistance < dragThreshold) return; if (dragDistance < dragThreshold) return;
UI.controlbarDrag = true; UI.controlbarDrag = true;
} }
var eventY = ptr.clientY - UI.controlbarMouseDownOffsetY; const eventY = ptr.clientY - UI.controlbarMouseDownOffsetY;
UI.moveControlbarHandle(eventY); UI.moveControlbarHandle(eventY);
@ -620,18 +617,18 @@ var UI = {
// Move the handle but don't allow any position outside the bounds // Move the handle but don't allow any position outside the bounds
moveControlbarHandle: function (viewportRelativeY) { moveControlbarHandle: function (viewportRelativeY) {
var handle = document.getElementById("noVNC_control_bar_handle"); const handle = document.getElementById("noVNC_control_bar_handle");
var handleHeight = handle.getBoundingClientRect().height; const handleHeight = handle.getBoundingClientRect().height;
var controlbarBounds = document.getElementById("noVNC_control_bar") const controlbarBounds = document.getElementById("noVNC_control_bar")
.getBoundingClientRect(); .getBoundingClientRect();
var margin = 10; const margin = 10;
// These heights need to be non-zero for the below logic to work // These heights need to be non-zero for the below logic to work
if (handleHeight === 0 || controlbarBounds.height === 0) { if (handleHeight === 0 || controlbarBounds.height === 0) {
return; return;
} }
var newY = viewportRelativeY; let newY = viewportRelativeY;
// Check if the coordinates are outside the control bar // Check if the coordinates are outside the control bar
if (newY < controlbarBounds.top + margin) { if (newY < controlbarBounds.top + margin) {
@ -652,15 +649,15 @@ var UI = {
} }
// The transform needs coordinates that are relative to the parent // The transform needs coordinates that are relative to the parent
var parentRelativeY = newY - controlbarBounds.top; const parentRelativeY = newY - controlbarBounds.top;
handle.style.transform = "translateY(" + parentRelativeY + "px)"; handle.style.transform = "translateY(" + parentRelativeY + "px)";
}, },
updateControlbarHandle: function () { updateControlbarHandle: function () {
// Since the control bar is fixed on the viewport and not the page, // Since the control bar is fixed on the viewport and not the page,
// the move function expects coordinates relative the the viewport. // the move function expects coordinates relative the the viewport.
var handle = document.getElementById("noVNC_control_bar_handle"); const handle = document.getElementById("noVNC_control_bar_handle");
var handleBounds = handle.getBoundingClientRect(); const handleBounds = handle.getBoundingClientRect();
UI.moveControlbarHandle(handleBounds.top); UI.moveControlbarHandle(handleBounds.top);
}, },
@ -682,10 +679,10 @@ var UI = {
controlbarHandleMouseDown: function(e) { controlbarHandleMouseDown: function(e) {
if ((e.type == "mousedown") && (e.button != 0)) return; if ((e.type == "mousedown") && (e.button != 0)) return;
var ptr = getPointerEvent(e); const ptr = getPointerEvent(e);
var handle = document.getElementById("noVNC_control_bar_handle"); const handle = document.getElementById("noVNC_control_bar_handle");
var bounds = handle.getBoundingClientRect(); const bounds = handle.getBoundingClientRect();
// Touch events have implicit capture // Touch events have implicit capture
if (e.type === "mousedown") { if (e.type === "mousedown") {
@ -722,7 +719,7 @@ var UI = {
// Initial page load read/initialization of settings // Initial page load read/initialization of settings
initSetting: function(name, defVal) { initSetting: function(name, defVal) {
// Check Query string followed by cookie // Check Query string followed by cookie
var val = WebUtil.getConfigVar(name); let val = WebUtil.getConfigVar(name);
if (val === null) { if (val === null) {
val = WebUtil.readSetting(name, defVal); val = WebUtil.readSetting(name, defVal);
} }
@ -736,14 +733,14 @@ var UI = {
updateSetting: function(name) { updateSetting: function(name) {
// Update the settings control // Update the settings control
var value = UI.getSetting(name); let value = UI.getSetting(name);
var ctrl = document.getElementById('noVNC_setting_' + name); const ctrl = document.getElementById('noVNC_setting_' + name);
if (ctrl.type === 'checkbox') { if (ctrl.type === 'checkbox') {
ctrl.checked = value; ctrl.checked = value;
} else if (typeof ctrl.options !== 'undefined') { } else if (typeof ctrl.options !== 'undefined') {
for (var i = 0; i < ctrl.options.length; i += 1) { for (let i = 0; i < ctrl.options.length; i += 1) {
if (ctrl.options[i].value === value) { if (ctrl.options[i].value === value) {
ctrl.selectedIndex = i; ctrl.selectedIndex = i;
break; break;
@ -761,7 +758,8 @@ var UI = {
// Save control setting to cookie // Save control setting to cookie
saveSetting: function(name) { saveSetting: function(name) {
var val, ctrl = document.getElementById('noVNC_setting_' + name); const ctrl = document.getElementById('noVNC_setting_' + name);
let val;
if (ctrl.type === 'checkbox') { if (ctrl.type === 'checkbox') {
val = ctrl.checked; val = ctrl.checked;
} else if (typeof ctrl.options !== 'undefined') { } else if (typeof ctrl.options !== 'undefined') {
@ -776,8 +774,8 @@ var UI = {
// Read form control compatible setting from cookie // Read form control compatible setting from cookie
getSetting: function(name) { getSetting: function(name) {
var ctrl = document.getElementById('noVNC_setting_' + name); const ctrl = document.getElementById('noVNC_setting_' + name);
var val = WebUtil.readSetting(name); let val = WebUtil.readSetting(name);
if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
val = false; val = false;
@ -792,13 +790,13 @@ var UI = {
// previous-sibling-selectors in CSS which are needed when we want to // previous-sibling-selectors in CSS which are needed when we want to
// disable the labels that belong to disabled input elements. // disable the labels that belong to disabled input elements.
disableSetting: function(name) { disableSetting: function(name) {
var ctrl = document.getElementById('noVNC_setting_' + name); const ctrl = document.getElementById('noVNC_setting_' + name);
ctrl.disabled = true; ctrl.disabled = true;
ctrl.label.classList.add('noVNC_disabled'); ctrl.label.classList.add('noVNC_disabled');
}, },
enableSetting: function(name) { enableSetting: function(name) {
var ctrl = document.getElementById('noVNC_setting_' + name); const ctrl = document.getElementById('noVNC_setting_' + name);
ctrl.disabled = false; ctrl.disabled = false;
ctrl.label.classList.remove('noVNC_disabled'); ctrl.label.classList.remove('noVNC_disabled');
}, },
@ -951,7 +949,7 @@ var UI = {
}, },
clipboardSend: function() { clipboardSend: function() {
var text = document.getElementById('noVNC_clipboard_text').value; const text = document.getElementById('noVNC_clipboard_text').value;
Log.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "..."); Log.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "...");
UI.rfb.clipboardPasteFrom(text); UI.rfb.clipboardPasteFrom(text);
Log.Debug("<< UI.clipboardSend"); Log.Debug("<< UI.clipboardSend");
@ -980,9 +978,9 @@ var UI = {
return; return;
} }
var host = UI.getSetting('host'); const host = UI.getSetting('host');
var port = UI.getSetting('port'); const port = UI.getSetting('port');
var path = UI.getSetting('path'); const path = UI.getSetting('path');
if (typeof password === 'undefined') { if (typeof password === 'undefined') {
password = WebUtil.getConfigVar('password'); password = WebUtil.getConfigVar('password');
@ -1006,7 +1004,7 @@ var UI = {
UI.updateVisualState('connecting'); UI.updateVisualState('connecting');
var url; let url;
url = UI.getSetting('encrypt') ? 'wss' : 'ws'; url = UI.getSetting('encrypt') ? 'wss' : 'ws';
@ -1090,7 +1088,7 @@ var UI = {
}, },
disconnectFinished: function (e) { disconnectFinished: function (e) {
let wasConnected = UI.connected; const wasConnected = UI.connected;
// This variable is ideally set when disconnection starts, but // This variable is ideally set when disconnection starts, but
// when the disconnection isn't clean or if it is initiated by // when the disconnection isn't clean or if it is initiated by
@ -1111,7 +1109,7 @@ var UI = {
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) { } else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) {
UI.updateVisualState('reconnecting'); UI.updateVisualState('reconnecting');
var delay = parseInt(UI.getSetting('reconnect_delay')); const delay = parseInt(UI.getSetting('reconnect_delay'));
UI.reconnect_callback = setTimeout(UI.reconnect, delay); UI.reconnect_callback = setTimeout(UI.reconnect, delay);
return; return;
} else { } else {
@ -1160,8 +1158,8 @@ var UI = {
// Prevent actually submitting the form // Prevent actually submitting the form
e.preventDefault(); e.preventDefault();
var inputElem = document.getElementById('noVNC_password_input'); const inputElem = document.getElementById('noVNC_password_input');
var password = inputElem.value; const password = inputElem.value;
// Clear the input after reading the password // Clear the input after reading the password
inputElem.value = ""; inputElem.value = "";
UI.rfb.sendCredentials({ password: password }); UI.rfb.sendCredentials({ password: password });
@ -1242,8 +1240,8 @@ var UI = {
updateViewClip: function() { updateViewClip: function() {
if (!UI.rfb) return; if (!UI.rfb) return;
var cur_clip = UI.rfb.clipViewport; const cur_clip = UI.rfb.clipViewport;
var new_clip = UI.getSetting('view_clip'); let new_clip = UI.getSetting('view_clip');
if (isTouchDevice) { if (isTouchDevice) {
// Touch devices usually have shit scrollbars // Touch devices usually have shit scrollbars
@ -1261,7 +1259,7 @@ var UI = {
// Handle special cases where viewport clipping is forced on/off or locked // Handle special cases where viewport clipping is forced on/off or locked
enableDisableViewClip: function() { enableDisableViewClip: function() {
var resizeSetting = UI.getSetting('resize'); const resizeSetting = UI.getSetting('resize');
// Disable clipping if we are scaling, connected or on touch // Disable clipping if we are scaling, connected or on touch
if (resizeSetting === 'scale' || if (resizeSetting === 'scale' ||
isTouchDevice) { isTouchDevice) {
@ -1280,7 +1278,7 @@ var UI = {
toggleViewDrag: function() { toggleViewDrag: function() {
if (!UI.rfb) return; if (!UI.rfb) return;
var drag = UI.rfb.dragViewport; const drag = UI.rfb.dragViewport;
UI.setViewDrag(!drag); UI.setViewDrag(!drag);
}, },
@ -1296,7 +1294,7 @@ var UI = {
updateViewDrag: function() { updateViewDrag: function() {
if (!UI.connected) return; if (!UI.connected) return;
var viewDragButton = document.getElementById('noVNC_view_drag_button'); const viewDragButton = document.getElementById('noVNC_view_drag_button');
if (!UI.rfb.clipViewport && UI.rfb.dragViewport) { if (!UI.rfb.clipViewport && UI.rfb.dragViewport) {
// We are no longer clipping the viewport. Make sure // We are no longer clipping the viewport. Make sure
@ -1340,23 +1338,25 @@ var UI = {
showVirtualKeyboard: function() { showVirtualKeyboard: function() {
if (!isTouchDevice) return; if (!isTouchDevice) return;
var input = document.getElementById('noVNC_keyboardinput'); const input = document.getElementById('noVNC_keyboardinput');
if (document.activeElement == input) return; if (document.activeElement == input) return;
input.focus(); input.focus();
try { try {
var l = input.value.length; const l = input.value.length;
// Move the caret to the end // Move the caret to the end
input.setSelectionRange(l, l); input.setSelectionRange(l, l);
} catch (err) {} // setSelectionRange is undefined in Google Chrome } catch (err) {
// setSelectionRange is undefined in Google Chrome
}
}, },
hideVirtualKeyboard: function() { hideVirtualKeyboard: function() {
if (!isTouchDevice) return; if (!isTouchDevice) return;
var input = document.getElementById('noVNC_keyboardinput'); const input = document.getElementById('noVNC_keyboardinput');
if (document.activeElement != input) return; if (document.activeElement != input) return;
@ -1389,7 +1389,7 @@ var UI = {
}, },
keepVirtualKeyboard: function(event) { keepVirtualKeyboard: function(event) {
var input = document.getElementById('noVNC_keyboardinput'); const input = document.getElementById('noVNC_keyboardinput');
// Only prevent focus change if the virtual keyboard is active // Only prevent focus change if the virtual keyboard is active
if (document.activeElement != input) { if (document.activeElement != input) {
@ -1417,7 +1417,7 @@ var UI = {
}, },
keyboardinputReset: function() { keyboardinputReset: function() {
var kbi = document.getElementById('noVNC_keyboardinput'); const kbi = document.getElementById('noVNC_keyboardinput');
kbi.value = new Array(UI.defaultKeyboardinputLen).join("_"); kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
UI.lastKeyboardinput = kbi.value; UI.lastKeyboardinput = kbi.value;
}, },
@ -1436,14 +1436,14 @@ var UI = {
if (!UI.rfb) return; if (!UI.rfb) return;
var newValue = event.target.value; const newValue = event.target.value;
if (!UI.lastKeyboardinput) { if (!UI.lastKeyboardinput) {
UI.keyboardinputReset(); UI.keyboardinputReset();
} }
var oldValue = UI.lastKeyboardinput; const oldValue = UI.lastKeyboardinput;
var newLen; let newLen;
try { try {
// Try to check caret position since whitespace at the end // Try to check caret position since whitespace at the end
// will not be considered by value.length in some browsers // will not be considered by value.length in some browsers
@ -1452,20 +1452,14 @@ var UI = {
// selectionStart is undefined in Google Chrome // selectionStart is undefined in Google Chrome
newLen = newValue.length; newLen = newValue.length;
} }
var oldLen = oldValue.length; const oldLen = oldValue.length;
var backspaces; let inputs = newLen - oldLen;
var inputs = newLen - oldLen; let backspaces = inputs < 0 ? -inputs : 0;
if (inputs < 0) {
backspaces = -inputs;
} else {
backspaces = 0;
}
// Compare the old string with the new to account for // Compare the old string with the new to account for
// text-corrections or other input that modify existing text // text-corrections or other input that modify existing text
var i; for (let i = 0; i < Math.min(oldLen, newLen); i++) {
for (i = 0; i < Math.min(oldLen, newLen); i++) {
if (newValue.charAt(i) != oldValue.charAt(i)) { if (newValue.charAt(i) != oldValue.charAt(i)) {
inputs = newLen - i; inputs = newLen - i;
backspaces = oldLen - i; backspaces = oldLen - i;
@ -1474,10 +1468,10 @@ var UI = {
} }
// Send the key events // Send the key events
for (i = 0; i < backspaces; i++) { for (let i = 0; i < backspaces; i++) {
UI.rfb.sendKey(KeyTable.XK_BackSpace, "Backspace"); UI.rfb.sendKey(KeyTable.XK_BackSpace, "Backspace");
} }
for (i = newLen - inputs; i < newLen; i++) { for (let i = newLen - inputs; i < newLen; i++) {
UI.rfb.sendKey(keysyms.lookup(newValue.charCodeAt(i))); UI.rfb.sendKey(keysyms.lookup(newValue.charCodeAt(i)));
} }
@ -1540,7 +1534,7 @@ var UI = {
}, },
toggleCtrl: function() { toggleCtrl: function() {
var btn = document.getElementById('noVNC_toggle_ctrl_button'); const btn = document.getElementById('noVNC_toggle_ctrl_button');
if (btn.classList.contains("noVNC_selected")) { if (btn.classList.contains("noVNC_selected")) {
UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false); UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
btn.classList.remove("noVNC_selected"); btn.classList.remove("noVNC_selected");
@ -1551,7 +1545,7 @@ var UI = {
}, },
toggleAlt: function() { toggleAlt: function() {
var btn = document.getElementById('noVNC_toggle_alt_button'); const btn = document.getElementById('noVNC_toggle_alt_button');
if (btn.classList.contains("noVNC_selected")) { if (btn.classList.contains("noVNC_selected")) {
UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false); UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
btn.classList.remove("noVNC_selected"); btn.classList.remove("noVNC_selected");
@ -1572,14 +1566,14 @@ var UI = {
* ------v------*/ * ------v------*/
setMouseButton: function(num) { setMouseButton: function(num) {
var view_only = UI.rfb.viewOnly; const view_only = UI.rfb.viewOnly;
if (UI.rfb && !view_only) { if (UI.rfb && !view_only) {
UI.rfb.touchButton = num; UI.rfb.touchButton = num;
} }
var blist = [0, 1,2,4]; const blist = [0, 1,2,4];
for (var b = 0; b < blist.length; b++) { for (let b = 0; b < blist.length; b++) {
var button = document.getElementById('noVNC_mouse_button' + const button = document.getElementById('noVNC_mouse_button' +
blist[b]); blist[b]);
if (blist[b] === num && !view_only) { if (blist[b] === num && !view_only) {
button.classList.remove("noVNC_hidden"); button.classList.remove("noVNC_hidden");
@ -1620,7 +1614,7 @@ var UI = {
bell: function(e) { bell: function(e) {
if (WebUtil.getConfigVar('bell', 'on') === 'on') { if (WebUtil.getConfigVar('bell', 'on') === 'on') {
var promise = document.getElementById('noVNC_bell').play(); const promise = document.getElementById('noVNC_bell').play();
// The standards disagree on the return value here // The standards disagree on the return value here
if (promise) { if (promise) {
promise.catch(function(e) { promise.catch(function(e) {
@ -1638,7 +1632,7 @@ var UI = {
//Helper to add options to dropdown. //Helper to add options to dropdown.
addOption: function(selectbox, text, value) { addOption: function(selectbox, text, value) {
var optn = document.createElement("OPTION"); const optn = document.createElement("OPTION");
optn.text = text; optn.text = text;
optn.value = value; optn.value = value;
selectbox.options.add(optn); selectbox.options.add(optn);
@ -1651,7 +1645,7 @@ var UI = {
}; };
// Set up translations // Set up translations
var LINGUAS = ["de", "el", "es", "nl", "pl", "sv", "tr", "zh_CN", "zh_TW"]; const LINGUAS = ["de", "el", "es", "nl", "pl", "sv", "tr", "zh_CN", "zh_TW"];
l10n.setup(LINGUAS); l10n.setup(LINGUAS);
if (l10n.language !== "en" && l10n.dictionary === undefined) { if (l10n.language !== "en" && l10n.dictionary === undefined) {
WebUtil.fetchJSON('app/locale/' + l10n.language + '.json', function (translations) { WebUtil.fetchJSON('app/locale/' + l10n.language + '.json', function (translations) {

View File

@ -15,47 +15,51 @@ export function init_logging (level) {
if (typeof level !== "undefined") { if (typeof level !== "undefined") {
main_init_logging(level); main_init_logging(level);
} else { } 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); main_init_logging(param || undefined);
} }
}; }
// Read a query string variable // Read a query string variable
export function getQueryVar (name, defVal) { export function getQueryVar (name, defVal) {
"use strict"; "use strict";
var re = new RegExp('.*[?&]' + name + '=([^&#]*)'), const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
match = document.location.href.match(re); match = document.location.href.match(re);
if (typeof defVal === 'undefined') { defVal = null; } if (typeof defVal === 'undefined') { defVal = null; }
if (match) { if (match) {
return decodeURIComponent(match[1]); return decodeURIComponent(match[1]);
} else {
return defVal;
} }
};
return defVal;
}
// Read a hash fragment variable // Read a hash fragment variable
export function getHashVar (name, defVal) { export function getHashVar (name, defVal) {
"use strict"; "use strict";
var re = new RegExp('.*[&#]' + name + '=([^&]*)'), const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
match = document.location.hash.match(re); match = document.location.hash.match(re);
if (typeof defVal === 'undefined') { defVal = null; } if (typeof defVal === 'undefined') { defVal = null; }
if (match) { if (match) {
return decodeURIComponent(match[1]); return decodeURIComponent(match[1]);
} else {
return defVal;
} }
};
return defVal;
}
// Read a variable from the fragment or the query string // Read a variable from the fragment or the query string
// Fragment takes precedence // Fragment takes precedence
export function getConfigVar (name, defVal) { export function getConfigVar (name, defVal) {
"use strict"; "use strict";
var val = getHashVar(name); const val = getHashVar(name);
if (val === null) { if (val === null) {
val = getQueryVar(name, defVal); return getQueryVar(name, defVal);
} }
return val; return val;
}; }
/* /*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
@ -64,7 +68,7 @@ export function getConfigVar (name, defVal) {
// No days means only for this browser session // No days means only for this browser session
export function createCookie (name, value, days) { export function createCookie (name, value, days) {
"use strict"; "use strict";
var date, expires; let date, expires;
if (days) { if (days) {
date = new Date(); date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
@ -73,42 +77,47 @@ export function createCookie (name, value, days) {
expires = ""; expires = "";
} }
var secure; let secure;
if (document.location.protocol === "https:") { if (document.location.protocol === "https:") {
secure = "; secure"; secure = "; secure";
} else { } else {
secure = ""; secure = "";
} }
document.cookie = name + "=" + value + expires + "; path=/" + secure; document.cookie = name + "=" + value + expires + "; path=/" + secure;
}; }
export function readCookie (name, defaultValue) { export function readCookie (name, defaultValue) {
"use strict"; "use strict";
var nameEQ = name + "=", const nameEQ = name + "=";
ca = document.cookie.split(';'); const ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i += 1) { for (let i = 0; i < ca.length; i += 1) {
var c = ca[i]; let c = ca[i];
while (c.charAt(0) === ' ') { c = c.substring(1, c.length); } while (c.charAt(0) === ' ') {
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); } c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
} }
return (typeof defaultValue !== 'undefined') ? defaultValue : null; return (typeof defaultValue !== 'undefined') ? defaultValue : null;
}; }
export function eraseCookie (name) { export function eraseCookie (name) {
"use strict"; "use strict";
createCookie(name, "", -1); createCookie(name, "", -1);
}; }
/* /*
* Setting handling. * Setting handling.
*/ */
var settings = {}; let settings = {};
export function initSettings (callback /*, ...callbackArgs */) { export function initSettings (callback /*, ...callbackArgs */) {
"use strict"; "use strict";
var callbackArgs = Array.prototype.slice.call(arguments, 1); const callbackArgs = Array.prototype.slice.call(arguments, 1);
if (window.chrome && window.chrome.storage) { if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.get(function (cfg) { window.chrome.storage.sync.get(function (cfg) {
settings = cfg; settings = cfg;
@ -122,12 +131,12 @@ export function initSettings (callback /*, ...callbackArgs */) {
callback.apply(this, callbackArgs); callback.apply(this, callbackArgs);
} }
} }
}; }
// Update the settings cache, but do not write to permanent storage // Update the settings cache, but do not write to permanent storage
export function setSetting (name, value) { export function setSetting (name, value) {
settings[name] = value; settings[name] = value;
}; }
// No days means only for this browser session // No days means only for this browser session
export function writeSetting (name, value) { export function writeSetting (name, value) {
@ -139,11 +148,11 @@ export function writeSetting (name, value) {
} else { } else {
localStorage.setItem(name, value); localStorage.setItem(name, value);
} }
}; }
export function readSetting (name, defaultValue) { export function readSetting (name, defaultValue) {
"use strict"; "use strict";
var value; let value;
if ((name in settings) || (window.chrome && window.chrome.storage)) { if ((name in settings) || (window.chrome && window.chrome.storage)) {
value = settings[name]; value = settings[name];
} else { } else {
@ -153,12 +162,13 @@ export function readSetting (name, defaultValue) {
if (typeof value === "undefined") { if (typeof value === "undefined") {
value = null; value = null;
} }
if (value === null && typeof defaultValue !== "undefined") { if (value === null && typeof defaultValue !== "undefined") {
return defaultValue; return defaultValue;
} else {
return value;
} }
};
return value;
}
export function eraseSetting (name) { export function eraseSetting (name) {
"use strict"; "use strict";
@ -173,18 +183,18 @@ export function eraseSetting (name) {
} else { } else {
localStorage.removeItem(name); localStorage.removeItem(name);
} }
}; }
export function injectParamIfMissing (path, param, value) { export function injectParamIfMissing (path, param, value) {
// force pretend that we're dealing with a relative path // force pretend that we're dealing with a relative path
// (assume that we wanted an extra if we pass one in) // (assume that we wanted an extra if we pass one in)
path = "/" + path; path = "/" + path;
var elem = document.createElement('a'); const elem = document.createElement('a');
elem.href = path; elem.href = path;
var param_eq = encodeURIComponent(param) + "="; const param_eq = encodeURIComponent(param) + "=";
var query; let query;
if (elem.search) { if (elem.search) {
query = elem.search.slice(1).split('&'); query = elem.search.slice(1).split('&');
} else { } else {
@ -200,10 +210,10 @@ export function injectParamIfMissing (path, param, value) {
// in the elem.pathname string. Handle that case gracefully. // in the elem.pathname string. Handle that case gracefully.
if (elem.pathname.charAt(0) == "/") { if (elem.pathname.charAt(0) == "/") {
return elem.pathname.slice(1) + elem.search + elem.hash; return elem.pathname.slice(1) + elem.search + elem.hash;
} else {
return elem.pathname + elem.search + elem.hash;
} }
};
return elem.pathname + elem.search + elem.hash;
}
// sadly, we can't use the Fetch API until we decide to drop // sadly, we can't use the Fetch API until we decide to drop
// IE11 support or polyfill promises and fetch in IE11. // IE11 support or polyfill promises and fetch in IE11.
@ -211,16 +221,16 @@ export function injectParamIfMissing (path, param, value) {
// will receive either an event or an error on failure. // will receive either an event or an error on failure.
export function fetchJSON(path, resolve, reject) { export function fetchJSON(path, resolve, reject) {
// NB: IE11 doesn't support JSON as a responseType // NB: IE11 doesn't support JSON as a responseType
var req = new XMLHttpRequest(); const req = new XMLHttpRequest();
req.open('GET', path); req.open('GET', path);
req.onload = function () { req.onload = function () {
if (req.status === 200) { if (req.status === 200) {
let resObj;
try { try {
var resObj = JSON.parse(req.responseText); resObj = JSON.parse(req.responseText);
} catch (err) { } catch (err) {
reject(err); reject(err);
return;
} }
resolve(resObj); resolve(resObj);
} else { } else {

View File

@ -13,33 +13,30 @@ export default {
encode: function (data) { encode: function (data) {
"use strict"; "use strict";
var result = ''; let result = '';
var toBase64Table = this.toBase64Table; const length = data.length;
var length = data.length; const lengthpad = (length % 3);
var lengthpad = (length % 3);
// Convert every three bytes to 4 ascii characters. // Convert every three bytes to 4 ascii characters.
for (var i = 0; i < (length - 2); i += 3) { for (let i = 0; i < (length - 2); i += 3) {
result += toBase64Table[data[i] >> 2]; result += this.toBase64Table[data[i] >> 2];
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
result += toBase64Table[data[i + 2] & 0x3f]; result += this.toBase64Table[data[i + 2] & 0x3f];
} }
// Convert the remaining 1 or 2 bytes, pad out to 4 characters. // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
var j = 0; const j = length - lengthpad;
if (lengthpad === 2) { if (lengthpad === 2) {
j = length - lengthpad; result += this.toBase64Table[data[j] >> 2];
result += toBase64Table[data[j] >> 2]; result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)]; result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
result += toBase64Table[(data[j + 1] & 0x0f) << 2]; result += this.toBase64Table[64];
result += toBase64Table[64];
} else if (lengthpad === 1) { } else if (lengthpad === 1) {
j = length - lengthpad; result += this.toBase64Table[data[j] >> 2];
result += toBase64Table[data[j] >> 2]; result += this.toBase64Table[(data[j] & 0x03) << 4];
result += toBase64Table[(data[j] & 0x03) << 4]; result += this.toBase64Table[64];
result += toBase64Table[64]; result += this.toBase64Table[64];
result += toBase64Table[64];
} }
return result; return result;
@ -60,23 +57,21 @@ export default {
decode: function (data, offset) { decode: function (data, offset) {
"use strict"; "use strict";
offset = typeof(offset) !== 'undefined' ? offset : 0; 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 data_length = data.indexOf('=') - offset;
if (data_length < 0) { data_length = data.length - offset; } if (data_length < 0) { data_length = data.length - offset; }
/* Every four characters is 3 resulting numbers */ /* Every four characters is 3 resulting numbers */
result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5); const result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
result = new Array(result_length); const result = new Array(result_length);
// Convert one by one. // Convert one by one.
for (var idx = 0, i = offset; i < data.length; i++) {
var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; let leftbits = 0; // number of bits decoded, but yet to be appended
var padding = (data.charAt(i) === base64Pad); let leftdata = 0; // bits decoded, but yet to be appended
for (let idx = 0, i = offset; i < data.length; i++) {
const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
const padding = (data.charAt(i) === this.base64Pad);
// Skip illegal characters and whitespace // Skip illegal characters and whitespace
if (c === -1) { if (c === -1) {
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i); Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
@ -100,7 +95,7 @@ export default {
// If there are any bits left, the base64 string was corrupted // If there are any bits left, the base64 string was corrupted
if (leftbits) { if (leftbits) {
err = new Error('Corrupted base64 string'); const err = new Error('Corrupted base64 string');
err.name = 'Base64-Error'; err.name = 'Base64-Error';
throw err; throw err;
} }

View File

@ -79,80 +79,76 @@ export default function DES(passwd) {
"use strict"; "use strict";
// Tables, permutations, S-boxes, etc. // Tables, permutations, S-boxes, etc.
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, 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 ], 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], 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, z = 0x0,
keys = []; keys = [];
let a,b,c,d,e,f;
a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e; 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, 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, 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]; 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; 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, 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|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]; 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; 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, 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, 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]; 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; 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, 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, 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]; 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; 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, 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, 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]; 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; 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, 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, 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|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; 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|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, 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]; 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; 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, 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, 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]; 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];
// Set the key. // Set the key.
function setKeys(keyBlock) { function setKeys(keyBlock) {
var i, j, l, m, n, o, pc1m = [], pcr = [], kn = [], const pc1m = [], pcr = [], kn = [];
raw0, raw1, rawi, KnLi;
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 l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
m = l & 0x7; const m = l & 0x7;
pc1m[j] = ((keyBlock[l >>> 3] & (1<<m)) !== 0) ? 1: 0; 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; const m = i << 1;
n = m + 1; const n = m + 1;
kn[m] = kn[n] = 0; kn[m] = kn[n] = 0;
for (o = 28; o < 59; o += 28) { for (let o = 28; o < 59; o += 28) {
for (j = o - 28; j < o; ++j) { for (let j = o - 28; j < o; ++j) {
l = j + totrot[i]; const l = j + totrot[i];
if (l < o) { pcr[j] = l < o ? pc1m[l] : pc1m[l - 28];
pcr[j] = pc1m[l];
} else {
pcr[j] = pc1m[l - 28];
}
} }
} }
for (j = 0; j < 24; ++j) { for (let j = 0; j < 24; ++j) {
if (pcr[PC2[j]] !== 0) { if (pcr[PC2[j]] !== 0) {
kn[m] |= 1 << (23 - j); kn[m] |= 1 << (23 - j);
} }
@ -163,9 +159,9 @@ export default function DES(passwd) {
} }
// cookey // cookey
for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) { for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
raw0 = kn[rawi++]; const raw0 = kn[rawi++];
raw1 = kn[rawi++]; const raw1 = kn[rawi++];
keys[KnLi] = (raw0 & 0x00fc0000) << 6; keys[KnLi] = (raw0 & 0x00fc0000) << 6;
keys[KnLi] |= (raw0 & 0x00000fc0) << 10; keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10; keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
@ -181,8 +177,8 @@ export default function DES(passwd) {
// Encrypt 8 bytes of text // Encrypt 8 bytes of text
function enc8(text) { function enc8(text) {
var i = 0, b = text.slice(), fval, keysi = 0, const b = text.slice();
l, r, x; // left, right, accumulator let i = 0, l, r, x; // left, right, accumulator
// Squash 8 bytes to 2 ints // Squash 8 bytes to 2 ints
l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
@ -206,10 +202,10 @@ export default function DES(passwd) {
r ^= x; r ^= x;
l = (l << 1) | ((l >>> 31) & 1); l = (l << 1) | ((l >>> 31) & 1);
for (i = 0; i < 8; ++i) { for (let i = 0, keysi = 0; i < 8; ++i) {
x = (r << 28) | (r >>> 4); x = (r << 28) | (r >>> 4);
x ^= keys[keysi++]; x ^= keys[keysi++];
fval = SP7[x & 0x3f]; let fval = SP7[x & 0x3f];
fval |= SP5[(x >>> 8) & 0x3f]; fval |= SP5[(x >>> 8) & 0x3f];
fval |= SP3[(x >>> 16) & 0x3f]; fval |= SP3[(x >>> 16) & 0x3f];
fval |= SP1[(x >>> 24) & 0x3f]; fval |= SP1[(x >>> 24) & 0x3f];
@ -268,4 +264,4 @@ export default function DES(passwd) {
setKeys(passwd); // Setup keys setKeys(passwd); // Setup keys
return {'encrypt': encrypt}; // Public interface return {'encrypt': encrypt}; // Public interface
}; // function DES }

View File

@ -68,9 +68,9 @@ export default function Display(target) {
this._tile16x16 = this._drawCtx.createImageData(16, 16); this._tile16x16 = this._drawCtx.createImageData(16, 16);
Log.Debug("<< Display.constructor"); Log.Debug("<< Display.constructor");
}; }
var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false; let SUPPORTS_IMAGEDATA_CONSTRUCTOR = false;
try { try {
new ImageData(new Uint8ClampedArray(4), 1, 1); new ImageData(new Uint8ClampedArray(4), 1, 1);
SUPPORTS_IMAGEDATA_CONSTRUCTOR = true; SUPPORTS_IMAGEDATA_CONSTRUCTOR = true;
@ -92,7 +92,7 @@ Display.prototype = {
set clipViewport(viewport) { set clipViewport(viewport) {
this._clipViewport = viewport; this._clipViewport = viewport;
// May need to readjust the viewport dimensions // May need to readjust the viewport dimensions
var vp = this._viewportLoc; const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h); this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0); this.viewportChangePos(0, 0);
}, },
@ -113,7 +113,7 @@ Display.prototype = {
// ===== PUBLIC METHODS ===== // ===== PUBLIC METHODS =====
viewportChangePos: function (deltaX, deltaY) { viewportChangePos: function (deltaX, deltaY) {
var vp = this._viewportLoc; const vp = this._viewportLoc;
deltaX = Math.floor(deltaX); deltaX = Math.floor(deltaX);
deltaY = Math.floor(deltaY); deltaY = Math.floor(deltaY);
@ -122,8 +122,8 @@ Display.prototype = {
deltaY = -vp.h; deltaY = -vp.h;
} }
var vx2 = vp.x + vp.w - 1; const vx2 = vp.x + vp.w - 1;
var vy2 = vp.y + vp.h - 1; const vy2 = vp.y + vp.h - 1;
// Position change // Position change
@ -172,12 +172,12 @@ Display.prototype = {
height = this._fb_height; height = this._fb_height;
} }
var vp = this._viewportLoc; const vp = this._viewportLoc;
if (vp.w !== width || vp.h !== height) { if (vp.w !== width || vp.h !== height) {
vp.w = width; vp.w = width;
vp.h = height; vp.h = height;
var canvas = this._target; const canvas = this._target;
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
@ -206,11 +206,11 @@ Display.prototype = {
this._fb_width = width; this._fb_width = width;
this._fb_height = height; this._fb_height = height;
var canvas = this._backbuffer; const canvas = this._backbuffer;
if (canvas.width !== width || canvas.height !== height) { if (canvas.width !== width || canvas.height !== height) {
// We have to save the canvas data since changing the size will clear it // 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) { if (canvas.width > 0 && canvas.height > 0) {
saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height); saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
} }
@ -229,7 +229,7 @@ Display.prototype = {
// Readjust the viewport as it may be incorrectly sized // Readjust the viewport as it may be incorrectly sized
// and positioned // and positioned
var vp = this._viewportLoc; const vp = this._viewportLoc;
this.viewportChangeSize(vp.w, vp.h); this.viewportChangeSize(vp.w, vp.h);
this.viewportChangePos(0, 0); this.viewportChangePos(0, 0);
}, },
@ -258,15 +258,13 @@ Display.prototype = {
'type': 'flip' 'type': 'flip'
}); });
} else { } else {
var x, y, vx, vy, w, h; let x = this._damageBounds.left;
let y = this._damageBounds.top;
let w = this._damageBounds.right - x;
let h = this._damageBounds.bottom - y;
x = this._damageBounds.left; let vx = x - this._viewportLoc.x;
y = this._damageBounds.top; let vy = y - this._viewportLoc.y;
w = this._damageBounds.right - x;
h = this._damageBounds.bottom - y;
vx = x - this._viewportLoc.x;
vy = y - this._viewportLoc.y;
if (vx < 0) { if (vx < 0) {
w += vx; w += vx;
@ -372,7 +370,7 @@ Display.prototype = {
}, },
imageRect: function(x, y, mime, arr) { imageRect: function(x, y, mime, arr) {
var img = new Image(); const img = new Image();
img.src = "data: " + mime + ";base64," + Base64.encode(arr); img.src = "data: " + mime + ";base64," + Base64.encode(arr);
this._renderQ_push({ this._renderQ_push({
'type': 'img', 'type': 'img',
@ -392,12 +390,12 @@ Display.prototype = {
this._tile = this._drawCtx.createImageData(width, height); this._tile = this._drawCtx.createImageData(width, height);
} }
var red = color[2]; const red = color[2];
var green = color[1]; const green = color[1];
var blue = color[0]; const blue = color[0];
var data = this._tile.data; const data = this._tile.data;
for (var i = 0; i < width * height * 4; i += 4) { for (let i = 0; i < width * height * 4; i += 4) {
data[i] = red; data[i] = red;
data[i + 1] = green; data[i + 1] = green;
data[i + 2] = blue; data[i + 2] = blue;
@ -407,17 +405,17 @@ Display.prototype = {
// update sub-rectangle of the current tile // update sub-rectangle of the current tile
subTile: function (x, y, w, h, color) { subTile: function (x, y, w, h, color) {
var red = color[2]; const red = color[2];
var green = color[1]; const green = color[1];
var blue = color[0]; const blue = color[0];
var xend = x + w; const xend = x + w;
var yend = y + h; const yend = y + h;
var data = this._tile.data; const data = this._tile.data;
var width = this._tile.width; const width = this._tile.width;
for (var j = y; j < yend; j++) { for (let j = y; j < yend; j++) {
for (var i = x; i < xend; i++) { for (let i = x; i < xend; i++) {
var p = (i + (j * width)) * 4; const p = (i + (j * width)) * 4;
data[p] = red; data[p] = red;
data[p + 1] = green; data[p + 1] = green;
data[p + 2] = blue; data[p + 2] = blue;
@ -438,7 +436,7 @@ Display.prototype = {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // 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, // 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 // 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)); new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({ this._renderQ_push({
'type': 'blit', 'type': 'blit',
@ -458,7 +456,7 @@ Display.prototype = {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // 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, // 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 // 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)); new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({ this._renderQ_push({
'type': 'blitRgb', 'type': 'blitRgb',
@ -478,7 +476,7 @@ Display.prototype = {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // 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, // 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 // 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)); new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
this._renderQ_push({ this._renderQ_push({
'type': 'blitRgbx', 'type': 'blitRgbx',
@ -511,11 +509,11 @@ Display.prototype = {
}, },
autoscale: function (containerWidth, containerHeight) { autoscale: function (containerWidth, containerHeight) {
var vp = this._viewportLoc; const vp = this._viewportLoc;
var targetAspectRatio = containerWidth / containerHeight; const targetAspectRatio = containerWidth / containerHeight;
var fbAspectRatio = vp.w / vp.h; const fbAspectRatio = vp.w / vp.h;
var scaleRatio; let scaleRatio;
if (fbAspectRatio >= targetAspectRatio) { if (fbAspectRatio >= targetAspectRatio) {
scaleRatio = containerWidth / vp.w; scaleRatio = containerWidth / vp.w;
} else { } else {
@ -529,14 +527,14 @@ Display.prototype = {
_rescale: function (factor) { _rescale: function (factor) {
this._scale = factor; this._scale = factor;
var vp = this._viewportLoc; const vp = this._viewportLoc;
// NB(directxman12): If you set the width directly, or set the // NB(directxman12): If you set the width directly, or set the
// style width to a number, the canvas is cleared. // style width to a number, the canvas is cleared.
// However, if you set the style width to a string // However, if you set the style width to a string
// ('NNNpx'), the canvas is scaled without clearing. // ('NNNpx'), the canvas is scaled without clearing.
var width = Math.round(factor * vp.w) + 'px'; const width = Math.round(factor * vp.w) + 'px';
var height = Math.round(factor * vp.h) + 'px'; const height = Math.round(factor * vp.h) + 'px';
if ((this._target.style.width !== width) || if ((this._target.style.width !== width) ||
(this._target.style.height !== height)) { (this._target.style.height !== height)) {
@ -546,7 +544,7 @@ Display.prototype = {
}, },
_setFillColor: function (color) { _setFillColor: function (color) {
var newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')'; const newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
if (newStyle !== this._prevDrawStyle) { if (newStyle !== this._prevDrawStyle) {
this._drawCtx.fillStyle = newStyle; this._drawCtx.fillStyle = newStyle;
this._prevDrawStyle = newStyle; this._prevDrawStyle = newStyle;
@ -554,9 +552,9 @@ Display.prototype = {
}, },
_rgbImageData: function (x, y, width, height, arr, offset) { _rgbImageData: function (x, y, width, height, arr, offset) {
var img = this._drawCtx.createImageData(width, height); const img = this._drawCtx.createImageData(width, height);
var data = img.data; const data = img.data;
for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) { for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
data[i] = arr[j]; data[i] = arr[j];
data[i + 1] = arr[j + 1]; data[i + 1] = arr[j + 1];
data[i + 2] = arr[j + 2]; data[i + 2] = arr[j + 2];
@ -567,9 +565,9 @@ Display.prototype = {
}, },
_bgrxImageData: function (x, y, width, height, arr, offset) { _bgrxImageData: function (x, y, width, height, arr, offset) {
var img = this._drawCtx.createImageData(width, height); const img = this._drawCtx.createImageData(width, height);
var data = img.data; const data = img.data;
for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 4) { for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
data[i] = arr[j + 2]; data[i] = arr[j + 2];
data[i + 1] = arr[j + 1]; data[i + 1] = arr[j + 1];
data[i + 2] = arr[j]; data[i + 2] = arr[j];
@ -581,7 +579,7 @@ Display.prototype = {
_rgbxImageData: function (x, y, width, height, arr, offset) { _rgbxImageData: function (x, y, width, height, arr, offset) {
// NB(directxman12): arr must be an Type Array view // NB(directxman12): arr must be an Type Array view
var img; let img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) { if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height); img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
} else { } else {
@ -609,9 +607,9 @@ Display.prototype = {
}, },
_scan_renderQ: function () { _scan_renderQ: function () {
var ready = true; let ready = true;
while (ready && this._renderQ.length > 0) { while (ready && this._renderQ.length > 0) {
var a = this._renderQ[0]; const a = this._renderQ[0];
switch (a.type) { switch (a.type) {
case 'flip': case 'flip':
this.flip(true); this.flip(true);
@ -663,12 +661,11 @@ Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
return; return;
} }
var cur = [] const cur = []
var y, x; for (let y = 0; y < h; y++) {
for (y = 0; y < h; y++) { for (let x = 0; x < w; x++) {
for (x = 0; x < w; x++) { let idx = y * Math.ceil(w / 8) + Math.floor(x / 8);
var idx = y * Math.ceil(w / 8) + Math.floor(x / 8); const alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
var alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
idx = ((w * y) + x) * 4; idx = ((w * y) + x) * 4;
cur.push(pixels[idx + 2]); // red cur.push(pixels[idx + 2]); // red
cur.push(pixels[idx + 1]); // green cur.push(pixels[idx + 1]); // green
@ -677,13 +674,13 @@ Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
} }
} }
var canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
canvas.width = w; canvas.width = w;
canvas.height = h; canvas.height = h;
var img; let img;
if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) { if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) {
img = new ImageData(new Uint8ClampedArray(cur), w, h); img = new ImageData(new Uint8ClampedArray(cur), w, h);
} else { } else {
@ -693,6 +690,6 @@ Display.changeCursor = function (target, pixels, mask, hotx, hoty, w, h) {
ctx.clearRect(0, 0, w, h); ctx.clearRect(0, 0, w, h);
ctx.putImageData(img, 0, 0); ctx.putImageData(img, 0, 0);
var url = canvas.toDataURL(); const url = canvas.toDataURL();
target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default';
}; };

View File

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

View File

@ -35,4 +35,4 @@ export default function Inflate() {
this.windowBits = 5; this.windowBits = 5;
inflateInit(this.strm, this.windowBits); 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. * See https://www.w3.org/TR/uievents-key/ for possible values.
*/ */
var DOMKeyTable = {}; const DOMKeyTable = {};
function addStandard(key, standard) function addStandard(key, standard)
{ {

View File

@ -31,7 +31,7 @@ export default function Keyboard(target) {
'blur': this._allKeysUp.bind(this), 'blur': this._allKeysUp.bind(this),
'checkalt': this._checkAlt.bind(this), 'checkalt': this._checkAlt.bind(this),
}; };
}; }
Keyboard.prototype = { Keyboard.prototype = {
// ===== EVENT HANDLERS ===== // ===== EVENT HANDLERS =====
@ -57,7 +57,7 @@ Keyboard.prototype = {
}, },
_getKeyCode: function (e) { _getKeyCode: function (e) {
var code = KeyboardUtil.getKeycode(e); const code = KeyboardUtil.getKeycode(e);
if (code !== 'Unidentified') { if (code !== 'Unidentified') {
return code; return code;
} }
@ -80,10 +80,8 @@ Keyboard.prototype = {
return e.keyIdentifier; return e.keyIdentifier;
} }
var codepoint = parseInt(e.keyIdentifier.substr(2), 16); const codepoint = parseInt(e.keyIdentifier.substr(2), 16);
var char = String.fromCharCode(codepoint); const char = String.fromCharCode(codepoint).toUpperCase();
// Some implementations fail to uppercase the symbols
char = char.toUpperCase();
return 'Platform' + char.charCodeAt(); return 'Platform' + char.charCodeAt();
} }
@ -92,8 +90,8 @@ Keyboard.prototype = {
}, },
_handleKeyDown: function (e) { _handleKeyDown: function (e) {
var code = this._getKeyCode(e); const code = this._getKeyCode(e);
var keysym = KeyboardUtil.getKeysym(e); let keysym = KeyboardUtil.getKeysym(e);
// Windows doesn't have a proper AltGr, but handles it using // Windows doesn't have a proper AltGr, but handles it using
// fake Ctrl+Alt. However the remote end might not be Windows, // fake Ctrl+Alt. However the remote end might not be Windows,
@ -211,8 +209,8 @@ Keyboard.prototype = {
return; return;
} }
var code = this._getKeyCode(e); let code = this._getKeyCode(e);
var keysym = KeyboardUtil.getKeysym(e); const keysym = KeyboardUtil.getKeysym(e);
// The key we were waiting for? // The key we were waiting for?
if ((code !== 'Unidentified') && (code != this._pendingKey)) { if ((code !== 'Unidentified') && (code != this._pendingKey)) {
@ -235,9 +233,9 @@ Keyboard.prototype = {
return; return;
} }
var code, keysym; let keysym;
code = this._pendingKey; const code = this._pendingKey;
this._pendingKey = null; this._pendingKey = null;
// We have no way of knowing the proper keysym with the // We have no way of knowing the proper keysym with the
@ -248,7 +246,7 @@ Keyboard.prototype = {
keysym = e.keyCode; keysym = e.keyCode;
} else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) { } else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) {
// Character (A-Z) // Character (A-Z)
var char = String.fromCharCode(e.keyCode); let char = String.fromCharCode(e.keyCode);
// A feeble attempt at the correct case // A feeble attempt at the correct case
if (e.shiftKey) if (e.shiftKey)
char = char.toUpperCase(); char = char.toUpperCase();
@ -266,7 +264,7 @@ Keyboard.prototype = {
_handleKeyUp: function (e) { _handleKeyUp: function (e) {
stopEvent(e); stopEvent(e);
var code = this._getKeyCode(e); const code = this._getKeyCode(e);
// We can't get a release in the middle of an AltGr sequence, so // We can't get a release in the middle of an AltGr sequence, so
// abort that detection // abort that detection
@ -294,9 +292,9 @@ Keyboard.prototype = {
_allKeysUp: function () { _allKeysUp: function () {
Log.Debug(">> Keyboard.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._sendKeyEvent(this._keyDownList[code], code, false);
}; }
Log.Debug("<< Keyboard.allKeysUp"); Log.Debug("<< Keyboard.allKeysUp");
}, },
@ -306,14 +304,14 @@ Keyboard.prototype = {
return; return;
} }
let target = this._target; const target = this._target;
let downList = this._keyDownList; const downList = this._keyDownList;
['AltLeft', 'AltRight'].forEach(function (code) { ['AltLeft', 'AltRight'].forEach(function (code) {
if (!(code in downList)) { if (!(code in downList)) {
return; return;
} }
let event = new KeyboardEvent('keyup', const event = new KeyboardEvent('keyup',
{ key: downList[code], { key: downList[code],
code: code }); code: code });
target.dispatchEvent(event); target.dispatchEvent(event);
@ -324,11 +322,10 @@ Keyboard.prototype = {
grab: function () { grab: function () {
//Log.Debug(">> Keyboard.grab"); //Log.Debug(">> Keyboard.grab");
var c = this._target;
c.addEventListener('keydown', this._eventHandlers.keydown); this._target.addEventListener('keydown', this._eventHandlers.keydown);
c.addEventListener('keyup', this._eventHandlers.keyup); this._target.addEventListener('keyup', this._eventHandlers.keyup);
c.addEventListener('keypress', this._eventHandlers.keypress); this._target.addEventListener('keypress', this._eventHandlers.keypress);
// Release (key up) if window loses focus // Release (key up) if window loses focus
window.addEventListener('blur', this._eventHandlers.blur); window.addEventListener('blur', this._eventHandlers.blur);
@ -337,7 +334,7 @@ Keyboard.prototype = {
// best we can for releases (still doesn't prevent the menu // best we can for releases (still doesn't prevent the menu
// from popping up though as we can't call preventDefault()) // from popping up though as we can't call preventDefault())
if (browser.isWindows() && browser.isFirefox()) { if (browser.isWindows() && browser.isFirefox()) {
let handler = this._eventHandlers.checkalt; const handler = this._eventHandlers.checkalt;
['mousedown', 'mouseup', 'mousemove', 'wheel', ['mousedown', 'mouseup', 'mousemove', 'wheel',
'touchstart', 'touchend', 'touchmove', 'touchstart', 'touchend', 'touchmove',
'keydown', 'keyup'].forEach(function (type) { 'keydown', 'keyup'].forEach(function (type) {
@ -352,10 +349,9 @@ Keyboard.prototype = {
ungrab: function () { ungrab: function () {
//Log.Debug(">> Keyboard.ungrab"); //Log.Debug(">> Keyboard.ungrab");
var c = this._target;
if (browser.isWindows() && browser.isFirefox()) { if (browser.isWindows() && browser.isFirefox()) {
let handler = this._eventHandlers.checkalt; const handler = this._eventHandlers.checkalt;
['mousedown', 'mouseup', 'mousemove', 'wheel', ['mousedown', 'mouseup', 'mousemove', 'wheel',
'touchstart', 'touchend', 'touchmove', 'touchstart', 'touchend', 'touchmove',
'keydown', 'keyup'].forEach(function (type) { 'keydown', 'keyup'].forEach(function (type) {
@ -363,9 +359,9 @@ Keyboard.prototype = {
}); });
} }
c.removeEventListener('keydown', this._eventHandlers.keydown); this._target.removeEventListener('keydown', this._eventHandlers.keydown);
c.removeEventListener('keyup', this._eventHandlers.keyup); this._target.removeEventListener('keyup', this._eventHandlers.keyup);
c.removeEventListener('keypress', this._eventHandlers.keypress); this._target.removeEventListener('keypress', this._eventHandlers.keypress);
window.removeEventListener('blur', this._eventHandlers.blur); window.removeEventListener('blur', this._eventHandlers.blur);
// Release (key up) all keys that are in a down state // Release (key up) all keys that are in a down state

View File

@ -7,7 +7,7 @@
/* Functions at the bottom */ /* Functions at the bottom */
var codepoints = { const codepoints = {
0x0100: 0x03c0, // XK_Amacron 0x0100: 0x03c0, // XK_Amacron
0x0101: 0x03e0, // XK_amacron 0x0101: 0x03e0, // XK_amacron
0x0102: 0x01c3, // XK_Abreve 0x0102: 0x01c3, // XK_Abreve
@ -677,7 +677,7 @@ export default {
} }
// Lookup table (fairly random) // Lookup table (fairly random)
var keysym = codepoints[u]; const keysym = codepoints[u];
if (keysym !== undefined) { if (keysym !== undefined) {
return keysym; return keysym;
} }

View File

@ -9,9 +9,9 @@ import * as Log from '../util/logging.js';
import { isTouchDevice } from '../util/browser.js'; import { isTouchDevice } from '../util/browser.js';
import { setCapture, stopEvent, getPointerEvent } from '../util/events.js'; import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
var WHEEL_STEP = 10; // Delta threshold for a mouse wheel step const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
var WHEEL_STEP_TIMEOUT = 50; // ms const WHEEL_STEP_TIMEOUT = 50; // ms
var WHEEL_LINE_HEIGHT = 19; const WHEEL_LINE_HEIGHT = 19;
export default function Mouse(target) { export default function Mouse(target) {
this._target = target || document; this._target = target || document;
@ -32,7 +32,7 @@ export default function Mouse(target) {
'mousewheel': this._handleMouseWheel.bind(this), 'mousewheel': this._handleMouseWheel.bind(this),
'mousedisable': this._handleMouseDisable.bind(this) 'mousedisable': this._handleMouseDisable.bind(this)
}; };
}; }
Mouse.prototype = { Mouse.prototype = {
// ===== PROPERTIES ===== // ===== PROPERTIES =====
@ -52,9 +52,9 @@ Mouse.prototype = {
_handleMouseButton: function (e, down) { _handleMouseButton: function (e, down) {
this._updateMousePosition(e); this._updateMousePosition(e);
var pos = this._pos; let pos = this._pos;
var bmask; let bmask;
if (e.touches || e.changedTouches) { if (e.touches || e.changedTouches) {
// Touch device // Touch device
@ -70,13 +70,13 @@ Mouse.prototype = {
// force the position of the latter touch to the position of // force the position of the latter touch to the position of
// the first. // the first.
var xs = this._lastTouchPos.x - pos.x; const xs = this._lastTouchPos.x - pos.x;
var ys = this._lastTouchPos.y - pos.y; const ys = this._lastTouchPos.y - pos.y;
var d = Math.sqrt((xs * xs) + (ys * ys)); const d = Math.sqrt((xs * xs) + (ys * ys));
// The goal is to trigger on a certain physical width, the // The goal is to trigger on a certain physical width, the
// devicePixelRatio brings us a bit closer but is not optimal. // 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) { if (d < threshold) {
pos = this._lastTouchPos; pos = this._lastTouchPos;
} }
@ -156,8 +156,8 @@ Mouse.prototype = {
this._updateMousePosition(e); this._updateMousePosition(e);
var dX = e.deltaX; let dX = e.deltaX;
var dY = e.deltaY; let dY = e.deltaY;
// Pixel units unless it's non-zero. // Pixel units unless it's non-zero.
// Note that if deltamode is line or page won't matter since we aren't // Note that if deltamode is line or page won't matter since we aren't
@ -215,8 +215,9 @@ Mouse.prototype = {
// Update coordinates relative to target // Update coordinates relative to target
_updateMousePosition: function(e) { _updateMousePosition: function(e) {
e = getPointerEvent(e); e = getPointerEvent(e);
var bounds = this._target.getBoundingClientRect(); const bounds = this._target.getBoundingClientRect();
var x, y; let x;
let y;
// Clip to target bounds // Clip to target bounds
if (e.clientX < bounds.left) { if (e.clientX < bounds.left) {
x = 0; x = 0;
@ -238,7 +239,7 @@ Mouse.prototype = {
// ===== PUBLIC METHODS ===== // ===== PUBLIC METHODS =====
grab: function () { grab: function () {
var c = this._target; const c = this._target;
if (isTouchDevice) { if (isTouchDevice) {
c.addEventListener('touchstart', this._eventHandlers.mousedown); c.addEventListener('touchstart', this._eventHandlers.mousedown);
@ -259,7 +260,7 @@ Mouse.prototype = {
}, },
ungrab: function () { ungrab: function () {
var c = this._target; const c = this._target;
this._resetWheelStepTimers(); this._resetWheelStepTimers();

View File

@ -1,4 +1,3 @@
import KeyTable from "./keysym.js";
import keysyms from "./keysymdef.js"; import keysyms from "./keysymdef.js";
import vkeys from "./vkeys.js"; import vkeys from "./vkeys.js";
import fixedkeys from "./fixedkeys.js"; import fixedkeys from "./fixedkeys.js";
@ -25,7 +24,7 @@ export function getKeycode(evt){
// in the 'keyCode' field for non-printable characters. However // in the 'keyCode' field for non-printable characters. However
// Webkit sets it to the same as charCode in 'keypress' events. // Webkit sets it to the same as charCode in 'keypress' events.
if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) { 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 // macOS has messed up this code for some reason
if (browser.isMac() && (code === 'ContextMenu')) { if (browser.isMac() && (code === 'ContextMenu')) {
@ -111,7 +110,7 @@ export function getKey(evt) {
} }
// Try to deduce it based on the physical key // Try to deduce it based on the physical key
var code = getKeycode(evt); const code = getKeycode(evt);
if (code in fixedkeys) { if (code in fixedkeys) {
return fixedkeys[code]; return fixedkeys[code];
} }
@ -127,7 +126,7 @@ export function getKey(evt) {
// Get the most reliable keysym value we can get from a key event // Get the most reliable keysym value we can get from a key event
export function getKeysym(evt){ export function getKeysym(evt){
var key = getKey(evt); const key = getKey(evt);
if (key === 'Unidentified') { if (key === 'Unidentified') {
return null; return null;
@ -135,7 +134,7 @@ export function getKeysym(evt){
// First look up special keys // First look up special keys
if (key in DOMKeyTable) { if (key in DOMKeyTable) {
var location = evt.location; let location = evt.location;
// Safari screws up location for the right cmd key // Safari screws up location for the right cmd key
if ((key === 'Meta') && (location === 0)) { if ((key === 'Meta') && (location === 0)) {
@ -151,14 +150,12 @@ export function getKeysym(evt){
// Now we need to look at the Unicode symbol instead // Now we need to look at the Unicode symbol instead
var codepoint;
// Special key? (FIXME: Should have been caught earlier) // Special key? (FIXME: Should have been caught earlier)
if (key.length !== 1) { if (key.length !== 1) {
return null; return null;
} }
codepoint = key.charCodeAt(); const codepoint = key.charCodeAt();
if (codepoint) { if (codepoint) {
return keysyms.lookup(codepoint); return keysyms.lookup(codepoint);
} }

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
import * as Log from './logging.js'; import * as Log from './logging.js';
// Touch detection // Touch detection
export var isTouchDevice = ('ontouchstart' in document.documentElement) || export let isTouchDevice = ('ontouchstart' in document.documentElement) ||
// requried for Chrome debugger // requried for Chrome debugger
(document.ontouchstart !== undefined) || (document.ontouchstart !== undefined) ||
// required for MS Surface // required for MS Surface
@ -20,12 +20,12 @@ window.addEventListener('touchstart', function onFirstTouch() {
window.removeEventListener('touchstart', onFirstTouch, false); window.removeEventListener('touchstart', onFirstTouch, false);
}, false); }, false);
var _cursor_uris_supported = null; let _cursor_uris_supported = null;
export function supportsCursorURIs () { export function supportsCursorURIs () {
if (_cursor_uris_supported === null) { if (_cursor_uris_supported === null) {
try { 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'; target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
if (target.style.cursor) { if (target.style.cursor) {
@ -42,7 +42,7 @@ export function supportsCursorURIs () {
} }
return _cursor_uris_supported; return _cursor_uris_supported;
}; }
export function isMac() { export function isMac() {
return navigator && !!(/mac/i).exec(navigator.platform); return navigator && !!(/mac/i).exec(navigator.platform);

View File

@ -12,22 +12,22 @@
export function getPointerEvent (e) { export function getPointerEvent (e) {
return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e; return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
}; }
export function stopEvent (e) { export function stopEvent (e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}; }
// Emulate Element.setCapture() when not supported // Emulate Element.setCapture() when not supported
var _captureRecursion = false; let _captureRecursion = false;
var _captureElem = null; let _captureElem = null;
function _captureProxy(e) { function _captureProxy(e) {
// Recursion protection as we'll see our own event // Recursion protection as we'll see our own event
if (_captureRecursion) return; if (_captureRecursion) return;
// Clone the event as we cannot dispatch an already dispatched event // Clone the event as we cannot dispatch an already dispatched event
var newEv = new e.constructor(e.type, e); const newEv = new e.constructor(e.type, e);
_captureRecursion = true; _captureRecursion = true;
_captureElem.dispatchEvent(newEv); _captureElem.dispatchEvent(newEv);
@ -45,16 +45,17 @@ function _captureProxy(e) {
if (e.type === "mouseup") { if (e.type === "mouseup") {
releaseCapture(); releaseCapture();
} }
}; }
// Follow cursor style of target element // Follow cursor style of target element
function _captureElemChanged() { 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; captureElem.style.cursor = window.getComputedStyle(_captureElem).cursor;
}; }
var _captureObserver = new MutationObserver(_captureElemChanged);
var _captureIndex = 0; const _captureObserver = new MutationObserver(_captureElemChanged);
let _captureIndex = 0;
export function setCapture (elem) { export function setCapture (elem) {
if (elem.setCapture) { if (elem.setCapture) {
@ -69,7 +70,7 @@ export function setCapture (elem) {
// called multiple times without coordination // called multiple times without coordination
releaseCapture(); releaseCapture();
var captureElem = document.getElementById("noVNC_mouse_capture_elem"); let captureElem = document.getElementById("noVNC_mouse_capture_elem");
if (captureElem === null) { if (captureElem === null) {
captureElem = document.createElement("div"); captureElem = document.createElement("div");
@ -105,7 +106,7 @@ export function setCapture (elem) {
window.addEventListener('mousemove', _captureProxy); window.addEventListener('mousemove', _captureProxy);
window.addEventListener('mouseup', _captureProxy); window.addEventListener('mouseup', _captureProxy);
} }
}; }
export function releaseCapture () { export function releaseCapture () {
if (document.releaseCapture) { if (document.releaseCapture) {
@ -129,10 +130,10 @@ export function releaseCapture () {
_captureObserver.disconnect(); _captureObserver.disconnect();
var captureElem = document.getElementById("noVNC_mouse_capture_elem"); const captureElem = document.getElementById("noVNC_mouse_capture_elem");
captureElem.style.display = "none"; captureElem.style.display = "none";
window.removeEventListener('mousemove', _captureProxy); window.removeEventListener('mousemove', _captureProxy);
window.removeEventListener('mouseup', _captureProxy); window.removeEventListener('mouseup', _captureProxy);
} }
}; }

View File

@ -6,7 +6,7 @@
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
var EventTargetMixin = { const EventTargetMixin = {
_listeners: null, _listeners: null,
addEventListener: function(type, callback) { addEventListener: function(type, callback) {

View File

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

View File

@ -16,13 +16,13 @@ if (typeof Object.assign != 'function') {
throw new TypeError('Cannot convert undefined or null to object'); 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++) { for (let index = 1; index < arguments.length; index++) {
var nextSource = arguments[index]; const nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null 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 // Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey]; to[nextKey] = nextSource[nextKey];
@ -41,7 +41,7 @@ if (typeof Object.assign != 'function') {
(function () { (function () {
function CustomEvent ( event, params ) { function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined }; 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 ); evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt; return evt;
} }

View File

@ -12,4 +12,4 @@
export function decodeUTF8 (utf8string) { export function decodeUTF8 (utf8string) {
"use strict"; "use strict";
return decodeURIComponent(escape(utf8string)); return decodeURIComponent(escape(utf8string));
}; }

View File

@ -37,20 +37,20 @@ export default function Websock() {
'close': function () {}, 'close': function () {},
'error': function () {} 'error': function () {}
}; };
}; }
// this has performance issues in some versions Chromium, and // this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox // doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future. // at the moment. It may be valuable to turn it on in the future.
var ENABLE_COPYWITHIN = false; const ENABLE_COPYWITHIN = false;
var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
var typedArrayToString = (function () { const typedArrayToString = (function () {
// This is only for PhantomJS, which doesn't like apply-ing // This is only for PhantomJS, which doesn't like apply-ing
// with Typed Arrays // with Typed Arrays
try { try {
var arr = new Uint8Array([1, 2, 3]); const arr = new Uint8Array([1, 2, 3]);
String.fromCharCode.apply(null, arr); String.fromCharCode.apply(null, arr);
return function (a) { return String.fromCharCode.apply(null, a); }; return function (a) { return String.fromCharCode.apply(null, a); };
} catch (ex) { } catch (ex) {
@ -115,7 +115,7 @@ Websock.prototype = {
rQshiftStr: function (len) { rQshiftStr: function (len) {
if (typeof(len) === 'undefined') { len = this.rQlen(); } 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; this._rQi += len;
return typedArrayToString(arr); return typedArrayToString(arr);
}, },
@ -149,7 +149,7 @@ Websock.prototype = {
// to be available in the receive queue. Return true if we need to // to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false. // wait (and possibly print a debug message), otherwise false.
rQwait: function (msg, num, goback) { rQwait: function (msg, num, goback) {
var rQlen = this._rQlen - this._rQi; // Skip rQlen() function call const rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
if (rQlen < num) { if (rQlen < num) {
if (goback) { if (goback) {
if (this._rQi < goback) { if (this._rQi < goback) {
@ -204,7 +204,6 @@ Websock.prototype = {
}, },
open: function (uri, protocols) { open: function (uri, protocols) {
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
this.init(); this.init();
this._websocket = new WebSocket(uri, protocols); this._websocket = new WebSocket(uri, protocols);
@ -252,7 +251,7 @@ Websock.prototype = {
}, },
_expand_compact_rQ: function (min_fit) { _expand_compact_rQ: function (min_fit) {
var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2; const resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
if (resizeNeeded) { if (resizeNeeded) {
if (!min_fit) { if (!min_fit) {
// just double the size if we need to do compaction // just double the size if we need to do compaction
@ -267,12 +266,12 @@ Websock.prototype = {
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) { if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
this._rQbufferSize = MAX_RQ_GROW_SIZE; this._rQbufferSize = MAX_RQ_GROW_SIZE;
if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) { 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) { if (resizeNeeded) {
var old_rQbuffer = this._rQ.buffer; const old_rQbuffer = this._rQ.buffer;
this._rQmax = this._rQbufferSize / 8; this._rQmax = this._rQbufferSize / 8;
this._rQ = new Uint8Array(this._rQbufferSize); this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi)); this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
@ -290,7 +289,7 @@ Websock.prototype = {
_decode_message: function (data) { _decode_message: function (data) {
// push arraybuffer values onto the end // push arraybuffer values onto the end
var u8 = new Uint8Array(data); const u8 = new Uint8Array(data);
if (u8.length > this._rQbufferSize - this._rQlen) { if (u8.length > this._rQbufferSize - this._rQlen) {
this._expand_compact_rQ(u8.length); this._expand_compact_rQ(u8.length);
} }

View File

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

View File

@ -1,29 +1,30 @@
// Karma configuration // Karma configuration
module.exports = function(config) { module.exports = function(config) {
var customLaunchers = {}; const customLaunchers = {};
var browsers = []; let browsers = [];
var useSauce = false; let useSauce = false;
let transpileToES5 = ['internet explorer'].includes(process.env.TEST_BROWSER_NAME);
// use Sauce when running on Travis // use Sauce when running on Travis
if (process.env.TRAVIS_JOB_NUMBER) { if (process.env.TRAVIS_JOB_NUMBER) {
useSauce = true; useSauce = true;
} }
if (useSauce && process.env.TEST_BROWSER_NAME && process.env.TEST_BROWSER_NAME != 'PhantomJS') { if (useSauce && process.env.TEST_BROWSER_NAME && process.env.TEST_BROWSER_NAME != 'PhantomJS') {
var names = process.env.TEST_BROWSER_NAME.split(','); const names = process.env.TEST_BROWSER_NAME.split(',');
var platforms = process.env.TEST_BROWSER_OS.split(','); const platforms = process.env.TEST_BROWSER_OS.split(',');
var versions = []; const versions = process.env.TEST_BROWSER_VERSION
if (process.env.TEST_BROWSER_VERSION) { ? process.env.TEST_BROWSER_VERSION.split(',')
versions = process.env.TEST_BROWSER_VERSION.split(','); : [null];
} else {
versions = [null];
}
for (var i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
for (var j = 0; j < platforms.length; j++) { for (let j = 0; j < platforms.length; j++) {
for (var k = 0; k < versions.length; k++) { // FIXME Skip tests in Linux since Sauce Labs browser versions are ancient.
var launcher_name = 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i]; // https://github.com/novnc/noVNC/pull/1013#issuecomment-382749805
if (platforms[j] === 'Linux') continue;
for (let k = 0; k < versions.length; k++) {
let launcher_name = 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i];
if (versions[k]) { if (versions[k]) {
launcher_name += '_' + versions[k]; launcher_name += '_' + versions[k];
} }
@ -48,7 +49,7 @@ module.exports = function(config) {
browsers = []; browsers = [];
} }
var my_conf = { const my_conf = {
// base path that will be used to resolve all patterns (eg. files, exclude) // base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '', basePath: '',
@ -103,6 +104,7 @@ module.exports = function(config) {
babelPreprocessor: { babelPreprocessor: {
options: { options: {
presets: transpileToES5 ? ['es2015'] : [],
plugins: ['transform-es2015-modules-amd', 'syntax-dynamic-import'], plugins: ['transform-es2015-modules-amd', 'syntax-dynamic-import'],
sourceMap: 'inline', sourceMap: 'inline',
}, },

View File

@ -7,7 +7,8 @@
"test": "tests" "test": "tests"
}, },
"scripts": { "scripts": {
"test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js", "lint": "eslint app core po tests utils",
"test": "karma start karma.conf.js",
"prepare": "node ./utils/use_require.js --as commonjs --clean" "prepare": "node ./utils/use_require.js --as commonjs --clean"
}, },
"repository": { "repository": {
@ -35,11 +36,13 @@
"babel-plugin-transform-es2015-modules-commonjs": "^6.18.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.18.0",
"babel-plugin-transform-es2015-modules-systemjs": "^6.22.0", "babel-plugin-transform-es2015-modules-systemjs": "^6.22.0",
"babel-plugin-transform-es2015-modules-umd": "^6.22.0", "babel-plugin-transform-es2015-modules-umd": "^6.22.0",
"babel-preset-es2015": "^6.24.1",
"babelify": "^7.3.0", "babelify": "^7.3.0",
"browserify": "^13.1.0", "browserify": "^13.1.0",
"chai": "^3.5.0", "chai": "^3.5.0",
"commander": "^2.9.0", "commander": "^2.9.0",
"es-module-loader": "^2.1.0", "es-module-loader": "^2.1.0",
"eslint": "^4.16.0",
"fs-extra": "^1.0.0", "fs-extra": "^1.0.0",
"jsdom": "*", "jsdom": "*",
"karma": "^1.3.0", "karma": "^1.3.0",

View File

@ -17,11 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
var getopt = require('node-getopt'); const getopt = require('node-getopt');
var fs = require('fs'); const fs = require('fs');
var po2json = require("po2json"); const po2json = require("po2json");
opt = getopt.create([ const opt = getopt.create([
['h' , 'help' , 'display this help'], ['h' , 'help' , 'display this help'],
]).bindHelp().parseSystem(); ]).bindHelp().parseSystem();
@ -30,14 +30,14 @@ if (opt.argv.length != 2) {
process.exit(1); process.exit(1);
} }
var data = po2json.parseFileSync(opt.argv[0]); const data = po2json.parseFileSync(opt.argv[0]);
var bodyPart = Object.keys(data).filter((msgid) => msgid !== "").map((msgid) => { const bodyPart = Object.keys(data).filter((msgid) => msgid !== "").map((msgid) => {
if (msgid === "") return; if (msgid === "") return;
var msgstr = data[msgid][1]; const msgstr = data[msgid][1];
return " " + JSON.stringify(msgid) + ": " + JSON.stringify(msgstr); return " " + JSON.stringify(msgid) + ": " + JSON.stringify(msgstr);
}).join(",\n"); }).join(",\n");
var output = "{\n" + bodyPart + "\n}"; const output = "{\n" + bodyPart + "\n}";
fs.writeFileSync(opt.argv[1], output); fs.writeFileSync(opt.argv[1], output);

View File

@ -5,17 +5,16 @@
* Licensed under MPL 2.0 (see LICENSE.txt) * Licensed under MPL 2.0 (see LICENSE.txt)
*/ */
var getopt = require('node-getopt'); const getopt = require('node-getopt');
const jsdom = require("jsdom");
const fs = require("fs");
var jsdom = require("jsdom"); const opt = getopt.create([
var fs = require("fs");
opt = getopt.create([
['o' , 'output=FILE' , 'write output to specified file'], ['o' , 'output=FILE' , 'write output to specified file'],
['h' , 'help' , 'display this help'], ['h' , 'help' , 'display this help'],
]).bindHelp().parseSystem(); ]).bindHelp().parseSystem();
var strings = {}; const strings = {};
function addString(str, location) { function addString(str, location) {
if (str.length == 0) { if (str.length == 0) {
@ -74,7 +73,7 @@ function process(elem, locator, enabled) {
} }
} }
for (var i = 0;i < elem.childNodes.length;i++) { for (let i = 0; i < elem.childNodes.length; i++) {
node = elem.childNodes[i]; node = elem.childNodes[i];
if (node.nodeType === node.ELEMENT_NODE) { if (node.nodeType === node.ELEMENT_NODE) {
process(node, locator, enabled); process(node, locator, enabled);
@ -84,24 +83,22 @@ function process(elem, locator, enabled) {
} }
} }
for (var i = 0;i < opt.argv.length;i++) { for (let i = 0; i < opt.argv.length; i++) {
var file; const fn = opt.argv[i];
const file = fs.readFileSync(fn, "utf8");
const dom = new jsdom.JSDOM(file, { includeNodeLocations: true });
const body = dom.window.document.body;
fn = opt.argv[i]; const locator = function (elem) {
file = fs.readFileSync(fn, "utf8"); const offset = dom.nodeLocation(elem).startOffset;
dom = new jsdom.JSDOM(file, { includeNodeLocations: true }); const line = file.slice(0, offset).split("\n").length;
body = dom.window.document.body;
locator = function (elem) {
offset = dom.nodeLocation(elem).startOffset;
line = file.slice(0, offset).split("\n").length;
return fn + ":" + line; return fn + ":" + line;
}; };
process(body, locator, true); process(body, locator, true);
} }
var output = ""; let output = "";
for (str in strings) { for (str in strings) {
output += "#:"; output += "#:";

9
tests/.eslintrc Normal file
View File

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

View File

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

View File

@ -1,9 +1,11 @@
import Base64 from '../core/base64.js';
// PhantomJS can't create Event objects directly, so we need to use this // PhantomJS can't create Event objects directly, so we need to use this
function make_event(name, props) { function make_event(name, props) {
var evt = document.createEvent('Event'); const evt = document.createEvent('Event');
evt.initEvent(name, true, true); evt.initEvent(name, true, true);
if (props) { if (props) {
for (var prop in props) { for (let prop in props) {
evt[prop] = props[prop]; evt[prop] = props[prop];
} }
} }
@ -27,7 +29,7 @@ export default function FakeWebSocket (uri, protocols) {
this.bufferedAmount = 0; this.bufferedAmount = 0;
this.__is_fake = true; this.__is_fake = true;
}; }
FakeWebSocket.prototype = { FakeWebSocket.prototype = {
close: function (code, reason) { close: function (code, reason) {
@ -48,7 +50,7 @@ FakeWebSocket.prototype = {
}, },
_get_sent_data: function () { _get_sent_data: function () {
var res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount); const res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount);
this.bufferedAmount = 0; this.bufferedAmount = 0;
return res; return res;
}, },
@ -74,7 +76,8 @@ FakeWebSocket.__is_fake = true;
FakeWebSocket.replace = function () { FakeWebSocket.replace = function () {
if (!WebSocket.__is_fake) { if (!WebSocket.__is_fake) {
var real_version = WebSocket; const real_version = WebSocket;
// eslint-disable-next-line no-global-assign
WebSocket = FakeWebSocket; WebSocket = FakeWebSocket;
FakeWebSocket.__real_version = real_version; FakeWebSocket.__real_version = real_version;
} }
@ -82,6 +85,7 @@ FakeWebSocket.replace = function () {
FakeWebSocket.restore = function () { FakeWebSocket.restore = function () {
if (WebSocket.__is_fake) { if (WebSocket.__is_fake) {
// eslint-disable-next-line no-global-assign
WebSocket = WebSocket.__real_version; WebSocket = WebSocket.__real_version;
} }
}; };

View File

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

View File

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

View File

@ -9,12 +9,12 @@ import * as Log from '../core/util/logging.js';
import Base64 from '../core/base64.js'; import Base64 from '../core/base64.js';
// Immediate polyfill // Immediate polyfill
if (setImmediate === undefined) { if (window.setImmediate === undefined) {
var _immediateIdCounter = 1; let _immediateIdCounter = 1;
var _immediateFuncs = {}; const _immediateFuncs = {};
var setImmediate = function (func) { window.setImmediate = function (func) {
var index = _immediateIdCounter++; const index = _immediateIdCounter++;
_immediateFuncs[index] = func; _immediateFuncs[index] = func;
window.postMessage("noVNC immediate trigger:" + index, "*"); window.postMessage("noVNC immediate trigger:" + index, "*");
return index; return index;
@ -24,15 +24,15 @@ if (setImmediate === undefined) {
_immediateFuncs[id]; _immediateFuncs[id];
}; };
var _onMessage = function (event) { const _onMessage = function (event) {
if ((typeof event.data !== "string") || if ((typeof event.data !== "string") ||
(event.data.indexOf("noVNC immediate trigger:") !== 0)) { (event.data.indexOf("noVNC immediate trigger:") !== 0)) {
return; 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) { if (callback === undefined) {
return; return;
} }
@ -51,8 +51,8 @@ export default function RecordingPlayer (frames, encoding, disconnected) {
this._disconnected = disconnected; this._disconnected = disconnected;
if (this._encoding === undefined) { if (this._encoding === undefined) {
let frame = this._frames[0]; const frame = this._frames[0];
let start = frame.indexOf('{', 1) + 1; const start = frame.indexOf('{', 1) + 1;
if (frame.slice(start).startsWith('UkZC')) { if (frame.slice(start).startsWith('UkZC')) {
this._encoding = 'base64'; this._encoding = 'base64';
} else { } else {
@ -108,7 +108,7 @@ RecordingPlayer.prototype = {
_queueNextPacket: function () { _queueNextPacket: function () {
if (!this._running) { return; } if (!this._running) { return; }
var frame = this._frames[this._frame_index]; let frame = this._frames[this._frame_index];
// skip send frames // skip send frames
while (this._frame_index < this._frame_length && frame.charAt(0) === "}") { while (this._frame_index < this._frame_length && frame.charAt(0) === "}") {
@ -129,8 +129,8 @@ RecordingPlayer.prototype = {
} }
if (this._realtime) { if (this._realtime) {
let foffset = frame.slice(1, frame.indexOf('{', 1)); const foffset = frame.slice(1, frame.indexOf('{', 1));
let toffset = (new Date()).getTime() - this._start_time; const toffset = (new Date()).getTime() - this._start_time;
let delay = foffset - toffset; let delay = foffset - toffset;
if (delay < 1) delay = 1; if (delay < 1) delay = 1;
@ -143,8 +143,8 @@ RecordingPlayer.prototype = {
_doPacket: function () { _doPacket: function () {
// Avoid having excessive queue buildup in non-realtime mode // Avoid having excessive queue buildup in non-realtime mode
if (this._trafficManagement && this._rfb._flushing) { if (this._trafficManagement && this._rfb._flushing) {
let player = this; const player = this;
let orig = this._rfb._display.onflush; const orig = this._rfb._display.onflush;
this._rfb._display.onflush = function () { this._rfb._display.onflush = function () {
player._rfb._display.onflush = orig; player._rfb._display.onflush = orig;
player._rfb._onFlush(); player._rfb._onFlush();
@ -154,12 +154,13 @@ RecordingPlayer.prototype = {
} }
const frame = this._frames[this._frame_index]; 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') { if (this._encoding === 'base64') {
var u8 = Base64.decode(frame.slice(start)); u8 = Base64.decode(frame.slice(start));
start = 0; start = 0;
} else { } else {
var u8 = new Uint8Array(frame.length - start); u8 = new Uint8Array(frame.length - start);
for (let i = 0; i < frame.length - start; i++) { for (let i = 0; i < frame.length - start; i++) {
u8[i] = frame.charCodeAt(start + i); u8[i] = frame.charCodeAt(start + i);
} }
@ -173,7 +174,7 @@ RecordingPlayer.prototype = {
_finish() { _finish() {
if (this._rfb._display.pending()) { if (this._rfb._display.pending()) {
var player = this; const player = this;
this._rfb._display.onflush = function () { this._rfb._display.onflush = function () {
if (player._rfb._flushing) { if (player._rfb._flushing) {
player._rfb._onFlush(); player._rfb._onFlush();

View File

@ -1,29 +1,28 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import Base64 from '../core/base64.js'; import Base64 from '../core/base64.js';
describe('Base64 Tools', function() { describe('Base64 Tools', function() {
"use strict"; "use strict";
var BIN_ARR = new Array(256); const BIN_ARR = new Array(256);
for (var i = 0; i < 256; i++) { for (let i = 0; i < 256; i++) {
BIN_ARR[i] = 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() { describe('encode', function() {
it('should encode a binary string into Base64', 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); expect(encoded).to.equal(B64_STR);
}); });
}); });
describe('decode', function() { describe('decode', function() {
it('should decode a Base64 string into a normal string', 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); expect(decoded).to.deep.equal(BIN_ARR);
}); });

View File

@ -1,4 +1,4 @@
var expect = chai.expect; const expect = chai.expect;
import Base64 from '../core/base64.js'; import Base64 from '../core/base64.js';
import Display from '../core/display.js'; import Display from '../core/display.js';
@ -6,37 +6,35 @@ import Display from '../core/display.js';
import sinon from '../vendor/sinon.js'; import sinon from '../vendor/sinon.js';
describe('Display/Canvas Helper', function () { 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, 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,
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]; const basic_data = new Uint8Array([0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255]);
basic_data = new Uint8Array(basic_data);
function make_image_canvas (input_data) { function make_image_canvas (input_data) {
var canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = 4; canvas.width = 4;
canvas.height = 4; canvas.height = 4;
var ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
var data = ctx.createImageData(4, 4); const data = ctx.createImageData(4, 4);
for (var i = 0; i < checked_data.length; i++) { data.data[i] = input_data[i]; } for (let i = 0; i < checked_data.length; i++) { data.data[i] = input_data[i]; }
ctx.putImageData(data, 0, 0); ctx.putImageData(data, 0, 0);
return canvas; return canvas;
} }
function make_image_png (input_data) { function make_image_png (input_data) {
var canvas = make_image_canvas(input_data); const canvas = make_image_canvas(input_data);
var url = canvas.toDataURL(); const url = canvas.toDataURL();
var data = url.split(",")[1]; const data = url.split(",")[1];
return Base64.decode(data); return Base64.decode(data);
} }
describe('viewport handling', function () { describe('viewport handling', function () {
var display; let display;
beforeEach(function () { beforeEach(function () {
display = new Display(document.createElement('canvas')); display = new Display(document.createElement('canvas'));
display.clipViewport = true; display.clipViewport = true;
@ -51,10 +49,9 @@ describe('Display/Canvas Helper', function () {
display.drawImage(make_image_canvas(basic_data), 1, 1); display.drawImage(make_image_canvas(basic_data), 1, 1);
display.flip(); display.flip();
var expected = new Uint8Array(16); const expected = new Uint8Array(16);
var i; for (let i = 0; i < 8; i++) { expected[i] = basic_data[i]; }
for (i = 0; i < 8; i++) { expected[i] = basic_data[i]; } for (let i = 8; i < 16; i++) { expected[i] = 0; }
for (i = 8; i < 16; i++) { expected[i] = 0; }
expect(display).to.have.displayed(expected); expect(display).to.have.displayed(expected);
}); });
@ -119,7 +116,7 @@ describe('Display/Canvas Helper', function () {
}); });
describe('resizing', function () { describe('resizing', function () {
var display; let display;
beforeEach(function () { beforeEach(function () {
display = new Display(document.createElement('canvas')); display = new Display(document.createElement('canvas'));
display.clipViewport = false; display.clipViewport = false;
@ -136,8 +133,8 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 4, 4, [0, 0, 0xff]); display.fillRect(0, 0, 4, 4, [0, 0, 0xff]);
display.resize(2, 2); display.resize(2, 2);
display.flip(); display.flip();
var expected = []; const expected = [];
for (var i = 0; i < 4 * 2*2; i += 4) { for (let i = 0; i < 4 * 2*2; i += 4) {
expected[i] = 0xff; expected[i] = 0xff;
expected[i+1] = expected[i+2] = 0; expected[i+1] = expected[i+2] = 0;
expected[i+3] = 0xff; expected[i+3] = 0xff;
@ -179,8 +176,8 @@ describe('Display/Canvas Helper', function () {
}); });
describe('rescaling', function () { describe('rescaling', function () {
var display; let display;
var canvas; let canvas;
beforeEach(function () { beforeEach(function () {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
@ -220,8 +217,8 @@ describe('Display/Canvas Helper', function () {
}); });
describe('autoscaling', function () { describe('autoscaling', function () {
var display; let display;
var canvas; let canvas;
beforeEach(function () { beforeEach(function () {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
@ -268,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 // TODO(directxman12): improve the tests for each of the drawing functions to cover more than just the
// basic cases // basic cases
var display; let display;
beforeEach(function () { beforeEach(function () {
display = new Display(document.createElement('canvas')); display = new Display(document.createElement('canvas'));
display.resize(4, 4); display.resize(4, 4);
@ -279,8 +276,8 @@ describe('Display/Canvas Helper', function () {
display._logo = null; display._logo = null;
display.clear(); display.clear();
display.resize(4, 4); display.resize(4, 4);
var empty = []; const empty = [];
for (var i = 0; i < 4 * display._fb_width * display._fb_height; i++) { empty[i] = 0; } for (let i = 0; i < 4 * display._fb_width * display._fb_height; i++) { empty[i] = 0; }
expect(display).to.have.displayed(new Uint8Array(empty)); expect(display).to.have.displayed(new Uint8Array(empty));
}); });
@ -300,8 +297,8 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 4, 4, [0, 0, 0xff]); display.fillRect(0, 0, 4, 4, [0, 0, 0xff]);
display.flip(); display.flip();
display.fillRect(0, 0, 4, 4, [0, 0xff, 0]); display.fillRect(0, 0, 4, 4, [0, 0xff, 0]);
var expected = []; const expected = [];
for (var i = 0; i < 4 * display._fb_width * display._fb_height; i += 4) { for (let i = 0; i < 4 * display._fb_width * display._fb_height; i += 4) {
expected[i] = 0xff; expected[i] = 0xff;
expected[i+1] = expected[i+2] = 0; expected[i+1] = expected[i+2] = 0;
expected[i+3] = 0xff; expected[i+3] = 0xff;
@ -346,7 +343,7 @@ describe('Display/Canvas Helper', function () {
// We have a special cache for 16x16 tiles that we need to test // We have a special cache for 16x16 tiles that we need to test
it('should support drawing a 16x16 tile', function () { it('should support drawing a 16x16 tile', function () {
let large_checked_data = new Uint8Array(16*16*4); const large_checked_data = new Uint8Array(16*16*4);
display.resize(16, 16); display.resize(16, 16);
for (let y = 0;y < 16;y++) { for (let y = 0;y < 16;y++) {
@ -371,8 +368,8 @@ describe('Display/Canvas Helper', function () {
}); });
it('should support drawing BGRX blit images with true color via #blitImage', function () { it('should support drawing BGRX blit images with true color via #blitImage', function () {
var data = []; const data = [];
for (var i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
data[i * 4] = checked_data[i * 4 + 2]; data[i * 4] = checked_data[i * 4 + 2];
data[i * 4 + 1] = checked_data[i * 4 + 1]; data[i * 4 + 1] = checked_data[i * 4 + 1];
data[i * 4 + 2] = checked_data[i * 4]; data[i * 4 + 2] = checked_data[i * 4];
@ -384,8 +381,8 @@ describe('Display/Canvas Helper', function () {
}); });
it('should support drawing RGB blit images with true color via #blitRgbImage', function () { it('should support drawing RGB blit images with true color via #blitRgbImage', function () {
var data = []; const data = [];
for (var i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
data[i * 3] = checked_data[i * 4]; data[i * 3] = checked_data[i * 4];
data[i * 3 + 1] = checked_data[i * 4 + 1]; data[i * 3 + 1] = checked_data[i * 4 + 1];
data[i * 3 + 2] = checked_data[i * 4 + 2]; data[i * 3 + 2] = checked_data[i * 4 + 2];
@ -396,7 +393,7 @@ describe('Display/Canvas Helper', function () {
}); });
it('should support drawing an image object via #drawImage', 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.drawImage(img, 0, 0);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checked_data);
@ -404,7 +401,7 @@ describe('Display/Canvas Helper', function () {
}); });
describe('the render queue processor', function () { describe('the render queue processor', function () {
var display; let display;
beforeEach(function () { beforeEach(function () {
display = new Display(document.createElement('canvas')); display = new Display(document.createElement('canvas'));
display.resize(4, 4); display.resize(4, 4);
@ -427,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 () { 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 }, display._renderQ = [{ type: 'img', x: 3, y: 4, img: img },
{ type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }]; { type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }];
display.drawImage = sinon.spy(); display.drawImage = sinon.spy();

View File

@ -1,5 +1,4 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import keysyms from '../core/input/keysymdef.js'; import keysyms from '../core/input/keysymdef.js';
import * as KeyboardUtil from "../core/input/util.js"; import * as KeyboardUtil from "../core/input/util.js";
@ -65,7 +64,7 @@ describe('Helpers', function() {
}); });
describe('Fix Meta on macOS', function() { describe('Fix Meta on macOS', function() {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these
@ -128,7 +127,7 @@ describe('Helpers', function() {
}); });
describe('Broken key AltGraph on IE/Edge', function() { describe('Broken key AltGraph on IE/Edge', function() {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these

View File

@ -1,5 +1,4 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import sinon from '../vendor/sinon.js'; import sinon from '../vendor/sinon.js';
@ -12,19 +11,19 @@ describe('Key Event Handling', function() {
// The real KeyboardEvent constructor might not work everywhere we // The real KeyboardEvent constructor might not work everywhere we
// want to run these tests // want to run these tests
function keyevent(typeArg, KeyboardEventInit) { function keyevent(typeArg, KeyboardEventInit) {
var e = { type: typeArg }; const e = { type: typeArg };
for (var key in KeyboardEventInit) { for (let key in KeyboardEventInit) {
e[key] = KeyboardEventInit[key]; e[key] = KeyboardEventInit[key];
} }
e.stopPropagation = sinon.spy(); e.stopPropagation = sinon.spy();
e.preventDefault = sinon.spy(); e.preventDefault = sinon.spy();
return e; return e;
}; }
describe('Decode Keyboard Events', function() { describe('Decode Keyboard Events', function() {
it('should decode keydown events', function(done) { it('should decode keydown events', function(done) {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -35,8 +34,8 @@ describe('Key Event Handling', function() {
}); });
it('should decode keyup events', function(done) { it('should decode keyup events', function(done) {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
var calls = 0; let calls = 0;
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -51,13 +50,13 @@ describe('Key Event Handling', function() {
describe('Legacy keypress Events', function() { describe('Legacy keypress Events', function() {
it('should wait for keypress when needed', function() { it('should wait for keypress when needed', function() {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
}); });
it('should decode keypress events', function(done) { it('should decode keypress events', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -68,14 +67,14 @@ describe('Key Event Handling', function() {
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyA', charCode: 0x61})); kbd._handleKeyPress(keyevent('keypress', {code: 'KeyA', charCode: 0x61}));
}); });
it('should ignore keypress with different code', function() { it('should ignore keypress with different code', function() {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61})); kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
}); });
it('should handle keypress with missing code', function(done) { it('should handle keypress with missing code', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -86,7 +85,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61})); kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61}));
}); });
it('should guess key if no keypress and numeric key', function(done) { it('should guess key if no keypress and numeric key', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x32); expect(keysym).to.be.equal(0x32);
expect(code).to.be.equal('Digit2'); expect(code).to.be.equal('Digit2');
@ -96,7 +95,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32})); kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32}));
}); });
it('should guess key if no keypress and alpha key', function(done) { it('should guess key if no keypress and alpha key', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -106,7 +105,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false})); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false}));
}); });
it('should guess key if no keypress and alpha key (with shift)', function(done) { it('should guess key if no keypress and alpha key (with shift)', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x41); expect(keysym).to.be.equal(0x41);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -116,7 +115,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true})); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true}));
}); });
it('should not guess key if no keypress and unknown key', function(done) { it('should not guess key if no keypress and unknown key', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0); expect(keysym).to.be.equal(0);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -132,27 +131,27 @@ describe('Key Event Handling', function() {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
}); });
it('should suppress anything with a valid key', function() { it('should suppress anything with a valid key', function() {
var kbd = new Keyboard(document, {}); const kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', key: 'a'}); const evt1 = keyevent('keydown', {code: 'KeyA', key: 'a'});
kbd._handleKeyDown(evt); kbd._handleKeyDown(evt1);
expect(evt.preventDefault).to.have.been.called; expect(evt1.preventDefault).to.have.been.called;
evt = keyevent('keyup', {code: 'KeyA', key: 'a'}); const evt2 = keyevent('keyup', {code: 'KeyA', key: 'a'});
kbd._handleKeyUp(evt); kbd._handleKeyUp(evt2);
expect(evt.preventDefault).to.have.been.called; expect(evt2.preventDefault).to.have.been.called;
}); });
it('should not suppress keys without key', function() { it('should not suppress keys without key', function() {
var kbd = new Keyboard(document, {}); const kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); const evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
kbd._handleKeyDown(evt); kbd._handleKeyDown(evt);
expect(evt.preventDefault).to.not.have.been.called; expect(evt.preventDefault).to.not.have.been.called;
}); });
it('should suppress the following keypress event', function() { it('should suppress the following keypress event', function() {
var kbd = new Keyboard(document, {}); const kbd = new Keyboard(document, {});
var evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); const evt1 = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
kbd._handleKeyDown(evt); kbd._handleKeyDown(evt1);
var evt = keyevent('keypress', {code: 'KeyA', charCode: 0x41}); const evt2 = keyevent('keypress', {code: 'KeyA', charCode: 0x41});
kbd._handleKeyPress(evt); kbd._handleKeyPress(evt2);
expect(evt.preventDefault).to.have.been.called; expect(evt2.preventDefault).to.have.been.called;
}); });
}); });
}); });
@ -160,8 +159,8 @@ describe('Key Event Handling', function() {
describe('Fake keyup', function() { describe('Fake keyup', function() {
it('should fake keyup events for virtual keyboards', function(done) { it('should fake keyup events for virtual keyboards', function(done) {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
var count = 0; let count = 0;
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
switch (count++) { switch (count++) {
case 0: case 0:
@ -180,7 +179,7 @@ describe('Key Event Handling', function() {
}); });
describe('iOS', function() { describe('iOS', function() {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these
@ -207,8 +206,8 @@ describe('Key Event Handling', function() {
it('should fake keyup events on iOS', function(done) { it('should fake keyup events on iOS', function(done) {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
var count = 0; let count = 0;
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
switch (count++) { switch (count++) {
case 0: case 0:
@ -233,7 +232,7 @@ describe('Key Event Handling', function() {
if (browser.isIE() || browser.isEdge()) this.skip(); if (browser.isIE() || browser.isEdge()) this.skip();
}); });
it('should send release using the same keysym as the press', function(done) { it('should send release using the same keysym as the press', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -245,8 +244,8 @@ describe('Key Event Handling', function() {
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'b'})); kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'b'}));
}); });
it('should send the same keysym for multiple presses', function() { it('should send the same keysym for multiple presses', function() {
var count = 0; let count = 0;
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA'); expect(code).to.be.equal('KeyA');
@ -258,7 +257,7 @@ describe('Key Event Handling', function() {
expect(count).to.be.equal(2); expect(count).to.be.equal(2);
}); });
it('should do nothing on keyup events if no keys are down', function() { 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.onkeyevent = sinon.spy();
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'})); kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
@ -266,7 +265,7 @@ describe('Key Event Handling', function() {
describe('Legacy Events', function() { describe('Legacy Events', function() {
it('should track keys using keyCode if no code', function(done) { it('should track keys using keyCode if no code', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Platform65'); expect(code).to.be.equal('Platform65');
@ -278,7 +277,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyUp(keyevent('keyup', {keyCode: 65, key: 'b'})); kbd._handleKeyUp(keyevent('keyup', {keyCode: 65, key: 'b'}));
}); });
it('should ignore compositing code', function() { it('should ignore compositing code', function() {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Unidentified'); expect(code).to.be.equal('Unidentified');
@ -286,7 +285,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {keyCode: 229, key: 'a'})); kbd._handleKeyDown(keyevent('keydown', {keyCode: 229, key: 'a'}));
}); });
it('should track keys using keyIdentifier if no code', function(done) { it('should track keys using keyIdentifier if no code', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0x61); expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('Platform65'); expect(code).to.be.equal('Platform65');
@ -301,7 +300,7 @@ describe('Key Event Handling', function() {
}); });
describe('Shuffle modifiers on macOS', function() { describe('Shuffle modifiers on macOS', function() {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these
@ -327,8 +326,8 @@ describe('Key Event Handling', function() {
}); });
it('should change Alt to AltGraph', function() { it('should change Alt to AltGraph', function() {
var count = 0; let count = 0;
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
switch (count++) { switch (count++) {
case 0: case 0:
@ -346,7 +345,7 @@ describe('Key Event Handling', function() {
expect(count).to.be.equal(2); expect(count).to.be.equal(2);
}); });
it('should change left Super to Alt', function(done) { it('should change left Super to Alt', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0xFFE9); expect(keysym).to.be.equal(0xFFE9);
expect(code).to.be.equal('MetaLeft'); expect(code).to.be.equal('MetaLeft');
@ -355,7 +354,7 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1}));
}); });
it('should change right Super to left Super', function(done) { it('should change right Super to left Super', function(done) {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = function(keysym, code, down) { kbd.onkeyevent = function(keysym, code, down) {
expect(keysym).to.be.equal(0xFFEB); expect(keysym).to.be.equal(0xFFEB);
expect(code).to.be.equal('MetaRight'); expect(code).to.be.equal('MetaRight');
@ -366,7 +365,7 @@ describe('Key Event Handling', function() {
}); });
describe('Escape AltGraph on Windows', function() { describe('Escape AltGraph on Windows', function() {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these
@ -395,14 +394,14 @@ describe('Key Event Handling', function() {
}); });
it('should supress ControlLeft until it knows if it is AltGr', function () { it('should supress ControlLeft until it knows if it is AltGr', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
}); });
it('should not trigger on repeating ControlLeft', function () { it('should not trigger on repeating ControlLeft', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
@ -412,7 +411,7 @@ describe('Key Event Handling', function() {
}); });
it('should not supress ControlRight', function () { it('should not supress ControlRight', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlRight', key: 'Control', location: 2})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlRight', key: 'Control', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledOnce; expect(kbd.onkeyevent).to.have.been.calledOnce;
@ -420,7 +419,7 @@ describe('Key Event Handling', function() {
}); });
it('should release ControlLeft after 100 ms', function () { it('should release ControlLeft after 100 ms', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
@ -430,7 +429,7 @@ describe('Key Event Handling', function() {
}); });
it('should release ControlLeft on other key press', function () { it('should release ControlLeft on other key press', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
expect(kbd.onkeyevent).to.not.have.been.called; expect(kbd.onkeyevent).to.not.have.been.called;
@ -446,7 +445,7 @@ describe('Key Event Handling', function() {
}); });
it('should release ControlLeft on other key release', function () { it('should release ControlLeft on other key release', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'})); kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
@ -464,7 +463,7 @@ describe('Key Event Handling', function() {
}); });
it('should generate AltGraph for quick Ctrl+Alt sequence', function () { it('should generate AltGraph for quick Ctrl+Alt sequence', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
this.clock.tick(20); this.clock.tick(20);
@ -479,7 +478,7 @@ describe('Key Event Handling', function() {
}); });
it('should generate Ctrl, Alt for slow Ctrl+Alt sequence', function () { it('should generate Ctrl, Alt for slow Ctrl+Alt sequence', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()})); kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1, timeStamp: Date.now()}));
this.clock.tick(60); this.clock.tick(60);
@ -495,7 +494,7 @@ describe('Key Event Handling', function() {
}); });
it('should pass through single Alt', function () { it('should pass through single Alt', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2})); kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledOnce; expect(kbd.onkeyevent).to.have.been.calledOnce;
@ -503,7 +502,7 @@ describe('Key Event Handling', function() {
}); });
it('should pass through single AltGr', function () { it('should pass through single AltGr', function () {
var kbd = new Keyboard(document); const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy(); kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'AltGraph', location: 2})); kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'AltGraph', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledOnce; expect(kbd.onkeyevent).to.have.been.calledOnce;

View File

@ -1,13 +1,11 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect; import { l10n } from '../app/localization.js';
import l10nGet, { l10n } from '../app/localization.js';
describe('Localization', function() { describe('Localization', function() {
"use strict"; "use strict";
describe('language selection', function () { describe('language selection', function () {
var origNavigator; let origNavigator;
beforeEach(function () { beforeEach(function () {
// window.navigator is a protected read-only property in many // window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these // environments, so we need to redefine it whilst running these

View File

@ -1,5 +1,4 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import sinon from '../vendor/sinon.js'; import sinon from '../vendor/sinon.js';
@ -15,24 +14,24 @@ describe('Mouse Event Handling', function() {
// located at coordinates 10x10 // located at coordinates 10x10
sinon.stub(Element.prototype, 'getBoundingClientRect').returns( sinon.stub(Element.prototype, 'getBoundingClientRect').returns(
{left: 10, right: 110, top: 10, bottom: 110, width: 100, height: 100}); {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 // The real constructors might not work everywhere we
// want to run these tests // want to run these tests
var mouseevent, touchevent; const mouseevent = function(typeArg, MouseEventInit) {
mouseevent = touchevent = function(typeArg, MouseEventInit) { const e = { type: typeArg };
var e = { type: typeArg }; for (let key in MouseEventInit) {
for (var key in MouseEventInit) {
e[key] = MouseEventInit[key]; e[key] = MouseEventInit[key];
} }
e.stopPropagation = sinon.spy(); e.stopPropagation = sinon.spy();
e.preventDefault = sinon.spy(); e.preventDefault = sinon.spy();
return e; return e;
}; };
const touchevent = mouseevent;
describe('Decode Mouse Events', function() { describe('Decode Mouse Events', function() {
it('should decode mousedown events', function(done) { it('should decode mousedown events', function(done) {
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
expect(bmask).to.be.equal(0x01); expect(bmask).to.be.equal(0x01);
expect(down).to.be.equal(1); expect(down).to.be.equal(1);
@ -41,8 +40,8 @@ describe('Mouse Event Handling', function() {
mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' })); mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' }));
}); });
it('should decode mouseup events', function(done) { it('should decode mouseup events', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
expect(bmask).to.be.equal(0x01); expect(bmask).to.be.equal(0x01);
if (calls++ === 1) { if (calls++ === 1) {
@ -54,7 +53,7 @@ describe('Mouse Event Handling', function() {
mouse._handleMouseUp(mouseevent('mouseup', { button: '0x01' })); mouse._handleMouseUp(mouseevent('mouseup', { button: '0x01' }));
}); });
it('should decode mousemove events', function(done) { it('should decode mousemove events', function(done) {
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousemove = function(x, y) { mouse.onmousemove = function(x, y) {
// Note that target relative coordinates are sent // Note that target relative coordinates are sent
expect(x).to.be.equal(40); expect(x).to.be.equal(40);
@ -65,8 +64,8 @@ describe('Mouse Event Handling', function() {
{ clientX: 50, clientY: 20 })); { clientX: 50, clientY: 20 }));
}); });
it('should decode mousewheel events', function(done) { it('should decode mousewheel events', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
calls++; calls++;
expect(bmask).to.be.equal(1<<6); expect(bmask).to.be.equal(1<<6);
@ -89,8 +88,8 @@ describe('Mouse Event Handling', function() {
afterEach(function () { this.clock.restore(); }); afterEach(function () { this.clock.restore(); });
it('should use same pos for 2nd tap if close enough', function(done) { it('should use same pos for 2nd tap if close enough', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
calls++; calls++;
if (calls === 1) { if (calls === 1) {
@ -120,8 +119,8 @@ describe('Mouse Event Handling', function() {
}); });
it('should not modify 2nd tap pos if far apart', function(done) { it('should not modify 2nd tap pos if far apart', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
calls++; calls++;
if (calls === 1) { if (calls === 1) {
@ -149,8 +148,8 @@ describe('Mouse Event Handling', function() {
}); });
it('should not modify 2nd tap pos if not soon enough', function(done) { it('should not modify 2nd tap pos if not soon enough', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
calls++; calls++;
if (calls === 1) { if (calls === 1) {
@ -178,8 +177,8 @@ describe('Mouse Event Handling', function() {
}); });
it('should not modify 2nd tap pos if not touch', function(done) { it('should not modify 2nd tap pos if not touch', function(done) {
var calls = 0; let calls = 0;
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = function(x, y, down, bmask) { mouse.onmousebutton = function(x, y, down, bmask) {
calls++; calls++;
if (calls === 1) { if (calls === 1) {
@ -214,7 +213,7 @@ describe('Mouse Event Handling', function() {
afterEach(function () { this.clock.restore(); }); afterEach(function () { this.clock.restore(); });
it('should accumulate wheel events if small enough', function () { it('should accumulate wheel events if small enough', function () {
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy(); mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent( mouse._handleMouseWheel(mouseevent(
@ -247,7 +246,7 @@ describe('Mouse Event Handling', function() {
}); });
it('should not accumulate large wheel events', function () { it('should not accumulate large wheel events', function () {
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy(); mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent( mouse._handleMouseWheel(mouseevent(
@ -266,7 +265,7 @@ describe('Mouse Event Handling', function() {
}); });
it('should send even small wheel events after a timeout', 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.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent( mouse._handleMouseWheel(mouseevent(
@ -278,7 +277,7 @@ describe('Mouse Event Handling', function() {
}); });
it('should account for non-zero deltaMode', function () { it('should account for non-zero deltaMode', function () {
var mouse = new Mouse(target); const mouse = new Mouse(target);
mouse.onmousebutton = sinon.spy(); mouse.onmousebutton = sinon.spy();
mouse._handleMouseWheel(mouseevent( mouse._handleMouseWheel(mouseevent(

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,5 +1,4 @@
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import Websock from '../core/websock.js'; import Websock from '../core/websock.js';
import FakeWebSocket from './fake.websocket.js'; import FakeWebSocket from './fake.websocket.js';
@ -10,8 +9,8 @@ describe('Websock', function() {
"use strict"; "use strict";
describe('Queue methods', function () { describe('Queue methods', function () {
var sock; let sock;
var RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]); const RQ_TEMPLATE = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
@ -36,8 +35,8 @@ describe('Websock', function() {
describe('rQpeek8', function () { describe('rQpeek8', function () {
it('should peek at the next byte without poping it off the queue', function () { it('should peek at the next byte without poping it off the queue', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
var peek = sock.rQpeek8(); const peek = sock.rQpeek8();
expect(sock.rQpeek8()).to.equal(peek); expect(sock.rQpeek8()).to.equal(peek);
expect(sock.rQlen()).to.equal(bef_len); expect(sock.rQlen()).to.equal(bef_len);
}); });
@ -45,8 +44,8 @@ describe('Websock', function() {
describe('rQshift8', function () { describe('rQshift8', function () {
it('should pop a single byte from the receive queue', function () { it('should pop a single byte from the receive queue', function () {
var peek = sock.rQpeek8(); const peek = sock.rQpeek8();
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
expect(sock.rQshift8()).to.equal(peek); expect(sock.rQshift8()).to.equal(peek);
expect(sock.rQlen()).to.equal(bef_len - 1); expect(sock.rQlen()).to.equal(bef_len - 1);
}); });
@ -54,8 +53,8 @@ describe('Websock', function() {
describe('rQshift16', function () { describe('rQshift16', function () {
it('should pop two bytes from the receive queue and return a single number', function () { it('should pop two bytes from the receive queue and return a single number', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
var expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1]; const expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1];
expect(sock.rQshift16()).to.equal(expected); expect(sock.rQshift16()).to.equal(expected);
expect(sock.rQlen()).to.equal(bef_len - 2); expect(sock.rQlen()).to.equal(bef_len - 2);
}); });
@ -63,8 +62,8 @@ describe('Websock', function() {
describe('rQshift32', function () { describe('rQshift32', function () {
it('should pop four bytes from the receive queue and return a single number', function () { it('should pop four bytes from the receive queue and return a single number', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
var expected = (RQ_TEMPLATE[0] << 24) + const expected = (RQ_TEMPLATE[0] << 24) +
(RQ_TEMPLATE[1] << 16) + (RQ_TEMPLATE[1] << 16) +
(RQ_TEMPLATE[2] << 8) + (RQ_TEMPLATE[2] << 8) +
RQ_TEMPLATE[3]; RQ_TEMPLATE[3];
@ -75,9 +74,9 @@ describe('Websock', function() {
describe('rQshiftStr', function () { describe('rQshiftStr', function () {
it('should shift the given number of bytes off of the receive queue and return a string', function () { it('should shift the given number of bytes off of the receive queue and return a string', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
var bef_rQi = sock.get_rQi(); const bef_rQi = sock.get_rQi();
var shifted = sock.rQshiftStr(3); const shifted = sock.rQshiftStr(3);
expect(shifted).to.be.a('string'); 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(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); expect(sock.rQlen()).to.equal(bef_len - 3);
@ -91,9 +90,9 @@ describe('Websock', function() {
describe('rQshiftBytes', function () { describe('rQshiftBytes', function () {
it('should shift the given number of bytes of the receive queue and return an array', function () { it('should shift the given number of bytes of the receive queue and return an array', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
var bef_rQi = sock.get_rQi(); const bef_rQi = sock.get_rQi();
var shifted = sock.rQshiftBytes(3); const shifted = sock.rQshiftBytes(3);
expect(shifted).to.be.an.instanceof(Uint8Array); expect(shifted).to.be.an.instanceof(Uint8Array);
expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3)); expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3));
expect(sock.rQlen()).to.equal(bef_len - 3); expect(sock.rQlen()).to.equal(bef_len - 3);
@ -111,19 +110,19 @@ describe('Websock', function() {
}); });
it('should not modify the receive queue', function () { it('should not modify the receive queue', function () {
var bef_len = sock.rQlen(); const bef_len = sock.rQlen();
sock.rQslice(0, 2); sock.rQslice(0, 2);
expect(sock.rQlen()).to.equal(bef_len); expect(sock.rQlen()).to.equal(bef_len);
}); });
it('should return an array containing the given slice of the receive queue', function () { 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.be.an.instanceof(Uint8Array);
expect(sl).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 0, 2)); 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 () { 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.have.length(RQ_TEMPLATE.length - 1);
expect(sl).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 1)); expect(sl).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 1));
}); });
@ -177,7 +176,7 @@ describe('Websock', function() {
sock._websocket.readyState = WebSocket.OPEN sock._websocket.readyState = WebSocket.OPEN
sock._sQ = new Uint8Array([1, 2, 3]); sock._sQ = new Uint8Array([1, 2, 3]);
sock._sQlen = 3; sock._sQlen = 3;
var encoded = sock._encode_message(); const encoded = sock._encode_message();
sock.flush(); sock.flush();
expect(sock._websocket.send).to.have.been.calledOnce; expect(sock._websocket.send).to.have.been.calledOnce;
@ -201,7 +200,7 @@ describe('Websock', function() {
it('should add to the send queue', function () { it('should add to the send queue', function () {
sock.send([1, 2, 3]); 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])); expect(new Uint8Array(sq.buffer, sock._sQlen - 3, 3)).to.array.equal(new Uint8Array([1, 2, 3]));
}); });
@ -224,21 +223,22 @@ describe('Websock', function() {
}); });
describe('lifecycle methods', function () { describe('lifecycle methods', function () {
var old_WS; let old_WS;
before(function () { before(function () {
old_WS = WebSocket; old_WS = WebSocket;
}); });
var sock; let sock;
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
WebSocket = sinon.spy(); // eslint-disable-next-line no-global-assign
WebSocket.OPEN = old_WS.OPEN; WebSocket = sinon.spy();
WebSocket.CONNECTING = old_WS.CONNECTING; WebSocket.OPEN = old_WS.OPEN;
WebSocket.CLOSING = old_WS.CLOSING; WebSocket.CONNECTING = old_WS.CONNECTING;
WebSocket.CLOSED = old_WS.CLOSED; WebSocket.CLOSING = old_WS.CLOSING;
WebSocket.CLOSED = old_WS.CLOSED;
WebSocket.prototype.binaryType = 'arraybuffer'; WebSocket.prototype.binaryType = 'arraybuffer';
}); });
describe('opening', function () { describe('opening', function () {
@ -327,19 +327,20 @@ describe('Websock', function() {
}); });
after(function () { after(function () {
// eslint-disable-next-line no-global-assign
WebSocket = old_WS; WebSocket = old_WS;
}); });
}); });
describe('WebSocket Receiving', function () { describe('WebSocket Receiving', function () {
var sock; let sock;
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
sock._allocate_buffers(); sock._allocate_buffers();
}); });
it('should support adding binary Uint8Array data to the receive queue', function () { 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._mode = 'binary';
sock._recv_message(msg); sock._recv_message(msg);
expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03'); expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03');
@ -347,7 +348,7 @@ describe('Websock', function() {
it('should call the message event handler if present', function () { it('should call the message event handler if present', function () {
sock._eventHandlers.message = sinon.spy(); 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._mode = 'binary';
sock._recv_message(msg); sock._recv_message(msg);
expect(sock._eventHandlers.message).to.have.been.calledOnce; expect(sock._eventHandlers.message).to.have.been.calledOnce;
@ -355,7 +356,7 @@ describe('Websock', function() {
it('should not call the message event handler if there is nothing in the receive queue', function () { it('should not call the message event handler if there is nothing in the receive queue', function () {
sock._eventHandlers.message = sinon.spy(); sock._eventHandlers.message = sinon.spy();
var msg = { data: new Uint8Array([]).buffer }; const msg = { data: new Uint8Array([]).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recv_message(msg);
expect(sock._eventHandlers.message).not.to.have.been.called; expect(sock._eventHandlers.message).not.to.have.been.called;
@ -368,7 +369,7 @@ describe('Websock', function() {
sock._rQlen = 6; sock._rQlen = 6;
sock.set_rQi(6); sock.set_rQi(6);
sock._rQmax = 3; 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._mode = 'binary';
sock._recv_message(msg); sock._recv_message(msg);
expect(sock._rQlen).to.equal(3); expect(sock._rQlen).to.equal(3);
@ -381,7 +382,7 @@ describe('Websock', function() {
sock.set_rQi(0); sock.set_rQi(0);
sock._rQbufferSize = 20; sock._rQbufferSize = 20;
sock._rQmax = 2; sock._rQmax = 2;
var msg = { data: new Uint8Array(30).buffer }; const msg = { data: new Uint8Array(30).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recv_message(msg);
expect(sock._rQlen).to.equal(30); expect(sock._rQlen).to.equal(30);
@ -395,7 +396,7 @@ describe('Websock', function() {
after(function () { FakeWebSocket.restore(); }); after(function () { FakeWebSocket.restore(); });
describe('as binary data', function () { describe('as binary data', function () {
var sock; let sock;
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
sock.open('ws://', 'binary'); sock.open('ws://', 'binary');
@ -405,7 +406,7 @@ describe('Websock', function() {
it('should only send the send queue up to the send queue length', 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._sQ = new Uint8Array([1, 2, 3, 4, 5]);
sock._sQlen = 3; sock._sQlen = 3;
var res = sock._encode_message(); const res = sock._encode_message();
expect(res).to.array.equal(new Uint8Array([1, 2, 3])); expect(res).to.array.equal(new Uint8Array([1, 2, 3]));
}); });

View File

@ -1,7 +1,6 @@
/* jshint expr: true */ /* jshint expr: true */
var assert = chai.assert; const expect = chai.expect;
var expect = chai.expect;
import * as WebUtil from '../app/webutil.js'; import * as WebUtil from '../app/webutil.js';
@ -13,7 +12,7 @@ describe('WebUtil', function() {
describe('settings', function () { describe('settings', function () {
describe('localStorage', function() { describe('localStorage', function() {
var chrome = window.chrome; let chrome = window.chrome;
before(function() { before(function() {
chrome = window.chrome; chrome = window.chrome;
window.chrome = null; window.chrome = null;
@ -22,7 +21,7 @@ describe('WebUtil', function() {
window.chrome = chrome; window.chrome = chrome;
}); });
var origLocalStorage; let origLocalStorage;
beforeEach(function() { beforeEach(function() {
origLocalStorage = Object.getOwnPropertyDescriptor(window, "localStorage"); origLocalStorage = Object.getOwnPropertyDescriptor(window, "localStorage");
if (origLocalStorage === undefined) { if (origLocalStorage === undefined) {
@ -111,8 +110,8 @@ describe('WebUtil', function() {
}); });
describe('chrome.storage', function() { describe('chrome.storage', function() {
var chrome = window.chrome; let chrome = window.chrome;
var settings = {}; let settings = {};
before(function() { before(function() {
chrome = window.chrome; chrome = window.chrome;
window.chrome = { window.chrome = {
@ -129,7 +128,7 @@ describe('WebUtil', function() {
window.chrome = chrome; window.chrome = chrome;
}); });
var csSandbox = sinon.createSandbox(); const csSandbox = sinon.createSandbox();
beforeEach(function() { beforeEach(function() {
settings = {}; settings = {};

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"; "use strict";
var fs = require('fs'); const fs = require('fs');
var show_help = process.argv.length === 2; let show_help = process.argv.length === 2;
var filename; let filename;
for (var i = 2; i < process.argv.length; ++i) { for (let i = 2; i < process.argv.length; ++i) {
switch (process.argv[i]) { switch (process.argv[i]) {
case "--help": case "--help":
case "-h": case "-h":
@ -36,28 +36,28 @@ if (show_help) {
console.log("Usage: node parse.js [options] filename:"); console.log("Usage: node parse.js [options] filename:");
console.log(" -h [ --help ] Produce this help message"); console.log(" -h [ --help ] Produce this help message");
console.log(" filename The keysymdef.h file to parse"); console.log(" filename The keysymdef.h file to parse");
return; process.exit(0);
} }
var buf = fs.readFileSync(filename); const buf = fs.readFileSync(filename);
var str = buf.toString('utf8'); 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) { for (let i = 0; i < arr.length; ++i) {
var result = re.exec(arr[i]); const result = re.exec(arr[i]);
if (result){ if (result){
var keyname = result[1]; const keyname = result[1];
var keysym = parseInt(result[2], 16); const keysym = parseInt(result[2], 16);
var remainder = result[3]; const remainder = result[3];
var unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder); const unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder);
if (unicodeRes) { if (unicodeRes) {
var unicode = parseInt(unicodeRes[1], 16); const unicode = parseInt(unicodeRes[1], 16);
// The first entry is the preferred one // The first entry is the preferred one
if (!codepoints[unicode]){ if (!codepoints[unicode]){
codepoints[unicode] = { keysym: keysym, name: keyname }; codepoints[unicode] = { keysym: keysym, name: keyname };
@ -66,7 +66,7 @@ for (var i = 0; i < arr.length; ++i) {
} }
} }
var out = let out =
"/*\n" + "/*\n" +
" * Mapping from Unicode codepoints to X11/RFB keysyms\n" + " * Mapping from Unicode codepoints to X11/RFB keysyms\n" +
" *\n" + " *\n" +
@ -76,17 +76,17 @@ var out =
"\n" + "\n" +
"/* Functions at the bottom */\n" + "/* Functions at the bottom */\n" +
"\n" + "\n" +
"var codepoints = {\n"; "const codepoints = {\n";
function toHex(num) { function toHex(num) {
var s = num.toString(16); let s = num.toString(16);
if (s.length < 4) { if (s.length < 4) {
s = ("0000" + s).slice(-4); s = ("0000" + s).slice(-4);
} }
return "0x" + s; return "0x" + s;
}; }
for (var codepoint in codepoints) { for (let codepoint in codepoints) {
codepoint = parseInt(codepoint); codepoint = parseInt(codepoint);
// Latin-1? // Latin-1?
@ -115,7 +115,7 @@ out +=
" }\n" + " }\n" +
"\n" + "\n" +
" // Lookup table (fairly random)\n" + " // Lookup table (fairly random)\n" +
" var keysym = codepoints[u];\n" + " const keysym = codepoints[u];\n" +
" if (keysym !== undefined) {\n" + " if (keysym !== undefined) {\n" +
" return keysym;\n" + " return keysym;\n" +
" }\n" + " }\n" +

View File

@ -1,10 +1,10 @@
#!/usr/bin/env node #!/usr/bin/env node
var path = require('path'); const path = require('path');
var program = require('commander'); const program = require('commander');
var fs = require('fs'); const fs = require('fs');
var fse = require('fs-extra'); const fse = require('fs-extra');
var babel = require('babel-core'); const babel = require('babel-core');
const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']); const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']);
@ -44,8 +44,8 @@ no_copy_files.forEach((file) => no_transform_files.add(file));
// util.promisify requires Node.js 8.x, so we have our own // util.promisify requires Node.js 8.x, so we have our own
function promisify(original) { function promisify(original) {
return function () { return function () {
let obj = this; const obj = this;
let args = Array.prototype.slice.call(arguments); const args = Array.prototype.slice.call(arguments);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
original.apply(obj, args.concat((err, value) => { original.apply(obj, args.concat((err, value) => {
if (err) return reject(err); if (err) return reject(err);
@ -70,10 +70,10 @@ const babelTransformFile = promisify(babel.transformFile);
// walkDir *recursively* walks directories trees, // walkDir *recursively* walks directories trees,
// calling the callback for all normal files found. // calling the callback for all normal files found.
var walkDir = function (base_path, cb, filter) { const walkDir = function (base_path, cb, filter) {
return readdir(base_path) return readdir(base_path)
.then(files => { .then(files => {
let paths = files.map(filename => path.join(base_path, filename)); const paths = files.map(filename => path.join(base_path, filename));
return Promise.all(paths.map((filepath) => { return Promise.all(paths.map((filepath) => {
return lstat(filepath) return lstat(filepath)
.then(stats => { .then(stats => {
@ -87,20 +87,20 @@ var walkDir = function (base_path, cb, filter) {
}); });
}; };
var transform_html = function (legacy_scripts, only_legacy) { const transform_html = function (legacy_scripts, only_legacy) {
// write out the modified vnc.html file that works with the bundle // write out the modified vnc.html file that works with the bundle
var src_html_path = path.resolve(__dirname, '..', 'vnc.html'); const src_html_path = path.resolve(__dirname, '..', 'vnc.html');
var out_html_path = path.resolve(paths.out_dir_base, 'vnc.html'); const out_html_path = path.resolve(paths.out_dir_base, 'vnc.html');
return readFile(src_html_path) return readFile(src_html_path)
.then(contents_raw => { .then(contents_raw => {
var contents = contents_raw.toString(); let contents = contents_raw.toString();
var start_marker = '<!-- begin scripts -->\n'; const start_marker = '<!-- begin scripts -->\n';
var end_marker = '<!-- end scripts -->'; const end_marker = '<!-- end scripts -->';
var start_ind = contents.indexOf(start_marker) + start_marker.length; const start_ind = contents.indexOf(start_marker) + start_marker.length;
var end_ind = contents.indexOf(end_marker, start_ind); const end_ind = contents.indexOf(end_marker, start_ind);
new_script = ''; let new_script = '';
if (only_legacy) { if (only_legacy) {
// Only legacy version, so include things directly // Only legacy version, so include things directly
@ -141,7 +141,7 @@ var transform_html = function (legacy_scripts, only_legacy) {
}); });
} }
var make_lib_files = function (import_format, source_maps, with_app_dir, only_legacy) { const make_lib_files = function (import_format, source_maps, with_app_dir, only_legacy) {
if (!import_format) { if (!import_format) {
throw new Error("you must specify an import format to generate compiled noVNC libraries"); throw new Error("you must specify an import format to generate compiled noVNC libraries");
} else if (!SUPPORTED_FORMATS.has(import_format)) { } else if (!SUPPORTED_FORMATS.has(import_format)) {
@ -151,6 +151,7 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
// NB: we need to make a copy of babel_opts, since babel sets some defaults on it // NB: we need to make a copy of babel_opts, since babel sets some defaults on it
const babel_opts = () => ({ const babel_opts = () => ({
plugins: [`transform-es2015-modules-${import_format}`], plugins: [`transform-es2015-modules-${import_format}`],
presets: ['es2015'],
ast: false, ast: false,
sourceMaps: source_maps, sourceMaps: source_maps,
}); });
@ -160,12 +161,13 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
only_legacy = true; only_legacy = true;
} }
var in_path; let in_path;
let out_path_base;
if (with_app_dir) { if (with_app_dir) {
var out_path_base = paths.out_dir_base; out_path_base = paths.out_dir_base;
in_path = paths.main; in_path = paths.main;
} else { } else {
var out_path_base = paths.lib_dir_base; out_path_base = paths.lib_dir_base;
} }
const legacy_path_base = only_legacy ? out_path_base : path.join(out_path_base, 'legacy'); const legacy_path_base = only_legacy ? out_path_base : path.join(out_path_base, 'legacy');
@ -176,7 +178,7 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
const outFiles = []; const outFiles = [];
var handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve() const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve()
.then(() => { .then(() => {
if (no_copy_files.has(filename)) return; if (no_copy_files.has(filename)) return;
@ -223,7 +225,8 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
return babelTransformFile(filename, opts) return babelTransformFile(filename, opts)
.then(res => { .then(res => {
console.log(`Writing ${legacy_path}`); console.log(`Writing ${legacy_path}`);
var {code, map, ast} = res; const {map} = res;
let {code} = res;
if (source_maps === true) { if (source_maps === true) {
// append URL for external source map // append URL for external source map
code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`; code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`;
@ -247,19 +250,19 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
Promise.resolve() Promise.resolve()
.then(() => { .then(() => {
let handler = handleDir.bind(null, true, false, in_path || paths.main); const handler = handleDir.bind(null, true, false, in_path || paths.main);
let filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !no_copy_files.has(filename);
return walkDir(paths.vendor, handler, filter); return walkDir(paths.vendor, handler, filter);
}) })
.then(() => { .then(() => {
let handler = handleDir.bind(null, true, !in_path, in_path || paths.core); const handler = handleDir.bind(null, true, !in_path, in_path || paths.core);
let filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !no_copy_files.has(filename);
return walkDir(paths.core, handler, filter); return walkDir(paths.core, handler, filter);
}) })
.then(() => { .then(() => {
if (!with_app_dir) return; if (!with_app_dir) return;
let handler = handleDir.bind(null, false, false, in_path); const handler = handleDir.bind(null, false, false, in_path);
let filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !no_copy_files.has(filename);
return walkDir(paths.app, handler, filter); return walkDir(paths.app, handler, filter);
}) })
.then(() => { .then(() => {
@ -273,8 +276,8 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
console.log(`Writing ${out_app_path}`); console.log(`Writing ${out_app_path}`);
return helper.appWriter(out_path_base, legacy_path_base, out_app_path) return helper.appWriter(out_path_base, legacy_path_base, out_app_path)
.then(extra_scripts => { .then(extra_scripts => {
let rel_app_path = path.relative(out_path_base, out_app_path); const rel_app_path = path.relative(out_path_base, out_app_path);
let legacy_scripts = extra_scripts.concat([rel_app_path]); const legacy_scripts = extra_scripts.concat([rel_app_path]);
transform_html(legacy_scripts, only_legacy); transform_html(legacy_scripts, only_legacy);
}) })
.then(() => { .then(() => {
@ -285,7 +288,7 @@ var make_lib_files = function (import_format, source_maps, with_app_dir, only_le
.then(() => { .then(() => {
// Try to clean up any empty directories if this // Try to clean up any empty directories if this
// was the last file in there // was the last file in there
let rmdir_r = dir => { const rmdir_r = dir => {
return rmdir(dir) return rmdir(dir)
.then(() => rmdir_r(path.dirname(dir))) .then(() => rmdir_r(path.dirname(dir)))
.catch(() => { .catch(() => {

View File

@ -1,13 +1,12 @@
// writes helpers require for vnc.html (they should output app.js) // writes helpers require for vnc.html (they should output app.js)
var fs = require('fs'); const fs = require('fs');
var fse = require('fs-extra'); const path = require('path');
var path = require('path');
// util.promisify requires Node.js 8.x, so we have our own // util.promisify requires Node.js 8.x, so we have our own
function promisify(original) { function promisify(original) {
return function () { return function () {
let obj = this; const obj = this;
let args = Array.prototype.slice.call(arguments); const args = Array.prototype.slice.call(arguments);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
original.apply(obj, args.concat((err, value) => { original.apply(obj, args.concat((err, value) => {
if (err) return reject(err); if (err) return reject(err);
@ -23,12 +22,12 @@ module.exports = {
'amd': { 'amd': {
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (base_out_path, script_base_path, out_path) => {
// setup for requirejs // setup for requirejs
let ui_path = path.relative(base_out_path, const ui_path = path.relative(base_out_path,
path.join(script_base_path, 'app', 'ui')); path.join(script_base_path, 'app', 'ui'));
return writeFile(out_path, `requirejs(["${ui_path}"], function (ui) {});`) return writeFile(out_path, `requirejs(["${ui_path}"], function (ui) {});`)
.then(() => { .then(() => {
console.log(`Please place RequireJS in ${path.join(script_base_path, 'require.js')}`); console.log(`Please place RequireJS in ${path.join(script_base_path, 'require.js')}`);
let require_path = path.relative(base_out_path, const require_path = path.relative(base_out_path,
path.join(script_base_path, 'require.js')) path.join(script_base_path, 'require.js'))
return [ require_path ]; return [ require_path ];
}); });
@ -41,8 +40,8 @@ module.exports = {
opts.plugins.unshift("add-module-exports"); opts.plugins.unshift("add-module-exports");
}, },
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (base_out_path, script_base_path, out_path) => {
var browserify = require('browserify'); const browserify = require('browserify');
var b = browserify(path.join(script_base_path, 'app/ui.js'), {}); const b = browserify(path.join(script_base_path, 'app/ui.js'), {});
return promisify(b.bundle).call(b) return promisify(b.bundle).call(b)
.then((buf) => writeFile(out_path, buf)) .then((buf) => writeFile(out_path, buf))
.then(() => []); .then(() => []);
@ -52,15 +51,15 @@ module.exports = {
}, },
'systemjs': { 'systemjs': {
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (base_out_path, script_base_path, out_path) => {
let ui_path = path.relative(base_out_path, const ui_path = path.relative(base_out_path,
path.join(script_base_path, 'app', 'ui.js')); path.join(script_base_path, 'app', 'ui.js'));
return writeFile(out_path, `SystemJS.import("${ui_path}");`) return writeFile(out_path, `SystemJS.import("${ui_path}");`)
.then(() => { .then(() => {
console.log(`Please place SystemJS in ${path.join(script_base_path, 'system-production.js')}`); console.log(`Please place SystemJS in ${path.join(script_base_path, 'system-production.js')}`);
// FIXME: Should probably be in the legacy directory // FIXME: Should probably be in the legacy directory
let promise_path = path.relative(base_out_path, const promise_path = path.relative(base_out_path,
path.join(base_out_path, 'vendor', 'promise.js')) path.join(base_out_path, 'vendor', 'promise.js'))
let systemjs_path = path.relative(base_out_path, const systemjs_path = path.relative(base_out_path,
path.join(script_base_path, 'system-production.js')) path.join(script_base_path, 'system-production.js'))
return [ promise_path, systemjs_path ]; return [ promise_path, systemjs_path ];
}); });

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@ import babelTransformES2015ModulesSystemJS from 'babel-plugin-transform-es2015-m
var babelTransform = require('babel-core').transform; var babelTransform = require('babel-core').transform;
var babelTransformDynamicImport = require('babel-plugin-syntax-dynamic-import'); var babelTransformDynamicImport = require('babel-plugin-syntax-dynamic-import');
var babelTransformES2015ModulesSystemJS = require('babel-plugin-transform-es2015-modules-systemjs'); var babelTransformES2015ModulesSystemJS = require('babel-plugin-transform-es2015-modules-systemjs');
var babelPresetES2015 = require('babel-preset-es2015');
self.onmessage = function (evt) { self.onmessage = function (evt) {
// transform source with Babel // transform source with Babel
@ -17,6 +18,7 @@ self.onmessage = function (evt) {
sourceMaps: 'inline', sourceMaps: 'inline',
babelrc: false, babelrc: false,
plugins: [babelTransformDynamicImport, babelTransformES2015ModulesSystemJS], plugins: [babelTransformDynamicImport, babelTransformES2015ModulesSystemJS],
presets: [babelPresetES2015],
}); });
self.postMessage({key: evt.data.key, code: output.code, source: evt.data.source}); self.postMessage({key: evt.data.key, code: output.code, source: evt.data.source});