Merge branch 'style' of https://github.com/CendioOssman/noVNC
This commit is contained in:
commit
9881899e7b
|
@ -0,0 +1 @@
|
||||||
|
**/xtscancodes.js
|
26
.eslintrc
26
.eslintrc
|
@ -8,6 +8,8 @@
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"extends": "eslint:recommended",
|
||||||
"rules": {
|
"rules": {
|
||||||
|
// Unsafe or confusing stuff that we forbid
|
||||||
|
|
||||||
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
|
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
|
||||||
"no-constant-condition": ["error", { "checkLoops": false }],
|
"no-constant-condition": ["error", { "checkLoops": false }],
|
||||||
"no-var": "error",
|
"no-var": "error",
|
||||||
|
@ -18,5 +20,29 @@
|
||||||
"arrow-parens": ["error", "as-needed", { "requireForBlockBody": true }],
|
"arrow-parens": ["error", "as-needed", { "requireForBlockBody": true }],
|
||||||
"arrow-spacing": ["error"],
|
"arrow-spacing": ["error"],
|
||||||
"no-confusing-arrow": ["error", { "allowParens": true }],
|
"no-confusing-arrow": ["error", { "allowParens": true }],
|
||||||
|
|
||||||
|
// Enforced coding style
|
||||||
|
|
||||||
|
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||||
|
"indent": ["error", 4, { "SwitchCase": 1,
|
||||||
|
"CallExpression": { "arguments": "first" },
|
||||||
|
"ArrayExpression": "first",
|
||||||
|
"ObjectExpression": "first",
|
||||||
|
"ignoreComments": true }],
|
||||||
|
"comma-spacing": ["error"],
|
||||||
|
"comma-style": ["error"],
|
||||||
|
"curly": ["error", "multi-line"],
|
||||||
|
"func-call-spacing": ["error"],
|
||||||
|
"func-names": ["error"],
|
||||||
|
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||||
|
"key-spacing": ["error"],
|
||||||
|
"keyword-spacing": ["error"],
|
||||||
|
"no-trailing-spaces": ["error"],
|
||||||
|
"semi": ["error"],
|
||||||
|
"space-before-blocks": ["error"],
|
||||||
|
"space-before-function-paren": ["error", { "anonymous": "always",
|
||||||
|
"named": "never",
|
||||||
|
"asyncArrow": "always" }],
|
||||||
|
"switch-colon-spacing": ["error"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
// No ES6 can be used in this file since it's used for the translation
|
// No ES6 can be used in this file since it's used for the translation
|
||||||
/* eslint-disable prefer-arrow-callback */
|
/* eslint-disable prefer-arrow-callback */
|
||||||
|
|
||||||
(function() {
|
(function _scope() {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Fallback for all uncought errors
|
// Fallback for all uncought errors
|
||||||
function handleError (event, err) {
|
function handleError(event, err) {
|
||||||
try {
|
try {
|
||||||
const msg = document.getElementById('noVNC_fallback_errormsg');
|
const msg = document.getElementById('noVNC_fallback_errormsg');
|
||||||
|
|
||||||
|
@ -53,6 +53,6 @@
|
||||||
// from being printed to the browser console.
|
// from being printed to the browser console.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
window.addEventListener('error', function (evt) { handleError(evt, evt.error); });
|
window.addEventListener('error', function onerror(evt) { handleError(evt, evt.error); });
|
||||||
window.addEventListener('unhandledrejection', function (evt) { handleError(evt.reason, evt.reason); });
|
window.addEventListener('unhandledrejection', function onreject(evt) { handleError(evt.reason, evt.reason); });
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -53,10 +53,12 @@ export class Localizer {
|
||||||
.replace("_", "-")
|
.replace("_", "-")
|
||||||
.split("-");
|
.split("-");
|
||||||
|
|
||||||
if (userLang[0] !== supLang[0])
|
if (userLang[0] !== supLang[0]) {
|
||||||
continue;
|
continue;
|
||||||
if (userLang[1] !== supLang[1])
|
}
|
||||||
|
if (userLang[1] !== supLang[1]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this.language = supportedLanguages[j];
|
this.language = supportedLanguages[j];
|
||||||
return;
|
return;
|
||||||
|
@ -69,10 +71,12 @@ export class Localizer {
|
||||||
.replace("_", "-")
|
.replace("_", "-")
|
||||||
.split("-");
|
.split("-");
|
||||||
|
|
||||||
if (userLang[0] !== supLang[0])
|
if (userLang[0] !== supLang[0]) {
|
||||||
continue;
|
continue;
|
||||||
if (supLang[1] !== undefined)
|
}
|
||||||
|
if (supLang[1] !== undefined) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this.language = supportedLanguages[j];
|
this.language = supportedLanguages[j];
|
||||||
return;
|
return;
|
||||||
|
@ -132,7 +136,7 @@ export class Localizer {
|
||||||
}
|
}
|
||||||
if (elem.hasAttribute("label") &&
|
if (elem.hasAttribute("label") &&
|
||||||
isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
|
isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
|
||||||
"OPTION", "TRACK"])) {
|
"OPTION", "TRACK"])) {
|
||||||
translateAttribute(elem, "label");
|
translateAttribute(elem, "label");
|
||||||
}
|
}
|
||||||
// FIXME: Should update "lang"
|
// FIXME: Should update "lang"
|
||||||
|
|
19
app/ui.js
19
app/ui.js
|
@ -145,10 +145,9 @@ const UI = {
|
||||||
// set manually
|
// set manually
|
||||||
let 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;
|
||||||
}
|
} else if (window.location.protocol.substring(0, 4) == 'http') {
|
||||||
else if (window.location.protocol.substring(0,4) == 'http') {
|
|
||||||
port = 80;
|
port = 80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,7 +778,7 @@ const UI = {
|
||||||
const ctrl = document.getElementById('noVNC_setting_' + name);
|
const ctrl = document.getElementById('noVNC_setting_' + name);
|
||||||
let 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;
|
||||||
} else {
|
} else {
|
||||||
val = true;
|
val = true;
|
||||||
|
@ -940,7 +939,7 @@ const UI = {
|
||||||
},
|
},
|
||||||
|
|
||||||
clipboardReceive(e) {
|
clipboardReceive(e) {
|
||||||
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0,40) + "...");
|
Log.Debug(">> UI.clipboardReceive: " + e.detail.text.substr(0, 40) + "...");
|
||||||
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
|
document.getElementById('noVNC_clipboard_text').value = e.detail.text;
|
||||||
Log.Debug("<< UI.clipboardReceive");
|
Log.Debug("<< UI.clipboardReceive");
|
||||||
},
|
},
|
||||||
|
@ -952,7 +951,7 @@ const UI = {
|
||||||
|
|
||||||
clipboardSend() {
|
clipboardSend() {
|
||||||
const 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");
|
||||||
},
|
},
|
||||||
|
@ -1011,7 +1010,7 @@ const UI = {
|
||||||
url = UI.getSetting('encrypt') ? 'wss' : 'ws';
|
url = UI.getSetting('encrypt') ? 'wss' : 'ws';
|
||||||
|
|
||||||
url += '://' + host;
|
url += '://' + host;
|
||||||
if(port) {
|
if (port) {
|
||||||
url += ':' + port;
|
url += ':' + port;
|
||||||
}
|
}
|
||||||
url += '/' + path;
|
url += '/' + path;
|
||||||
|
@ -1334,7 +1333,7 @@ const UI = {
|
||||||
// Move the caret to the end
|
// Move the caret to the end
|
||||||
input.setSelectionRange(l, l);
|
input.setSelectionRange(l, l);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// setSelectionRange is undefined in Google Chrome
|
// setSelectionRange is undefined in Google Chrome
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1502,7 +1501,7 @@ const UI = {
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleExtraKeys() {
|
toggleExtraKeys() {
|
||||||
if(document.getElementById('noVNC_modifiers')
|
if (document.getElementById('noVNC_modifiers')
|
||||||
.classList.contains("noVNC_open")) {
|
.classList.contains("noVNC_open")) {
|
||||||
UI.closeExtraKeys();
|
UI.closeExtraKeys();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1556,7 +1555,7 @@ const UI = {
|
||||||
UI.rfb.touchButton = num;
|
UI.rfb.touchButton = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
const blist = [0, 1,2,4];
|
const blist = [0, 1, 2, 4];
|
||||||
for (let b = 0; b < blist.length; b++) {
|
for (let b = 0; b < blist.length; b++) {
|
||||||
const button = document.getElementById('noVNC_mouse_button' +
|
const button = document.getElementById('noVNC_mouse_button' +
|
||||||
blist[b]);
|
blist[b]);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
import { init_logging as main_init_logging } from '../core/util/logging.js';
|
import { init_logging as main_init_logging } from '../core/util/logging.js';
|
||||||
|
|
||||||
// init log level reading the logging HTTP param
|
// init log level reading the logging HTTP param
|
||||||
export function init_logging (level) {
|
export function init_logging(level) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof level !== "undefined") {
|
if (typeof level !== "undefined") {
|
||||||
main_init_logging(level);
|
main_init_logging(level);
|
||||||
|
@ -21,12 +21,12 @@ export function init_logging (level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a query string variable
|
// Read a query string variable
|
||||||
export function getQueryVar (name, defVal) {
|
export function getQueryVar(name, defVal) {
|
||||||
"use strict";
|
"use strict";
|
||||||
const 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]);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ export function getQueryVar (name, 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";
|
||||||
const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
|
const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
|
||||||
match = document.location.hash.match(re);
|
match = document.location.hash.match(re);
|
||||||
|
@ -50,7 +50,7 @@ export function getHashVar (name, 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";
|
||||||
const val = getHashVar(name);
|
const val = getHashVar(name);
|
||||||
|
|
||||||
|
@ -66,7 +66,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";
|
||||||
let date, expires;
|
let date, expires;
|
||||||
if (days) {
|
if (days) {
|
||||||
|
@ -86,7 +86,7 @@ export function createCookie (name, value, days) {
|
||||||
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";
|
||||||
const nameEQ = name + "=";
|
const nameEQ = name + "=";
|
||||||
const ca = document.cookie.split(';');
|
const ca = document.cookie.split(';');
|
||||||
|
@ -104,7 +104,7 @@ export function readCookie (name, defaultValue) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ export function eraseCookie (name) {
|
||||||
|
|
||||||
let settings = {};
|
let settings = {};
|
||||||
|
|
||||||
export function initSettings (callback /*, ...callbackArgs */) {
|
export function initSettings(callback /*, ...callbackArgs */) {
|
||||||
"use strict";
|
"use strict";
|
||||||
const 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) {
|
||||||
|
@ -134,12 +134,12 @@ export function initSettings (callback /*, ...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) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (settings[name] === value) return;
|
if (settings[name] === value) return;
|
||||||
settings[name] = value;
|
settings[name] = value;
|
||||||
|
@ -150,7 +150,7 @@ export function writeSetting (name, value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readSetting (name, defaultValue) {
|
export function readSetting(name, defaultValue) {
|
||||||
"use strict";
|
"use strict";
|
||||||
let value;
|
let value;
|
||||||
if ((name in settings) || (window.chrome && window.chrome.storage)) {
|
if ((name in settings) || (window.chrome && window.chrome.storage)) {
|
||||||
|
@ -170,7 +170,7 @@ export function readSetting (name, defaultValue) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function eraseSetting (name) {
|
export function eraseSetting(name) {
|
||||||
"use strict";
|
"use strict";
|
||||||
// Deleting here means that next time the setting is read when using local
|
// Deleting here means that next time the setting is read when using local
|
||||||
// storage, it will be pulled from local storage again.
|
// storage, it will be pulled from local storage again.
|
||||||
|
@ -185,7 +185,7 @@ export function eraseSetting (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;
|
||||||
|
|
|
@ -8,8 +8,8 @@ import * as Log from './util/logging.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
/* Convert data (an array of integers) to a Base64 string. */
|
/* Convert data (an array of integers) to a Base64 string. */
|
||||||
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
|
toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
|
||||||
base64Pad : '=',
|
base64Pad: '=',
|
||||||
|
|
||||||
encode(data) {
|
encode(data) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -43,7 +43,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Convert Base64 data to a string */
|
/* Convert Base64 data to a string */
|
||||||
toBinaryTable : [
|
/* eslint-disable comma-spacing */
|
||||||
|
toBinaryTable: [
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
|
||||||
|
@ -53,6 +54,7 @@ export default {
|
||||||
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
||||||
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
|
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
|
||||||
],
|
],
|
||||||
|
/* eslint-enable comma-spacing */
|
||||||
|
|
||||||
decode(data, offset) {
|
decode(data, offset) {
|
||||||
offset = typeof(offset) !== 'undefined' ? offset : 0;
|
offset = typeof(offset) !== 'undefined' ? offset : 0;
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default class RawDecoder {
|
||||||
|
|
||||||
// Convert data if needed
|
// Convert data if needed
|
||||||
if (depth == 8) {
|
if (depth == 8) {
|
||||||
const pixels = width * curr_height
|
const pixels = width * curr_height;
|
||||||
const newdata = new Uint8Array(pixels * 4);
|
const newdata = new Uint8Array(pixels * 4);
|
||||||
for (let i = 0; i < pixels; i++) {
|
for (let i = 0; i < pixels; i++) {
|
||||||
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default class TightDecoder {
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
this._zlibs[i] = new Inflator();
|
this._zlibs[i] = new Inflator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeRect(x, y, width, height, sock, display, depth) {
|
decodeRect(x, y, width, height, sock, display, depth) {
|
||||||
if (this._ctl === null) {
|
if (this._ctl === null) {
|
||||||
|
@ -81,7 +81,7 @@ export default class TightDecoder {
|
||||||
const rQi = sock.get_rQi();
|
const rQi = sock.get_rQi();
|
||||||
const rQ = sock.rQwhole();
|
const rQ = sock.rQwhole();
|
||||||
|
|
||||||
display.fillRect(x, y, width, height,
|
display.fillRect(x, y, width, height,
|
||||||
[rQ[rQi + 2], rQ[rQi + 1], rQ[rQi]], false);
|
[rQ[rQi + 2], rQ[rQi + 1], rQ[rQi]], false);
|
||||||
sock.rQskipBytes(3);
|
sock.rQskipBytes(3);
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@
|
||||||
* fine Java utilities: http://www.acme.com/java/
|
* fine Java utilities: http://www.acme.com/java/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable comma-spacing */
|
||||||
|
|
||||||
export default function DES(passwd) {
|
export default function DES(passwd) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ export default class Display {
|
||||||
this._backbuffer = document.createElement('canvas');
|
this._backbuffer = document.createElement('canvas');
|
||||||
this._drawCtx = this._backbuffer.getContext('2d');
|
this._drawCtx = this._backbuffer.getContext('2d');
|
||||||
|
|
||||||
this._damageBounds = { left:0, top:0,
|
this._damageBounds = { left: 0, top: 0,
|
||||||
right: this._backbuffer.width,
|
right: this._backbuffer.width,
|
||||||
bottom: this._backbuffer.height };
|
bottom: this._backbuffer.height };
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ export default class Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blitRgbImage(x, y , width, height, arr, offset, from_queue) {
|
blitRgbImage(x, y, width, height, arr, offset, from_queue) {
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
if (this._renderQ.length !== 0 && !from_queue) {
|
||||||
// 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,
|
||||||
|
|
|
@ -15,23 +15,20 @@ import KeyTable from "./keysym.js";
|
||||||
|
|
||||||
const DOMKeyTable = {};
|
const DOMKeyTable = {};
|
||||||
|
|
||||||
function addStandard(key, standard)
|
function addStandard(key, standard) {
|
||||||
{
|
|
||||||
if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
||||||
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
||||||
DOMKeyTable[key] = [standard, standard, standard, standard];
|
DOMKeyTable[key] = [standard, standard, standard, standard];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLeftRight(key, left, right)
|
function addLeftRight(key, left, right) {
|
||||||
{
|
|
||||||
if (left === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
if (left === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
||||||
if (right === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
if (right === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
||||||
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
||||||
DOMKeyTable[key] = [left, left, right, left];
|
DOMKeyTable[key] = [left, left, right, left];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addNumpad(key, standard, numpad)
|
function addNumpad(key, standard, numpad) {
|
||||||
{
|
|
||||||
if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
if (standard === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
||||||
if (numpad === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
if (numpad === undefined) throw "Undefined keysym for key \"" + key + "\"";
|
||||||
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
if (key in DOMKeyTable) throw "Duplicate entry for key \"" + key + "\"";
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
* See https://www.w3.org/TR/uievents-key/ for possible values.
|
* See https://www.w3.org/TR/uievents-key/ for possible values.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable key-spacing */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
// 3.1.1.1. Writing System Keys
|
// 3.1.1.1. Writing System Keys
|
||||||
|
|
|
@ -140,18 +140,18 @@ export default class Keyboard {
|
||||||
// possibly others).
|
// possibly others).
|
||||||
if (browser.isMac()) {
|
if (browser.isMac()) {
|
||||||
switch (keysym) {
|
switch (keysym) {
|
||||||
case KeyTable.XK_Super_L:
|
case KeyTable.XK_Super_L:
|
||||||
keysym = KeyTable.XK_Alt_L;
|
keysym = KeyTable.XK_Alt_L;
|
||||||
break;
|
break;
|
||||||
case KeyTable.XK_Super_R:
|
case KeyTable.XK_Super_R:
|
||||||
keysym = KeyTable.XK_Super_L;
|
keysym = KeyTable.XK_Super_L;
|
||||||
break;
|
break;
|
||||||
case KeyTable.XK_Alt_L:
|
case KeyTable.XK_Alt_L:
|
||||||
keysym = KeyTable.XK_Mode_switch;
|
keysym = KeyTable.XK_Mode_switch;
|
||||||
break;
|
break;
|
||||||
case KeyTable.XK_Alt_R:
|
case KeyTable.XK_Alt_R:
|
||||||
keysym = KeyTable.XK_ISO_Level3_Shift;
|
keysym = KeyTable.XK_ISO_Level3_Shift;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,10 +249,11 @@ export default class Keyboard {
|
||||||
// Character (A-Z)
|
// Character (A-Z)
|
||||||
let 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();
|
||||||
else
|
} else {
|
||||||
char = char.toLowerCase();
|
char = char.toLowerCase();
|
||||||
|
}
|
||||||
keysym = char.charCodeAt();
|
keysym = char.charCodeAt();
|
||||||
} else {
|
} else {
|
||||||
// Unknown, give up
|
// Unknown, give up
|
||||||
|
@ -313,8 +314,8 @@ export default class Keyboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
const 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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable key-spacing */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
XK_VoidSymbol: 0xffffff, /* Void symbol */
|
XK_VoidSymbol: 0xffffff, /* Void symbol */
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,7 @@ export default class Mouse {
|
||||||
} else {
|
} else {
|
||||||
y = e.clientY - bounds.top;
|
y = e.clientY - bounds.top;
|
||||||
}
|
}
|
||||||
this._pos = {x:x, y:y};
|
this._pos = {x: x, y: y};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== PUBLIC METHODS =====
|
// ===== PUBLIC METHODS =====
|
||||||
|
|
|
@ -5,7 +5,7 @@ import DOMKeyTable from "./domkeytable.js";
|
||||||
import * as browser from "../util/browser.js";
|
import * as browser from "../util/browser.js";
|
||||||
|
|
||||||
// Get 'KeyboardEvent.code', handling legacy browsers
|
// Get 'KeyboardEvent.code', handling legacy browsers
|
||||||
export function getKeycode(evt){
|
export function getKeycode(evt) {
|
||||||
// Are we getting proper key identifiers?
|
// Are we getting proper key identifiers?
|
||||||
// (unfortunately Firefox and Chrome are crappy here and gives
|
// (unfortunately Firefox and Chrome are crappy here and gives
|
||||||
// us an empty string on some platforms, rather than leaving it
|
// us an empty string on some platforms, rather than leaving it
|
||||||
|
@ -125,7 +125,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) {
|
||||||
const key = getKey(evt);
|
const key = getKey(evt);
|
||||||
|
|
||||||
if (key === 'Unidentified') {
|
if (key === 'Unidentified') {
|
||||||
|
|
30
core/rfb.js
30
core/rfb.js
|
@ -939,7 +939,7 @@ export default class RFB extends EventTargetMixin {
|
||||||
this.dispatchEvent(new CustomEvent(
|
this.dispatchEvent(new CustomEvent(
|
||||||
"credentialsrequired",
|
"credentialsrequired",
|
||||||
{ detail: { types: ["username", "password", "target"] } }));
|
{ detail: { types: ["username", "password", "target"] } }));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const xvp_auth_str = String.fromCharCode(this._rfb_credentials.username.length) +
|
const xvp_auth_str = String.fromCharCode(this._rfb_credentials.username.length) +
|
||||||
|
@ -1407,7 +1407,7 @@ export default class RFB extends EventTargetMixin {
|
||||||
case 2: // Bell
|
case 2: // Bell
|
||||||
Log.Debug("Bell");
|
Log.Debug("Bell");
|
||||||
this.dispatchEvent(new CustomEvent(
|
this.dispatchEvent(new CustomEvent(
|
||||||
"bell",
|
"bell",
|
||||||
{ detail: {} }));
|
{ detail: {} }));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1598,18 +1598,18 @@ export default class RFB extends EventTargetMixin {
|
||||||
let msg = "";
|
let msg = "";
|
||||||
// The y-position indicates the status code from the server
|
// The y-position indicates the status code from the server
|
||||||
switch (this._FBU.y) {
|
switch (this._FBU.y) {
|
||||||
case 1:
|
case 1:
|
||||||
msg = "Resize is administratively prohibited";
|
msg = "Resize is administratively prohibited";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
msg = "Out of resources";
|
msg = "Out of resources";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
msg = "Invalid screen layout";
|
msg = "Invalid screen layout";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg = "Unknown reason";
|
msg = "Unknown reason";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Log.Warn("Server did not accept the resize request: "
|
Log.Warn("Server did not accept the resize request: "
|
||||||
+ msg);
|
+ msg);
|
||||||
|
@ -2036,11 +2036,13 @@ RFB.cursors = {
|
||||||
},
|
},
|
||||||
|
|
||||||
dot: {
|
dot: {
|
||||||
|
/* eslint-disable indent */
|
||||||
rgbaPixels: new Uint8Array([
|
rgbaPixels: new Uint8Array([
|
||||||
255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255,
|
||||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255,
|
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||||
255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255,
|
255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255,
|
||||||
]),
|
]),
|
||||||
|
/* eslint-enable indent */
|
||||||
w: 3, h: 3,
|
w: 3, h: 3,
|
||||||
hotx: 1, hoty: 1,
|
hotx: 1, hoty: 1,
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export let dragThreshold = 10 * (window.devicePixelRatio || 1);
|
||||||
|
|
||||||
let _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 {
|
||||||
const target = document.createElement('canvas');
|
const target = document.createElement('canvas');
|
||||||
|
|
|
@ -174,13 +174,15 @@ export default class Cursor {
|
||||||
}
|
}
|
||||||
|
|
||||||
_showCursor() {
|
_showCursor() {
|
||||||
if (this._canvas.style.visibility === 'hidden')
|
if (this._canvas.style.visibility === 'hidden') {
|
||||||
this._canvas.style.visibility = '';
|
this._canvas.style.visibility = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_hideCursor() {
|
_hideCursor() {
|
||||||
if (this._canvas.style.visibility !== 'hidden')
|
if (this._canvas.style.visibility !== 'hidden') {
|
||||||
this._canvas.style.visibility = 'hidden';
|
this._canvas.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should we currently display the cursor?
|
// Should we currently display the cursor?
|
||||||
|
@ -188,24 +190,28 @@ export default class Cursor {
|
||||||
// different cursor set)
|
// different cursor set)
|
||||||
_shouldShowCursor(target) {
|
_shouldShowCursor(target) {
|
||||||
// Easy case
|
// Easy case
|
||||||
if (target === this._target)
|
if (target === this._target) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
// Other part of the DOM?
|
// Other part of the DOM?
|
||||||
if (!this._target.contains(target))
|
if (!this._target.contains(target)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
// Has the child its own cursor?
|
// Has the child its own cursor?
|
||||||
// FIXME: How can we tell that a sub element has an
|
// FIXME: How can we tell that a sub element has an
|
||||||
// explicit "cursor: none;"?
|
// explicit "cursor: none;"?
|
||||||
if (window.getComputedStyle(target).cursor !== 'none')
|
if (window.getComputedStyle(target).cursor !== 'none') {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateVisibility(target) {
|
_updateVisibility(target) {
|
||||||
if (this._shouldShowCursor(target))
|
if (this._shouldShowCursor(target)) {
|
||||||
this._showCursor();
|
this._showCursor();
|
||||||
else
|
} else {
|
||||||
this._hideCursor();
|
this._hideCursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePosition() {
|
_updatePosition() {
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
* Cross-browser event and position routines
|
* Cross-browser event and position routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ const _captureObserver = new MutationObserver(_captureElemChanged);
|
||||||
|
|
||||||
let _captureIndex = 0;
|
let _captureIndex = 0;
|
||||||
|
|
||||||
export function setCapture (elem) {
|
export function setCapture(elem) {
|
||||||
if (elem.setCapture) {
|
if (elem.setCapture) {
|
||||||
|
|
||||||
elem.setCapture();
|
elem.setCapture();
|
||||||
|
@ -96,7 +96,7 @@ export function setCapture (elem) {
|
||||||
_captureIndex++;
|
_captureIndex++;
|
||||||
|
|
||||||
// Track cursor and get initial cursor
|
// Track cursor and get initial cursor
|
||||||
_captureObserver.observe(elem, {attributes:true});
|
_captureObserver.observe(elem, {attributes: true});
|
||||||
_captureElemChanged();
|
_captureElemChanged();
|
||||||
|
|
||||||
captureElem.style.display = "";
|
captureElem.style.display = "";
|
||||||
|
@ -108,7 +108,7 @@ export function setCapture (elem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function releaseCapture () {
|
export function releaseCapture() {
|
||||||
if (document.releaseCapture) {
|
if (document.releaseCapture) {
|
||||||
|
|
||||||
document.releaseCapture();
|
document.releaseCapture();
|
||||||
|
|
|
@ -11,30 +11,30 @@ export default class EventTargetMixin {
|
||||||
this._listeners = null;
|
this._listeners = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener(type, callback) {
|
addEventListener(type, callback) {
|
||||||
if (!this._listeners) {
|
if (!this._listeners) {
|
||||||
this._listeners = new Map();
|
this._listeners = new Map();
|
||||||
}
|
}
|
||||||
if (!this._listeners.has(type)) {
|
if (!this._listeners.has(type)) {
|
||||||
this._listeners.set(type, new Set());
|
this._listeners.set(type, new Set());
|
||||||
}
|
}
|
||||||
this._listeners.get(type).add(callback);
|
this._listeners.get(type).add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEventListener(type, callback) {
|
removeEventListener(type, callback) {
|
||||||
if (!this._listeners || !this._listeners.has(type)) {
|
if (!this._listeners || !this._listeners.has(type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._listeners.get(type).delete(callback);
|
this._listeners.get(type).delete(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchEvent(event) {
|
dispatchEvent(event) {
|
||||||
if (!this._listeners || !this._listeners.has(event.type)) {
|
if (!this._listeners || !this._listeners.has(event.type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this._listeners.get(event.type).forEach((callback) => {
|
this._listeners.get(event.type).forEach((callback) => {
|
||||||
callback.call(this, event);
|
callback.call(this, event);
|
||||||
}, this);
|
}, this);
|
||||||
return !event.defaultPrevented;
|
return !event.defaultPrevented;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ let Info = () => {};
|
||||||
let Warn = () => {};
|
let Warn = () => {};
|
||||||
let Error = () => {};
|
let Error = () => {};
|
||||||
|
|
||||||
export function init_logging (level) {
|
export function init_logging(level) {
|
||||||
if (typeof level === 'undefined') {
|
if (typeof level === 'undefined') {
|
||||||
level = _log_level;
|
level = _log_level;
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,7 +46,7 @@ export function init_logging (level) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_logging () {
|
export function get_logging() {
|
||||||
return _log_level;
|
return _log_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ if (typeof Object.assign != 'function') {
|
||||||
|
|
||||||
/* CustomEvent constructor (taken from MDN) */
|
/* CustomEvent constructor (taken from MDN) */
|
||||||
(() => {
|
(() => {
|
||||||
function CustomEvent (event, params) {
|
function CustomEvent(event, params) {
|
||||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||||
const 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 );
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
/*
|
/*
|
||||||
* Decode from UTF-8
|
* Decode from UTF-8
|
||||||
*/
|
*/
|
||||||
export function decodeUTF8 (utf8string) {
|
export function decodeUTF8(utf8string) {
|
||||||
return decodeURIComponent(escape(utf8string));
|
return decodeURIComponent(escape(utf8string));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
"sinon": false
|
"sinon": false
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"prefer-arrow-callback": 0
|
"prefer-arrow-callback": 0,
|
||||||
|
// Too many anonymous callbacks
|
||||||
|
"func-names": "off",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,17 @@ chai.use(function (_chai, utils) {
|
||||||
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,
|
||||||
"expected #{this} to have displayed the image #{exp}, but instead it displayed #{act}",
|
"expected #{this} to have displayed the image #{exp}, but instead it displayed #{act}",
|
||||||
"expected #{this} not to have displayed the image #{act}",
|
"expected #{this} not to have displayed the image #{act}",
|
||||||
target_data,
|
target_data,
|
||||||
data);
|
data);
|
||||||
});
|
});
|
||||||
|
|
||||||
_chai.Assertion.addMethod('sent', function (target_data) {
|
_chai.Assertion.addMethod('sent', function (target_data) {
|
||||||
const obj = this._obj;
|
const obj = this._obj;
|
||||||
obj.inspect = () => {
|
obj.inspect = () => {
|
||||||
const 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;
|
||||||
};
|
};
|
||||||
|
@ -51,10 +51,10 @@ chai.use(function (_chai, utils) {
|
||||||
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,
|
||||||
"expected #{this} to have sent the data #{exp}, but it actually sent #{act}",
|
"expected #{this} to have sent the data #{exp}, but it actually sent #{act}",
|
||||||
"expected #{this} not to have sent the data #{act}",
|
"expected #{this} not to have sent the data #{act}",
|
||||||
Array.prototype.slice.call(target_data),
|
Array.prototype.slice.call(target_data),
|
||||||
Array.prototype.slice.call(data));
|
Array.prototype.slice.call(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
_chai.Assertion.addProperty('array', function () {
|
_chai.Assertion.addProperty('array', function () {
|
||||||
|
@ -77,9 +77,9 @@ chai.use(function (_chai, utils) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.assert(same,
|
this.assert(same,
|
||||||
"expected #{this} to have elements deeply equal to #{exp}",
|
"expected #{this} to have elements deeply equal to #{exp}",
|
||||||
"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 (let i = 0; i < obj.length; i++) {
|
for (let i = 0; i < obj.length; i++) {
|
||||||
if (obj[i] != target[i]) {
|
if (obj[i] != target[i]) {
|
||||||
|
@ -89,9 +89,9 @@ chai.use(function (_chai, utils) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.assert(same,
|
this.assert(same,
|
||||||
"expected #{this} to have elements equal to #{exp}",
|
"expected #{this} to have elements equal to #{exp}",
|
||||||
"expected #{this} not to have elements equal to #{exp}",
|
"expected #{this} not to have elements equal to #{exp}",
|
||||||
Array.prototype.slice.call(target));
|
Array.prototype.slice.call(target));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_super.apply(this, arguments);
|
_super.apply(this, arguments);
|
||||||
|
|
|
@ -35,8 +35,9 @@ document.body.appendChild(script);
|
||||||
function fallback() {
|
function fallback() {
|
||||||
if (!window._noVNC_has_module_support) {
|
if (!window._noVNC_has_module_support) {
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
if (console)
|
if (console) {
|
||||||
console.log("No module support detected. Loading fallback...");
|
console.log("No module support detected. Loading fallback...");
|
||||||
|
}
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
let loader = document.createElement("script");
|
let loader = document.createElement("script");
|
||||||
loader.src = "base/vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
|
loader.src = "base/vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
|
||||||
|
|
|
@ -49,8 +49,9 @@ function enableUI() {
|
||||||
|
|
||||||
frames = VNC_frame_data;
|
frames = VNC_frame_data;
|
||||||
// Only present in older recordings
|
// Only present in older recordings
|
||||||
if (window.VNC_frame_encoding)
|
if (window.VNC_frame_encoding) {
|
||||||
encoding = VNC_frame_encoding;
|
encoding = VNC_frame_encoding;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IterationPlayer {
|
class IterationPlayer {
|
||||||
|
|
|
@ -51,8 +51,8 @@ export default class RecordingPlayer {
|
||||||
this._disconnected = disconnected;
|
this._disconnected = disconnected;
|
||||||
|
|
||||||
if (this._encoding === undefined) {
|
if (this._encoding === undefined) {
|
||||||
const frame = this._frames[0];
|
const frame = this._frames[0];
|
||||||
const 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 {
|
||||||
|
|
|
@ -2,7 +2,7 @@ const 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";
|
||||||
|
|
||||||
const BIN_ARR = new Array(256);
|
const BIN_ARR = new Array(256);
|
||||||
|
@ -13,20 +13,20 @@ describe('Base64 Tools', function() {
|
||||||
const 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 () {
|
||||||
const 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 () {
|
||||||
const 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);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if we have extra characters at the end of the string', function() {
|
it('should throw an error if we have extra characters at the end of the string', function () {
|
||||||
expect(() => Base64.decode(B64_STR+'abcdef')).to.throw(Error);
|
expect(() => Base64.decode(B64_STR+'abcdef')).to.throw(Error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
|
|
||||||
const basic_data = new Uint8Array([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]);
|
||||||
|
|
||||||
function make_image_canvas (input_data) {
|
function make_image_canvas(input_data) {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = 4;
|
canvas.width = 4;
|
||||||
canvas.height = 4;
|
canvas.height = 4;
|
||||||
|
@ -24,7 +24,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_image_png (input_data) {
|
function make_image_png(input_data) {
|
||||||
const canvas = make_image_canvas(input_data);
|
const canvas = make_image_canvas(input_data);
|
||||||
const url = canvas.toDataURL();
|
const url = canvas.toDataURL();
|
||||||
const data = url.split(",")[1];
|
const data = url.split(",")[1];
|
||||||
|
@ -53,13 +53,13 @@ describe('Display/Canvas Helper', function () {
|
||||||
expect(display).to.have.displayed(expected);
|
expect(display).to.have.displayed(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should resize the target canvas when resizing the viewport', function() {
|
it('should resize the target canvas when resizing the viewport', function () {
|
||||||
display.viewportChangeSize(2, 2);
|
display.viewportChangeSize(2, 2);
|
||||||
expect(display._target.width).to.equal(2);
|
expect(display._target.width).to.equal(2);
|
||||||
expect(display._target.height).to.equal(2);
|
expect(display._target.height).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should move the viewport if necessary', function() {
|
it('should move the viewport if necessary', function () {
|
||||||
display.viewportChangeSize(5, 5);
|
display.viewportChangeSize(5, 5);
|
||||||
expect(display.absX(0)).to.equal(0);
|
expect(display.absX(0)).to.equal(0);
|
||||||
expect(display.absY(0)).to.equal(0);
|
expect(display.absY(0)).to.equal(0);
|
||||||
|
@ -67,7 +67,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
expect(display._target.height).to.equal(5);
|
expect(display._target.height).to.equal(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should limit the viewport to the framebuffer size', function() {
|
it('should limit the viewport to the framebuffer size', function () {
|
||||||
display.viewportChangeSize(6, 6);
|
display.viewportChangeSize(6, 6);
|
||||||
expect(display._target.width).to.equal(5);
|
expect(display._target.width).to.equal(5);
|
||||||
expect(display._target.height).to.equal(5);
|
expect(display._target.height).to.equal(5);
|
||||||
|
@ -85,7 +85,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
expect(display.flip).to.have.been.calledOnce;
|
expect(display.flip).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the entire framebuffer when disabling the viewport', function() {
|
it('should show the entire framebuffer when disabling the viewport', function () {
|
||||||
display.clipViewport = false;
|
display.clipViewport = false;
|
||||||
expect(display.absX(0)).to.equal(0);
|
expect(display.absX(0)).to.equal(0);
|
||||||
expect(display.absY(0)).to.equal(0);
|
expect(display.absY(0)).to.equal(0);
|
||||||
|
@ -93,7 +93,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
expect(display._target.height).to.equal(5);
|
expect(display._target.height).to.equal(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore viewport changes when the viewport is disabled', function() {
|
it('should ignore viewport changes when the viewport is disabled', function () {
|
||||||
display.clipViewport = false;
|
display.clipViewport = false;
|
||||||
display.viewportChangeSize(2, 2);
|
display.viewportChangeSize(2, 2);
|
||||||
display.viewportChangePos(1, 1);
|
display.viewportChangePos(1, 1);
|
||||||
|
@ -103,7 +103,7 @@ describe('Display/Canvas Helper', function () {
|
||||||
expect(display._target.height).to.equal(5);
|
expect(display._target.height).to.equal(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the entire framebuffer just after enabling the viewport', function() {
|
it('should show the entire framebuffer just after enabling the viewport', function () {
|
||||||
display.clipViewport = false;
|
display.clipViewport = false;
|
||||||
display.clipViewport = true;
|
display.clipViewport = true;
|
||||||
expect(display.absX(0)).to.equal(0);
|
expect(display.absX(0)).to.equal(0);
|
||||||
|
@ -422,7 +422,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 () {
|
||||||
const 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();
|
||||||
|
|
|
@ -4,66 +4,66 @@ import keysyms from '../core/input/keysymdef.js';
|
||||||
import * as KeyboardUtil from "../core/input/util.js";
|
import * as KeyboardUtil from "../core/input/util.js";
|
||||||
import * as browser from '../core/util/browser.js';
|
import * as browser from '../core/util/browser.js';
|
||||||
|
|
||||||
describe('Helpers', function() {
|
describe('Helpers', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('keysyms.lookup', function() {
|
describe('keysyms.lookup', function () {
|
||||||
it('should map ASCII characters to keysyms', function() {
|
it('should map ASCII characters to keysyms', function () {
|
||||||
expect(keysyms.lookup('a'.charCodeAt())).to.be.equal(0x61);
|
expect(keysyms.lookup('a'.charCodeAt())).to.be.equal(0x61);
|
||||||
expect(keysyms.lookup('A'.charCodeAt())).to.be.equal(0x41);
|
expect(keysyms.lookup('A'.charCodeAt())).to.be.equal(0x41);
|
||||||
});
|
});
|
||||||
it('should map Latin-1 characters to keysyms', function() {
|
it('should map Latin-1 characters to keysyms', function () {
|
||||||
expect(keysyms.lookup('ø'.charCodeAt())).to.be.equal(0xf8);
|
expect(keysyms.lookup('ø'.charCodeAt())).to.be.equal(0xf8);
|
||||||
|
|
||||||
expect(keysyms.lookup('é'.charCodeAt())).to.be.equal(0xe9);
|
expect(keysyms.lookup('é'.charCodeAt())).to.be.equal(0xe9);
|
||||||
});
|
});
|
||||||
it('should map characters that are in Windows-1252 but not in Latin-1 to keysyms', function() {
|
it('should map characters that are in Windows-1252 but not in Latin-1 to keysyms', function () {
|
||||||
expect(keysyms.lookup('Š'.charCodeAt())).to.be.equal(0x01a9);
|
expect(keysyms.lookup('Š'.charCodeAt())).to.be.equal(0x01a9);
|
||||||
});
|
});
|
||||||
it('should map characters which aren\'t in Latin1 *or* Windows-1252 to keysyms', function() {
|
it('should map characters which aren\'t in Latin1 *or* Windows-1252 to keysyms', function () {
|
||||||
expect(keysyms.lookup('ũ'.charCodeAt())).to.be.equal(0x03fd);
|
expect(keysyms.lookup('ũ'.charCodeAt())).to.be.equal(0x03fd);
|
||||||
});
|
});
|
||||||
it('should map unknown codepoints to the Unicode range', function() {
|
it('should map unknown codepoints to the Unicode range', function () {
|
||||||
expect(keysyms.lookup('\n'.charCodeAt())).to.be.equal(0x100000a);
|
expect(keysyms.lookup('\n'.charCodeAt())).to.be.equal(0x100000a);
|
||||||
expect(keysyms.lookup('\u262D'.charCodeAt())).to.be.equal(0x100262d);
|
expect(keysyms.lookup('\u262D'.charCodeAt())).to.be.equal(0x100262d);
|
||||||
});
|
});
|
||||||
// This requires very recent versions of most browsers... skipping for now
|
// This requires very recent versions of most browsers... skipping for now
|
||||||
it.skip('should map UCS-4 codepoints to the Unicode range', function() {
|
it.skip('should map UCS-4 codepoints to the Unicode range', function () {
|
||||||
//expect(keysyms.lookup('\u{1F686}'.codePointAt())).to.be.equal(0x101f686);
|
//expect(keysyms.lookup('\u{1F686}'.codePointAt())).to.be.equal(0x101f686);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getKeycode', function() {
|
describe('getKeycode', function () {
|
||||||
it('should pass through proper code', function() {
|
it('should pass through proper code', function () {
|
||||||
expect(KeyboardUtil.getKeycode({code: 'Semicolon'})).to.be.equal('Semicolon');
|
expect(KeyboardUtil.getKeycode({code: 'Semicolon'})).to.be.equal('Semicolon');
|
||||||
});
|
});
|
||||||
it('should map legacy values', function() {
|
it('should map legacy values', function () {
|
||||||
expect(KeyboardUtil.getKeycode({code: ''})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKeycode({code: ''})).to.be.equal('Unidentified');
|
||||||
expect(KeyboardUtil.getKeycode({code: 'OSLeft'})).to.be.equal('MetaLeft');
|
expect(KeyboardUtil.getKeycode({code: 'OSLeft'})).to.be.equal('MetaLeft');
|
||||||
});
|
});
|
||||||
it('should map keyCode to code when possible', function() {
|
it('should map keyCode to code when possible', function () {
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x14})).to.be.equal('CapsLock');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x14})).to.be.equal('CapsLock');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x5b})).to.be.equal('MetaLeft');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x5b})).to.be.equal('MetaLeft');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x35})).to.be.equal('Digit5');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x35})).to.be.equal('Digit5');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x65})).to.be.equal('Numpad5');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x65})).to.be.equal('Numpad5');
|
||||||
});
|
});
|
||||||
it('should map keyCode left/right side', function() {
|
it('should map keyCode left/right side', function () {
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 1})).to.be.equal('ShiftLeft');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 1})).to.be.equal('ShiftLeft');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 2})).to.be.equal('ShiftRight');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 2})).to.be.equal('ShiftRight');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 1})).to.be.equal('ControlLeft');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 1})).to.be.equal('ControlLeft');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 2})).to.be.equal('ControlRight');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 2})).to.be.equal('ControlRight');
|
||||||
});
|
});
|
||||||
it('should map keyCode on numpad', function() {
|
it('should map keyCode on numpad', function () {
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 0})).to.be.equal('Enter');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 0})).to.be.equal('Enter');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 3})).to.be.equal('NumpadEnter');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 3})).to.be.equal('NumpadEnter');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 0})).to.be.equal('End');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 0})).to.be.equal('End');
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 3})).to.be.equal('Numpad1');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 3})).to.be.equal('Numpad1');
|
||||||
});
|
});
|
||||||
it('should return Unidentified when it cannot map the keyCode', function() {
|
it('should return Unidentified when it cannot map the keyCode', function () {
|
||||||
expect(KeyboardUtil.getKeycode({keycode: 0x42})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKeycode({keycode: 0x42})).to.be.equal('Unidentified');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Fix Meta on macOS', function() {
|
describe('Fix Meta on macOS', function () {
|
||||||
let 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
|
||||||
|
@ -89,44 +89,44 @@ describe('Helpers', function() {
|
||||||
Object.defineProperty(window, "navigator", origNavigator);
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respect ContextMenu on modern browser', function() {
|
it('should respect ContextMenu on modern browser', function () {
|
||||||
expect(KeyboardUtil.getKeycode({code: 'ContextMenu', keyCode: 0x5d})).to.be.equal('ContextMenu');
|
expect(KeyboardUtil.getKeycode({code: 'ContextMenu', keyCode: 0x5d})).to.be.equal('ContextMenu');
|
||||||
});
|
});
|
||||||
it('should translate legacy ContextMenu to MetaRight', function() {
|
it('should translate legacy ContextMenu to MetaRight', function () {
|
||||||
expect(KeyboardUtil.getKeycode({keyCode: 0x5d})).to.be.equal('MetaRight');
|
expect(KeyboardUtil.getKeycode({keyCode: 0x5d})).to.be.equal('MetaRight');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getKey', function() {
|
describe('getKey', function () {
|
||||||
it('should prefer key', function() {
|
it('should prefer key', function () {
|
||||||
if (browser.isIE() || browser.isEdge()) this.skip();
|
if (browser.isIE() || browser.isEdge()) this.skip();
|
||||||
expect(KeyboardUtil.getKey({key: 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal('a');
|
expect(KeyboardUtil.getKey({key: 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal('a');
|
||||||
});
|
});
|
||||||
it('should map legacy values', function() {
|
it('should map legacy values', function () {
|
||||||
expect(KeyboardUtil.getKey({key: 'Spacebar'})).to.be.equal(' ');
|
expect(KeyboardUtil.getKey({key: 'Spacebar'})).to.be.equal(' ');
|
||||||
expect(KeyboardUtil.getKey({key: 'Left'})).to.be.equal('ArrowLeft');
|
expect(KeyboardUtil.getKey({key: 'Left'})).to.be.equal('ArrowLeft');
|
||||||
expect(KeyboardUtil.getKey({key: 'OS'})).to.be.equal('Meta');
|
expect(KeyboardUtil.getKey({key: 'OS'})).to.be.equal('Meta');
|
||||||
expect(KeyboardUtil.getKey({key: 'Win'})).to.be.equal('Meta');
|
expect(KeyboardUtil.getKey({key: 'Win'})).to.be.equal('Meta');
|
||||||
expect(KeyboardUtil.getKey({key: 'UIKeyInputLeftArrow'})).to.be.equal('ArrowLeft');
|
expect(KeyboardUtil.getKey({key: 'UIKeyInputLeftArrow'})).to.be.equal('ArrowLeft');
|
||||||
});
|
});
|
||||||
it('should use code if no key', function() {
|
it('should use code if no key', function () {
|
||||||
expect(KeyboardUtil.getKey({code: 'NumpadBackspace'})).to.be.equal('Backspace');
|
expect(KeyboardUtil.getKey({code: 'NumpadBackspace'})).to.be.equal('Backspace');
|
||||||
});
|
});
|
||||||
it('should not use code fallback for character keys', function() {
|
it('should not use code fallback for character keys', function () {
|
||||||
expect(KeyboardUtil.getKey({code: 'KeyA'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({code: 'KeyA'})).to.be.equal('Unidentified');
|
||||||
expect(KeyboardUtil.getKey({code: 'Digit1'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({code: 'Digit1'})).to.be.equal('Unidentified');
|
||||||
expect(KeyboardUtil.getKey({code: 'Period'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({code: 'Period'})).to.be.equal('Unidentified');
|
||||||
expect(KeyboardUtil.getKey({code: 'Numpad1'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({code: 'Numpad1'})).to.be.equal('Unidentified');
|
||||||
});
|
});
|
||||||
it('should use charCode if no key', function() {
|
it('should use charCode if no key', function () {
|
||||||
expect(KeyboardUtil.getKey({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal('Š');
|
expect(KeyboardUtil.getKey({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal('Š');
|
||||||
});
|
});
|
||||||
it('should return Unidentified when it cannot map the key', function() {
|
it('should return Unidentified when it cannot map the key', function () {
|
||||||
expect(KeyboardUtil.getKey({keycode: 0x42})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({keycode: 0x42})).to.be.equal('Unidentified');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Broken key AltGraph on IE/Edge', function() {
|
describe('Broken key AltGraph on IE/Edge', function () {
|
||||||
let 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
|
||||||
|
@ -150,28 +150,28 @@ describe('Helpers', function() {
|
||||||
Object.defineProperty(window, "navigator", origNavigator);
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore printable character key on IE', function() {
|
it('should ignore printable character key on IE', function () {
|
||||||
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
|
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
|
||||||
expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified');
|
||||||
});
|
});
|
||||||
it('should ignore printable character key on Edge', function() {
|
it('should ignore printable character key on Edge', function () {
|
||||||
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
|
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
|
||||||
expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified');
|
expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified');
|
||||||
});
|
});
|
||||||
it('should allow non-printable character key on IE', function() {
|
it('should allow non-printable character key on IE', function () {
|
||||||
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
|
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
|
||||||
expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift');
|
expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift');
|
||||||
});
|
});
|
||||||
it('should allow non-printable character key on Edge', function() {
|
it('should allow non-printable character key on Edge', function () {
|
||||||
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
|
window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
|
||||||
expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift');
|
expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getKeysym', function() {
|
describe('getKeysym', function () {
|
||||||
describe('Non-character keys', function() {
|
describe('Non-character keys', function () {
|
||||||
it('should recognize the right keys', function() {
|
it('should recognize the right keys', function () {
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Enter'})).to.be.equal(0xFF0D);
|
expect(KeyboardUtil.getKeysym({key: 'Enter'})).to.be.equal(0xFF0D);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Backspace'})).to.be.equal(0xFF08);
|
expect(KeyboardUtil.getKeysym({key: 'Backspace'})).to.be.equal(0xFF08);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Tab'})).to.be.equal(0xFF09);
|
expect(KeyboardUtil.getKeysym({key: 'Tab'})).to.be.equal(0xFF09);
|
||||||
|
@ -182,38 +182,38 @@ describe('Helpers', function() {
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Escape'})).to.be.equal(0xFF1B);
|
expect(KeyboardUtil.getKeysym({key: 'Escape'})).to.be.equal(0xFF1B);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'ArrowUp'})).to.be.equal(0xFF52);
|
expect(KeyboardUtil.getKeysym({key: 'ArrowUp'})).to.be.equal(0xFF52);
|
||||||
});
|
});
|
||||||
it('should map left/right side', function() {
|
it('should map left/right side', function () {
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Shift', location: 1})).to.be.equal(0xFFE1);
|
expect(KeyboardUtil.getKeysym({key: 'Shift', location: 1})).to.be.equal(0xFFE1);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Shift', location: 2})).to.be.equal(0xFFE2);
|
expect(KeyboardUtil.getKeysym({key: 'Shift', location: 2})).to.be.equal(0xFFE2);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Control', location: 1})).to.be.equal(0xFFE3);
|
expect(KeyboardUtil.getKeysym({key: 'Control', location: 1})).to.be.equal(0xFFE3);
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Control', location: 2})).to.be.equal(0xFFE4);
|
expect(KeyboardUtil.getKeysym({key: 'Control', location: 2})).to.be.equal(0xFFE4);
|
||||||
});
|
});
|
||||||
it('should handle AltGraph', function() {
|
it('should handle AltGraph', function () {
|
||||||
expect(KeyboardUtil.getKeysym({code: 'AltRight', key: 'Alt', location: 2})).to.be.equal(0xFFEA);
|
expect(KeyboardUtil.getKeysym({code: 'AltRight', key: 'Alt', location: 2})).to.be.equal(0xFFEA);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'AltRight', key: 'AltGraph', location: 2})).to.be.equal(0xFE03);
|
expect(KeyboardUtil.getKeysym({code: 'AltRight', key: 'AltGraph', location: 2})).to.be.equal(0xFE03);
|
||||||
});
|
});
|
||||||
it('should return null for unknown keys', function() {
|
it('should return null for unknown keys', function () {
|
||||||
expect(KeyboardUtil.getKeysym({key: 'Semicolon'})).to.be.null;
|
expect(KeyboardUtil.getKeysym({key: 'Semicolon'})).to.be.null;
|
||||||
expect(KeyboardUtil.getKeysym({key: 'BracketRight'})).to.be.null;
|
expect(KeyboardUtil.getKeysym({key: 'BracketRight'})).to.be.null;
|
||||||
});
|
});
|
||||||
it('should handle remappings', function() {
|
it('should handle remappings', function () {
|
||||||
expect(KeyboardUtil.getKeysym({code: 'ControlLeft', key: 'Tab'})).to.be.equal(0xFF09);
|
expect(KeyboardUtil.getKeysym({code: 'ControlLeft', key: 'Tab'})).to.be.equal(0xFF09);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Numpad', function() {
|
describe('Numpad', function () {
|
||||||
it('should handle Numpad numbers', function() {
|
it('should handle Numpad numbers', function () {
|
||||||
if (browser.isIE() || browser.isEdge()) this.skip();
|
if (browser.isIE() || browser.isEdge()) this.skip();
|
||||||
expect(KeyboardUtil.getKeysym({code: 'Digit5', key: '5', location: 0})).to.be.equal(0x0035);
|
expect(KeyboardUtil.getKeysym({code: 'Digit5', key: '5', location: 0})).to.be.equal(0x0035);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'Numpad5', key: '5', location: 3})).to.be.equal(0xFFB5);
|
expect(KeyboardUtil.getKeysym({code: 'Numpad5', key: '5', location: 3})).to.be.equal(0xFFB5);
|
||||||
});
|
});
|
||||||
it('should handle Numpad non-character keys', function() {
|
it('should handle Numpad non-character keys', function () {
|
||||||
expect(KeyboardUtil.getKeysym({code: 'Home', key: 'Home', location: 0})).to.be.equal(0xFF50);
|
expect(KeyboardUtil.getKeysym({code: 'Home', key: 'Home', location: 0})).to.be.equal(0xFF50);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'Numpad5', key: 'Home', location: 3})).to.be.equal(0xFF95);
|
expect(KeyboardUtil.getKeysym({code: 'Numpad5', key: 'Home', location: 3})).to.be.equal(0xFF95);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'Delete', key: 'Delete', location: 0})).to.be.equal(0xFFFF);
|
expect(KeyboardUtil.getKeysym({code: 'Delete', key: 'Delete', location: 0})).to.be.equal(0xFFFF);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: 'Delete', location: 3})).to.be.equal(0xFF9F);
|
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: 'Delete', location: 3})).to.be.equal(0xFF9F);
|
||||||
});
|
});
|
||||||
it('should handle Numpad Decimal key', function() {
|
it('should handle Numpad Decimal key', function () {
|
||||||
if (browser.isIE() || browser.isEdge()) this.skip();
|
if (browser.isIE() || browser.isEdge()) this.skip();
|
||||||
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: '.', location: 3})).to.be.equal(0xFFAE);
|
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: '.', location: 3})).to.be.equal(0xFFAE);
|
||||||
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: ',', location: 3})).to.be.equal(0xFFAC);
|
expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: ',', location: 3})).to.be.equal(0xFFAC);
|
||||||
|
|
|
@ -3,7 +3,7 @@ const expect = chai.expect;
|
||||||
import Keyboard from '../core/input/keyboard.js';
|
import Keyboard from '../core/input/keyboard.js';
|
||||||
import * as browser from '../core/util/browser.js';
|
import * as browser from '../core/util/browser.js';
|
||||||
|
|
||||||
describe('Key Event Handling', function() {
|
describe('Key Event Handling', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// The real KeyboardEvent constructor might not work everywhere we
|
// The real KeyboardEvent constructor might not work everywhere we
|
||||||
|
@ -18,8 +18,8 @@ describe('Key Event Handling', function() {
|
||||||
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();
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
|
@ -30,7 +30,7 @@ describe('Key Event Handling', function() {
|
||||||
};
|
};
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
|
||||||
});
|
});
|
||||||
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();
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
|
@ -46,14 +46,14 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
|
kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'}));
|
||||||
});
|
});
|
||||||
|
|
||||||
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 () {
|
||||||
const 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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -64,14 +64,14 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
||||||
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 () {
|
||||||
const 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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -82,7 +82,7 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
||||||
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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x32);
|
expect(keysym).to.be.equal(0x32);
|
||||||
|
@ -92,7 +92,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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -102,7 +102,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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x41);
|
expect(keysym).to.be.equal(0x41);
|
||||||
|
@ -112,7 +112,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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0);
|
expect(keysym).to.be.equal(0);
|
||||||
|
@ -124,11 +124,11 @@ describe('Key Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('suppress the right events at the right time', function() {
|
describe('suppress the right events at the right time', function () {
|
||||||
beforeEach(function () {
|
beforeEach(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 () {
|
||||||
const kbd = new Keyboard(document, {});
|
const kbd = new Keyboard(document, {});
|
||||||
const evt1 = keyevent('keydown', {code: 'KeyA', key: 'a'});
|
const evt1 = keyevent('keydown', {code: 'KeyA', key: 'a'});
|
||||||
kbd._handleKeyDown(evt1);
|
kbd._handleKeyDown(evt1);
|
||||||
|
@ -137,13 +137,13 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyUp(evt2);
|
kbd._handleKeyUp(evt2);
|
||||||
expect(evt2.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 () {
|
||||||
const kbd = new Keyboard(document, {});
|
const kbd = new Keyboard(document, {});
|
||||||
const 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 () {
|
||||||
const kbd = new Keyboard(document, {});
|
const kbd = new Keyboard(document, {});
|
||||||
const evt1 = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
|
const evt1 = keyevent('keydown', {code: 'KeyA', keyCode: 0x41});
|
||||||
kbd._handleKeyDown(evt1);
|
kbd._handleKeyDown(evt1);
|
||||||
|
@ -154,8 +154,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();
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
|
@ -176,7 +176,7 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'Unidentified', key: 'a'}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'Unidentified', key: 'a'}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('iOS', function() {
|
describe('iOS', function () {
|
||||||
let 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
|
||||||
|
@ -202,7 +202,7 @@ describe('Key Event Handling', function() {
|
||||||
Object.defineProperty(window, "navigator", origNavigator);
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
});
|
});
|
||||||
|
|
||||||
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();
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
|
@ -225,11 +225,11 @@ describe('Key Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Track Key State', function() {
|
describe('Track Key State', function () {
|
||||||
beforeEach(function () {
|
beforeEach(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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -241,7 +241,7 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
|
||||||
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 () {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
|
@ -254,15 +254,15 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'b'}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'b'}));
|
||||||
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 () {
|
||||||
const 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;
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -274,7 +274,7 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {keyCode: 65, key: 'a'}));
|
kbd._handleKeyDown(keyevent('keydown', {keyCode: 65, key: 'a'}));
|
||||||
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 () {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -282,7 +282,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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0x61);
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
@ -297,7 +297,7 @@ describe('Key Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Shuffle modifiers on macOS', function() {
|
describe('Shuffle modifiers on macOS', function () {
|
||||||
let 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
|
||||||
|
@ -323,7 +323,7 @@ describe('Key Event Handling', function() {
|
||||||
Object.defineProperty(window, "navigator", origNavigator);
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change Alt to AltGraph', function() {
|
it('should change Alt to AltGraph', function () {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
|
@ -342,7 +342,7 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
|
||||||
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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0xFFE9);
|
expect(keysym).to.be.equal(0xFFE9);
|
||||||
|
@ -351,7 +351,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) {
|
||||||
const kbd = new Keyboard(document);
|
const kbd = new Keyboard(document);
|
||||||
kbd.onkeyevent = (keysym, code, down) => {
|
kbd.onkeyevent = (keysym, code, down) => {
|
||||||
expect(keysym).to.be.equal(0xFFEB);
|
expect(keysym).to.be.equal(0xFFEB);
|
||||||
|
@ -362,7 +362,7 @@ describe('Key Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Escape AltGraph on Windows', function() {
|
describe('Escape AltGraph on Windows', function () {
|
||||||
let 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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
import { l10n } from '../app/localization.js';
|
import { l10n } from '../app/localization.js';
|
||||||
|
|
||||||
describe('Localization', function() {
|
describe('Localization', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('language selection', function () {
|
describe('language selection', function () {
|
||||||
|
@ -30,40 +30,40 @@ describe('Localization', function() {
|
||||||
Object.defineProperty(window, "navigator", origNavigator);
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use English by default', function() {
|
it('should use English by default', function () {
|
||||||
expect(l10n.language).to.equal('en');
|
expect(l10n.language).to.equal('en');
|
||||||
});
|
});
|
||||||
it('should use English if no user language matches', function() {
|
it('should use English if no user language matches', function () {
|
||||||
window.navigator.languages = ["nl", "de"];
|
window.navigator.languages = ["nl", "de"];
|
||||||
l10n.setup(["es", "fr"]);
|
l10n.setup(["es", "fr"]);
|
||||||
expect(l10n.language).to.equal('en');
|
expect(l10n.language).to.equal('en');
|
||||||
});
|
});
|
||||||
it('should use the most preferred user language', function() {
|
it('should use the most preferred user language', function () {
|
||||||
window.navigator.languages = ["nl", "de", "fr"];
|
window.navigator.languages = ["nl", "de", "fr"];
|
||||||
l10n.setup(["es", "fr", "de"]);
|
l10n.setup(["es", "fr", "de"]);
|
||||||
expect(l10n.language).to.equal('de');
|
expect(l10n.language).to.equal('de');
|
||||||
});
|
});
|
||||||
it('should prefer sub-languages languages', function() {
|
it('should prefer sub-languages languages', function () {
|
||||||
window.navigator.languages = ["pt-BR"];
|
window.navigator.languages = ["pt-BR"];
|
||||||
l10n.setup(["pt", "pt-BR"]);
|
l10n.setup(["pt", "pt-BR"]);
|
||||||
expect(l10n.language).to.equal('pt-BR');
|
expect(l10n.language).to.equal('pt-BR');
|
||||||
});
|
});
|
||||||
it('should fall back to language "parents"', function() {
|
it('should fall back to language "parents"', function () {
|
||||||
window.navigator.languages = ["pt-BR"];
|
window.navigator.languages = ["pt-BR"];
|
||||||
l10n.setup(["fr", "pt", "de"]);
|
l10n.setup(["fr", "pt", "de"]);
|
||||||
expect(l10n.language).to.equal('pt');
|
expect(l10n.language).to.equal('pt');
|
||||||
});
|
});
|
||||||
it('should not use specific language when user asks for a generic language', function() {
|
it('should not use specific language when user asks for a generic language', function () {
|
||||||
window.navigator.languages = ["pt", "de"];
|
window.navigator.languages = ["pt", "de"];
|
||||||
l10n.setup(["fr", "pt-BR", "de"]);
|
l10n.setup(["fr", "pt-BR", "de"]);
|
||||||
expect(l10n.language).to.equal('de');
|
expect(l10n.language).to.equal('de');
|
||||||
});
|
});
|
||||||
it('should handle underscore as a separator', function() {
|
it('should handle underscore as a separator', function () {
|
||||||
window.navigator.languages = ["pt-BR"];
|
window.navigator.languages = ["pt-BR"];
|
||||||
l10n.setup(["pt_BR"]);
|
l10n.setup(["pt_BR"]);
|
||||||
expect(l10n.language).to.equal('pt_BR');
|
expect(l10n.language).to.equal('pt_BR');
|
||||||
});
|
});
|
||||||
it('should handle difference in case', function() {
|
it('should handle difference in case', function () {
|
||||||
window.navigator.languages = ["pt-br"];
|
window.navigator.languages = ["pt-br"];
|
||||||
l10n.setup(["pt-BR"]);
|
l10n.setup(["pt-BR"]);
|
||||||
expect(l10n.language).to.equal('pt-BR');
|
expect(l10n.language).to.equal('pt-BR');
|
||||||
|
|
|
@ -2,7 +2,7 @@ const expect = chai.expect;
|
||||||
|
|
||||||
import Mouse from '../core/input/mouse.js';
|
import Mouse from '../core/input/mouse.js';
|
||||||
|
|
||||||
describe('Mouse Event Handling', function() {
|
describe('Mouse Event Handling', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
let target;
|
let target;
|
||||||
|
@ -36,8 +36,8 @@ describe('Mouse Event Handling', function() {
|
||||||
};
|
};
|
||||||
const touchevent = mouseevent;
|
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) {
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
expect(bmask).to.be.equal(0x01);
|
expect(bmask).to.be.equal(0x01);
|
||||||
|
@ -46,7 +46,7 @@ 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) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -59,7 +59,7 @@ describe('Mouse Event Handling', function() {
|
||||||
mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' }));
|
mouse._handleMouseDown(mouseevent('mousedown', { button: '0x01' }));
|
||||||
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) {
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousemove = (x, y) => {
|
mouse.onmousemove = (x, y) => {
|
||||||
// Note that target relative coordinates are sent
|
// Note that target relative coordinates are sent
|
||||||
|
@ -70,7 +70,7 @@ describe('Mouse Event Handling', function() {
|
||||||
mouse._handleMouseMove(mouseevent('mousemove',
|
mouse._handleMouseMove(mouseevent('mousemove',
|
||||||
{ clientX: 50, clientY: 20 }));
|
{ clientX: 50, clientY: 20 }));
|
||||||
});
|
});
|
||||||
it('should decode mousewheel events', function(done) {
|
it('should decode mousewheel events', function (done) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -89,12 +89,12 @@ describe('Mouse Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Double-click for Touch', function() {
|
describe('Double-click for Touch', function () {
|
||||||
|
|
||||||
beforeEach(function () { this.clock = sinon.useFakeTimers(); });
|
beforeEach(function () { this.clock = sinon.useFakeTimers(); });
|
||||||
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) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -125,7 +125,7 @@ describe('Mouse Event Handling', function() {
|
||||||
'touchend', { touches: [{ clientX: 66, clientY: 36 }]}));
|
'touchend', { touches: [{ clientX: 66, clientY: 36 }]}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not modify 2nd tap pos if far apart', function(done) {
|
it('should not modify 2nd tap pos if far apart', function (done) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -154,7 +154,7 @@ describe('Mouse Event Handling', function() {
|
||||||
'touchend', { touches: [{ clientX: 56, clientY: 36 }]}));
|
'touchend', { touches: [{ clientX: 56, clientY: 36 }]}));
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -183,7 +183,7 @@ describe('Mouse Event Handling', function() {
|
||||||
'touchend', { touches: [{ clientX: 66, clientY: 36 }]}));
|
'touchend', { touches: [{ clientX: 66, clientY: 36 }]}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not modify 2nd tap pos if not touch', function(done) {
|
it('should not modify 2nd tap pos if not touch', function (done) {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const mouse = new Mouse(target);
|
const mouse = new Mouse(target);
|
||||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||||
|
@ -214,7 +214,7 @@ describe('Mouse Event Handling', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Accumulate mouse wheel events with small delta', function() {
|
describe('Accumulate mouse wheel events with small delta', function () {
|
||||||
|
|
||||||
beforeEach(function () { this.clock = sinon.useFakeTimers(); });
|
beforeEach(function () { this.clock = sinon.useFakeTimers(); });
|
||||||
afterEach(function () { this.clock.restore(); });
|
afterEach(function () { this.clock.restore(); });
|
||||||
|
|
|
@ -10,7 +10,7 @@ import FakeWebSocket from './fake.websocket.js';
|
||||||
(() => {
|
(() => {
|
||||||
if (typeof window.UIEvent === "function") return;
|
if (typeof window.UIEvent === "function") return;
|
||||||
|
|
||||||
function UIEvent ( event, params ) {
|
function UIEvent( event, params ) {
|
||||||
params = params || { bubbles: false, cancelable: false, view: window, detail: undefined };
|
params = params || { bubbles: false, cancelable: false, view: window, detail: undefined };
|
||||||
const evt = document.createEvent( 'UIEvent' );
|
const evt = document.createEvent( 'UIEvent' );
|
||||||
evt.initUIEvent( event, params.bubbles, params.cancelable, params.view, params.detail );
|
evt.initUIEvent( event, params.bubbles, params.cancelable, params.view, params.detail );
|
||||||
|
@ -30,18 +30,18 @@ function push8(arr, num) {
|
||||||
function push16(arr, num) {
|
function push16(arr, num) {
|
||||||
"use strict";
|
"use strict";
|
||||||
arr.push((num >> 8) & 0xFF,
|
arr.push((num >> 8) & 0xFF,
|
||||||
num & 0xFF);
|
num & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
function push32(arr, num) {
|
function push32(arr, num) {
|
||||||
"use strict";
|
"use strict";
|
||||||
arr.push((num >> 24) & 0xFF,
|
arr.push((num >> 24) & 0xFF,
|
||||||
(num >> 16) & 0xFF,
|
(num >> 16) & 0xFF,
|
||||||
(num >> 8) & 0xFF,
|
(num >> 8) & 0xFF,
|
||||||
num & 0xFF);
|
num & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Remote Frame Buffer Protocol Client', function() {
|
describe('Remote Frame Buffer Protocol Client', function () {
|
||||||
let clock;
|
let clock;
|
||||||
let raf;
|
let raf;
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
container = null;
|
container = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
function make_rfb (url, options) {
|
function make_rfb(url, options) {
|
||||||
url = url || 'wss://host:8675';
|
url = url || 'wss://host:8675';
|
||||||
const rfb = new RFB(container, url, options);
|
const rfb = new RFB(container, url, options);
|
||||||
clock.tick();
|
clock.tick();
|
||||||
|
@ -286,7 +286,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
describe('#clipboardPasteFrom', function () {
|
describe('#clipboardPasteFrom', function () {
|
||||||
it('should send the given text in a paste event', function () {
|
it('should send the given text in a paste event', function () {
|
||||||
const expected = {_sQ: new Uint8Array(11), _sQlen: 0,
|
const expected = {_sQ: new Uint8Array(11), _sQlen: 0,
|
||||||
_sQbufferSize: 11, flush: () => {}};
|
_sQbufferSize: 11, flush: () => {}};
|
||||||
RFB.messages.clientCutText(expected, 'abc');
|
RFB.messages.clientCutText(expected, 'abc');
|
||||||
client.clipboardPasteFrom('abc');
|
client.clipboardPasteFrom('abc');
|
||||||
expect(client._sock).to.have.sent(expected._sQ);
|
expect(client._sock).to.have.sent(expected._sQ);
|
||||||
|
@ -376,10 +376,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
it('should update the viewport when the remote session resizes', function () {
|
it('should update the viewport when the remote session resizes', function () {
|
||||||
// Simple ExtendedDesktopSize FBU message
|
// Simple ExtendedDesktopSize FBU message
|
||||||
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
|
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0x00 ];
|
0x00, 0x00, 0x00, 0x00 ];
|
||||||
|
|
||||||
sinon.spy(client._display, "viewportChangeSize");
|
sinon.spy(client._display, "viewportChangeSize");
|
||||||
|
|
||||||
|
@ -566,10 +566,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
it('should update the scaling when the remote session resizes', function () {
|
it('should update the scaling when the remote session resizes', function () {
|
||||||
// Simple ExtendedDesktopSize FBU message
|
// Simple ExtendedDesktopSize FBU message
|
||||||
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
|
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0x00 ];
|
0x00, 0x00, 0x00, 0x00 ];
|
||||||
|
|
||||||
sinon.spy(client._display, "autoscale");
|
sinon.spy(client._display, "autoscale");
|
||||||
|
|
||||||
|
@ -619,10 +619,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
it('should request a resize when initially connecting', function () {
|
it('should request a resize when initially connecting', function () {
|
||||||
// Simple ExtendedDesktopSize FBU message
|
// Simple ExtendedDesktopSize FBU message
|
||||||
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
|
0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
|
||||||
0x00, 0x00, 0x00, 0x00 ];
|
0x00, 0x00, 0x00, 0x00 ];
|
||||||
|
|
||||||
// First message should trigger a resize
|
// First message should trigger a resize
|
||||||
|
|
||||||
|
@ -715,10 +715,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
it('should not try to override a server resize', function () {
|
it('should not try to override a server resize', function () {
|
||||||
// Simple ExtendedDesktopSize FBU message
|
// Simple ExtendedDesktopSize FBU message
|
||||||
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
const incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
|
0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
|
||||||
0x00, 0x00, 0x00, 0x00 ];
|
0x00, 0x00, 0x00, 0x00 ];
|
||||||
|
|
||||||
client._sock._websocket._receive_data(new Uint8Array(incoming));
|
client._sock._websocket._receive_data(new Uint8Array(incoming));
|
||||||
|
|
||||||
|
@ -827,7 +827,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
describe('connecting', function () {
|
describe('connecting', function () {
|
||||||
it('should open the websocket connection', function () {
|
it('should open the websocket connection', function () {
|
||||||
const client = new RFB(document.createElement('div'),
|
const client = new RFB(document.createElement('div'),
|
||||||
'ws://HOST:8675/PATH');
|
'ws://HOST:8675/PATH');
|
||||||
sinon.spy(client._sock, 'open');
|
sinon.spy(client._sock, 'open');
|
||||||
this.clock.tick();
|
this.clock.tick();
|
||||||
expect(client._sock.open).to.have.been.calledOnce;
|
expect(client._sock.open).to.have.been.calledOnce;
|
||||||
|
@ -931,7 +931,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ProtocolVersion', function () {
|
describe('ProtocolVersion', function () {
|
||||||
function send_ver (ver, client) {
|
function send_ver(ver, client) {
|
||||||
const arr = new Uint8Array(12);
|
const arr = new Uint8Array(12);
|
||||||
for (let i = 0; i < ver.length; i++) {
|
for (let i = 0; i < ver.length; i++) {
|
||||||
arr[i+4] = ver.charCodeAt(i);
|
arr[i+4] = ver.charCodeAt(i);
|
||||||
|
@ -1192,7 +1192,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(client._negotiate_std_vnc_auth).to.have.been.calledOnce;
|
expect(client._negotiate_std_vnc_auth).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire the credentialsrequired event if all credentials are missing', function() {
|
it('should fire the credentialsrequired event if all credentials are missing', function () {
|
||||||
const spy = sinon.spy();
|
const spy = sinon.spy();
|
||||||
client.addEventListener("credentialsrequired", spy);
|
client.addEventListener("credentialsrequired", spy);
|
||||||
client._rfb_credentials = {};
|
client._rfb_credentials = {};
|
||||||
|
@ -1203,7 +1203,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
expect(spy.args[0][0].detail.types).to.have.members(["username", "password", "target"]);
|
expect(spy.args[0][0].detail.types).to.have.members(["username", "password", "target"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire the credentialsrequired event if some credentials are missing', function() {
|
it('should fire the credentialsrequired event if some credentials are missing', function () {
|
||||||
const spy = sinon.spy();
|
const spy = sinon.spy();
|
||||||
client.addEventListener("credentialsrequired", spy);
|
client.addEventListener("credentialsrequired", spy);
|
||||||
client._rfb_credentials = { username: 'user',
|
client._rfb_credentials = { username: 'user',
|
||||||
|
@ -1357,7 +1357,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
const spy = sinon.spy();
|
const spy = sinon.spy();
|
||||||
client.addEventListener("securityfailure", spy);
|
client.addEventListener("securityfailure", spy);
|
||||||
const failure_data = [0, 0, 0, 1, 0, 0, 0, 12, 115, 117, 99, 104,
|
const failure_data = [0, 0, 0, 1, 0, 0, 0, 12, 115, 117, 99, 104,
|
||||||
32, 102, 97, 105, 108, 117, 114, 101];
|
32, 102, 97, 105, 108, 117, 114, 101];
|
||||||
client._sock._websocket._receive_data(new Uint8Array(failure_data));
|
client._sock._websocket._receive_data(new Uint8Array(failure_data));
|
||||||
expect(spy.args[0][0].detail.status).to.equal(1);
|
expect(spy.args[0][0].detail.status).to.equal(1);
|
||||||
expect(spy.args[0][0].detail.reason).to.equal('such failure');
|
expect(spy.args[0][0].detail.reason).to.equal('such failure');
|
||||||
|
@ -1416,8 +1416,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
function send_server_init(opts, client) {
|
function send_server_init(opts, client) {
|
||||||
const full_opts = { width: 10, height: 12, bpp: 24, depth: 24, big_endian: 0,
|
const full_opts = { width: 10, height: 12, bpp: 24, depth: 24, big_endian: 0,
|
||||||
true_color: 1, red_max: 255, green_max: 255, blue_max: 255,
|
true_color: 1, red_max: 255, green_max: 255, blue_max: 255,
|
||||||
red_shift: 16, green_shift: 8, blue_shift: 0, name: 'a name' };
|
red_shift: 16, green_shift: 8, blue_shift: 0, name: 'a name' };
|
||||||
for (let opt in opts) {
|
for (let opt in opts) {
|
||||||
full_opts[opt] = opts[opt];
|
full_opts[opt] = opts[opt];
|
||||||
}
|
}
|
||||||
|
@ -1588,7 +1588,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
target_data_check = new Uint8Array(target_data_check_arr);
|
target_data_check = new Uint8Array(target_data_check_arr);
|
||||||
});
|
});
|
||||||
|
|
||||||
function send_fbu_msg (rect_info, rect_data, client, rect_cnt) {
|
function send_fbu_msg(rect_info, rect_data, client, rect_cnt) {
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|
||||||
if (!rect_cnt || rect_cnt > -1) {
|
if (!rect_cnt || rect_cnt > -1) {
|
||||||
|
@ -1664,7 +1664,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
client._display.blitRgbxImage(0, 0, 4, 2, new Uint8Array(target_data_check_arr.slice(0, 32)), 0);
|
client._display.blitRgbxImage(0, 0, 4, 2, new Uint8Array(target_data_check_arr.slice(0, 32)), 0);
|
||||||
|
|
||||||
const info = [{ x: 0, y: 2, width: 2, height: 2, encoding: 0x01},
|
const info = [{ x: 0, y: 2, width: 2, height: 2, encoding: 0x01},
|
||||||
{ x: 2, y: 2, width: 2, height: 2, encoding: 0x01}];
|
{ x: 2, y: 2, width: 2, height: 2, encoding: 0x01}];
|
||||||
// data says [{ old_x: 2, old_y: 0 }, { old_x: 0, old_y: 0 }]
|
// data says [{ old_x: 2, old_y: 0 }, { old_x: 0, old_y: 0 }]
|
||||||
const rects = [[0, 2, 0, 0], [0, 0, 0, 0]];
|
const rects = [[0, 2, 0, 0], [0, 0, 0, 0]];
|
||||||
send_fbu_msg([info[0]], [rects[0]], client, 2);
|
send_fbu_msg([info[0]], [rects[0]], client, 2);
|
||||||
|
@ -1683,9 +1683,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
it('should handle the RAW encoding', function () {
|
it('should handle the RAW encoding', function () {
|
||||||
const info = [{ x: 0, y: 0, width: 2, height: 2, encoding: 0x00 },
|
const info = [{ x: 0, y: 0, width: 2, height: 2, encoding: 0x00 },
|
||||||
{ x: 2, y: 0, width: 2, height: 2, encoding: 0x00 },
|
{ x: 2, y: 0, width: 2, height: 2, encoding: 0x00 },
|
||||||
{ x: 0, y: 2, width: 4, height: 1, encoding: 0x00 },
|
{ x: 0, y: 2, width: 4, height: 1, encoding: 0x00 },
|
||||||
{ x: 0, y: 3, width: 4, height: 1, encoding: 0x00 }];
|
{ x: 0, y: 3, width: 4, height: 1, encoding: 0x00 }];
|
||||||
// data is in bgrx
|
// data is in bgrx
|
||||||
const rects = [
|
const rects = [
|
||||||
[0x00, 0x00, 0xff, 0, 0x00, 0xff, 0x00, 0, 0x00, 0xff, 0x00, 0, 0x00, 0x00, 0xff, 0],
|
[0x00, 0x00, 0xff, 0, 0x00, 0xff, 0x00, 0, 0x00, 0xff, 0x00, 0, 0x00, 0x00, 0xff, 0],
|
||||||
|
@ -1698,9 +1698,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
it('should handle the RAW encoding in low colour mode', function () {
|
it('should handle the RAW encoding in low colour mode', function () {
|
||||||
const info = [{ x: 0, y: 0, width: 2, height: 2, encoding: 0x00 },
|
const info = [{ x: 0, y: 0, width: 2, height: 2, encoding: 0x00 },
|
||||||
{ x: 2, y: 0, width: 2, height: 2, encoding: 0x00 },
|
{ x: 2, y: 0, width: 2, height: 2, encoding: 0x00 },
|
||||||
{ x: 0, y: 2, width: 4, height: 1, encoding: 0x00 },
|
{ x: 0, y: 2, width: 4, height: 1, encoding: 0x00 },
|
||||||
{ x: 0, y: 3, width: 4, height: 1, encoding: 0x00 }];
|
{ x: 0, y: 3, width: 4, height: 1, encoding: 0x00 }];
|
||||||
const rects = [
|
const rects = [
|
||||||
[0x03, 0x03, 0x03, 0x03],
|
[0x03, 0x03, 0x03, 0x03],
|
||||||
[0x0c, 0x0c, 0x0c, 0x0c],
|
[0x0c, 0x0c, 0x0c, 0x0c],
|
||||||
|
@ -1716,7 +1716,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
client._display.blitRgbxImage(0, 0, 4, 2, new Uint8Array(target_data_check_arr.slice(0, 32)), 0);
|
client._display.blitRgbxImage(0, 0, 4, 2, new Uint8Array(target_data_check_arr.slice(0, 32)), 0);
|
||||||
|
|
||||||
const info = [{ x: 0, y: 2, width: 2, height: 2, encoding: 0x01},
|
const info = [{ x: 0, y: 2, width: 2, height: 2, encoding: 0x01},
|
||||||
{ x: 2, y: 2, width: 2, height: 2, encoding: 0x01}];
|
{ x: 2, y: 2, width: 2, height: 2, encoding: 0x01}];
|
||||||
// data says [{ old_x: 0, old_y: 0 }, { old_x: 0, old_y: 0 }]
|
// data says [{ old_x: 0, old_y: 0 }, { old_x: 0, old_y: 0 }]
|
||||||
const rects = [[0, 2, 0, 0], [0, 0, 0, 0]];
|
const rects = [[0, 2, 0, 0], [0, 0, 0, 0]];
|
||||||
send_fbu_msg(info, rects, client);
|
send_fbu_msg(info, rects, client);
|
||||||
|
@ -1876,7 +1876,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail on an invalid subencoding', function () {
|
it('should fail on an invalid subencoding', function () {
|
||||||
sinon.spy(client,"_fail");
|
sinon.spy(client, "_fail");
|
||||||
const info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }];
|
const info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }];
|
||||||
const rects = [[45]]; // an invalid subencoding
|
const rects = [[45]]; // an invalid subencoding
|
||||||
send_fbu_msg(info, rects, client);
|
send_fbu_msg(info, rects, client);
|
||||||
|
@ -1912,7 +1912,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
sinon.spy(client._display, 'resize');
|
sinon.spy(client._display, 'resize');
|
||||||
});
|
});
|
||||||
|
|
||||||
function make_screen_data (nr_of_screens) {
|
function make_screen_data(nr_of_screens) {
|
||||||
const data = [];
|
const data = [];
|
||||||
push8(data, nr_of_screens); // number-of-screens
|
push8(data, nr_of_screens); // number-of-screens
|
||||||
push8(data, 0); // padding
|
push8(data, 0); // padding
|
||||||
|
@ -2184,7 +2184,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
|
|
||||||
describe('WebSocket event handlers', function () {
|
describe('WebSocket event handlers', function () {
|
||||||
// message events
|
// message events
|
||||||
it ('should do nothing if we receive an empty message and have nothing in the queue', function () {
|
it('should do nothing if we receive an empty message and have nothing in the queue', function () {
|
||||||
client._normal_msg = sinon.spy();
|
client._normal_msg = sinon.spy();
|
||||||
client._sock._websocket._receive_data(new Uint8Array([]));
|
client._sock._websocket._receive_data(new Uint8Array([]));
|
||||||
expect(client._normal_msg).to.not.have.been.called;
|
expect(client._normal_msg).to.not.have.been.called;
|
||||||
|
|
|
@ -3,7 +3,7 @@ const expect = chai.expect;
|
||||||
|
|
||||||
import * as Log from '../core/util/logging.js';
|
import * as Log from '../core/util/logging.js';
|
||||||
|
|
||||||
describe('Utils', function() {
|
describe('Utils', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('logging functions', function () {
|
describe('logging functions', function () {
|
||||||
|
|
|
@ -3,7 +3,7 @@ const 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';
|
||||||
|
|
||||||
describe('Websock', function() {
|
describe('Websock', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('Queue methods', function () {
|
describe('Queue methods', function () {
|
||||||
|
@ -19,9 +19,9 @@ describe('Websock', function() {
|
||||||
});
|
});
|
||||||
describe('rQlen', function () {
|
describe('rQlen', function () {
|
||||||
it('should return the length of the receive queue', function () {
|
it('should return the length of the receive queue', function () {
|
||||||
sock.set_rQi(0);
|
sock.set_rQi(0);
|
||||||
|
|
||||||
expect(sock.rQlen()).to.equal(RQ_TEMPLATE.length);
|
expect(sock.rQlen()).to.equal(RQ_TEMPLATE.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the proper length if we read some from the receive queue", function () {
|
it("should return the proper length if we read some from the receive queue", function () {
|
||||||
|
@ -195,7 +195,7 @@ describe('Websock', function() {
|
||||||
|
|
||||||
it('should actually send on the websocket', function () {
|
it('should actually send on the websocket', function () {
|
||||||
sock._websocket.bufferedAmount = 8;
|
sock._websocket.bufferedAmount = 8;
|
||||||
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;
|
||||||
const encoded = sock._encode_message();
|
const encoded = sock._encode_message();
|
||||||
|
@ -247,7 +247,7 @@ describe('Websock', function() {
|
||||||
describe('lifecycle methods', function () {
|
describe('lifecycle methods', function () {
|
||||||
let old_WS;
|
let old_WS;
|
||||||
before(function () {
|
before(function () {
|
||||||
old_WS = WebSocket;
|
old_WS = WebSocket;
|
||||||
});
|
});
|
||||||
|
|
||||||
let sock;
|
let sock;
|
||||||
|
@ -264,7 +264,7 @@ describe('Websock', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('opening', function () {
|
describe('opening', function () {
|
||||||
it('should pick the correct protocols if none are given' , function () {
|
it('should pick the correct protocols if none are given', function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -357,8 +357,8 @@ describe('Websock', function() {
|
||||||
describe('WebSocket Receiving', function () {
|
describe('WebSocket Receiving', function () {
|
||||||
let 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 () {
|
||||||
|
|
|
@ -4,23 +4,23 @@ const expect = chai.expect;
|
||||||
|
|
||||||
import * as WebUtil from '../app/webutil.js';
|
import * as WebUtil from '../app/webutil.js';
|
||||||
|
|
||||||
describe('WebUtil', function() {
|
describe('WebUtil', function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('settings', function () {
|
describe('settings', function () {
|
||||||
|
|
||||||
describe('localStorage', function() {
|
describe('localStorage', function () {
|
||||||
let chrome = window.chrome;
|
let chrome = window.chrome;
|
||||||
before(function() {
|
before(function () {
|
||||||
chrome = window.chrome;
|
chrome = window.chrome;
|
||||||
window.chrome = null;
|
window.chrome = null;
|
||||||
});
|
});
|
||||||
after(function() {
|
after(function () {
|
||||||
window.chrome = chrome;
|
window.chrome = chrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
let origLocalStorage;
|
let origLocalStorage;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
origLocalStorage = Object.getOwnPropertyDescriptor(window, "localStorage");
|
origLocalStorage = Object.getOwnPropertyDescriptor(window, "localStorage");
|
||||||
if (origLocalStorage === undefined) {
|
if (origLocalStorage === undefined) {
|
||||||
// Object.getOwnPropertyDescriptor() doesn't work
|
// Object.getOwnPropertyDescriptor() doesn't work
|
||||||
|
@ -41,56 +41,56 @@ describe('WebUtil', function() {
|
||||||
|
|
||||||
WebUtil.initSettings();
|
WebUtil.initSettings();
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
Object.defineProperty(window, "localStorage", origLocalStorage);
|
Object.defineProperty(window, "localStorage", origLocalStorage);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('writeSetting', function() {
|
describe('writeSetting', function () {
|
||||||
it('should save the setting value to local storage', function() {
|
it('should save the setting value to local storage', function () {
|
||||||
WebUtil.writeSetting('test', 'value');
|
WebUtil.writeSetting('test', 'value');
|
||||||
expect(window.localStorage.setItem).to.have.been.calledWithExactly('test', 'value');
|
expect(window.localStorage.setItem).to.have.been.calledWithExactly('test', 'value');
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setSetting', function() {
|
describe('setSetting', function () {
|
||||||
it('should update the setting but not save to local storage', function() {
|
it('should update the setting but not save to local storage', function () {
|
||||||
WebUtil.setSetting('test', 'value');
|
WebUtil.setSetting('test', 'value');
|
||||||
expect(window.localStorage.setItem).to.not.have.been.called;
|
expect(window.localStorage.setItem).to.not.have.been.called;
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('readSetting', function() {
|
describe('readSetting', function () {
|
||||||
it('should read the setting value from local storage', function() {
|
it('should read the setting value from local storage', function () {
|
||||||
localStorage.getItem.returns('value');
|
localStorage.getItem.returns('value');
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the default value when not in local storage', function() {
|
it('should return the default value when not in local storage', function () {
|
||||||
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the cached value even if local storage changed', function() {
|
it('should return the cached value even if local storage changed', function () {
|
||||||
localStorage.getItem.returns('value');
|
localStorage.getItem.returns('value');
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
localStorage.getItem.returns('something else');
|
localStorage.getItem.returns('something else');
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should cache the value even if it is not initially in local storage', function() {
|
it('should cache the value even if it is not initially in local storage', function () {
|
||||||
expect(WebUtil.readSetting('test')).to.be.null;
|
expect(WebUtil.readSetting('test')).to.be.null;
|
||||||
localStorage.getItem.returns('value');
|
localStorage.getItem.returns('value');
|
||||||
expect(WebUtil.readSetting('test')).to.be.null;
|
expect(WebUtil.readSetting('test')).to.be.null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the default value always if the first read was not in local storage', function() {
|
it('should return the default value always if the first read was not in local storage', function () {
|
||||||
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
||||||
localStorage.getItem.returns('value');
|
localStorage.getItem.returns('value');
|
||||||
expect(WebUtil.readSetting('test', 'another default')).to.equal('another default');
|
expect(WebUtil.readSetting('test', 'another default')).to.equal('another default');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the last local written value', function() {
|
it('should return the last local written value', function () {
|
||||||
localStorage.getItem.returns('value');
|
localStorage.getItem.returns('value');
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
WebUtil.writeSetting('test', 'something else');
|
WebUtil.writeSetting('test', 'something else');
|
||||||
|
@ -99,72 +99,72 @@ describe('WebUtil', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// this doesn't appear to be used anywhere
|
// this doesn't appear to be used anywhere
|
||||||
describe('eraseSetting', function() {
|
describe('eraseSetting', function () {
|
||||||
it('should remove the setting from local storage', function() {
|
it('should remove the setting from local storage', function () {
|
||||||
WebUtil.eraseSetting('test');
|
WebUtil.eraseSetting('test');
|
||||||
expect(window.localStorage.removeItem).to.have.been.calledWithExactly('test');
|
expect(window.localStorage.removeItem).to.have.been.calledWithExactly('test');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('chrome.storage', function() {
|
describe('chrome.storage', function () {
|
||||||
let chrome = window.chrome;
|
let chrome = window.chrome;
|
||||||
let settings = {};
|
let settings = {};
|
||||||
before(function() {
|
before(function () {
|
||||||
chrome = window.chrome;
|
chrome = window.chrome;
|
||||||
window.chrome = {
|
window.chrome = {
|
||||||
storage: {
|
storage: {
|
||||||
sync: {
|
sync: {
|
||||||
get(cb){ cb(settings); },
|
get(cb) { cb(settings); },
|
||||||
set(){},
|
set() {},
|
||||||
remove() {}
|
remove() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
after(function() {
|
after(function () {
|
||||||
window.chrome = chrome;
|
window.chrome = chrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
const csSandbox = sinon.createSandbox();
|
const csSandbox = sinon.createSandbox();
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
settings = {};
|
settings = {};
|
||||||
csSandbox.spy(window.chrome.storage.sync, 'set');
|
csSandbox.spy(window.chrome.storage.sync, 'set');
|
||||||
csSandbox.spy(window.chrome.storage.sync, 'remove');
|
csSandbox.spy(window.chrome.storage.sync, 'remove');
|
||||||
WebUtil.initSettings();
|
WebUtil.initSettings();
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
csSandbox.restore();
|
csSandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('writeSetting', function() {
|
describe('writeSetting', function () {
|
||||||
it('should save the setting value to chrome storage', function() {
|
it('should save the setting value to chrome storage', function () {
|
||||||
WebUtil.writeSetting('test', 'value');
|
WebUtil.writeSetting('test', 'value');
|
||||||
expect(window.chrome.storage.sync.set).to.have.been.calledWithExactly(sinon.match({ test: 'value' }));
|
expect(window.chrome.storage.sync.set).to.have.been.calledWithExactly(sinon.match({ test: 'value' }));
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setSetting', function() {
|
describe('setSetting', function () {
|
||||||
it('should update the setting but not save to chrome storage', function() {
|
it('should update the setting but not save to chrome storage', function () {
|
||||||
WebUtil.setSetting('test', 'value');
|
WebUtil.setSetting('test', 'value');
|
||||||
expect(window.chrome.storage.sync.set).to.not.have.been.called;
|
expect(window.chrome.storage.sync.set).to.not.have.been.called;
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('readSetting', function() {
|
describe('readSetting', function () {
|
||||||
it('should read the setting value from chrome storage', function() {
|
it('should read the setting value from chrome storage', function () {
|
||||||
settings.test = 'value';
|
settings.test = 'value';
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the default value when not in chrome storage', function() {
|
it('should return the default value when not in chrome storage', function () {
|
||||||
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
expect(WebUtil.readSetting('test', 'default')).to.equal('default');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the last local written value', function() {
|
it('should return the last local written value', function () {
|
||||||
settings.test = 'value';
|
settings.test = 'value';
|
||||||
expect(WebUtil.readSetting('test')).to.equal('value');
|
expect(WebUtil.readSetting('test')).to.equal('value');
|
||||||
WebUtil.writeSetting('test', 'something else');
|
WebUtil.writeSetting('test', 'something else');
|
||||||
|
@ -173,8 +173,8 @@ describe('WebUtil', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// this doesn't appear to be used anywhere
|
// this doesn't appear to be used anywhere
|
||||||
describe('eraseSetting', function() {
|
describe('eraseSetting', function () {
|
||||||
it('should remove the setting from chrome storage', function() {
|
it('should remove the setting from chrome storage', function () {
|
||||||
WebUtil.eraseSetting('test');
|
WebUtil.eraseSetting('test');
|
||||||
expect(window.chrome.storage.sync.remove).to.have.been.calledWithExactly('test');
|
expect(window.chrome.storage.sync.remove).to.have.been.calledWithExactly('test');
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,29 +14,29 @@ let show_help = process.argv.length === 2;
|
||||||
let filename;
|
let filename;
|
||||||
|
|
||||||
for (let 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":
|
||||||
show_help = true;
|
show_help = true;
|
||||||
break;
|
break;
|
||||||
case "--file":
|
case "--file":
|
||||||
case "-f":
|
case "-f":
|
||||||
default:
|
default:
|
||||||
filename = process.argv[i];
|
filename = process.argv[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
show_help = true;
|
show_help = true;
|
||||||
console.log("Error: No filename specified\n");
|
console.log("Error: No filename specified\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_help) {
|
if (show_help) {
|
||||||
console.log("Parses a *nix keysymdef.h to generate Unicode code point mappings");
|
console.log("Parses a *nix keysymdef.h to generate Unicode code point mappings");
|
||||||
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");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buf = fs.readFileSync(filename);
|
const buf = fs.readFileSync(filename);
|
||||||
|
@ -50,7 +50,7 @@ const codepoints = {};
|
||||||
|
|
||||||
for (let i = 0; i < arr.length; ++i) {
|
for (let i = 0; i < arr.length; ++i) {
|
||||||
const result = re.exec(arr[i]);
|
const result = re.exec(arr[i]);
|
||||||
if (result){
|
if (result) {
|
||||||
const keyname = result[1];
|
const keyname = result[1];
|
||||||
const keysym = parseInt(result[2], 16);
|
const keysym = parseInt(result[2], 16);
|
||||||
const remainder = result[3];
|
const remainder = result[3];
|
||||||
|
@ -59,7 +59,7 @@ for (let i = 0; i < arr.length; ++i) {
|
||||||
if (unicodeRes) {
|
if (unicodeRes) {
|
||||||
const 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 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ 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 promise_wrap() {
|
||||||
const 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(this, args.concat((err, value) => {
|
original.apply(this, args.concat((err, value) => {
|
||||||
|
@ -51,7 +51,7 @@ function promisify(original) {
|
||||||
resolve(value);
|
resolve(value);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const readFile = promisify(fs.readFile);
|
const readFile = promisify(fs.readFile);
|
||||||
|
@ -71,43 +71,43 @@ const babelTransformFile = promisify(babel.transformFile);
|
||||||
// calling the callback for all normal files found.
|
// calling the callback for all normal files found.
|
||||||
function walkDir(base_path, cb, filter) {
|
function walkDir(base_path, cb, filter) {
|
||||||
return readdir(base_path)
|
return readdir(base_path)
|
||||||
.then((files) => {
|
.then((files) => {
|
||||||
const 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 => lstat(filepath)
|
return Promise.all(paths.map(filepath => lstat(filepath)
|
||||||
.then((stats) => {
|
.then((stats) => {
|
||||||
if (filter !== undefined && !filter(filepath, stats)) return;
|
if (filter !== undefined && !filter(filepath, stats)) return;
|
||||||
|
|
||||||
if (stats.isSymbolicLink()) return;
|
if (stats.isSymbolicLink()) return;
|
||||||
if (stats.isFile()) return cb(filepath);
|
if (stats.isFile()) return cb(filepath);
|
||||||
if (stats.isDirectory()) return walkDir(filepath, cb, filter);
|
if (stats.isDirectory()) return walkDir(filepath, cb, filter);
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function transform_html (legacy_scripts, only_legacy) {
|
function transform_html(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
|
||||||
const src_html_path = path.resolve(__dirname, '..', 'vnc.html');
|
const src_html_path = path.resolve(__dirname, '..', 'vnc.html');
|
||||||
const 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) => {
|
||||||
let contents = contents_raw.toString();
|
let contents = contents_raw.toString();
|
||||||
|
|
||||||
const start_marker = '<!-- begin scripts -->\n';
|
const start_marker = '<!-- begin scripts -->\n';
|
||||||
const end_marker = '<!-- end scripts -->';
|
const end_marker = '<!-- end scripts -->';
|
||||||
const start_ind = contents.indexOf(start_marker) + start_marker.length;
|
const start_ind = contents.indexOf(start_marker) + start_marker.length;
|
||||||
const end_ind = contents.indexOf(end_marker, start_ind);
|
const end_ind = contents.indexOf(end_marker, start_ind);
|
||||||
|
|
||||||
let 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
|
||||||
for (let i = 0;i < legacy_scripts.length;i++) {
|
for (let i = 0;i < legacy_scripts.length;i++) {
|
||||||
new_script += ` <script src="${legacy_scripts[i]}"></script>\n`;
|
new_script += ` <script src="${legacy_scripts[i]}"></script>\n`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise detect if it's a modern browser and select
|
// Otherwise detect if it's a modern browser and select
|
||||||
// variant accordingly
|
// variant accordingly
|
||||||
new_script += `\
|
new_script += `\
|
||||||
<script type="module">\n\
|
<script type="module">\n\
|
||||||
window._noVNC_has_module_support = true;\n\
|
window._noVNC_has_module_support = true;\n\
|
||||||
</script>\n\
|
</script>\n\
|
||||||
|
@ -125,17 +125,17 @@ function transform_html (legacy_scripts, only_legacy) {
|
||||||
</script>\n`;
|
</script>\n`;
|
||||||
|
|
||||||
// Original, ES6 modules
|
// Original, ES6 modules
|
||||||
new_script += ' <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n';
|
new_script += ' <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind);
|
contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind);
|
||||||
|
|
||||||
return contents;
|
return contents;
|
||||||
})
|
})
|
||||||
.then((contents) => {
|
.then((contents) => {
|
||||||
console.log(`Writing ${out_html_path}`);
|
console.log(`Writing ${out_html_path}`);
|
||||||
return writeFile(out_html_path, contents);
|
return writeFile(out_html_path, contents);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
|
function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
|
||||||
|
@ -176,130 +176,130 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
|
||||||
const outFiles = [];
|
const outFiles = [];
|
||||||
|
|
||||||
const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve()
|
const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve()
|
||||||
.then(() => {
|
|
||||||
if (no_copy_files.has(filename)) return;
|
|
||||||
|
|
||||||
const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
|
|
||||||
const legacy_path = path.join(legacy_path_base, path.relative(in_path_base, filename));
|
|
||||||
|
|
||||||
if(path.extname(filename) !== '.js') {
|
|
||||||
if (!js_only) {
|
|
||||||
console.log(`Writing ${out_path}`);
|
|
||||||
return copy(filename, out_path);
|
|
||||||
}
|
|
||||||
return; // skip non-javascript files
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (only_legacy && !no_transform_files.has(filename)) {
|
if (no_copy_files.has(filename)) return;
|
||||||
return;
|
|
||||||
}
|
const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
|
||||||
return ensureDir(path.dirname(out_path))
|
const legacy_path = path.join(legacy_path_base, path.relative(in_path_base, filename));
|
||||||
.then(() => {
|
|
||||||
console.log(`Writing ${out_path}`);
|
if (path.extname(filename) !== '.js') {
|
||||||
return copy(filename, out_path);
|
if (!js_only) {
|
||||||
})
|
console.log(`Writing ${out_path}`);
|
||||||
})
|
return copy(filename, out_path);
|
||||||
.then(() => ensureDir(path.dirname(legacy_path)))
|
}
|
||||||
.then(() => {
|
return; // skip non-javascript files
|
||||||
if (no_transform_files.has(filename)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const opts = babel_opts();
|
return Promise.resolve()
|
||||||
if (helper && helpers.optionsOverride) {
|
.then(() => {
|
||||||
helper.optionsOverride(opts);
|
if (only_legacy && !no_transform_files.has(filename)) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
return ensureDir(path.dirname(out_path))
|
||||||
|
.then(() => {
|
||||||
|
console.log(`Writing ${out_path}`);
|
||||||
|
return copy(filename, out_path);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => ensureDir(path.dirname(legacy_path)))
|
||||||
|
.then(() => {
|
||||||
|
if (no_transform_files.has(filename)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const opts = babel_opts();
|
||||||
|
if (helper && helpers.optionsOverride) {
|
||||||
|
helper.optionsOverride(opts);
|
||||||
|
}
|
||||||
// Adjust for the fact that we move the core files relative
|
// Adjust for the fact that we move the core files relative
|
||||||
// to the vendor directory
|
// to the vendor directory
|
||||||
if (vendor_rewrite) {
|
if (vendor_rewrite) {
|
||||||
opts.plugins.push(["import-redirect",
|
opts.plugins.push(["import-redirect",
|
||||||
{"root": legacy_path_base,
|
{"root": legacy_path_base,
|
||||||
"redirect": { "vendor/(.+)": "./vendor/$1"}}]);
|
"redirect": { "vendor/(.+)": "./vendor/$1"}}]);
|
||||||
}
|
|
||||||
|
|
||||||
return babelTransformFile(filename, opts)
|
|
||||||
.then((res) => {
|
|
||||||
console.log(`Writing ${legacy_path}`);
|
|
||||||
const {map} = res;
|
|
||||||
let {code} = res;
|
|
||||||
if (source_maps === true) {
|
|
||||||
// append URL for external source map
|
|
||||||
code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`;
|
|
||||||
}
|
|
||||||
outFiles.push(`${legacy_path}`);
|
|
||||||
return writeFile(legacy_path, code)
|
|
||||||
.then(() => {
|
|
||||||
if (source_maps === true || source_maps === 'both') {
|
|
||||||
console.log(` and ${legacy_path}.map`);
|
|
||||||
outFiles.push(`${legacy_path}.map`);
|
|
||||||
return writeFile(`${legacy_path}.map`, JSON.stringify(map));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return babelTransformFile(filename, opts)
|
||||||
|
.then((res) => {
|
||||||
|
console.log(`Writing ${legacy_path}`);
|
||||||
|
const {map} = res;
|
||||||
|
let {code} = res;
|
||||||
|
if (source_maps === true) {
|
||||||
|
// append URL for external source map
|
||||||
|
code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`;
|
||||||
|
}
|
||||||
|
outFiles.push(`${legacy_path}`);
|
||||||
|
return writeFile(legacy_path, code)
|
||||||
|
.then(() => {
|
||||||
|
if (source_maps === true || source_maps === 'both') {
|
||||||
|
console.log(` and ${legacy_path}.map`);
|
||||||
|
outFiles.push(`${legacy_path}.map`);
|
||||||
|
return writeFile(`${legacy_path}.map`, JSON.stringify(map));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (with_app_dir && helper && helper.noCopyOverride) {
|
if (with_app_dir && helper && helper.noCopyOverride) {
|
||||||
helper.noCopyOverride(paths, no_copy_files);
|
helper.noCopyOverride(paths, no_copy_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.resolve()
|
Promise.resolve()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const handler = handleDir.bind(null, true, false, in_path || paths.main);
|
const handler = handleDir.bind(null, true, false, in_path || paths.main);
|
||||||
const 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(() => {
|
|
||||||
const handler = handleDir.bind(null, true, !in_path, in_path || paths.core);
|
|
||||||
const filter = (filename, stats) => !no_copy_files.has(filename);
|
|
||||||
return walkDir(paths.core, handler, filter);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
if (!with_app_dir) return;
|
|
||||||
const handler = handleDir.bind(null, false, false, in_path);
|
|
||||||
const filter = (filename, stats) => !no_copy_files.has(filename);
|
|
||||||
return walkDir(paths.app, handler, filter);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
if (!with_app_dir) return;
|
|
||||||
|
|
||||||
if (!helper || !helper.appWriter) {
|
|
||||||
throw new Error(`Unable to generate app for the ${import_format} format!`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const out_app_path = path.join(legacy_path_base, 'app.js');
|
|
||||||
console.log(`Writing ${out_app_path}`);
|
|
||||||
return helper.appWriter(out_path_base, legacy_path_base, out_app_path)
|
|
||||||
.then((extra_scripts) => {
|
|
||||||
const rel_app_path = path.relative(out_path_base, out_app_path);
|
|
||||||
const legacy_scripts = extra_scripts.concat([rel_app_path]);
|
|
||||||
transform_html(legacy_scripts, only_legacy);
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (!helper.removeModules) return;
|
const handler = handleDir.bind(null, true, !in_path, in_path || paths.core);
|
||||||
console.log(`Cleaning up temporary files...`);
|
const filter = (filename, stats) => !no_copy_files.has(filename);
|
||||||
return Promise.all(outFiles.map((filepath) => {
|
return walkDir(paths.core, handler, filter);
|
||||||
unlink(filepath)
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (!with_app_dir) return;
|
||||||
|
const handler = handleDir.bind(null, false, false, in_path);
|
||||||
|
const filter = (filename, stats) => !no_copy_files.has(filename);
|
||||||
|
return walkDir(paths.app, handler, filter);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (!with_app_dir) return;
|
||||||
|
|
||||||
|
if (!helper || !helper.appWriter) {
|
||||||
|
throw new Error(`Unable to generate app for the ${import_format} format!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const out_app_path = path.join(legacy_path_base, 'app.js');
|
||||||
|
console.log(`Writing ${out_app_path}`);
|
||||||
|
return helper.appWriter(out_path_base, legacy_path_base, out_app_path)
|
||||||
|
.then((extra_scripts) => {
|
||||||
|
const rel_app_path = path.relative(out_path_base, out_app_path);
|
||||||
|
const legacy_scripts = extra_scripts.concat([rel_app_path]);
|
||||||
|
transform_html(legacy_scripts, only_legacy);
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
if (!helper.removeModules) return;
|
||||||
|
console.log(`Cleaning up temporary files...`);
|
||||||
|
return Promise.all(outFiles.map((filepath) => {
|
||||||
|
unlink(filepath)
|
||||||
|
.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
|
||||||
const rmdir_r = dir =>
|
const rmdir_r = dir =>
|
||||||
rmdir(dir)
|
rmdir(dir)
|
||||||
.then(() => rmdir_r(path.dirname(dir)))
|
.then(() => rmdir_r(path.dirname(dir)))
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// Assume the error was ENOTEMPTY and ignore it
|
// Assume the error was ENOTEMPTY and ignore it
|
||||||
});
|
});
|
||||||
return rmdir_r(path.dirname(filepath));
|
return rmdir_r(path.dirname(filepath));
|
||||||
|
});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
}));
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`Failure converting modules: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`Failure converting modules: ${err}`);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.clean) {
|
if (program.clean) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const 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 promise_wrap() {
|
||||||
const 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(this, args.concat((err, value) => {
|
original.apply(this, args.concat((err, value) => {
|
||||||
|
@ -12,7 +12,7 @@ function promisify(original) {
|
||||||
resolve(value);
|
resolve(value);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeFile = promisify(fs.writeFile);
|
const writeFile = promisify(fs.writeFile);
|
||||||
|
@ -22,19 +22,19 @@ module.exports = {
|
||||||
appWriter: (base_out_path, script_base_path, out_path) => {
|
appWriter: (base_out_path, script_base_path, out_path) => {
|
||||||
// setup for requirejs
|
// setup for requirejs
|
||||||
const 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}"], (ui) => {});`)
|
return writeFile(out_path, `requirejs(["${ui_path}"], (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')}`);
|
||||||
const 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 ];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
noCopyOverride: () => {},
|
noCopyOverride: () => {},
|
||||||
},
|
},
|
||||||
'commonjs': {
|
'commonjs': {
|
||||||
optionsOverride: (opts) => {
|
optionsOverride: (opts) => {
|
||||||
// CommonJS supports properly shifting the default export to work as normal
|
// CommonJS supports properly shifting the default export to work as normal
|
||||||
opts.plugins.unshift("add-module-exports");
|
opts.plugins.unshift("add-module-exports");
|
||||||
},
|
},
|
||||||
|
@ -42,8 +42,8 @@ module.exports = {
|
||||||
const browserify = require('browserify');
|
const browserify = require('browserify');
|
||||||
const 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(() => []);
|
||||||
},
|
},
|
||||||
noCopyOverride: () => {},
|
noCopyOverride: () => {},
|
||||||
removeModules: true,
|
removeModules: true,
|
||||||
|
@ -51,26 +51,26 @@ module.exports = {
|
||||||
'systemjs': {
|
'systemjs': {
|
||||||
appWriter: (base_out_path, script_base_path, out_path) => {
|
appWriter: (base_out_path, script_base_path, out_path) => {
|
||||||
const 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
|
||||||
const 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'));
|
||||||
const 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 ];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
noCopyOverride: (paths, no_copy_files) => {
|
noCopyOverride: (paths, no_copy_files) => {
|
||||||
no_copy_files.delete(path.join(paths.vendor, 'promise.js'));
|
no_copy_files.delete(path.join(paths.vendor, 'promise.js'));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'umd': {
|
'umd': {
|
||||||
optionsOverride: (opts) => {
|
optionsOverride: (opts) => {
|
||||||
// umd supports properly shifting the default export to work as normal
|
// umd supports properly shifting the default export to work as normal
|
||||||
opts.plugins.unshift("add-module-exports");
|
opts.plugins.unshift("add-module-exports");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
Loading…
Reference in New Issue