This commit is contained in:
Pierre Ossman 2020-06-05 09:41:25 +02:00
commit f694c32fd5
24 changed files with 532 additions and 522 deletions

View File

@ -44,5 +44,6 @@
"named": "never", "named": "never",
"asyncArrow": "always" }], "asyncArrow": "always" }],
"switch-colon-spacing": ["error"], "switch-colon-spacing": ["error"],
"camelcase": ["error", { allow: ["^XK_", "^XF86XK_"] }],
} }
} }

View File

@ -37,9 +37,9 @@ const UI = {
lastKeyboardinput: null, lastKeyboardinput: null,
defaultKeyboardinputLen: 100, defaultKeyboardinputLen: 100,
inhibit_reconnect: true, inhibitReconnect: true,
reconnect_callback: null, reconnectCallback: null,
reconnect_password: null, reconnectPassword: null,
prime() { prime() {
return WebUtil.initSettings().then(() => { return WebUtil.initSettings().then(() => {
@ -394,25 +394,25 @@ const UI = {
document.documentElement.classList.remove("noVNC_disconnecting"); document.documentElement.classList.remove("noVNC_disconnecting");
document.documentElement.classList.remove("noVNC_reconnecting"); document.documentElement.classList.remove("noVNC_reconnecting");
const transition_elem = document.getElementById("noVNC_transition_text"); const transitionElem = document.getElementById("noVNC_transition_text");
switch (state) { switch (state) {
case 'init': case 'init':
break; break;
case 'connecting': case 'connecting':
transition_elem.textContent = _("Connecting..."); transitionElem.textContent = _("Connecting...");
document.documentElement.classList.add("noVNC_connecting"); document.documentElement.classList.add("noVNC_connecting");
break; break;
case 'connected': case 'connected':
document.documentElement.classList.add("noVNC_connected"); document.documentElement.classList.add("noVNC_connected");
break; break;
case 'disconnecting': case 'disconnecting':
transition_elem.textContent = _("Disconnecting..."); transitionElem.textContent = _("Disconnecting...");
document.documentElement.classList.add("noVNC_disconnecting"); document.documentElement.classList.add("noVNC_disconnecting");
break; break;
case 'disconnected': case 'disconnected':
break; break;
case 'reconnecting': case 'reconnecting':
transition_elem.textContent = _("Reconnecting..."); transitionElem.textContent = _("Reconnecting...");
document.documentElement.classList.add("noVNC_reconnecting"); document.documentElement.classList.add("noVNC_reconnecting");
break; break;
default: default:
@ -452,11 +452,11 @@ const UI = {
.classList.remove('noVNC_open'); .classList.remove('noVNC_open');
}, },
showStatus(text, status_type, time) { showStatus(text, statusType, time) {
const statusElem = document.getElementById('noVNC_status'); const statusElem = document.getElementById('noVNC_status');
if (typeof status_type === 'undefined') { if (typeof statusType === 'undefined') {
status_type = 'normal'; statusType = 'normal';
} }
// Don't overwrite more severe visible statuses and never // Don't overwrite more severe visible statuses and never
@ -466,14 +466,14 @@ const UI = {
return; return;
} }
if (statusElem.classList.contains("noVNC_status_warn") && if (statusElem.classList.contains("noVNC_status_warn") &&
status_type === 'normal') { statusType === 'normal') {
return; return;
} }
} }
clearTimeout(UI.statusTimeout); clearTimeout(UI.statusTimeout);
switch (status_type) { switch (statusType) {
case 'error': case 'error':
statusElem.classList.remove("noVNC_status_warn"); statusElem.classList.remove("noVNC_status_warn");
statusElem.classList.remove("noVNC_status_normal"); statusElem.classList.remove("noVNC_status_normal");
@ -503,7 +503,7 @@ const UI = {
} }
// Error messages do not timeout // Error messages do not timeout
if (status_type !== 'error') { if (statusType !== 'error') {
UI.statusTimeout = window.setTimeout(UI.hideStatus, time); UI.statusTimeout = window.setTimeout(UI.hideStatus, time);
} }
}, },
@ -1003,7 +1003,7 @@ const UI = {
if (typeof password === 'undefined') { if (typeof password === 'undefined') {
password = WebUtil.getConfigVar('password'); password = WebUtil.getConfigVar('password');
UI.reconnect_password = password; UI.reconnectPassword = password;
} }
if (password === null) { if (password === null) {
@ -1060,7 +1060,7 @@ const UI = {
UI.connected = false; UI.connected = false;
// Disable automatic reconnecting // Disable automatic reconnecting
UI.inhibit_reconnect = true; UI.inhibitReconnect = true;
UI.updateVisualState('disconnecting'); UI.updateVisualState('disconnecting');
@ -1068,20 +1068,20 @@ const UI = {
}, },
reconnect() { reconnect() {
UI.reconnect_callback = null; UI.reconnectCallback = null;
// if reconnect has been disabled in the meantime, do nothing. // if reconnect has been disabled in the meantime, do nothing.
if (UI.inhibit_reconnect) { if (UI.inhibitReconnect) {
return; return;
} }
UI.connect(null, UI.reconnect_password); UI.connect(null, UI.reconnectPassword);
}, },
cancelReconnect() { cancelReconnect() {
if (UI.reconnect_callback !== null) { if (UI.reconnectCallback !== null) {
clearTimeout(UI.reconnect_callback); clearTimeout(UI.reconnectCallback);
UI.reconnect_callback = null; UI.reconnectCallback = null;
} }
UI.updateVisualState('disconnected'); UI.updateVisualState('disconnected');
@ -1092,7 +1092,7 @@ const UI = {
connectFinished(e) { connectFinished(e) {
UI.connected = true; UI.connected = true;
UI.inhibit_reconnect = false; UI.inhibitReconnect = false;
let msg; let msg;
if (UI.getSetting('encrypt')) { if (UI.getSetting('encrypt')) {
@ -1126,11 +1126,11 @@ const UI = {
} else { } else {
UI.showStatus(_("Failed to connect to server"), 'error'); UI.showStatus(_("Failed to connect to server"), 'error');
} }
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) { } else if (UI.getSetting('reconnect', false) === true && !UI.inhibitReconnect) {
UI.updateVisualState('reconnecting'); UI.updateVisualState('reconnecting');
const delay = parseInt(UI.getSetting('reconnect_delay')); const delay = parseInt(UI.getSetting('reconnect_delay'));
UI.reconnect_callback = setTimeout(UI.reconnect, delay); UI.reconnectCallback = setTimeout(UI.reconnect, delay);
return; return;
} else { } else {
UI.updateVisualState('disconnected'); UI.updateVisualState('disconnected');
@ -1203,7 +1203,7 @@ const UI = {
inputElemPassword.value = ""; inputElemPassword.value = "";
UI.rfb.sendCredentials({ username: username, password: password }); UI.rfb.sendCredentials({ username: username, password: password });
UI.reconnect_password = password; UI.reconnectPassword = password;
document.getElementById('noVNC_credentials_dlg') document.getElementById('noVNC_credentials_dlg')
.classList.remove('noVNC_open'); .classList.remove('noVNC_open');
}, },
@ -1634,8 +1634,8 @@ const UI = {
* ------v------*/ * ------v------*/
setMouseButton(num) { setMouseButton(num) {
const view_only = UI.rfb.viewOnly; const viewOnly = UI.rfb.viewOnly;
if (UI.rfb && !view_only) { if (UI.rfb && !viewOnly) {
UI.rfb.touchButton = num; UI.rfb.touchButton = num;
} }
@ -1643,7 +1643,7 @@ const UI = {
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]);
if (blist[b] === num && !view_only) { if (blist[b] === num && !viewOnly) {
button.classList.remove("noVNC_hidden"); button.classList.remove("noVNC_hidden");
} else { } else {
button.classList.add("noVNC_hidden"); button.classList.add("noVNC_hidden");
@ -1683,7 +1683,7 @@ const UI = {
}, },
updateLogging() { updateLogging() {
WebUtil.init_logging(UI.getSetting('logging')); WebUtil.initLogging(UI.getSetting('logging'));
}, },
updateDesktopName(e) { updateDesktopName(e) {

View File

@ -6,16 +6,16 @@
* See README.md for usage and integration instructions. * See README.md for usage and integration instructions.
*/ */
import { init_logging as main_init_logging } from '../core/util/logging.js'; import { initLogging as mainInitLogging } 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 initLogging(level) {
"use strict"; "use strict";
if (typeof level !== "undefined") { if (typeof level !== "undefined") {
main_init_logging(level); mainInitLogging(level);
} else { } else {
const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/); const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
main_init_logging(param || undefined); mainInitLogging(param || undefined);
} }
} }
@ -184,7 +184,7 @@ export function injectParamIfMissing(path, param, value) {
const elem = document.createElement('a'); const elem = document.createElement('a');
elem.href = path; elem.href = path;
const param_eq = encodeURIComponent(param) + "="; const paramEq = encodeURIComponent(param) + "=";
let query; let query;
if (elem.search) { if (elem.search) {
query = elem.search.slice(1).split('&'); query = elem.search.slice(1).split('&');
@ -192,8 +192,8 @@ export function injectParamIfMissing(path, param, value) {
query = []; query = [];
} }
if (!query.some(v => v.startsWith(param_eq))) { if (!query.some(v => v.startsWith(paramEq))) {
query.push(param_eq + encodeURIComponent(value)); query.push(paramEq + encodeURIComponent(value));
elem.search = "?" + query.join("&"); elem.search = "?" + query.join("&");
} }

View File

@ -57,12 +57,12 @@ export default {
/* eslint-enable comma-spacing */ /* eslint-enable comma-spacing */
decode(data, offset = 0) { decode(data, offset = 0) {
let data_length = data.indexOf('=') - offset; let dataLength = data.indexOf('=') - offset;
if (data_length < 0) { data_length = data.length - offset; } if (dataLength < 0) { dataLength = data.length - offset; }
/* Every four characters is 3 resulting numbers */ /* Every four characters is 3 resulting numbers */
const result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5); const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
const result = new Array(result_length); const result = new Array(resultLength);
// Convert one by one. // Convert one by one.

View File

@ -17,10 +17,10 @@ export default class HextileDecoder {
decodeRect(x, y, width, height, sock, display, depth) { decodeRect(x, y, width, height, sock, display, depth) {
if (this._tiles === 0) { if (this._tiles === 0) {
this._tiles_x = Math.ceil(width / 16); this._tilesX = Math.ceil(width / 16);
this._tiles_y = Math.ceil(height / 16); this._tilesY = Math.ceil(height / 16);
this._total_tiles = this._tiles_x * this._tiles_y; this._totalTiles = this._tilesX * this._tilesY;
this._tiles = this._total_tiles; this._tiles = this._totalTiles;
} }
while (this._tiles > 0) { while (this._tiles > 0) {
@ -39,11 +39,11 @@ export default class HextileDecoder {
subencoding + ")"); subencoding + ")");
} }
const curr_tile = this._total_tiles - this._tiles; const currTile = this._totalTiles - this._tiles;
const tile_x = curr_tile % this._tiles_x; const tileX = currTile % this._tilesX;
const tile_y = Math.floor(curr_tile / this._tiles_x); const tileY = Math.floor(currTile / this._tilesX);
const tx = x + tile_x * 16; const tx = x + tileX * 16;
const ty = y + tile_y * 16; const ty = y + tileY * 16;
const tw = Math.min(16, (x + width) - tx); const tw = Math.min(16, (x + width) - tx);
const th = Math.min(16, (y + height) - ty); const th = Math.min(16, (y + height) - ty);

View File

@ -24,15 +24,15 @@ export default class RawDecoder {
return false; return false;
} }
const cur_y = y + (height - this._lines); const curY = y + (height - this._lines);
const curr_height = Math.min(this._lines, const currHeight = Math.min(this._lines,
Math.floor(sock.rQlen / bytesPerLine)); Math.floor(sock.rQlen / bytesPerLine));
let data = sock.rQ; let data = sock.rQ;
let index = sock.rQi; let index = sock.rQi;
// Convert data if needed // Convert data if needed
if (depth == 8) { if (depth == 8) {
const pixels = width * curr_height; const pixels = width * currHeight;
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;
@ -44,9 +44,9 @@ export default class RawDecoder {
index = 0; index = 0;
} }
display.blitImage(x, cur_y, width, curr_height, data, index); display.blitImage(x, curY, width, currHeight, data, index);
sock.rQskipBytes(curr_height * bytesPerLine); sock.rQskipBytes(currHeight * bytesPerLine);
this._lines -= curr_height; this._lines -= currHeight;
if (this._lines > 0) { if (this._lines > 0) {
return false; return false;
} }

View File

@ -21,12 +21,14 @@ export default class Deflator {
} }
deflate(inData) { deflate(inData) {
/* eslint-disable camelcase */
this.strm.input = inData; this.strm.input = inData;
this.strm.avail_in = this.strm.input.length; this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0; this.strm.next_in = 0;
this.strm.output = this.outputBuffer; this.strm.output = this.outputBuffer;
this.strm.avail_out = this.chunkSize; this.strm.avail_out = this.chunkSize;
this.strm.next_out = 0; this.strm.next_out = 0;
/* eslint-enable camelcase */
let lastRet = deflate(this.strm, Z_FULL_FLUSH); let lastRet = deflate(this.strm, Z_FULL_FLUSH);
let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
@ -41,9 +43,11 @@ export default class Deflator {
let chunks = [outData]; let chunks = [outData];
let totalLen = outData.length; let totalLen = outData.length;
do { do {
/* eslint-disable camelcase */
this.strm.output = new Uint8Array(this.chunkSize); this.strm.output = new Uint8Array(this.chunkSize);
this.strm.next_out = 0; this.strm.next_out = 0;
this.strm.avail_out = this.chunkSize; this.strm.avail_out = this.chunkSize;
/* eslint-enable camelcase */
lastRet = deflate(this.strm, Z_FULL_FLUSH); lastRet = deflate(this.strm, Z_FULL_FLUSH);
@ -69,9 +73,11 @@ export default class Deflator {
outData = newData; outData = newData;
} }
/* eslint-disable camelcase */
this.strm.input = null; this.strm.input = null;
this.strm.avail_in = 0; this.strm.avail_in = 0;
this.strm.next_in = 0; this.strm.next_in = 0;
/* eslint-enable camelcase */
return outData; return outData;
} }

View File

@ -13,20 +13,19 @@ import { supportsImageMetadata } from './util/browser.js';
export default class Display { export default class Display {
constructor(target) { constructor(target) {
this._drawCtx = null; this._drawCtx = null;
this._c_forceCanvas = false;
this._renderQ = []; // queue drawing actions for in-oder rendering this._renderQ = []; // queue drawing actions for in-oder rendering
this._flushing = false; this._flushing = false;
// the full frame buffer (logical canvas) size // the full frame buffer (logical canvas) size
this._fb_width = 0; this._fbWidth = 0;
this._fb_height = 0; this._fbHeight = 0;
this._prevDrawStyle = ""; this._prevDrawStyle = "";
this._tile = null; this._tile = null;
this._tile16x16 = null; this._tile16x16 = null;
this._tile_x = 0; this._tileX = 0;
this._tile_y = 0; this._tileY = 0;
Log.Debug(">> Display.constructor"); Log.Debug(">> Display.constructor");
@ -95,11 +94,11 @@ export default class Display {
} }
get width() { get width() {
return this._fb_width; return this._fbWidth;
} }
get height() { get height() {
return this._fb_height; return this._fbHeight;
} }
// ===== PUBLIC METHODS ===== // ===== PUBLIC METHODS =====
@ -122,15 +121,15 @@ export default class Display {
if (deltaX < 0 && vp.x + deltaX < 0) { if (deltaX < 0 && vp.x + deltaX < 0) {
deltaX = -vp.x; deltaX = -vp.x;
} }
if (vx2 + deltaX >= this._fb_width) { if (vx2 + deltaX >= this._fbWidth) {
deltaX -= vx2 + deltaX - this._fb_width + 1; deltaX -= vx2 + deltaX - this._fbWidth + 1;
} }
if (vp.y + deltaY < 0) { if (vp.y + deltaY < 0) {
deltaY = -vp.y; deltaY = -vp.y;
} }
if (vy2 + deltaY >= this._fb_height) { if (vy2 + deltaY >= this._fbHeight) {
deltaY -= (vy2 + deltaY - this._fb_height + 1); deltaY -= (vy2 + deltaY - this._fbHeight + 1);
} }
if (deltaX === 0 && deltaY === 0) { if (deltaX === 0 && deltaY === 0) {
@ -153,18 +152,18 @@ export default class Display {
typeof(height) === "undefined") { typeof(height) === "undefined") {
Log.Debug("Setting viewport to full display region"); Log.Debug("Setting viewport to full display region");
width = this._fb_width; width = this._fbWidth;
height = this._fb_height; height = this._fbHeight;
} }
width = Math.floor(width); width = Math.floor(width);
height = Math.floor(height); height = Math.floor(height);
if (width > this._fb_width) { if (width > this._fbWidth) {
width = this._fb_width; width = this._fbWidth;
} }
if (height > this._fb_height) { if (height > this._fbHeight) {
height = this._fb_height; height = this._fbHeight;
} }
const vp = this._viewportLoc; const vp = this._viewportLoc;
@ -204,8 +203,8 @@ export default class Display {
resize(width, height) { resize(width, height) {
this._prevDrawStyle = ""; this._prevDrawStyle = "";
this._fb_width = width; this._fbWidth = width;
this._fb_height = height; this._fbHeight = height;
const canvas = this._backbuffer; const canvas = this._backbuffer;
if (canvas.width !== width || canvas.height !== height) { if (canvas.width !== width || canvas.height !== height) {
@ -253,9 +252,9 @@ export default class Display {
// Update the visible canvas with the contents of the // Update the visible canvas with the contents of the
// rendering canvas // rendering canvas
flip(from_queue) { flip(fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
this._renderQ_push({ this._renderQPush({
'type': 'flip' 'type': 'flip'
}); });
} else { } else {
@ -311,9 +310,9 @@ export default class Display {
} }
} }
fillRect(x, y, width, height, color, from_queue) { fillRect(x, y, width, height, color, fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
this._renderQ_push({ this._renderQPush({
'type': 'fill', 'type': 'fill',
'x': x, 'x': x,
'y': y, 'y': y,
@ -328,14 +327,14 @@ export default class Display {
} }
} }
copyImage(old_x, old_y, new_x, new_y, w, h, from_queue) { copyImage(oldX, oldY, newX, newY, w, h, fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
this._renderQ_push({ this._renderQPush({
'type': 'copy', 'type': 'copy',
'old_x': old_x, 'oldX': oldX,
'old_y': old_y, 'oldY': oldY,
'x': new_x, 'x': newX,
'y': new_y, 'y': newY,
'width': w, 'width': w,
'height': h, 'height': h,
}); });
@ -353,9 +352,9 @@ export default class Display {
this._drawCtx.imageSmoothingEnabled = false; this._drawCtx.imageSmoothingEnabled = false;
this._drawCtx.drawImage(this._backbuffer, this._drawCtx.drawImage(this._backbuffer,
old_x, old_y, w, h, oldX, oldY, w, h,
new_x, new_y, w, h); newX, newY, w, h);
this._damage(new_x, new_y, w, h); this._damage(newX, newY, w, h);
} }
} }
@ -368,7 +367,7 @@ export default class Display {
const img = new Image(); const img = new Image();
img.src = "data: " + mime + ";base64," + Base64.encode(arr); img.src = "data: " + mime + ";base64," + Base64.encode(arr);
this._renderQ_push({ this._renderQPush({
'type': 'img', 'type': 'img',
'img': img, 'img': img,
'x': x, 'x': x,
@ -380,8 +379,8 @@ export default class Display {
// start updating a tile // start updating a tile
startTile(x, y, width, height, color) { startTile(x, y, width, height, color) {
this._tile_x = x; this._tileX = x;
this._tile_y = y; this._tileY = y;
if (width === 16 && height === 16) { if (width === 16 && height === 16) {
this._tile = this._tile16x16; this._tile = this._tile16x16;
} else { } else {
@ -424,21 +423,21 @@ export default class Display {
// draw the current tile to the screen // draw the current tile to the screen
finishTile() { finishTile() {
this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y); this._drawCtx.putImageData(this._tile, this._tileX, this._tileY);
this._damage(this._tile_x, this._tile_y, this._damage(this._tileX, this._tileY,
this._tile.width, this._tile.height); this._tile.width, this._tile.height);
} }
blitImage(x, y, width, height, arr, offset, from_queue) { blitImage(x, y, width, height, arr, offset, fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much // this probably isn't getting called *nearly* as much
const new_arr = new Uint8Array(width * height * 4); const newArr = new Uint8Array(width * height * 4);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); newArr.set(new Uint8Array(arr.buffer, 0, newArr.length));
this._renderQ_push({ this._renderQPush({
'type': 'blit', 'type': 'blit',
'data': new_arr, 'data': newArr,
'x': x, 'x': x,
'y': y, 'y': y,
'width': width, 'width': width,
@ -449,16 +448,16 @@ export default class Display {
} }
} }
blitRgbImage(x, y, width, height, arr, offset, from_queue) { blitRgbImage(x, y, width, height, arr, offset, fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much // this probably isn't getting called *nearly* as much
const new_arr = new Uint8Array(width * height * 3); const newArr = new Uint8Array(width * height * 3);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); newArr.set(new Uint8Array(arr.buffer, 0, newArr.length));
this._renderQ_push({ this._renderQPush({
'type': 'blitRgb', 'type': 'blitRgb',
'data': new_arr, 'data': newArr,
'x': x, 'x': x,
'y': y, 'y': y,
'width': width, 'width': width,
@ -469,16 +468,16 @@ export default class Display {
} }
} }
blitRgbxImage(x, y, width, height, arr, offset, from_queue) { blitRgbxImage(x, y, width, height, arr, offset, fromQueue) {
if (this._renderQ.length !== 0 && !from_queue) { if (this._renderQ.length !== 0 && !fromQueue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays, // NB(directxman12): it's technically more performant here to use preallocated arrays,
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
// this probably isn't getting called *nearly* as much // this probably isn't getting called *nearly* as much
const new_arr = new Uint8Array(width * height * 4); const newArr = new Uint8Array(width * height * 4);
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); newArr.set(new Uint8Array(arr.buffer, 0, newArr.length));
this._renderQ_push({ this._renderQPush({
'type': 'blitRgbx', 'type': 'blitRgbx',
'data': new_arr, 'data': newArr,
'x': x, 'x': x,
'y': y, 'y': y,
'width': width, 'width': width,
@ -583,23 +582,23 @@ export default class Display {
this._damage(x, y, img.width, img.height); this._damage(x, y, img.width, img.height);
} }
_renderQ_push(action) { _renderQPush(action) {
this._renderQ.push(action); this._renderQ.push(action);
if (this._renderQ.length === 1) { if (this._renderQ.length === 1) {
// If this can be rendered immediately it will be, otherwise // If this can be rendered immediately it will be, otherwise
// the scanner will wait for the relevant event // the scanner will wait for the relevant event
this._scan_renderQ(); this._scanRenderQ();
} }
} }
_resume_renderQ() { _resumeRenderQ() {
// "this" is the object that is ready, not the // "this" is the object that is ready, not the
// display object // display object
this.removeEventListener('load', this._noVNC_display._resume_renderQ); this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ);
this._noVNC_display._scan_renderQ(); this._noVNCDisplay._scanRenderQ();
} }
_scan_renderQ() { _scanRenderQ() {
let ready = true; let ready = true;
while (ready && this._renderQ.length > 0) { while (ready && this._renderQ.length > 0) {
const a = this._renderQ[0]; const a = this._renderQ[0];
@ -608,7 +607,7 @@ export default class Display {
this.flip(true); this.flip(true);
break; break;
case 'copy': case 'copy':
this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true); this.copyImage(a.oldX, a.oldY, a.x, a.y, a.width, a.height, true);
break; break;
case 'fill': case 'fill':
this.fillRect(a.x, a.y, a.width, a.height, a.color, true); this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
@ -633,8 +632,8 @@ export default class Display {
} }
this.drawImage(a.img, a.x, a.y); this.drawImage(a.img, a.x, a.y);
} else { } else {
a.img._noVNC_display = this; a.img._noVNCDisplay = this;
a.img.addEventListener('load', this._resume_renderQ); a.img.addEventListener('load', this._resumeRenderQ);
// We need to wait for this image to 'load' // We need to wait for this image to 'load'
// to keep things in-order // to keep things in-order
ready = false; ready = false;

View File

@ -22,6 +22,7 @@ export default class Inflate {
setInput(data) { setInput(data) {
if (!data) { if (!data) {
//FIXME: flush remaining data. //FIXME: flush remaining data.
/* eslint-disable camelcase */
this.strm.input = null; this.strm.input = null;
this.strm.avail_in = 0; this.strm.avail_in = 0;
this.strm.next_in = 0; this.strm.next_in = 0;
@ -29,6 +30,7 @@ export default class Inflate {
this.strm.input = data; this.strm.input = data;
this.strm.avail_in = this.strm.input.length; this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0; this.strm.next_in = 0;
/* eslint-enable camelcase */
} }
} }
@ -41,8 +43,10 @@ export default class Inflate {
this.strm.output = new Uint8Array(this.chunkSize); this.strm.output = new Uint8Array(this.chunkSize);
} }
/* eslint-disable camelcase */
this.strm.next_out = 0; this.strm.next_out = 0;
this.strm.avail_out = expected; this.strm.avail_out = expected;
/* eslint-enable camelcase */
let ret = inflate(this.strm, 0); // Flush argument not used. let ret = inflate(this.strm, 0); // Flush argument not used.
if (ret < 0) { if (ret < 0) {

View File

@ -947,7 +947,7 @@ export default class RFB extends EventTargetMixin {
while (repeaterID.length < 250) { while (repeaterID.length < 250) {
repeaterID += "\0"; repeaterID += "\0";
} }
this._sock.send_string(repeaterID); this._sock.sendString(repeaterID);
return true; return true;
} }
@ -957,7 +957,7 @@ export default class RFB extends EventTargetMixin {
const cversion = "00" + parseInt(this._rfbVersion, 10) + const cversion = "00" + parseInt(this._rfbVersion, 10) +
".00" + ((this._rfbVersion * 10) % 10); ".00" + ((this._rfbVersion * 10) % 10);
this._sock.send_string("RFB " + cversion + "\n"); this._sock.sendString("RFB " + cversion + "\n");
Log.Debug('Sent ProtocolVersion: ' + cversion); Log.Debug('Sent ProtocolVersion: ' + cversion);
this._rfbInitState = 'Security'; this._rfbInitState = 'Security';
@ -1071,7 +1071,7 @@ export default class RFB extends EventTargetMixin {
String.fromCharCode(this._rfbCredentials.target.length) + String.fromCharCode(this._rfbCredentials.target.length) +
this._rfbCredentials.username + this._rfbCredentials.username +
this._rfbCredentials.target; this._rfbCredentials.target;
this._sock.send_string(xvpAuthStr); this._sock.sendString(xvpAuthStr);
this._rfbAuthScheme = 2; this._rfbAuthScheme = 2;
return this._negotiateAuthentication(); return this._negotiateAuthentication();
} }
@ -1156,8 +1156,8 @@ export default class RFB extends EventTargetMixin {
// XXX we assume lengths are <= 255 (should not be an issue in the real world) // XXX we assume lengths are <= 255 (should not be an issue in the real world)
this._sock.send([0, 0, 0, user.length]); this._sock.send([0, 0, 0, user.length]);
this._sock.send([0, 0, 0, pass.length]); this._sock.send([0, 0, 0, pass.length]);
this._sock.send_string(user); this._sock.sendString(user);
this._sock.send_string(pass); this._sock.sendString(pass);
this._rfbInitState = "SecurityResult"; this._rfbInitState = "SecurityResult";
return true; return true;
@ -1193,8 +1193,8 @@ export default class RFB extends EventTargetMixin {
this._sock.send([0, 0, 0, this._rfbCredentials.username.length]); this._sock.send([0, 0, 0, this._rfbCredentials.username.length]);
this._sock.send([0, 0, 0, this._rfbCredentials.password.length]); this._sock.send([0, 0, 0, this._rfbCredentials.password.length]);
this._sock.send_string(this._rfbCredentials.username); this._sock.sendString(this._rfbCredentials.username);
this._sock.send_string(this._rfbCredentials.password); this._sock.sendString(this._rfbCredentials.password);
this._rfbInitState = "SecurityResult"; this._rfbInitState = "SecurityResult";
return true; return true;
} }

View File

@ -10,18 +10,18 @@
* Logging/debug routines * Logging/debug routines
*/ */
let _log_level = 'warn'; let _logLevel = 'warn';
let Debug = () => {}; let Debug = () => {};
let Info = () => {}; let Info = () => {};
let Warn = () => {}; let Warn = () => {};
let Error = () => {}; let Error = () => {};
export function init_logging(level) { export function initLogging(level) {
if (typeof level === 'undefined') { if (typeof level === 'undefined') {
level = _log_level; level = _logLevel;
} else { } else {
_log_level = level; _logLevel = level;
} }
Debug = Info = Warn = Error = () => {}; Debug = Info = Warn = Error = () => {};
@ -46,11 +46,11 @@ export function init_logging(level) {
} }
} }
export function get_logging() { export function getLogging() {
return _log_level; return _logLevel;
} }
export { Debug, Info, Warn, Error }; export { Debug, Info, Warn, Error };
// Initialize logging level // Initialize logging level
init_logging(); initLogging();

View File

@ -144,7 +144,7 @@ export default class Websock {
flush() { flush() {
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) { if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
this._websocket.send(this._encode_message()); this._websocket.send(this._encodeMessage());
this._sQlen = 0; this._sQlen = 0;
} }
} }
@ -155,7 +155,7 @@ export default class Websock {
this.flush(); this.flush();
} }
send_string(str) { sendString(str) {
this.send(str.split('').map(chr => chr.charCodeAt(0))); this.send(str.split('').map(chr => chr.charCodeAt(0)));
} }
@ -168,13 +168,13 @@ export default class Websock {
this._eventHandlers[evt] = handler; this._eventHandlers[evt] = handler;
} }
_allocate_buffers() { _allocateBuffers() {
this._rQ = new Uint8Array(this._rQbufferSize); this._rQ = new Uint8Array(this._rQbufferSize);
this._sQ = new Uint8Array(this._sQbufferSize); this._sQ = new Uint8Array(this._sQbufferSize);
} }
init() { init() {
this._allocate_buffers(); this._allocateBuffers();
this._rQi = 0; this._rQi = 0;
this._websocket = null; this._websocket = null;
} }
@ -185,7 +185,7 @@ export default class Websock {
this._websocket = new WebSocket(uri, protocols); this._websocket = new WebSocket(uri, protocols);
this._websocket.binaryType = 'arraybuffer'; this._websocket.binaryType = 'arraybuffer';
this._websocket.onmessage = this._recv_message.bind(this); this._websocket.onmessage = this._recvMessage.bind(this);
this._websocket.onopen = () => { this._websocket.onopen = () => {
Log.Debug('>> WebSock.onopen'); Log.Debug('>> WebSock.onopen');
if (this._websocket.protocol) { if (this._websocket.protocol) {
@ -220,7 +220,7 @@ export default class Websock {
} }
// private methods // private methods
_encode_message() { _encodeMessage() {
// Put in a binary arraybuffer // Put in a binary arraybuffer
// according to the spec, you can send ArrayBufferViews with the send method // according to the spec, you can send ArrayBufferViews with the send method
return new Uint8Array(this._sQ.buffer, 0, this._sQlen); return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
@ -231,30 +231,30 @@ export default class Websock {
// The function also expands the receive que if needed, and for // The function also expands the receive que if needed, and for
// performance reasons we combine these two actions to avoid // performance reasons we combine these two actions to avoid
// unneccessary copying. // unneccessary copying.
_expand_compact_rQ(min_fit) { _expandCompactRQ(minFit) {
// if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place // if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place
// instead of resizing // instead of resizing
const required_buffer_size = (this._rQlen - this._rQi + min_fit) * 8; const requiredBufferSize = (this._rQlen - this._rQi + minFit) * 8;
const resizeNeeded = this._rQbufferSize < required_buffer_size; const resizeNeeded = this._rQbufferSize < requiredBufferSize;
if (resizeNeeded) { if (resizeNeeded) {
// Make sure we always *at least* double the buffer size, and have at least space for 8x // Make sure we always *at least* double the buffer size, and have at least space for 8x
// the current amount of data // the current amount of data
this._rQbufferSize = Math.max(this._rQbufferSize * 2, required_buffer_size); this._rQbufferSize = Math.max(this._rQbufferSize * 2, requiredBufferSize);
} }
// we don't want to grow unboundedly // we don't want to grow unboundedly
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) { if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
this._rQbufferSize = MAX_RQ_GROW_SIZE; this._rQbufferSize = MAX_RQ_GROW_SIZE;
if (this._rQbufferSize - this.rQlen < min_fit) { if (this._rQbufferSize - this.rQlen < minFit) {
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
} }
} }
if (resizeNeeded) { if (resizeNeeded) {
const old_rQbuffer = this._rQ.buffer; const oldRQbuffer = this._rQ.buffer;
this._rQ = new Uint8Array(this._rQbufferSize); this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi, this._rQlen - this._rQi)); this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi));
} else { } else {
if (ENABLE_COPYWITHIN) { if (ENABLE_COPYWITHIN) {
this._rQ.copyWithin(0, this._rQi, this._rQlen); this._rQ.copyWithin(0, this._rQi, this._rQlen);
@ -268,17 +268,17 @@ export default class Websock {
} }
// push arraybuffer values onto the end of the receive que // push arraybuffer values onto the end of the receive que
_decode_message(data) { _DecodeMessage(data) {
const u8 = new Uint8Array(data); const u8 = new Uint8Array(data);
if (u8.length > this._rQbufferSize - this._rQlen) { if (u8.length > this._rQbufferSize - this._rQlen) {
this._expand_compact_rQ(u8.length); this._expandCompactRQ(u8.length);
} }
this._rQ.set(u8, this._rQlen); this._rQ.set(u8, this._rQlen);
this._rQlen += u8.length; this._rQlen += u8.length;
} }
_recv_message(e) { _recvMessage(e) {
this._decode_message(e.data); this._DecodeMessage(e.data);
if (this.rQlen > 0) { if (this.rQlen > 0) {
this._eventHandlers.message(); this._eventHandlers.message();
if (this._rQlen == this._rQi) { if (this._rQlen == this._rQi) {

View File

@ -1,32 +1,32 @@
// noVNC specific assertions // noVNC specific assertions
chai.use(function (_chai, utils) { chai.use(function (_chai, utils) {
_chai.Assertion.addMethod('displayed', function (target_data) { _chai.Assertion.addMethod('displayed', function (targetData) {
const obj = this._obj; const obj = this._obj;
const ctx = obj._target.getContext('2d'); const ctx = obj._target.getContext('2d');
const data_cl = ctx.getImageData(0, 0, obj._target.width, obj._target.height).data; const dataCl = ctx.getImageData(0, 0, obj._target.width, obj._target.height).data;
// NB(directxman12): PhantomJS 1.x doesn't implement Uint8ClampedArray, so work around that // NB(directxman12): PhantomJS 1.x doesn't implement Uint8ClampedArray, so work around that
const data = new Uint8Array(data_cl); const data = new Uint8Array(dataCl);
const len = data_cl.length; const len = dataCl.length;
new chai.Assertion(len).to.be.equal(target_data.length, "unexpected display size"); new chai.Assertion(len).to.be.equal(targetData.length, "unexpected display size");
let same = true; let same = true;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
if (data[i] != target_data[i]) { if (data[i] != targetData[i]) {
same = false; same = false;
break; break;
} }
} }
if (!same) { if (!same) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log("expected data: %o, actual data: %o", target_data, data); console.log("expected data: %o, actual data: %o", targetData, 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, targetData,
data); data);
}); });
_chai.Assertion.addMethod('sent', function (target_data) { _chai.Assertion.addMethod('sent', function (targetData) {
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),
@ -34,13 +34,13 @@ chai.use(function (_chai, utils) {
res.prototype = obj; res.prototype = obj;
return res; return res;
}; };
const data = obj._websocket._get_sent_data(); const data = obj._websocket._getSentData();
let same = true; let same = true;
if (data.length != target_data.length) { if (data.length != targetData.length) {
same = false; same = false;
} else { } else {
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
if (data[i] != target_data[i]) { if (data[i] != targetData[i]) {
same = false; same = false;
break; break;
} }
@ -48,12 +48,12 @@ chai.use(function (_chai, utils) {
} }
if (!same) { if (!same) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log("expected data: %o, actual data: %o", target_data, data); console.log("expected data: %o, actual data: %o", targetData, 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(targetData),
Array.prototype.slice.call(data)); Array.prototype.slice.call(data));
}); });

View File

@ -1,7 +1,7 @@
import Base64 from '../core/base64.js'; import Base64 from '../core/base64.js';
// PhantomJS can't create Event objects directly, so we need to use this // PhantomJS can't create Event objects directly, so we need to use this
function make_event(name, props) { function makeEvent(name, props) {
const evt = document.createEvent('Event'); const evt = document.createEvent('Event');
evt.initEvent(name, true, true); evt.initEvent(name, true, true);
if (props) { if (props) {
@ -24,18 +24,18 @@ export default class FakeWebSocket {
this.protocol = protocols[0]; this.protocol = protocols[0];
} }
this._send_queue = new Uint8Array(20000); this._sendQueue = new Uint8Array(20000);
this.readyState = FakeWebSocket.CONNECTING; this.readyState = FakeWebSocket.CONNECTING;
this.bufferedAmount = 0; this.bufferedAmount = 0;
this.__is_fake = true; this._isFake = true;
} }
close(code, reason) { close(code, reason) {
this.readyState = FakeWebSocket.CLOSED; this.readyState = FakeWebSocket.CLOSED;
if (this.onclose) { if (this.onclose) {
this.onclose(make_event("close", { 'code': code, 'reason': reason, 'wasClean': true })); this.onclose(makeEvent("close", { 'code': code, 'reason': reason, 'wasClean': true }));
} }
} }
@ -45,12 +45,12 @@ export default class FakeWebSocket {
} else { } else {
data = new Uint8Array(data); data = new Uint8Array(data);
} }
this._send_queue.set(data, this.bufferedAmount); this._sendQueue.set(data, this.bufferedAmount);
this.bufferedAmount += data.length; this.bufferedAmount += data.length;
} }
_get_sent_data() { _getSentData() {
const res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount); const res = new Uint8Array(this._sendQueue.buffer, 0, this.bufferedAmount);
this.bufferedAmount = 0; this.bufferedAmount = 0;
return res; return res;
} }
@ -58,16 +58,16 @@ export default class FakeWebSocket {
_open() { _open() {
this.readyState = FakeWebSocket.OPEN; this.readyState = FakeWebSocket.OPEN;
if (this.onopen) { if (this.onopen) {
this.onopen(make_event('open')); this.onopen(makeEvent('open'));
} }
} }
_receive_data(data) { _receiveData(data) {
// Break apart the data to expose bugs where we assume data is // Break apart the data to expose bugs where we assume data is
// neatly packaged // neatly packaged
for (let i = 0;i < data.length;i++) { for (let i = 0;i < data.length;i++) {
let buf = data.subarray(i, i+1); let buf = data.subarray(i, i+1);
this.onmessage(make_event("message", { 'data': buf })); this.onmessage(makeEvent("message", { 'data': buf }));
} }
} }
} }
@ -77,20 +77,20 @@ FakeWebSocket.CONNECTING = WebSocket.CONNECTING;
FakeWebSocket.CLOSING = WebSocket.CLOSING; FakeWebSocket.CLOSING = WebSocket.CLOSING;
FakeWebSocket.CLOSED = WebSocket.CLOSED; FakeWebSocket.CLOSED = WebSocket.CLOSED;
FakeWebSocket.__is_fake = true; FakeWebSocket._isFake = true;
FakeWebSocket.replace = () => { FakeWebSocket.replace = () => {
if (!WebSocket.__is_fake) { if (!WebSocket._isFake) {
const real_version = WebSocket; const realVersion = WebSocket;
// eslint-disable-next-line no-global-assign // eslint-disable-next-line no-global-assign
WebSocket = FakeWebSocket; WebSocket = FakeWebSocket;
FakeWebSocket.__real_version = real_version; FakeWebSocket._realVersion = realVersion;
} }
}; };
FakeWebSocket.restore = () => { FakeWebSocket.restore = () => {
if (WebSocket.__is_fake) { if (WebSocket._isFake) {
// eslint-disable-next-line no-global-assign // eslint-disable-next-line no-global-assign
WebSocket = WebSocket.__real_version; WebSocket = WebSocket._realVersion;
} }
}; };

View File

@ -1,4 +1,4 @@
/* global VNC_frame_data, VNC_frame_encoding */ /* global vncFrameData, vncFrameEncoding */
import * as WebUtil from '../app/webutil.js'; import * as WebUtil from '../app/webutil.js';
import RecordingPlayer from './playback.js'; import RecordingPlayer from './playback.js';
@ -41,7 +41,7 @@ function enableUI() {
document.getElementById('mode1').checked = true; document.getElementById('mode1').checked = true;
} }
message("Loaded " + VNC_frame_data.length + " frames"); message("Loaded " + vncFrameData.length + " frames");
const startButton = document.getElementById('startButton'); const startButton = document.getElementById('startButton');
startButton.disabled = false; startButton.disabled = false;
@ -49,12 +49,12 @@ function enableUI() {
message("Converting..."); message("Converting...");
frames = VNC_frame_data; frames = vncFrameData;
let encoding; let encoding;
// Only present in older recordings // Only present in older recordings
if (window.VNC_frame_encoding) { if (window.vncFrameEncoding) {
encoding = VNC_frame_encoding; encoding = vncFrameEncoding;
} else { } else {
let frame = frames[0]; let frame = frames[0];
let start = frame.indexOf('{', 1) + 1; let start = frame.indexOf('{', 1) + 1;
@ -102,7 +102,7 @@ class IterationPlayer {
this._iteration = undefined; this._iteration = undefined;
this._player = undefined; this._player = undefined;
this._start_time = undefined; this._startTime = undefined;
this._frames = frames; this._frames = frames;
@ -115,7 +115,7 @@ class IterationPlayer {
start(realtime) { start(realtime) {
this._iteration = 0; this._iteration = 0;
this._start_time = (new Date()).getTime(); this._startTime = (new Date()).getTime();
this._realtime = realtime; this._realtime = realtime;
@ -139,7 +139,7 @@ class IterationPlayer {
_finish() { _finish() {
const endTime = (new Date()).getTime(); const endTime = (new Date()).getTime();
const totalDuration = endTime - this._start_time; const totalDuration = endTime - this._startTime;
const evt = new CustomEvent('finish', const evt = new CustomEvent('finish',
{ detail: { detail:

View File

@ -49,10 +49,10 @@ export default class RecordingPlayer {
this._disconnected = disconnected; this._disconnected = disconnected;
this._rfb = undefined; this._rfb = undefined;
this._frame_length = this._frames.length; this._frameLength = this._frames.length;
this._frame_index = 0; this._frameIndex = 0;
this._start_time = undefined; this._startTime = undefined;
this._realtime = true; this._realtime = true;
this._trafficManagement = true; this._trafficManagement = true;
@ -72,8 +72,8 @@ export default class RecordingPlayer {
this._enablePlaybackMode(); this._enablePlaybackMode();
// reset the frame index and timer // reset the frame index and timer
this._frame_index = 0; this._frameIndex = 0;
this._start_time = (new Date()).getTime(); this._startTime = (new Date()).getTime();
this._realtime = realtime; this._realtime = realtime;
this._trafficManagement = (trafficManagement === undefined) ? !realtime : trafficManagement; this._trafficManagement = (trafficManagement === undefined) ? !realtime : trafficManagement;
@ -97,22 +97,22 @@ export default class RecordingPlayer {
_queueNextPacket() { _queueNextPacket() {
if (!this._running) { return; } if (!this._running) { return; }
let frame = this._frames[this._frame_index]; let frame = this._frames[this._frameIndex];
// skip send frames // skip send frames
while (this._frame_index < this._frame_length && frame.fromClient) { while (this._frameIndex < this._frameLength && frame.fromClient) {
this._frame_index++; this._frameIndex++;
frame = this._frames[this._frame_index]; frame = this._frames[this._frameIndex];
} }
if (this._frame_index >= this._frame_length) { if (this._frameIndex >= this._frameLength) {
Log.Debug('Finished, no more frames'); Log.Debug('Finished, no more frames');
this._finish(); this._finish();
return; return;
} }
if (this._realtime) { if (this._realtime) {
const toffset = (new Date()).getTime() - this._start_time; const toffset = (new Date()).getTime() - this._startTime;
let delay = frame.timestamp - toffset; let delay = frame.timestamp - toffset;
if (delay < 1) delay = 1; if (delay < 1) delay = 1;
@ -134,10 +134,10 @@ export default class RecordingPlayer {
return; return;
} }
const frame = this._frames[this._frame_index]; const frame = this._frames[this._frameIndex];
this._rfb._sock._recv_message({'data': frame.data}); this._rfb._sock._recv_message({'data': frame.data});
this._frame_index++; this._frameIndex++;
this._queueNextPacket(); this._queueNextPacket();
} }
@ -155,13 +155,13 @@ export default class RecordingPlayer {
this._running = false; this._running = false;
this._rfb._sock._eventHandlers.close({code: 1000, reason: ""}); this._rfb._sock._eventHandlers.close({code: 1000, reason: ""});
delete this._rfb; delete this._rfb;
this.onfinish((new Date()).getTime() - this._start_time); this.onfinish((new Date()).getTime() - this._startTime);
} }
} }
_handleDisconnect(evt) { _handleDisconnect(evt) {
this._running = false; this._running = false;
this._disconnected(evt.detail.clean, this._frame_index); this._disconnected(evt.detail.clean, this._frameIndex);
} }
_handleCredentials(evt) { _handleCredentials(evt) {

View File

@ -17,12 +17,14 @@ function _inflator(compText, expected) {
strm.output = new Uint8Array(chunkSize); strm.output = new Uint8Array(chunkSize);
} }
/* eslint-disable camelcase */
strm.input = compText; strm.input = compText;
strm.avail_in = strm.input.length; strm.avail_in = strm.input.length;
strm.next_in = 0; strm.next_in = 0;
strm.next_out = 0; strm.next_out = 0;
strm.avail_out = expected.length; strm.avail_out = expected.length;
/* eslint-enable camelcase */
let ret = inflate(strm, 0); let ret = inflate(strm, 0);

View File

@ -4,28 +4,28 @@ import Base64 from '../core/base64.js';
import Display from '../core/display.js'; import Display from '../core/display.js';
describe('Display/Canvas Helper', function () { describe('Display/Canvas Helper', function () {
const checked_data = new Uint8Array([ const checkedData = new Uint8Array([
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255,
0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255
]); ]);
const basic_data = new Uint8Array([0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255]); const basicData = 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 makeImageCanvas(inputData) {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = 4; canvas.width = 4;
canvas.height = 4; canvas.height = 4;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
const data = ctx.createImageData(4, 4); const data = ctx.createImageData(4, 4);
for (let i = 0; i < checked_data.length; i++) { data.data[i] = input_data[i]; } for (let i = 0; i < checkedData.length; i++) { data.data[i] = inputData[i]; }
ctx.putImageData(data, 0, 0); ctx.putImageData(data, 0, 0);
return canvas; return canvas;
} }
function make_image_png(input_data) { function makeImagePng(inputData) {
const canvas = make_image_canvas(input_data); const canvas = makeImageCanvas(inputData);
const url = canvas.toDataURL(); const url = canvas.toDataURL();
const data = url.split(",")[1]; const data = url.split(",")[1];
return Base64.decode(data); return Base64.decode(data);
@ -44,11 +44,11 @@ describe('Display/Canvas Helper', function () {
it('should take viewport location into consideration when drawing images', function () { it('should take viewport location into consideration when drawing images', function () {
display.resize(4, 4); display.resize(4, 4);
display.viewportChangeSize(2, 2); display.viewportChangeSize(2, 2);
display.drawImage(make_image_canvas(basic_data), 1, 1); display.drawImage(makeImageCanvas(basicData), 1, 1);
display.flip(); display.flip();
const expected = new Uint8Array(16); const expected = new Uint8Array(16);
for (let i = 0; i < 8; i++) { expected[i] = basic_data[i]; } for (let i = 0; i < 8; i++) { expected[i] = basicData[i]; }
for (let i = 8; i < 16; i++) { expected[i] = 0; } for (let i = 8; i < 16; i++) { expected[i] = 0; }
expect(display).to.have.displayed(expected); expect(display).to.have.displayed(expected);
}); });
@ -123,8 +123,8 @@ describe('Display/Canvas Helper', function () {
it('should change the size of the logical canvas', function () { it('should change the size of the logical canvas', function () {
display.resize(5, 7); display.resize(5, 7);
expect(display._fb_width).to.equal(5); expect(display._fbWidth).to.equal(5);
expect(display._fb_height).to.equal(7); expect(display._fbHeight).to.equal(7);
}); });
it('should keep the framebuffer data', function () { it('should keep the framebuffer data', function () {
@ -275,7 +275,7 @@ describe('Display/Canvas Helper', function () {
display.flip(); display.flip();
display.fillRect(0, 0, 4, 4, [0, 0xff, 0]); display.fillRect(0, 0, 4, 4, [0, 0xff, 0]);
const expected = []; const expected = [];
for (let i = 0; i < 4 * display._fb_width * display._fb_height; i += 4) { for (let i = 0; i < 4 * display._fbWidth * display._fbHeight; i += 4) {
expected[i] = 0xff; expected[i] = 0xff;
expected[i+1] = expected[i+2] = 0; expected[i+1] = expected[i+2] = 0;
expected[i+3] = 0xff; expected[i+3] = 0xff;
@ -288,7 +288,7 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 2, 2, [0xff, 0, 0]); display.fillRect(0, 0, 2, 2, [0xff, 0, 0]);
display.fillRect(2, 2, 2, 2, [0xff, 0, 0]); display.fillRect(2, 2, 2, 2, [0xff, 0, 0]);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
it('should support copying an portion of the canvas via #copyImage', function () { it('should support copying an portion of the canvas via #copyImage', function () {
@ -296,14 +296,14 @@ describe('Display/Canvas Helper', function () {
display.fillRect(0, 0, 2, 2, [0xff, 0, 0x00]); display.fillRect(0, 0, 2, 2, [0xff, 0, 0x00]);
display.copyImage(0, 0, 2, 2, 2, 2); display.copyImage(0, 0, 2, 2, 2, 2);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
it('should support drawing images via #imageRect', function (done) { it('should support drawing images via #imageRect', function (done) {
display.imageRect(0, 0, 4, 4, "image/png", make_image_png(checked_data)); display.imageRect(0, 0, 4, 4, "image/png", makeImagePng(checkedData));
display.flip(); display.flip();
display.onflush = () => { display.onflush = () => {
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
done(); done();
}; };
display.flush(); display.flush();
@ -315,12 +315,12 @@ describe('Display/Canvas Helper', function () {
display.subTile(2, 2, 2, 2, [0xff, 0, 0]); display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
display.finishTile(); display.finishTile();
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
// We have a special cache for 16x16 tiles that we need to test // We have a special cache for 16x16 tiles that we need to test
it('should support drawing a 16x16 tile', function () { it('should support drawing a 16x16 tile', function () {
const large_checked_data = new Uint8Array(16*16*4); const largeCheckedData = new Uint8Array(16*16*4);
display.resize(16, 16); display.resize(16, 16);
for (let y = 0;y < 16;y++) { for (let y = 0;y < 16;y++) {
@ -328,11 +328,11 @@ describe('Display/Canvas Helper', function () {
let pixel; let pixel;
if ((x < 4) && (y < 4)) { if ((x < 4) && (y < 4)) {
// NB: of course IE11 doesn't support #slice on ArrayBufferViews... // NB: of course IE11 doesn't support #slice on ArrayBufferViews...
pixel = Array.prototype.slice.call(checked_data, (y*4+x)*4, (y*4+x+1)*4); pixel = Array.prototype.slice.call(checkedData, (y*4+x)*4, (y*4+x+1)*4);
} else { } else {
pixel = [0, 0xff, 0, 255]; pixel = [0, 0xff, 0, 255];
} }
large_checked_data.set(pixel, (y*16+x)*4); largeCheckedData.set(pixel, (y*16+x)*4);
} }
} }
@ -341,39 +341,39 @@ describe('Display/Canvas Helper', function () {
display.subTile(2, 2, 2, 2, [0xff, 0, 0]); display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
display.finishTile(); display.finishTile();
display.flip(); display.flip();
expect(display).to.have.displayed(large_checked_data); expect(display).to.have.displayed(largeCheckedData);
}); });
it('should support drawing BGRX blit images with true color via #blitImage', function () { it('should support drawing BGRX blit images with true color via #blitImage', function () {
const data = []; const data = [];
for (let i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
data[i * 4] = checked_data[i * 4 + 2]; data[i * 4] = checkedData[i * 4 + 2];
data[i * 4 + 1] = checked_data[i * 4 + 1]; data[i * 4 + 1] = checkedData[i * 4 + 1];
data[i * 4 + 2] = checked_data[i * 4]; data[i * 4 + 2] = checkedData[i * 4];
data[i * 4 + 3] = checked_data[i * 4 + 3]; data[i * 4 + 3] = checkedData[i * 4 + 3];
} }
display.blitImage(0, 0, 4, 4, data, 0); display.blitImage(0, 0, 4, 4, data, 0);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
it('should support drawing RGB blit images with true color via #blitRgbImage', function () { it('should support drawing RGB blit images with true color via #blitRgbImage', function () {
const data = []; const data = [];
for (let i = 0; i < 16; i++) { for (let i = 0; i < 16; i++) {
data[i * 3] = checked_data[i * 4]; data[i * 3] = checkedData[i * 4];
data[i * 3 + 1] = checked_data[i * 4 + 1]; data[i * 3 + 1] = checkedData[i * 4 + 1];
data[i * 3 + 2] = checked_data[i * 4 + 2]; data[i * 3 + 2] = checkedData[i * 4 + 2];
} }
display.blitRgbImage(0, 0, 4, 4, data, 0); display.blitRgbImage(0, 0, 4, 4, data, 0);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
it('should support drawing an image object via #drawImage', function () { it('should support drawing an image object via #drawImage', function () {
const img = make_image_canvas(checked_data); const img = makeImageCanvas(checkedData);
display.drawImage(img, 0, 0); display.drawImage(img, 0, 0);
display.flip(); display.flip();
expect(display).to.have.displayed(checked_data); expect(display).to.have.displayed(checkedData);
}); });
}); });
@ -382,22 +382,18 @@ describe('Display/Canvas Helper', function () {
beforeEach(function () { beforeEach(function () {
display = new Display(document.createElement('canvas')); display = new Display(document.createElement('canvas'));
display.resize(4, 4); display.resize(4, 4);
sinon.spy(display, '_scan_renderQ'); sinon.spy(display, '_scanRenderQ');
});
afterEach(function () {
window.requestAnimationFrame = this.old_requestAnimationFrame;
}); });
it('should try to process an item when it is pushed on, if nothing else is on the queue', function () { it('should try to process an item when it is pushed on, if nothing else is on the queue', function () {
display._renderQ_push({ type: 'noop' }); // does nothing display._renderQPush({ type: 'noop' }); // does nothing
expect(display._scan_renderQ).to.have.been.calledOnce; expect(display._scanRenderQ).to.have.been.calledOnce;
}); });
it('should not try to process an item when it is pushed on if we are waiting for other items', function () { it('should not try to process an item when it is pushed on if we are waiting for other items', function () {
display._renderQ.length = 2; display._renderQ.length = 2;
display._renderQ_push({ type: 'noop' }); display._renderQPush({ type: 'noop' });
expect(display._scan_renderQ).to.not.have.been.called; expect(display._scanRenderQ).to.not.have.been.called;
}); });
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 () {
@ -407,13 +403,13 @@ describe('Display/Canvas Helper', function () {
display.drawImage = sinon.spy(); display.drawImage = sinon.spy();
display.fillRect = sinon.spy(); display.fillRect = sinon.spy();
display._scan_renderQ(); display._scanRenderQ();
expect(display.drawImage).to.not.have.been.called; expect(display.drawImage).to.not.have.been.called;
expect(display.fillRect).to.not.have.been.called; expect(display.fillRect).to.not.have.been.called;
expect(img.addEventListener).to.have.been.calledOnce; expect(img.addEventListener).to.have.been.calledOnce;
display._renderQ[0].img.complete = true; display._renderQ[0].img.complete = true;
display._scan_renderQ(); display._scanRenderQ();
expect(display.drawImage).to.have.been.calledOnce; expect(display.drawImage).to.have.been.calledOnce;
expect(display.fillRect).to.have.been.calledOnce; expect(display.fillRect).to.have.been.calledOnce;
expect(img.addEventListener).to.have.been.calledOnce; expect(img.addEventListener).to.have.been.calledOnce;
@ -426,7 +422,7 @@ describe('Display/Canvas Helper', function () {
display.drawImage = sinon.spy(); display.drawImage = sinon.spy();
display.fillRect = sinon.spy(); display.fillRect = sinon.spy();
display._scan_renderQ(); display._scanRenderQ();
expect(display.drawImage).to.not.have.been.called; expect(display.drawImage).to.not.have.been.called;
expect(display.fillRect).to.not.have.been.called; expect(display.fillRect).to.not.have.been.called;
expect(img.addEventListener).to.have.been.calledOnce; expect(img.addEventListener).to.have.been.calledOnce;
@ -434,7 +430,7 @@ describe('Display/Canvas Helper', function () {
display._renderQ[0].img.complete = true; display._renderQ[0].img.complete = true;
display._renderQ[0].img.width = 4; display._renderQ[0].img.width = 4;
display._renderQ[0].img.height = 4; display._renderQ[0].img.height = 4;
display._scan_renderQ(); display._scanRenderQ();
expect(display.drawImage).to.have.been.calledOnce; expect(display.drawImage).to.have.been.calledOnce;
expect(display.fillRect).to.have.been.calledOnce; expect(display.fillRect).to.have.been.calledOnce;
expect(img.addEventListener).to.have.been.calledOnce; expect(img.addEventListener).to.have.been.calledOnce;
@ -450,35 +446,35 @@ describe('Display/Canvas Helper', function () {
it('should draw a blit image on type "blit"', function () { it('should draw a blit image on type "blit"', function () {
display.blitImage = sinon.spy(); display.blitImage = sinon.spy();
display._renderQ_push({ type: 'blit', x: 3, y: 4, width: 5, height: 6, data: [7, 8, 9] }); display._renderQPush({ type: 'blit', x: 3, y: 4, width: 5, height: 6, data: [7, 8, 9] });
expect(display.blitImage).to.have.been.calledOnce; expect(display.blitImage).to.have.been.calledOnce;
expect(display.blitImage).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9], 0); expect(display.blitImage).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9], 0);
}); });
it('should draw a blit RGB image on type "blitRgb"', function () { it('should draw a blit RGB image on type "blitRgb"', function () {
display.blitRgbImage = sinon.spy(); display.blitRgbImage = sinon.spy();
display._renderQ_push({ type: 'blitRgb', x: 3, y: 4, width: 5, height: 6, data: [7, 8, 9] }); display._renderQPush({ type: 'blitRgb', x: 3, y: 4, width: 5, height: 6, data: [7, 8, 9] });
expect(display.blitRgbImage).to.have.been.calledOnce; expect(display.blitRgbImage).to.have.been.calledOnce;
expect(display.blitRgbImage).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9], 0); expect(display.blitRgbImage).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9], 0);
}); });
it('should copy a region on type "copy"', function () { it('should copy a region on type "copy"', function () {
display.copyImage = sinon.spy(); display.copyImage = sinon.spy();
display._renderQ_push({ type: 'copy', x: 3, y: 4, width: 5, height: 6, old_x: 7, old_y: 8 }); display._renderQPush({ type: 'copy', x: 3, y: 4, width: 5, height: 6, oldX: 7, oldY: 8 });
expect(display.copyImage).to.have.been.calledOnce; expect(display.copyImage).to.have.been.calledOnce;
expect(display.copyImage).to.have.been.calledWith(7, 8, 3, 4, 5, 6); expect(display.copyImage).to.have.been.calledWith(7, 8, 3, 4, 5, 6);
}); });
it('should fill a rect with a given color on type "fill"', function () { it('should fill a rect with a given color on type "fill"', function () {
display.fillRect = sinon.spy(); display.fillRect = sinon.spy();
display._renderQ_push({ type: 'fill', x: 3, y: 4, width: 5, height: 6, color: [7, 8, 9]}); display._renderQPush({ type: 'fill', x: 3, y: 4, width: 5, height: 6, color: [7, 8, 9]});
expect(display.fillRect).to.have.been.calledOnce; expect(display.fillRect).to.have.been.calledOnce;
expect(display.fillRect).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9]); expect(display.fillRect).to.have.been.calledWith(3, 4, 5, 6, [7, 8, 9]);
}); });
it('should draw an image from an image object on type "img" (if complete)', function () { it('should draw an image from an image object on type "img" (if complete)', function () {
display.drawImage = sinon.spy(); display.drawImage = sinon.spy();
display._renderQ_push({ type: 'img', x: 3, y: 4, img: { complete: true } }); display._renderQPush({ type: 'img', x: 3, y: 4, img: { complete: true } });
expect(display.drawImage).to.have.been.calledOnce; expect(display.drawImage).to.have.been.calledOnce;
expect(display.drawImage).to.have.been.calledWith({ complete: true }, 3, 4); expect(display.drawImage).to.have.been.calledWith({ complete: true }, 3, 4);
}); });

View File

@ -70,11 +70,13 @@ function deflateWithSize(data) {
strm.output = new Uint8Array(chunkSize); strm.output = new Uint8Array(chunkSize);
deflateInit(strm, 5); deflateInit(strm, 5);
/* eslint-disable camelcase */
strm.input = unCompData; strm.input = unCompData;
strm.avail_in = strm.input.length; strm.avail_in = strm.input.length;
strm.next_in = 0; strm.next_in = 0;
strm.next_out = 0; strm.next_out = 0;
strm.avail_out = chunkSize; strm.avail_out = chunkSize;
/* eslint-enable camelcase */
deflate(strm, 3); deflate(strm, 3);
@ -99,8 +101,8 @@ describe('Remote Frame Buffer Protocol Client', function () {
const _sQ = new Uint8Array(sock._sQbufferSize); const _sQ = new Uint8Array(sock._sQbufferSize);
const rQ = new Uint8Array(sock._rQbufferSize); const rQ = new Uint8Array(sock._rQbufferSize);
Websock.prototype._old_allocate_buffers = Websock.prototype._allocate_buffers; Websock.prototype._oldAllocateBuffers = Websock.prototype._allocateBuffers;
Websock.prototype._allocate_buffers = function () { Websock.prototype._allocateBuffers = function () {
this._sQ = _sQ; this._sQ = _sQ;
this._rQ = rQ; this._rQ = rQ;
}; };
@ -108,7 +110,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
}); });
after(function () { after(function () {
Websock.prototype._allocate_buffers = Websock.prototype._old_allocate_buffers; Websock.prototype._allocateBuffers = Websock.prototype._oldAllocateBuffers;
this.clock.restore(); this.clock.restore();
window.requestAnimationFrame = raf; window.requestAnimationFrame = raf;
}); });
@ -352,7 +354,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
push32(data, toUnsigned32bit(-8)); push32(data, toUnsigned32bit(-8));
data = data.concat(flags); data = data.concat(flags);
data = data.concat(fileSizes); data = data.concat(fileSizes);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
client.clipboardPasteFrom('extended test'); client.clipboardPasteFrom('extended test');
expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce;
@ -450,7 +452,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
sinon.spy(client._display, "viewportChangeSize"); sinon.spy(client._display, "viewportChangeSize");
client._sock._websocket._receive_data(new Uint8Array(incoming)); client._sock._websocket._receiveData(new Uint8Array(incoming));
// FIXME: Display implicitly calls viewportChangeSize() when // FIXME: Display implicitly calls viewportChangeSize() when
// resizing the framebuffer, hence calledTwice. // resizing the framebuffer, hence calledTwice.
@ -647,7 +649,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
sinon.spy(client._display, "autoscale"); sinon.spy(client._display, "autoscale");
client._sock._websocket._receive_data(new Uint8Array(incoming)); client._sock._websocket._receiveData(new Uint8Array(incoming));
expect(client._display.autoscale).to.have.been.calledOnce; expect(client._display.autoscale).to.have.been.calledOnce;
expect(client._display.autoscale).to.have.been.calledWith(70, 80); expect(client._display.autoscale).to.have.been.calledWith(70, 80);
@ -702,7 +704,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._supportsSetDesktopSize = false; client._supportsSetDesktopSize = false;
client._sock._websocket._receive_data(new Uint8Array(incoming)); client._sock._websocket._receiveData(new Uint8Array(incoming));
expect(RFB.messages.setDesktopSize).to.have.been.calledOnce; expect(RFB.messages.setDesktopSize).to.have.been.calledOnce;
expect(RFB.messages.setDesktopSize).to.have.been.calledWith(sinon.match.object, 70, 80, 0, 0); expect(RFB.messages.setDesktopSize).to.have.been.calledWith(sinon.match.object, 70, 80, 0, 0);
@ -711,7 +713,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
// Second message should not trigger a resize // Second message should not trigger a resize
client._sock._websocket._receive_data(new Uint8Array(incoming)); client._sock._websocket._receiveData(new Uint8Array(incoming));
expect(RFB.messages.setDesktopSize).to.not.have.been.called; expect(RFB.messages.setDesktopSize).to.not.have.been.called;
}); });
@ -794,7 +796,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
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._receiveData(new Uint8Array(incoming));
expect(RFB.messages.setDesktopSize).to.not.have.been.called; expect(RFB.messages.setDesktopSize).to.not.have.been.called;
}); });
@ -1012,7 +1014,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
} }
arr[0] = 'R'; arr[1] = 'F'; arr[2] = 'B'; arr[3] = ' '; arr[0] = 'R'; arr[1] = 'F'; arr[2] = 'B'; arr[3] = ' ';
arr[11] = '\n'; arr[11] = '\n';
client._sock._websocket._receive_data(arr); client._sock._websocket._receiveData(arr);
} }
describe('version parsing', function () { describe('version parsing', function () {
@ -1090,7 +1092,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
sendVer('000.000', client); sendVer('000.000', client);
expect(client._rfbVersion).to.equal(0); expect(client._rfbVersion).to.equal(0);
const sentData = client._sock._websocket._get_sent_data(); const sentData = client._sock._websocket._getSentData();
expect(new Uint8Array(sentData.buffer, 0, 9)).to.array.equal(new Uint8Array([73, 68, 58, 49, 50, 51, 52, 53, 0])); expect(new Uint8Array(sentData.buffer, 0, 9)).to.array.equal(new Uint8Array([73, 68, 58, 49, 50, 51, 52, 53, 0]));
expect(sentData).to.have.length(250); expect(sentData).to.have.length(250);
}); });
@ -1113,14 +1115,14 @@ describe('Remote Frame Buffer Protocol Client', function () {
const authSchemeRaw = [1, 2, 3, 4]; const authSchemeRaw = [1, 2, 3, 4];
const authScheme = (authSchemeRaw[0] << 24) + (authSchemeRaw[1] << 16) + const authScheme = (authSchemeRaw[0] << 24) + (authSchemeRaw[1] << 16) +
(authSchemeRaw[2] << 8) + authSchemeRaw[3]; (authSchemeRaw[2] << 8) + authSchemeRaw[3];
client._sock._websocket._receive_data(new Uint8Array(authSchemeRaw)); client._sock._websocket._receiveData(new Uint8Array(authSchemeRaw));
expect(client._rfbAuthScheme).to.equal(authScheme); expect(client._rfbAuthScheme).to.equal(authScheme);
}); });
it('should prefer no authentication is possible', function () { it('should prefer no authentication is possible', function () {
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
const authSchemes = [2, 1, 3]; const authSchemes = [2, 1, 3];
client._sock._websocket._receive_data(new Uint8Array(authSchemes)); client._sock._websocket._receiveData(new Uint8Array(authSchemes));
expect(client._rfbAuthScheme).to.equal(1); expect(client._rfbAuthScheme).to.equal(1);
expect(client._sock).to.have.sent(new Uint8Array([1, 1])); expect(client._sock).to.have.sent(new Uint8Array([1, 1]));
}); });
@ -1128,7 +1130,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should choose for the most prefered scheme possible for versions >= 3.7', function () { it('should choose for the most prefered scheme possible for versions >= 3.7', function () {
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
const authSchemes = [2, 22, 16]; const authSchemes = [2, 22, 16];
client._sock._websocket._receive_data(new Uint8Array(authSchemes)); client._sock._websocket._receiveData(new Uint8Array(authSchemes));
expect(client._rfbAuthScheme).to.equal(22); expect(client._rfbAuthScheme).to.equal(22);
expect(client._sock).to.have.sent(new Uint8Array([22])); expect(client._sock).to.have.sent(new Uint8Array([22]));
}); });
@ -1137,7 +1139,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
sinon.spy(client, "_fail"); sinon.spy(client, "_fail");
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
const authSchemes = [1, 32]; const authSchemes = [1, 32];
client._sock._websocket._receive_data(new Uint8Array(authSchemes)); client._sock._websocket._receiveData(new Uint8Array(authSchemes));
expect(client._fail).to.have.been.calledOnce; expect(client._fail).to.have.been.calledOnce;
}); });
@ -1145,7 +1147,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
const failureData = [0, 0, 0, 0, 6, 119, 104, 111, 111, 112, 115]; const failureData = [0, 0, 0, 0, 6, 119, 104, 111, 111, 112, 115];
sinon.spy(client, '_fail'); sinon.spy(client, '_fail');
client._sock._websocket._receive_data(new Uint8Array(failureData)); client._sock._websocket._receiveData(new Uint8Array(failureData));
expect(client._fail).to.have.been.calledOnce; expect(client._fail).to.have.been.calledOnce;
expect(client._fail).to.have.been.calledWith( expect(client._fail).to.have.been.calledWith(
@ -1156,7 +1158,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
const authSchemes = [1, 1]; const authSchemes = [1, 1];
client._negotiateAuthentication = sinon.spy(); client._negotiateAuthentication = sinon.spy();
client._sock._websocket._receive_data(new Uint8Array(authSchemes)); client._sock._websocket._receiveData(new Uint8Array(authSchemes));
expect(client._rfbInitState).to.equal('Authentication'); expect(client._rfbInitState).to.equal('Authentication');
expect(client._negotiateAuthentication).to.have.been.calledOnce; expect(client._negotiateAuthentication).to.have.been.calledOnce;
}); });
@ -1168,7 +1170,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
}); });
function sendSecurity(type, cl) { function sendSecurity(type, cl) {
cl._sock._websocket._receive_data(new Uint8Array([1, type])); cl._sock._websocket._receiveData(new Uint8Array([1, type]));
} }
it('should fail on auth scheme 0 (pre 3.7) with the given message', function () { it('should fail on auth scheme 0 (pre 3.7) with the given message', function () {
@ -1182,7 +1184,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
} }
sinon.spy(client, '_fail'); sinon.spy(client, '_fail');
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(client._fail).to.have.been.calledWith( expect(client._fail).to.have.been.calledWith(
'Security negotiation failed on authentication scheme (reason: Whoopsies)'); 'Security negotiation failed on authentication scheme (reason: Whoopsies)');
}); });
@ -1219,7 +1221,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const challenge = []; const challenge = [];
for (let i = 0; i < 16; i++) { challenge[i] = i; } for (let i = 0; i < 16; i++) { challenge[i] = i; }
client._sock._websocket._receive_data(new Uint8Array(challenge)); client._sock._websocket._receiveData(new Uint8Array(challenge));
expect(client._rfbCredentials).to.be.empty; expect(client._rfbCredentials).to.be.empty;
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
@ -1229,11 +1231,11 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should encrypt the password with DES and then send it back', function () { it('should encrypt the password with DES and then send it back', function () {
client._rfbCredentials = { password: 'passwd' }; client._rfbCredentials = { password: 'passwd' };
sendSecurity(2, client); sendSecurity(2, client);
client._sock._websocket._get_sent_data(); // skip the choice of auth reply client._sock._websocket._getSentData(); // skip the choice of auth reply
const challenge = []; const challenge = [];
for (let i = 0; i < 16; i++) { challenge[i] = i; } for (let i = 0; i < 16; i++) { challenge[i] = i; }
client._sock._websocket._receive_data(new Uint8Array(challenge)); client._sock._websocket._receiveData(new Uint8Array(challenge));
const desPass = RFB.genDES('passwd', challenge); const desPass = RFB.genDES('passwd', challenge);
expect(client._sock).to.have.sent(new Uint8Array(desPass)); expect(client._sock).to.have.sent(new Uint8Array(desPass));
@ -1245,7 +1247,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const challenge = []; const challenge = [];
for (let i = 0; i < 16; i++) { challenge[i] = i; } for (let i = 0; i < 16; i++) { challenge[i] = i; }
client._sock._websocket._receive_data(new Uint8Array(challenge)); client._sock._websocket._receiveData(new Uint8Array(challenge));
expect(client._rfbInitState).to.equal('SecurityResult'); expect(client._rfbInitState).to.equal('SecurityResult');
}); });
@ -1308,7 +1310,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbInitState = 'Security'; client._rfbInitState = 'Security';
client._rfbVersion = 3.8; client._rfbVersion = 3.8;
sendSecurity(16, client); sendSecurity(16, client);
client._sock._websocket._get_sent_data(); // skip the security reply client._sock._websocket._getSentData(); // skip the security reply
}); });
function sendNumStrPairs(pairs, client) { function sendNumStrPairs(pairs, client) {
@ -1325,11 +1327,11 @@ describe('Remote Frame Buffer Protocol Client', function () {
} }
} }
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
} }
it('should skip tunnel negotiation if no tunnels are requested', function () { it('should skip tunnel negotiation if no tunnels are requested', function () {
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 0]));
expect(client._rfbTightVNC).to.be.true; expect(client._rfbTightVNC).to.be.true;
}); });
@ -1351,7 +1353,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should continue to sub-auth negotiation after tunnel negotiation', function () { it('should continue to sub-auth negotiation after tunnel negotiation', function () {
sendNumStrPairs([[0, 'TGHT', 'NOTUNNEL']], client); sendNumStrPairs([[0, 'TGHT', 'NOTUNNEL']], client);
client._sock._websocket._get_sent_data(); // skip the tunnel choice here client._sock._websocket._getSentData(); // skip the tunnel choice here
sendNumStrPairs([[1, 'STDV', 'NOAUTH__']], client); sendNumStrPairs([[1, 'STDV', 'NOAUTH__']], client);
expect(client._sock).to.have.sent(new Uint8Array([0, 0, 0, 1])); expect(client._sock).to.have.sent(new Uint8Array([0, 0, 0, 1]));
expect(client._rfbInitState).to.equal('SecurityResult'); expect(client._rfbInitState).to.equal('SecurityResult');
@ -1397,7 +1399,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
}); });
it('should fall through to ServerInitialisation on a response code of 0', function () { it('should fall through to ServerInitialisation on a response code of 0', function () {
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 0]));
expect(client._rfbInitState).to.equal('ServerInitialisation'); expect(client._rfbInitState).to.equal('ServerInitialisation');
}); });
@ -1405,7 +1407,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbVersion = 3.8; client._rfbVersion = 3.8;
sinon.spy(client, '_fail'); sinon.spy(client, '_fail');
const failureData = [0, 0, 0, 1, 0, 0, 0, 6, 119, 104, 111, 111, 112, 115]; const failureData = [0, 0, 0, 1, 0, 0, 0, 6, 119, 104, 111, 111, 112, 115];
client._sock._websocket._receive_data(new Uint8Array(failureData)); client._sock._websocket._receiveData(new Uint8Array(failureData));
expect(client._fail).to.have.been.calledWith( expect(client._fail).to.have.been.calledWith(
'Security negotiation failed on security result (reason: whoops)'); 'Security negotiation failed on security result (reason: whoops)');
}); });
@ -1413,7 +1415,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should fail on an error code of 1 with a standard message for version < 3.8', function () { it('should fail on an error code of 1 with a standard message for version < 3.8', function () {
sinon.spy(client, '_fail'); sinon.spy(client, '_fail');
client._rfbVersion = 3.7; client._rfbVersion = 3.7;
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 1])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 1]));
expect(client._fail).to.have.been.calledWith( expect(client._fail).to.have.been.calledWith(
'Security handshake failed'); 'Security handshake failed');
}); });
@ -1421,7 +1423,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should result in securityfailure event when receiving a non zero status', function () { it('should result in securityfailure event when receiving a non zero status', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("securityfailure", spy); client.addEventListener("securityfailure", spy);
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 2])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 2]));
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.status).to.equal(2); expect(spy.args[0][0].detail.status).to.equal(2);
}); });
@ -1432,7 +1434,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client.addEventListener("securityfailure", spy); client.addEventListener("securityfailure", spy);
const failureData = [0, 0, 0, 1, 0, 0, 0, 12, 115, 117, 99, 104, const failureData = [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(failureData)); client._sock._websocket._receiveData(new Uint8Array(failureData));
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');
}); });
@ -1442,7 +1444,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 failureData = [0, 0, 0, 1, 0, 0, 0, 0]; const failureData = [0, 0, 0, 1, 0, 0, 0, 0];
client._sock._websocket._receive_data(new Uint8Array(failureData)); client._sock._websocket._receiveData(new Uint8Array(failureData));
expect(spy.args[0][0].detail.status).to.equal(1); expect(spy.args[0][0].detail.status).to.equal(1);
expect('reason' in spy.args[0][0].detail).to.be.false; expect('reason' in spy.args[0][0].detail).to.be.false;
}); });
@ -1451,7 +1453,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbVersion = 3.6; client._rfbVersion = 3.6;
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("securityfailure", spy); client.addEventListener("securityfailure", spy);
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 2])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 2]));
expect(spy.args[0][0].detail.status).to.equal(2); expect(spy.args[0][0].detail.status).to.equal(2);
expect('reason' in spy.args[0][0].detail).to.be.false; expect('reason' in spy.args[0][0].detail).to.be.false;
}); });
@ -1462,7 +1464,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const client = makeRFB(); const client = makeRFB();
client._rfbConnectionState = 'connecting'; client._rfbConnectionState = 'connecting';
client._rfbInitState = 'SecurityResult'; client._rfbInitState = 'SecurityResult';
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 0]));
expect(client._rfbInitState).to.equal('ServerInitialisation'); expect(client._rfbInitState).to.equal('ServerInitialisation');
}); });
@ -1470,7 +1472,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const client = makeRFB('wss://host:8675', { shared: true }); const client = makeRFB('wss://host:8675', { shared: true });
client._rfbConnectionState = 'connecting'; client._rfbConnectionState = 'connecting';
client._rfbInitState = 'SecurityResult'; client._rfbInitState = 'SecurityResult';
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 0]));
expect(client._sock).to.have.sent(new Uint8Array([1])); expect(client._sock).to.have.sent(new Uint8Array([1]));
}); });
@ -1478,7 +1480,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const client = makeRFB('wss://host:8675', { shared: false }); const client = makeRFB('wss://host:8675', { shared: false });
client._rfbConnectionState = 'connecting'; client._rfbConnectionState = 'connecting';
client._rfbInitState = 'SecurityResult'; client._rfbInitState = 'SecurityResult';
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 0])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 0]));
expect(client._sock).to.have.sent(new Uint8Array([0])); expect(client._sock).to.have.sent(new Uint8Array([0]));
}); });
}); });
@ -1489,8 +1491,8 @@ describe('Remote Frame Buffer Protocol Client', function () {
}); });
function sendServerInit(opts, client) { function sendServerInit(opts, client) {
const fullOpts = { width: 10, height: 12, bpp: 24, depth: 24, big_endian: 0, const fullOpts = { width: 10, height: 12, bpp: 24, depth: 24, bigEndian: 0,
true_color: 1, redMax: 255, greenMax: 255, blueMax: 255, trueColor: 1, redMax: 255, greenMax: 255, blueMax: 255,
redShift: 16, greenShift: 8, blueShift: 0, name: 'a name' }; redShift: 16, greenShift: 8, blueShift: 0, name: 'a name' };
for (let opt in opts) { for (let opt in opts) {
fullOpts[opt] = opts[opt]; fullOpts[opt] = opts[opt];
@ -1502,8 +1504,8 @@ describe('Remote Frame Buffer Protocol Client', function () {
data.push(fullOpts.bpp); data.push(fullOpts.bpp);
data.push(fullOpts.depth); data.push(fullOpts.depth);
data.push(fullOpts.big_endian); data.push(fullOpts.bigEndian);
data.push(fullOpts.true_color); data.push(fullOpts.trueColor);
push16(data, fullOpts.redMax); push16(data, fullOpts.redMax);
push16(data, fullOpts.greenMax); push16(data, fullOpts.greenMax);
@ -1517,15 +1519,15 @@ describe('Remote Frame Buffer Protocol Client', function () {
push8(data, 0); push8(data, 0);
push8(data, 0); push8(data, 0);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
const nameData = []; const nameData = [];
let nameLen = []; let nameLen = [];
pushString(nameData, fullOpts.name); pushString(nameData, fullOpts.name);
push32(nameLen, nameData.length); push32(nameLen, nameData.length);
client._sock._websocket._receive_data(new Uint8Array(nameLen)); client._sock._websocket._receiveData(new Uint8Array(nameLen));
client._sock._websocket._receive_data(new Uint8Array(nameData)); client._sock._websocket._receiveData(new Uint8Array(nameData));
} }
it('should set the framebuffer width and height', function () { it('should set the framebuffer width and height', function () {
@ -1560,7 +1562,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
for (let i = 0; i < 16 + 32 + 48; i++) { for (let i = 0; i < 16 + 32 + 48; i++) {
tightData.push(i); tightData.push(i);
} }
client._sock._websocket._receive_data(new Uint8Array(tightData)); client._sock._websocket._receiveData(new Uint8Array(tightData));
expect(client._rfbConnectionState).to.equal('connected'); expect(client._rfbConnectionState).to.equal('connected');
}); });
@ -1684,7 +1686,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
data = data.concat(rectData[i]); data = data.concat(rectData[i]);
} }
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
} }
it('should send an update request if there is sufficient data', function () { it('should send an update request if there is sufficient data', function () {
@ -1692,14 +1694,14 @@ describe('Remote Frame Buffer Protocol Client', function () {
RFB.messages.fbUpdateRequest(expectedMsg, true, 0, 0, 640, 20); RFB.messages.fbUpdateRequest(expectedMsg, true, 0, 0, 640, 20);
client._framebufferUpdate = () => true; client._framebufferUpdate = () => true;
client._sock._websocket._receive_data(new Uint8Array([0])); client._sock._websocket._receiveData(new Uint8Array([0]));
expect(client._sock).to.have.sent(expectedMsg._sQ); expect(client._sock).to.have.sent(expectedMsg._sQ);
}); });
it('should not send an update request if we need more data', function () { it('should not send an update request if we need more data', function () {
client._sock._websocket._receive_data(new Uint8Array([0])); client._sock._websocket._receiveData(new Uint8Array([0]));
expect(client._sock._websocket._get_sent_data()).to.have.length(0); expect(client._sock._websocket._getSentData()).to.have.length(0);
}); });
it('should resume receiving an update if we previously did not have enough data', function () { it('should resume receiving an update if we previously did not have enough data', function () {
@ -1707,21 +1709,21 @@ describe('Remote Frame Buffer Protocol Client', function () {
RFB.messages.fbUpdateRequest(expectedMsg, true, 0, 0, 640, 20); RFB.messages.fbUpdateRequest(expectedMsg, true, 0, 0, 640, 20);
// just enough to set FBU.rects // just enough to set FBU.rects
client._sock._websocket._receive_data(new Uint8Array([0, 0, 0, 3])); client._sock._websocket._receiveData(new Uint8Array([0, 0, 0, 3]));
expect(client._sock._websocket._get_sent_data()).to.have.length(0); expect(client._sock._websocket._getSentData()).to.have.length(0);
client._framebufferUpdate = function () { this._sock.rQskipBytes(1); return true; }; // we magically have enough data client._framebufferUpdate = function () { this._sock.rQskipBytes(1); return true; }; // we magically have enough data
// 247 should *not* be used as the message type here // 247 should *not* be used as the message type here
client._sock._websocket._receive_data(new Uint8Array([247])); client._sock._websocket._receiveData(new Uint8Array([247]));
expect(client._sock).to.have.sent(expectedMsg._sQ); expect(client._sock).to.have.sent(expectedMsg._sQ);
}); });
it('should not send a request in continuous updates mode', function () { it('should not send a request in continuous updates mode', function () {
client._enabledContinuousUpdates = true; client._enabledContinuousUpdates = true;
client._framebufferUpdate = () => true; client._framebufferUpdate = () => true;
client._sock._websocket._receive_data(new Uint8Array([0])); client._sock._websocket._receiveData(new Uint8Array([0]));
expect(client._sock._websocket._get_sent_data()).to.have.length(0); expect(client._sock._websocket._getSentData()).to.have.length(0);
}); });
it('should fail on an unsupported encoding', function () { it('should fail on an unsupported encoding', function () {
@ -2388,7 +2390,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () { it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("capabilities", spy); client.addEventListener("capabilities", spy);
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1])); client._sock._websocket._receiveData(new Uint8Array([250, 0, 10, 1]));
expect(client._rfbXvpVer).to.equal(10); expect(client._rfbXvpVer).to.equal(10);
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.capabilities.power).to.be.true; expect(spy.args[0][0].detail.capabilities.power).to.be.true;
@ -2397,7 +2399,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should fail on unknown XVP message types', function () { it('should fail on unknown XVP message types', function () {
sinon.spy(client, "_fail"); sinon.spy(client, "_fail");
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 237])); client._sock._websocket._receiveData(new Uint8Array([250, 0, 10, 237]));
expect(client._fail).to.have.been.calledOnce; expect(client._fail).to.have.been.calledOnce;
}); });
}); });
@ -2411,7 +2413,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("clipboard", spy); client.addEventListener("clipboard", spy);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.text).to.equal(expectedStr); expect(spy.args[0][0].detail.text).to.equal(expectedStr);
}); });
@ -2437,7 +2439,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
push32(data, toUnsigned32bit(-12)); push32(data, toUnsigned32bit(-12));
data = data.concat(flags); data = data.concat(flags);
data = data.concat(fileSizes); data = data.concat(fileSizes);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
// Check that we give an response caps when we receive one // Check that we give an response caps when we receive one
expect(RFB.messages.extendedClipboardCaps).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardCaps).to.have.been.calledOnce;
@ -2463,7 +2465,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
push32(data, toUnsigned32bit(-8)); push32(data, toUnsigned32bit(-8));
data = data.concat(flags); data = data.concat(flags);
data = data.concat(fileSizes); data = data.concat(fileSizes);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
}); });
describe('Handle Provide', function () { describe('Handle Provide', function () {
@ -2487,7 +2489,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("clipboard", spy); client.addEventListener("clipboard", spy);
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.text).to.equal(expectedData); expect(spy.args[0][0].detail.text).to.equal(expectedData);
client.removeEventListener("clipboard", spy); client.removeEventListener("clipboard", spy);
@ -2514,7 +2516,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("clipboard", spy); client.addEventListener("clipboard", spy);
client._sock._websocket._receive_data(sendData); client._sock._websocket._receiveData(sendData);
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.text).to.equal(expectedData); expect(spy.args[0][0].detail.text).to.equal(expectedData);
client.removeEventListener("clipboard", spy); client.removeEventListener("clipboard", spy);
@ -2546,7 +2548,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("clipboard", spy); client.addEventListener("clipboard", spy);
client._sock._websocket._receive_data(sendData); client._sock._websocket._receiveData(sendData);
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
expect(spy.args[0][0].detail.text).to.equal(expectedData); expect(spy.args[0][0].detail.text).to.equal(expectedData);
client.removeEventListener("clipboard", spy); client.removeEventListener("clipboard", spy);
@ -2570,7 +2572,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
data = data.concat(flags); data = data.concat(flags);
let expectedData = [0x01]; let expectedData = [0x01];
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(RFB.messages.extendedClipboardRequest).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardRequest).to.have.been.calledOnce;
expect(RFB.messages.extendedClipboardRequest).to.have.been.calledWith(client._sock, expectedData); expect(RFB.messages.extendedClipboardRequest).to.have.been.calledWith(client._sock, expectedData);
@ -2593,7 +2595,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
data = data.concat(flags); data = data.concat(flags);
let expectedData = []; let expectedData = [];
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce;
expect(RFB.messages.extendedClipboardNotify).to.have.been.calledWith(client._sock, expectedData); expect(RFB.messages.extendedClipboardNotify).to.have.been.calledWith(client._sock, expectedData);
@ -2611,7 +2613,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client.clipboardPasteFrom("HejHej"); client.clipboardPasteFrom("HejHej");
RFB.messages.extendedClipboardNotify.resetHistory(); RFB.messages.extendedClipboardNotify.resetHistory();
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardNotify).to.have.been.calledOnce;
expect(RFB.messages.extendedClipboardNotify).to.have.been.calledWith(client._sock, expectedData); expect(RFB.messages.extendedClipboardNotify).to.have.been.calledWith(client._sock, expectedData);
@ -2637,7 +2639,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client.clipboardPasteFrom("HejHej"); client.clipboardPasteFrom("HejHej");
expect(RFB.messages.extendedClipboardProvide).to.not.have.been.called; expect(RFB.messages.extendedClipboardProvide).to.not.have.been.called;
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receiveData(new Uint8Array(data));
expect(RFB.messages.extendedClipboardProvide).to.have.been.calledOnce; expect(RFB.messages.extendedClipboardProvide).to.have.been.calledOnce;
expect(RFB.messages.extendedClipboardProvide).to.have.been.calledWith(client._sock, expectedData, ["HejHej"]); expect(RFB.messages.extendedClipboardProvide).to.have.been.calledWith(client._sock, expectedData, ["HejHej"]);
@ -2650,7 +2652,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should fire the bell callback on Bell', function () { it('should fire the bell callback on Bell', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("bell", spy); client.addEventListener("bell", spy);
client._sock._websocket._receive_data(new Uint8Array([2])); client._sock._websocket._receiveData(new Uint8Array([2]));
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
}); });
@ -2664,7 +2666,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
RFB.messages.clientFence(expectedMsg, (1<<0) | (1<<1), payload); RFB.messages.clientFence(expectedMsg, (1<<0) | (1<<1), payload);
RFB.messages.clientFence(incomingMsg, 0xffffffff, payload); RFB.messages.clientFence(incomingMsg, 0xffffffff, payload);
client._sock._websocket._receive_data(incomingMsg._sQ); client._sock._websocket._receiveData(incomingMsg._sQ);
expect(client._sock).to.have.sent(expectedMsg._sQ); expect(client._sock).to.have.sent(expectedMsg._sQ);
@ -2674,7 +2676,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
RFB.messages.clientFence(expectedMsg, (1<<0), payload); RFB.messages.clientFence(expectedMsg, (1<<0), payload);
RFB.messages.clientFence(incomingMsg, (1<<0) | (1<<31), payload); RFB.messages.clientFence(incomingMsg, (1<<0) | (1<<31), payload);
client._sock._websocket._receive_data(incomingMsg._sQ); client._sock._websocket._receiveData(incomingMsg._sQ);
expect(client._sock).to.have.sent(expectedMsg._sQ); expect(client._sock).to.have.sent(expectedMsg._sQ);
}); });
@ -2686,7 +2688,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
expect(client._enabledContinuousUpdates).to.be.false; expect(client._enabledContinuousUpdates).to.be.false;
client._sock._websocket._receive_data(new Uint8Array([150])); client._sock._websocket._receiveData(new Uint8Array([150]));
expect(client._enabledContinuousUpdates).to.be.true; expect(client._enabledContinuousUpdates).to.be.true;
expect(client._sock).to.have.sent(expectedMsg._sQ); expect(client._sock).to.have.sent(expectedMsg._sQ);
@ -2696,7 +2698,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._enabledContinuousUpdates = true; client._enabledContinuousUpdates = true;
client._supportsContinuousUpdates = true; client._supportsContinuousUpdates = true;
client._sock._websocket._receive_data(new Uint8Array([150])); client._sock._websocket._receiveData(new Uint8Array([150]));
expect(client._enabledContinuousUpdates).to.be.false; expect(client._enabledContinuousUpdates).to.be.false;
}); });
@ -2707,7 +2709,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._resize(450, 160); client._resize(450, 160);
expect(client._sock._websocket._get_sent_data()).to.have.length(0); expect(client._sock._websocket._getSentData()).to.have.length(0);
client._enabledContinuousUpdates = true; client._enabledContinuousUpdates = true;
@ -2718,7 +2720,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
it('should fail on an unknown message type', function () { it('should fail on an unknown message type', function () {
sinon.spy(client, "_fail"); sinon.spy(client, "_fail");
client._sock._websocket._receive_data(new Uint8Array([87])); client._sock._websocket._receiveData(new Uint8Array([87]));
expect(client._fail).to.have.been.calledOnce; expect(client._fail).to.have.been.calledOnce;
}); });
}); });
@ -2763,7 +2765,7 @@ describe('Remote Frame Buffer Protocol Client', function () {
}); });
it('should send a mask of 0 on mouseup', function () { it('should send a mask of 0 on mouseup', function () {
client._mouse_buttonMask = 0x001; client._mouseButtonMask = 0x001;
client._handleMouseButton(105, 120, 0, 0x001); client._handleMouseButton(105, 120, 0, 0x001);
expect(RFB.messages.pointerEvent).to.have.been.calledWith( expect(RFB.messages.pointerEvent).to.have.been.calledWith(
client._sock, 105, 120, 0x000); client._sock, 105, 120, 0x000);
@ -2892,13 +2894,13 @@ describe('Remote Frame Buffer Protocol Client', 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._normalMsg = sinon.spy(); client._normalMsg = sinon.spy();
client._sock._websocket._receive_data(new Uint8Array([])); client._sock._websocket._receiveData(new Uint8Array([]));
expect(client._normalMsg).to.not.have.been.called; expect(client._normalMsg).to.not.have.been.called;
}); });
it('should handle a message in the connected state as a normal message', function () { it('should handle a message in the connected state as a normal message', function () {
client._normalMsg = sinon.spy(); client._normalMsg = sinon.spy();
client._sock._websocket._receive_data(new Uint8Array([1, 2, 3])); client._sock._websocket._receiveData(new Uint8Array([1, 2, 3]));
expect(client._normalMsg).to.have.been.called; expect(client._normalMsg).to.have.been.called;
}); });
@ -2906,14 +2908,14 @@ describe('Remote Frame Buffer Protocol Client', function () {
client._rfbConnectionState = 'connecting'; client._rfbConnectionState = 'connecting';
client._rfbInitState = 'ProtocolVersion'; client._rfbInitState = 'ProtocolVersion';
client._initMsg = sinon.spy(); client._initMsg = sinon.spy();
client._sock._websocket._receive_data(new Uint8Array([1, 2, 3])); client._sock._websocket._receiveData(new Uint8Array([1, 2, 3]));
expect(client._initMsg).to.have.been.called; expect(client._initMsg).to.have.been.called;
}); });
it('should process all normal messages directly', function () { it('should process all normal messages directly', function () {
const spy = sinon.spy(); const spy = sinon.spy();
client.addEventListener("bell", spy); client.addEventListener("bell", spy);
client._sock._websocket._receive_data(new Uint8Array([0x02, 0x02])); client._sock._websocket._receiveData(new Uint8Array([0x02, 0x02]));
expect(spy).to.have.been.calledTwice; expect(spy).to.have.been.calledTwice;
}); });

View File

@ -22,37 +22,37 @@ describe('Utils', function () {
console.warn.restore(); console.warn.restore();
console.error.restore(); console.error.restore();
console.info.restore(); console.info.restore();
Log.init_logging(); Log.initLogging();
}); });
it('should use noop for levels lower than the min level', function () { it('should use noop for levels lower than the min level', function () {
Log.init_logging('warn'); Log.initLogging('warn');
Log.Debug('hi'); Log.Debug('hi');
Log.Info('hello'); Log.Info('hello');
expect(console.log).to.not.have.been.called; expect(console.log).to.not.have.been.called;
}); });
it('should use console.debug for Debug', function () { it('should use console.debug for Debug', function () {
Log.init_logging('debug'); Log.initLogging('debug');
Log.Debug('dbg'); Log.Debug('dbg');
expect(console.debug).to.have.been.calledWith('dbg'); expect(console.debug).to.have.been.calledWith('dbg');
}); });
it('should use console.info for Info', function () { it('should use console.info for Info', function () {
Log.init_logging('debug'); Log.initLogging('debug');
Log.Info('inf'); Log.Info('inf');
expect(console.info).to.have.been.calledWith('inf'); expect(console.info).to.have.been.calledWith('inf');
}); });
it('should use console.warn for Warn', function () { it('should use console.warn for Warn', function () {
Log.init_logging('warn'); Log.initLogging('warn');
Log.Warn('wrn'); Log.Warn('wrn');
expect(console.warn).to.have.been.called; expect(console.warn).to.have.been.called;
expect(console.warn).to.have.been.calledWith('wrn'); expect(console.warn).to.have.been.calledWith('wrn');
}); });
it('should use console.error for Error', function () { it('should use console.error for Error', function () {
Log.init_logging('error'); Log.initLogging('error');
Log.Error('err'); Log.Error('err');
expect(console.error).to.have.been.called; expect(console.error).to.have.been.called;
expect(console.error).to.have.been.calledWith('err'); expect(console.error).to.have.been.calledWith('err');

View File

@ -13,7 +13,7 @@ describe('Websock', function () {
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
// skip init // skip init
sock._allocate_buffers(); sock._allocateBuffers();
sock._rQ.set(RQ_TEMPLATE); sock._rQ.set(RQ_TEMPLATE);
sock._rQlen = RQ_TEMPLATE.length; sock._rQlen = RQ_TEMPLATE.length;
}); });
@ -33,51 +33,51 @@ describe('Websock', function () {
describe('rQpeek8', function () { describe('rQpeek8', function () {
it('should peek at the next byte without poping it off the queue', function () { it('should peek at the next byte without poping it off the queue', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
const peek = sock.rQpeek8(); const peek = sock.rQpeek8();
expect(sock.rQpeek8()).to.equal(peek); expect(sock.rQpeek8()).to.equal(peek);
expect(sock.rQlen).to.equal(bef_len); expect(sock.rQlen).to.equal(befLen);
}); });
}); });
describe('rQshift8()', function () { describe('rQshift8()', function () {
it('should pop a single byte from the receive queue', function () { it('should pop a single byte from the receive queue', function () {
const peek = sock.rQpeek8(); const peek = sock.rQpeek8();
const bef_len = sock.rQlen; const befLen = sock.rQlen;
expect(sock.rQshift8()).to.equal(peek); expect(sock.rQshift8()).to.equal(peek);
expect(sock.rQlen).to.equal(bef_len - 1); expect(sock.rQlen).to.equal(befLen - 1);
}); });
}); });
describe('rQshift16()', function () { describe('rQshift16()', function () {
it('should pop two bytes from the receive queue and return a single number', function () { it('should pop two bytes from the receive queue and return a single number', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
const expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1]; const expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1];
expect(sock.rQshift16()).to.equal(expected); expect(sock.rQshift16()).to.equal(expected);
expect(sock.rQlen).to.equal(bef_len - 2); expect(sock.rQlen).to.equal(befLen - 2);
}); });
}); });
describe('rQshift32()', function () { describe('rQshift32()', function () {
it('should pop four bytes from the receive queue and return a single number', function () { it('should pop four bytes from the receive queue and return a single number', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
const expected = (RQ_TEMPLATE[0] << 24) + const expected = (RQ_TEMPLATE[0] << 24) +
(RQ_TEMPLATE[1] << 16) + (RQ_TEMPLATE[1] << 16) +
(RQ_TEMPLATE[2] << 8) + (RQ_TEMPLATE[2] << 8) +
RQ_TEMPLATE[3]; RQ_TEMPLATE[3];
expect(sock.rQshift32()).to.equal(expected); expect(sock.rQshift32()).to.equal(expected);
expect(sock.rQlen).to.equal(bef_len - 4); expect(sock.rQlen).to.equal(befLen - 4);
}); });
}); });
describe('rQshiftStr', function () { describe('rQshiftStr', function () {
it('should shift the given number of bytes off of the receive queue and return a string', function () { it('should shift the given number of bytes off of the receive queue and return a string', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
const bef_rQi = sock.rQi; const befRQi = sock.rQi;
const shifted = sock.rQshiftStr(3); const shifted = sock.rQshiftStr(3);
expect(shifted).to.be.a('string'); expect(shifted).to.be.a('string');
expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3)))); expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3))));
expect(sock.rQlen).to.equal(bef_len - 3); expect(sock.rQlen).to.equal(befLen - 3);
}); });
it('should shift the entire rest of the queue off if no length is given', function () { it('should shift the entire rest of the queue off if no length is given', function () {
@ -112,12 +112,12 @@ describe('Websock', function () {
describe('rQshiftBytes', function () { describe('rQshiftBytes', function () {
it('should shift the given number of bytes of the receive queue and return an array', function () { it('should shift the given number of bytes of the receive queue and return an array', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
const bef_rQi = sock.rQi; const befRQi = sock.rQi;
const shifted = sock.rQshiftBytes(3); const shifted = sock.rQshiftBytes(3);
expect(shifted).to.be.an.instanceof(Uint8Array); expect(shifted).to.be.an.instanceof(Uint8Array);
expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3)); expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3));
expect(sock.rQlen).to.equal(bef_len - 3); expect(sock.rQlen).to.equal(befLen - 3);
}); });
it('should shift the entire rest of the queue off if no length is given', function () { it('should shift the entire rest of the queue off if no length is given', function () {
@ -132,9 +132,9 @@ describe('Websock', function () {
}); });
it('should not modify the receive queue', function () { it('should not modify the receive queue', function () {
const bef_len = sock.rQlen; const befLen = sock.rQlen;
sock.rQslice(0, 2); sock.rQslice(0, 2);
expect(sock.rQlen).to.equal(bef_len); expect(sock.rQlen).to.equal(befLen);
}); });
it('should return an array containing the given slice of the receive queue', function () { it('should return an array containing the given slice of the receive queue', function () {
@ -198,7 +198,7 @@ describe('Websock', function () {
sock._websocket.readyState = WebSocket.OPEN; sock._websocket.readyState = WebSocket.OPEN;
sock._sQ = new Uint8Array([1, 2, 3]); sock._sQ = new Uint8Array([1, 2, 3]);
sock._sQlen = 3; sock._sQlen = 3;
const encoded = sock._encode_message(); const encoded = sock._encodeMessage();
sock.flush(); sock.flush();
expect(sock._websocket.send).to.have.been.calledOnce; expect(sock._websocket.send).to.have.been.calledOnce;
@ -232,22 +232,22 @@ describe('Websock', function () {
}); });
}); });
describe('send_string', function () { describe('sendString', function () {
beforeEach(function () { beforeEach(function () {
sock.send = sinon.spy(); sock.send = sinon.spy();
}); });
it('should call send after converting the string to an array', function () { it('should call send after converting the string to an array', function () {
sock.send_string("\x01\x02\x03"); sock.sendString("\x01\x02\x03");
expect(sock.send).to.have.been.calledWith([1, 2, 3]); expect(sock.send).to.have.been.calledWith([1, 2, 3]);
}); });
}); });
}); });
describe('lifecycle methods', function () { describe('lifecycle methods', function () {
let old_WS; let oldWS;
before(function () { before(function () {
old_WS = WebSocket; oldWS = WebSocket;
}); });
let sock; let sock;
@ -255,10 +255,10 @@ describe('Websock', function () {
sock = new Websock(); sock = new Websock();
// eslint-disable-next-line no-global-assign // eslint-disable-next-line no-global-assign
WebSocket = sinon.spy(); WebSocket = sinon.spy();
WebSocket.OPEN = old_WS.OPEN; WebSocket.OPEN = oldWS.OPEN;
WebSocket.CONNECTING = old_WS.CONNECTING; WebSocket.CONNECTING = oldWS.CONNECTING;
WebSocket.CLOSING = old_WS.CLOSING; WebSocket.CLOSING = oldWS.CLOSING;
WebSocket.CLOSED = old_WS.CLOSED; WebSocket.CLOSED = oldWS.CLOSED;
WebSocket.prototype.binaryType = 'arraybuffer'; WebSocket.prototype.binaryType = 'arraybuffer';
}); });
@ -306,30 +306,30 @@ describe('Websock', function () {
expect(sock._websocket.close).not.to.have.been.called; expect(sock._websocket.close).not.to.have.been.called;
}); });
it('should reset onmessage to not call _recv_message', function () { it('should reset onmessage to not call _recvMessage', function () {
sinon.spy(sock, '_recv_message'); sinon.spy(sock, '_recvMessage');
sock.close(); sock.close();
sock._websocket.onmessage(null); sock._websocket.onmessage(null);
try { try {
expect(sock._recv_message).not.to.have.been.called; expect(sock._recvMessage).not.to.have.been.called;
} finally { } finally {
sock._recv_message.restore(); sock._recvMessage.restore();
} }
}); });
}); });
describe('event handlers', function () { describe('event handlers', function () {
beforeEach(function () { beforeEach(function () {
sock._recv_message = sinon.spy(); sock._recvMessage = sinon.spy();
sock.on('open', sinon.spy()); sock.on('open', sinon.spy());
sock.on('close', sinon.spy()); sock.on('close', sinon.spy());
sock.on('error', sinon.spy()); sock.on('error', sinon.spy());
sock.open('ws://'); sock.open('ws://');
}); });
it('should call _recv_message on a message', function () { it('should call _recvMessage on a message', function () {
sock._websocket.onmessage(null); sock._websocket.onmessage(null);
expect(sock._recv_message).to.have.been.calledOnce; expect(sock._recvMessage).to.have.been.calledOnce;
}); });
it('should call the open event handler on opening', function () { it('should call the open event handler on opening', function () {
@ -350,7 +350,7 @@ describe('Websock', function () {
after(function () { after(function () {
// eslint-disable-next-line no-global-assign // eslint-disable-next-line no-global-assign
WebSocket = old_WS; WebSocket = oldWS;
}); });
}); });
@ -358,13 +358,13 @@ describe('Websock', function () {
let sock; let sock;
beforeEach(function () { beforeEach(function () {
sock = new Websock(); sock = new Websock();
sock._allocate_buffers(); sock._allocateBuffers();
}); });
it('should support adding binary Uint8Array data to the receive queue', function () { it('should support adding binary Uint8Array data to the receive queue', function () {
const msg = { data: new Uint8Array([1, 2, 3]) }; const msg = { data: new Uint8Array([1, 2, 3]) };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03'); expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03');
}); });
@ -372,7 +372,7 @@ describe('Websock', function () {
sock._eventHandlers.message = sinon.spy(); sock._eventHandlers.message = sinon.spy();
const msg = { data: new Uint8Array([1, 2, 3]).buffer }; const msg = { data: new Uint8Array([1, 2, 3]).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._eventHandlers.message).to.have.been.calledOnce; expect(sock._eventHandlers.message).to.have.been.calledOnce;
}); });
@ -380,7 +380,7 @@ describe('Websock', function () {
sock._eventHandlers.message = sinon.spy(); sock._eventHandlers.message = sinon.spy();
const msg = { data: new Uint8Array([]).buffer }; const msg = { data: new Uint8Array([]).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._eventHandlers.message).not.to.have.been.called; expect(sock._eventHandlers.message).not.to.have.been.called;
}); });
@ -391,7 +391,7 @@ describe('Websock', function () {
sock.rQi = 6; sock.rQi = 6;
const msg = { data: new Uint8Array([1, 2, 3]).buffer }; const msg = { data: new Uint8Array([1, 2, 3]).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._rQlen).to.equal(0); expect(sock._rQlen).to.equal(0);
expect(sock.rQi).to.equal(0); expect(sock.rQi).to.equal(0);
}); });
@ -403,7 +403,7 @@ describe('Websock', function () {
sock.rQi = 10; sock.rQi = 10;
const msg = { data: new Uint8Array([1, 2]).buffer }; const msg = { data: new Uint8Array([1, 2]).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._rQlen).to.equal(12); expect(sock._rQlen).to.equal(12);
expect(sock.rQi).to.equal(0); expect(sock.rQi).to.equal(0);
}); });
@ -415,7 +415,7 @@ describe('Websock', function () {
sock._rQbufferSize = 20; sock._rQbufferSize = 20;
const msg = { data: new Uint8Array(30).buffer }; const msg = { data: new Uint8Array(30).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._rQlen).to.equal(30); expect(sock._rQlen).to.equal(30);
expect(sock.rQi).to.equal(0); expect(sock.rQi).to.equal(0);
expect(sock._rQ.length).to.equal(240); // keep the invariant that rQbufferSize / 8 >= rQlen expect(sock._rQ.length).to.equal(240); // keep the invariant that rQbufferSize / 8 >= rQlen
@ -428,7 +428,7 @@ describe('Websock', function () {
sock._rQbufferSize = 20; sock._rQbufferSize = 20;
const msg = { data: new Uint8Array(6).buffer }; const msg = { data: new Uint8Array(6).buffer };
sock._mode = 'binary'; sock._mode = 'binary';
sock._recv_message(msg); sock._recvMessage(msg);
expect(sock._rQlen).to.equal(6); expect(sock._rQlen).to.equal(6);
expect(sock.rQi).to.equal(0); expect(sock.rQi).to.equal(0);
expect(sock._rQ.length).to.equal(48); expect(sock._rQ.length).to.equal(48);
@ -450,13 +450,13 @@ describe('Websock', function () {
it('should only send the send queue up to the send queue length', function () { it('should only send the send queue up to the send queue length', function () {
sock._sQ = new Uint8Array([1, 2, 3, 4, 5]); sock._sQ = new Uint8Array([1, 2, 3, 4, 5]);
sock._sQlen = 3; sock._sQlen = 3;
const res = sock._encode_message(); const res = sock._encodeMessage();
expect(res).to.array.equal(new Uint8Array([1, 2, 3])); expect(res).to.array.equal(new Uint8Array([1, 2, 3]));
}); });
it('should properly pass the encoded data off to the actual WebSocket', function () { it('should properly pass the encoded data off to the actual WebSocket', function () {
sock.send([1, 2, 3]); sock.send([1, 2, 3]);
expect(sock._websocket._get_sent_data()).to.array.equal(new Uint8Array([1, 2, 3])); expect(sock._websocket._getSentData()).to.array.equal(new Uint8Array([1, 2, 3]));
}); });
}); });
}); });

View File

@ -9,14 +9,14 @@
const fs = require('fs'); const fs = require('fs');
let show_help = process.argv.length === 2; let showHelp = 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; showHelp = true;
break; break;
case "--file": case "--file":
case "-f": case "-f":
@ -26,11 +26,11 @@ for (let i = 2; i < process.argv.length; ++i) {
} }
if (!filename) { if (!filename) {
show_help = true; showHelp = true;
console.log("Error: No filename specified\n"); console.log("Error: No filename specified\n");
} }
if (show_help) { if (showHelp) {
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");

View File

@ -22,31 +22,31 @@ const paths = {
core: path.resolve(__dirname, '..', 'core'), core: path.resolve(__dirname, '..', 'core'),
app: path.resolve(__dirname, '..', 'app'), app: path.resolve(__dirname, '..', 'app'),
vendor: path.resolve(__dirname, '..', 'vendor'), vendor: path.resolve(__dirname, '..', 'vendor'),
out_dir_base: path.resolve(__dirname, '..', 'build'), outDirBase: path.resolve(__dirname, '..', 'build'),
lib_dir_base: path.resolve(__dirname, '..', 'lib'), libDirBase: path.resolve(__dirname, '..', 'lib'),
}; };
const no_copy_files = new Set([ const noCopyFiles = new Set([
// skip these -- they don't belong in the processed application // skip these -- they don't belong in the processed application
path.join(paths.vendor, 'sinon.js'), path.join(paths.vendor, 'sinon.js'),
path.join(paths.vendor, 'browser-es-module-loader'), path.join(paths.vendor, 'browser-es-module-loader'),
path.join(paths.app, 'images', 'icons', 'Makefile'), path.join(paths.app, 'images', 'icons', 'Makefile'),
]); ]);
const only_legacy_scripts = new Set([ const onlyLegacyScripts = new Set([
path.join(paths.vendor, 'promise.js'), path.join(paths.vendor, 'promise.js'),
]); ]);
const no_transform_files = new Set([ const noTransformFiles = new Set([
// don't transform this -- we want it imported as-is to properly catch loading errors // don't transform this -- we want it imported as-is to properly catch loading errors
path.join(paths.app, 'error-handler.js'), path.join(paths.app, 'error-handler.js'),
]); ]);
no_copy_files.forEach(file => no_transform_files.add(file)); noCopyFiles.forEach(file => noTransformFiles.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 promise_wrap() { return function promiseWrap() {
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) => {
@ -72,10 +72,10 @@ const babelTransformFile = promisify(babel.transformFile);
// walkDir *recursively* walks directories trees, // walkDir *recursively* walks directories trees,
// calling the callback for all normal files found. // calling the callback for all normal files found.
function walkDir(base_path, cb, filter) { function walkDir(basePath, cb, filter) {
return readdir(base_path) return readdir(basePath)
.then((files) => { .then((files) => {
const paths = files.map(filename => path.join(base_path, filename)); const paths = files.map(filename => path.join(basePath, 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;
@ -87,157 +87,157 @@ function walkDir(base_path, cb, filter) {
}); });
} }
function transform_html(legacy_scripts, only_legacy) { function transformHtml(legacyScripts, onlyLegacy) {
// 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 srcHtmlPath = path.resolve(__dirname, '..', 'vnc.html');
const out_html_path = path.resolve(paths.out_dir_base, 'vnc.html'); const outHtmlPath = path.resolve(paths.outDirBase, 'vnc.html');
return readFile(src_html_path) return readFile(srcHtmlPath)
.then((contents_raw) => { .then((contentsRaw) => {
let contents = contents_raw.toString(); let contents = contentsRaw.toString();
const start_marker = '<!-- begin scripts -->\n'; const startMarker = '<!-- begin scripts -->\n';
const end_marker = '<!-- end scripts -->'; const endMarker = '<!-- end scripts -->';
const start_ind = contents.indexOf(start_marker) + start_marker.length; const startInd = contents.indexOf(startMarker) + startMarker.length;
const end_ind = contents.indexOf(end_marker, start_ind); const endInd = contents.indexOf(endMarker, startInd);
let new_script = ''; let newScript = '';
if (only_legacy) { if (onlyLegacy) {
// 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 < legacyScripts.length;i++) {
new_script += ` <script src="${legacy_scripts[i]}"></script>\n`; newScript += ` <script src="${legacyScripts[i]}"></script>\n`;
} }
} else { } else {
// Otherwise include both modules and legacy fallbacks // Otherwise include both modules and legacy fallbacks
new_script += ' <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n'; newScript += ' <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n';
for (let i = 0;i < legacy_scripts.length;i++) { for (let i = 0;i < legacyScripts.length;i++) {
new_script += ` <script nomodule src="${legacy_scripts[i]}"></script>\n`; newScript += ` <script nomodule src="${legacyScripts[i]}"></script>\n`;
} }
} }
contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind); contents = contents.slice(0, startInd) + `${newScript}\n` + contents.slice(endInd);
return contents; return contents;
}) })
.then((contents) => { .then((contents) => {
console.log(`Writing ${out_html_path}`); console.log(`Writing ${outHtmlPath}`);
return writeFile(out_html_path, contents); return writeFile(outHtmlPath, contents);
}); });
} }
function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) { function makeLibFiles(importFormat, sourceMaps, withAppDir, onlyLegacy) {
if (!import_format) { if (!importFormat) {
throw new Error("you must specify an import format to generate compiled noVNC libraries"); throw new Error("you must specify an import format to generate compiled noVNC libraries");
} else if (!SUPPORTED_FORMATS.has(import_format)) { } else if (!SUPPORTED_FORMATS.has(importFormat)) {
throw new Error(`unsupported output format "${import_format}" for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported`); throw new Error(`unsupported output format "${importFormat}" for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported`);
} }
// NB: we need to make a copy of babel_opts, since babel sets some defaults on it // NB: we need to make a copy of babelOpts, since babel sets some defaults on it
const babel_opts = () => ({ const babelOpts = () => ({
plugins: [], plugins: [],
presets: [ presets: [
[ '@babel/preset-env', [ '@babel/preset-env',
{ targets: 'ie >= 11', { targets: 'ie >= 11',
modules: import_format } ] modules: importFormat } ]
], ],
ast: false, ast: false,
sourceMaps: source_maps, sourceMaps: sourceMaps,
}); });
// No point in duplicate files without the app, so force only converted files // No point in duplicate files without the app, so force only converted files
if (!with_app_dir) { if (!withAppDir) {
only_legacy = true; onlyLegacy = true;
} }
let in_path; let inPath;
let out_path_base; let outPathBase;
if (with_app_dir) { if (withAppDir) {
out_path_base = paths.out_dir_base; outPathBase = paths.outDirBase;
in_path = paths.main; inPath = paths.main;
} else { } else {
out_path_base = paths.lib_dir_base; outPathBase = paths.libDirBase;
} }
const legacy_path_base = only_legacy ? out_path_base : path.join(out_path_base, 'legacy'); const legacyPathBase = onlyLegacy ? outPathBase : path.join(outPathBase, 'legacy');
fse.ensureDirSync(out_path_base); fse.ensureDirSync(outPathBase);
const helpers = require('./use_require_helpers'); const helpers = require('./use_require_helpers');
const helper = helpers[import_format]; const helper = helpers[importFormat];
const outFiles = []; const outFiles = [];
const legacyFiles = []; const legacyFiles = [];
const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve() const handleDir = (jsOnly, vendorRewrite, inPathBase, filename) => Promise.resolve()
.then(() => { .then(() => {
const out_path = path.join(out_path_base, path.relative(in_path_base, filename)); const outPath = path.join(outPathBase, path.relative(inPathBase, filename));
const legacy_path = path.join(legacy_path_base, path.relative(in_path_base, filename)); const legacyPath = path.join(legacyPathBase, path.relative(inPathBase, filename));
if (path.extname(filename) !== '.js') { if (path.extname(filename) !== '.js') {
if (!js_only) { if (!jsOnly) {
console.log(`Writing ${out_path}`); console.log(`Writing ${outPath}`);
return copy(filename, out_path); return copy(filename, outPath);
} }
return; // skip non-javascript files return; // skip non-javascript files
} }
if (no_transform_files.has(filename)) { if (noTransformFiles.has(filename)) {
return ensureDir(path.dirname(out_path)) return ensureDir(path.dirname(outPath))
.then(() => { .then(() => {
console.log(`Writing ${out_path}`); console.log(`Writing ${outPath}`);
return copy(filename, out_path); return copy(filename, outPath);
}); });
} }
if (only_legacy_scripts.has(filename)) { if (onlyLegacyScripts.has(filename)) {
legacyFiles.push(legacy_path); legacyFiles.push(legacyPath);
return ensureDir(path.dirname(legacy_path)) return ensureDir(path.dirname(legacyPath))
.then(() => { .then(() => {
console.log(`Writing ${legacy_path}`); console.log(`Writing ${legacyPath}`);
return copy(filename, legacy_path); return copy(filename, legacyPath);
}); });
} }
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
if (only_legacy) { if (onlyLegacy) {
return; return;
} }
return ensureDir(path.dirname(out_path)) return ensureDir(path.dirname(outPath))
.then(() => { .then(() => {
console.log(`Writing ${out_path}`); console.log(`Writing ${outPath}`);
return copy(filename, out_path); return copy(filename, outPath);
}); });
}) })
.then(() => ensureDir(path.dirname(legacy_path))) .then(() => ensureDir(path.dirname(legacyPath)))
.then(() => { .then(() => {
const opts = babel_opts(); const opts = babelOpts();
if (helper && helpers.optionsOverride) { if (helper && helpers.optionsOverride) {
helper.optionsOverride(opts); 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 (vendorRewrite) {
opts.plugins.push(["import-redirect", opts.plugins.push(["import-redirect",
{"root": legacy_path_base, {"root": legacyPathBase,
"redirect": { "vendor/(.+)": "./vendor/$1"}}]); "redirect": { "vendor/(.+)": "./vendor/$1"}}]);
} }
return babelTransformFile(filename, opts) return babelTransformFile(filename, opts)
.then((res) => { .then((res) => {
console.log(`Writing ${legacy_path}`); console.log(`Writing ${legacyPath}`);
const {map} = res; const {map} = res;
let {code} = res; let {code} = res;
if (source_maps === true) { if (sourceMaps === true) {
// append URL for external source map // append URL for external source map
code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`; code += `\n//# sourceMappingURL=${path.basename(legacyPath)}.map\n`;
} }
outFiles.push(`${legacy_path}`); outFiles.push(`${legacyPath}`);
return writeFile(legacy_path, code) return writeFile(legacyPath, code)
.then(() => { .then(() => {
if (source_maps === true || source_maps === 'both') { if (sourceMaps === true || sourceMaps === 'both') {
console.log(` and ${legacy_path}.map`); console.log(` and ${legacyPath}.map`);
outFiles.push(`${legacy_path}.map`); outFiles.push(`${legacyPath}.map`);
return writeFile(`${legacy_path}.map`, JSON.stringify(map)); return writeFile(`${legacyPath}.map`, JSON.stringify(map));
} }
}); });
}); });
@ -246,45 +246,45 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
Promise.resolve() Promise.resolve()
.then(() => { .then(() => {
const handler = handleDir.bind(null, true, false, in_path || paths.main); const handler = handleDir.bind(null, true, false, inPath || paths.main);
const filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !noCopyFiles.has(filename);
return walkDir(paths.vendor, handler, filter); return walkDir(paths.vendor, handler, filter);
}) })
.then(() => { .then(() => {
const handler = handleDir.bind(null, true, !in_path, in_path || paths.core); const handler = handleDir.bind(null, true, !inPath, inPath || paths.core);
const filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !noCopyFiles.has(filename);
return walkDir(paths.core, handler, filter); return walkDir(paths.core, handler, filter);
}) })
.then(() => { .then(() => {
if (!with_app_dir) return; if (!withAppDir) return;
const handler = handleDir.bind(null, false, false, in_path); const handler = handleDir.bind(null, false, false, inPath);
const filter = (filename, stats) => !no_copy_files.has(filename); const filter = (filename, stats) => !noCopyFiles.has(filename);
return walkDir(paths.app, handler, filter); return walkDir(paths.app, handler, filter);
}) })
.then(() => { .then(() => {
if (!with_app_dir) return; if (!withAppDir) return;
if (!helper || !helper.appWriter) { if (!helper || !helper.appWriter) {
throw new Error(`Unable to generate app for the ${import_format} format!`); throw new Error(`Unable to generate app for the ${importFormat} format!`);
} }
const out_app_path = path.join(legacy_path_base, 'app.js'); const outAppPath = path.join(legacyPathBase, 'app.js');
console.log(`Writing ${out_app_path}`); console.log(`Writing ${outAppPath}`);
return helper.appWriter(out_path_base, legacy_path_base, out_app_path) return helper.appWriter(outPathBase, legacyPathBase, outAppPath)
.then((extra_scripts) => { .then((extraScripts) => {
let legacy_scripts = []; let legacyScripts = [];
legacyFiles.forEach((file) => { legacyFiles.forEach((file) => {
let rel_file_path = path.relative(out_path_base, file); let relFilePath = path.relative(outPathBase, file);
legacy_scripts.push(rel_file_path); legacyScripts.push(relFilePath);
}); });
legacy_scripts = legacy_scripts.concat(extra_scripts); legacyScripts = legacyScripts.concat(extraScripts);
let rel_app_path = path.relative(out_path_base, out_app_path); let relAppPath = path.relative(outPathBase, outAppPath);
legacy_scripts.push(rel_app_path); legacyScripts.push(relAppPath);
transform_html(legacy_scripts, only_legacy); transformHtml(legacyScripts, onlyLegacy);
}) })
.then(() => { .then(() => {
if (!helper.removeModules) return; if (!helper.removeModules) return;
@ -292,15 +292,15 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
return Promise.all(outFiles.map((filepath) => { return Promise.all(outFiles.map((filepath) => {
unlink(filepath) unlink(filepath)
.then(() => { .then(() => {
// Try to clean up any empty directories if this // Try to clean up any empty directories if
// was the last file in there // this was the last file in there
const rmdir_r = dir => const rmdirR = dir =>
rmdir(dir) rmdir(dir)
.then(() => rmdir_r(path.dirname(dir))) .then(() => rmdirR(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 rmdirR(path.dirname(filepath));
}); });
})); }));
}); });
@ -312,11 +312,11 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
} }
if (program.clean) { if (program.clean) {
console.log(`Removing ${paths.lib_dir_base}`); console.log(`Removing ${paths.libDirBase}`);
fse.removeSync(paths.lib_dir_base); fse.removeSync(paths.libDirBase);
console.log(`Removing ${paths.out_dir_base}`); console.log(`Removing ${paths.outDirBase}`);
fse.removeSync(paths.out_dir_base); fse.removeSync(paths.outDirBase);
} }
make_lib_files(program.as, program.withSourceMaps, program.withApp, program.onlyLegacy); makeLibFiles(program.as, program.withSourceMaps, program.withApp, program.onlyLegacy);

View File

@ -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 promise_wrap() { return function promiseWrap() {
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) => {
@ -19,39 +19,39 @@ const writeFile = promisify(fs.writeFile);
module.exports = { module.exports = {
'amd': { 'amd': {
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (baseOutPath, scriptBasePath, outPath) => {
// setup for requirejs // setup for requirejs
const ui_path = path.relative(base_out_path, const uiPath = path.relative(baseOutPath,
path.join(script_base_path, 'app', 'ui')); path.join(scriptBasePath, 'app', 'ui'));
return writeFile(out_path, `requirejs(["${ui_path}"], function (ui) {});`) return writeFile(outPath, `requirejs(["${uiPath}"], function (ui) {});`)
.then(() => { .then(() => {
console.log(`Please place RequireJS in ${path.join(script_base_path, 'require.js')}`); console.log(`Please place RequireJS in ${path.join(scriptBasePath, 'require.js')}`);
const require_path = path.relative(base_out_path, const requirePath = path.relative(baseOutPath,
path.join(script_base_path, 'require.js')); path.join(scriptBasePath, 'require.js'));
return [ require_path ]; return [ requirePath ];
}); });
}, },
}, },
'commonjs': { 'commonjs': {
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (baseOutPath, scriptBasePath, outPath) => {
const browserify = require('browserify'); const browserify = require('browserify');
const b = browserify(path.join(script_base_path, 'app/ui.js'), {}); const b = browserify(path.join(scriptBasePath, 'app/ui.js'), {});
return promisify(b.bundle).call(b) return promisify(b.bundle).call(b)
.then(buf => writeFile(out_path, buf)) .then(buf => writeFile(outPath, buf))
.then(() => []); .then(() => []);
}, },
removeModules: true, removeModules: true,
}, },
'systemjs': { 'systemjs': {
appWriter: (base_out_path, script_base_path, out_path) => { appWriter: (baseOutPath, scriptBasePath, outPath) => {
const ui_path = path.relative(base_out_path, const uiPath = path.relative(baseOutPath,
path.join(script_base_path, 'app', 'ui.js')); path.join(scriptBasePath, 'app', 'ui.js'));
return writeFile(out_path, `SystemJS.import("${ui_path}");`) return writeFile(outPath, `SystemJS.import("${uiPath}");`)
.then(() => { .then(() => {
console.log(`Please place SystemJS in ${path.join(script_base_path, 'system-production.js')}`); console.log(`Please place SystemJS in ${path.join(scriptBasePath, 'system-production.js')}`);
const systemjs_path = path.relative(base_out_path, const systemjsPath = path.relative(baseOutPath,
path.join(script_base_path, 'system-production.js')); path.join(scriptBasePath, 'system-production.js'));
return [ systemjs_path ]; return [ systemjsPath ];
}); });
}, },
}, },