diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5b03504f..a0bcb36b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,8 +17,6 @@ jobs: browser: Safari - os: windows-latest browser: EdgeHeadless - - os: windows-latest - browser: IE fail-fast: false runs-on: ${{ matrix.os }} steps: diff --git a/LICENSE.txt b/LICENSE.txt index ed6b6575..ee81d202 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -42,12 +42,6 @@ licenses (all MPL 2.0 compatible): vendor/pako/ : MIT - vendor/browser-es-module-loader/src/ : MIT - - vendor/browser-es-module-loader/dist/ : Various BSD style licenses - - vendor/promise.js : MIT - Any other files not mentioned above are typically marked with a copyright/license header at the top of the file. The default noVNC license is MPL-2.0. diff --git a/README.md b/README.md index b5b84c3c..42b5d22d 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ noVNC uses many modern web technologies so a formal requirement list is not available. However these are the minimum versions we are currently aware of: -* Chrome 49, Firefox 44, Safari 11, Opera 36, IE 11, Edge 12 +* Chrome 49, Firefox 44, Safari 11, Opera 36, Edge 79 ### Server Requirements diff --git a/app/ui.js b/app/ui.js index c70743dc..8e2e78ff 100644 --- a/app/ui.js +++ b/app/ui.js @@ -61,7 +61,13 @@ const UI = { // Translate the DOM l10n.translateDOM(); - WebUtil.fetchJSON('./package.json') + fetch('./package.json') + .then((response) => { + if (!response.ok) { + throw Error("" + response.status + " " + response.statusText); + } + return response.json(); + }) .then((packageInfo) => { Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version); }) @@ -755,11 +761,6 @@ const UI = { } } } else { - /*Weird IE9 error leads to 'null' appearring - in textboxes instead of ''.*/ - if (value === null) { - value = ""; - } ctrl.value = value; } }, @@ -1699,7 +1700,13 @@ l10n.setup(LINGUAS); if (l10n.language === "en" || l10n.dictionary !== undefined) { UI.prime(); } else { - WebUtil.fetchJSON('app/locale/' + l10n.language + '.json') + fetch('app/locale/' + l10n.language + '.json') + .then((response) => { + if (!response.ok) { + throw Error("" + response.status + " " + response.statusText); + } + return response.json(); + }) .then((translations) => { l10n.dictionary = translations; }) .catch(err => Log.Error("Failed to load translations: " + err)) .then(UI.prime); diff --git a/app/webutil.js b/app/webutil.js index a099f9d7..a9fee322 100644 --- a/app/webutil.js +++ b/app/webutil.js @@ -175,65 +175,3 @@ export function eraseSetting(name) { localStorage.removeItem(name); } } - -export function injectParamIfMissing(path, param, value) { - // force pretend that we're dealing with a relative path - // (assume that we wanted an extra if we pass one in) - path = "/" + path; - - const elem = document.createElement('a'); - elem.href = path; - - const paramEq = encodeURIComponent(param) + "="; - let query; - if (elem.search) { - query = elem.search.slice(1).split('&'); - } else { - query = []; - } - - if (!query.some(v => v.startsWith(paramEq))) { - query.push(paramEq + encodeURIComponent(value)); - elem.search = "?" + query.join("&"); - } - - // some browsers (e.g. IE11) may occasionally omit the leading slash - // in the elem.pathname string. Handle that case gracefully. - if (elem.pathname.charAt(0) == "/") { - return elem.pathname.slice(1) + elem.search + elem.hash; - } - - return elem.pathname + elem.search + elem.hash; -} - -// sadly, we can't use the Fetch API until we decide to drop -// IE11 support or polyfill promises and fetch in IE11. -// resolve will receive an object on success, while reject -// will receive either an event or an error on failure. -export function fetchJSON(path) { - return new Promise((resolve, reject) => { - // NB: IE11 doesn't support JSON as a responseType - const req = new XMLHttpRequest(); - req.open('GET', path); - - req.onload = () => { - if (req.status === 200) { - let resObj; - try { - resObj = JSON.parse(req.responseText); - } catch (err) { - reject(err); - } - resolve(resObj); - } else { - reject(new Error("XHR got non-200 status while trying to load '" + path + "': " + req.status)); - } - }; - - req.onerror = evt => reject(new Error("XHR encountered an error while trying to load '" + path + "': " + evt.message)); - - req.ontimeout = evt => reject(new Error("XHR timed out while trying to load '" + path + "'")); - - req.send(); - }); -} diff --git a/core/display.js b/core/display.js index 8eaa8001..701eba4a 100644 --- a/core/display.js +++ b/core/display.js @@ -8,7 +8,6 @@ import * as Log from './util/logging.js'; import Base64 from "./base64.js"; -import { supportsImageMetadata } from './util/browser.js'; import { toSigned32bit } from './util/int.js'; export default class Display { @@ -56,11 +55,6 @@ export default class Display { Log.Debug("User Agent: " + navigator.userAgent); - // Check canvas features - if (!('createImageData' in this._drawCtx)) { - throw new Error("Canvas does not support createImageData"); - } - Log.Debug("<< Display.constructor"); // ===== PROPERTIES ===== @@ -393,13 +387,7 @@ export default class Display { let data = new Uint8ClampedArray(arr.buffer, arr.byteOffset + offset, width * height * 4); - let img; - if (supportsImageMetadata) { - img = new ImageData(data, width, height); - } else { - img = this._drawCtx.createImageData(width, height); - img.data.set(data); - } + let img = new ImageData(data, width, height); this._drawCtx.putImageData(img, x, y); this._damage(x, y, width, height); } @@ -494,8 +482,7 @@ export default class Display { this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true); break; case 'img': - /* IE tends to set "complete" prematurely, so check dimensions */ - if (a.img.complete && (a.img.width !== 0) && (a.img.height !== 0)) { + if (a.img.complete) { if (a.img.width !== a.width || a.img.height !== a.height) { Log.Error("Decoded image has incorrect dimensions. Got " + a.img.width + "x" + a.img.height + ". Expected " + diff --git a/core/input/keyboard.js b/core/input/keyboard.js index 3ffa6e7a..ed3b1bf1 100644 --- a/core/input/keyboard.js +++ b/core/input/keyboard.js @@ -20,14 +20,12 @@ export default class Keyboard { this._keyDownList = {}; // List of depressed keys // (even if they are happy) - this._pendingKey = null; // Key waiting for keypress this._altGrArmed = false; // Windows AltGr detection // keep these here so we can refer to them later this._eventHandlers = { 'keyup': this._handleKeyUp.bind(this), 'keydown': this._handleKeyDown.bind(this), - 'keypress': this._handleKeyPress.bind(this), 'blur': this._allKeysUp.bind(this), }; @@ -61,9 +59,7 @@ export default class Keyboard { } // Unstable, but we don't have anything else to go on - // (don't use it for 'keypress' events thought since - // WebKit sets it to the same as charCode) - if (e.keyCode && (e.type !== 'keypress')) { + if (e.keyCode) { // 229 is used for composition events if (e.keyCode !== 229) { return 'Platform' + e.keyCode; @@ -168,20 +164,6 @@ export default class Keyboard { return; } - // If this is a legacy browser then we'll need to wait for - // a keypress event as well - // (IE and Edge has a broken KeyboardEvent.key, so we can't - // just check for the presence of that field) - if (!keysym && (!e.key || browser.isIE() || browser.isEdge())) { - this._pendingKey = code; - // However we might not get a keypress event if the key - // is non-printable, which needs some special fallback - // handling - setTimeout(this._handleKeyPressTimeout.bind(this), 10, e); - return; - } - - this._pendingKey = null; stopEvent(e); // Possible start of AltGr sequence? (see above) @@ -196,69 +178,6 @@ export default class Keyboard { this._sendKeyEvent(keysym, code, true); } - // Legacy event for browsers without code/key - _handleKeyPress(e) { - stopEvent(e); - - // Are we expecting a keypress? - if (this._pendingKey === null) { - return; - } - - let code = this._getKeyCode(e); - const keysym = KeyboardUtil.getKeysym(e); - - // The key we were waiting for? - if ((code !== 'Unidentified') && (code != this._pendingKey)) { - return; - } - - code = this._pendingKey; - this._pendingKey = null; - - if (!keysym) { - Log.Info('keypress with no keysym:', e); - return; - } - - this._sendKeyEvent(keysym, code, true); - } - - _handleKeyPressTimeout(e) { - // Did someone manage to sort out the key already? - if (this._pendingKey === null) { - return; - } - - let keysym; - - const code = this._pendingKey; - this._pendingKey = null; - - // We have no way of knowing the proper keysym with the - // information given, but the following are true for most - // layouts - if ((e.keyCode >= 0x30) && (e.keyCode <= 0x39)) { - // Digit - keysym = e.keyCode; - } else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) { - // Character (A-Z) - let char = String.fromCharCode(e.keyCode); - // A feeble attempt at the correct case - if (e.shiftKey) { - char = char.toUpperCase(); - } else { - char = char.toLowerCase(); - } - keysym = char.charCodeAt(); - } else { - // Unknown, give up - keysym = 0; - } - - this._sendKeyEvent(keysym, code, true); - } - _handleKeyUp(e) { stopEvent(e); @@ -318,7 +237,6 @@ export default class Keyboard { this._target.addEventListener('keydown', this._eventHandlers.keydown); this._target.addEventListener('keyup', this._eventHandlers.keyup); - this._target.addEventListener('keypress', this._eventHandlers.keypress); // Release (key up) if window loses focus window.addEventListener('blur', this._eventHandlers.blur); @@ -331,7 +249,6 @@ export default class Keyboard { this._target.removeEventListener('keydown', this._eventHandlers.keydown); this._target.removeEventListener('keyup', this._eventHandlers.keyup); - this._target.removeEventListener('keypress', this._eventHandlers.keypress); window.removeEventListener('blur', this._eventHandlers.blur); // Release (key up) all keys that are in a down state diff --git a/core/input/util.js b/core/input/util.js index 1b98040b..182be7f7 100644 --- a/core/input/util.js +++ b/core/input/util.js @@ -22,9 +22,8 @@ export function getKeycode(evt) { } // The de-facto standard is to use Windows Virtual-Key codes - // in the 'keyCode' field for non-printable characters. However - // Webkit sets it to the same as charCode in 'keypress' events. - if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) { + // in the 'keyCode' field for non-printable characters + if (evt.keyCode in vkeys) { let code = vkeys[evt.keyCode]; // macOS has messed up this code for some reason @@ -69,26 +68,6 @@ export function getKeycode(evt) { export function getKey(evt) { // Are we getting a proper key value? if (evt.key !== undefined) { - // IE and Edge use some ancient version of the spec - // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/ - switch (evt.key) { - case 'Spacebar': return ' '; - case 'Esc': return 'Escape'; - case 'Scroll': return 'ScrollLock'; - case 'Win': return 'Meta'; - case 'Apps': return 'ContextMenu'; - case 'Up': return 'ArrowUp'; - case 'Left': return 'ArrowLeft'; - case 'Right': return 'ArrowRight'; - case 'Down': return 'ArrowDown'; - case 'Del': return 'Delete'; - case 'Divide': return '/'; - case 'Multiply': return '*'; - case 'Subtract': return '-'; - case 'Add': return '+'; - case 'Decimal': return evt.char; - } - // Mozilla isn't fully in sync with the spec yet switch (evt.key) { case 'OS': return 'Meta'; @@ -110,18 +89,7 @@ export function getKey(evt) { return 'Delete'; } - // IE and Edge need special handling, but for everyone else we - // can trust the value provided - if (!browser.isIE() && !browser.isEdge()) { - return evt.key; - } - - // IE and Edge have broken handling of AltGraph so we can only - // trust them for non-printable characters (and unfortunately - // they also specify 'Unidentified' for some problem keys) - if ((evt.key.length !== 1) && (evt.key !== 'Unidentified')) { - return evt.key; - } + return evt.key; } // Try to deduce it based on the physical key diff --git a/core/input/vkeys.js b/core/input/vkeys.js index f84109b2..dacc3580 100644 --- a/core/input/vkeys.js +++ b/core/input/vkeys.js @@ -13,7 +13,6 @@ export default { 0x08: 'Backspace', 0x09: 'Tab', 0x0a: 'NumpadClear', - 0x0c: 'Numpad5', // IE11 sends evt.keyCode: 12 when numlock is off 0x0d: 'Enter', 0x10: 'ShiftLeft', 0x11: 'ControlLeft', diff --git a/core/rfb.js b/core/rfb.js index b1ed4756..26cdfcd0 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -25,7 +25,6 @@ import DES from "./des.js"; import KeyTable from "./input/keysym.js"; import XtScancode from "./input/xtscancodes.js"; import { encodings } from "./encodings.js"; -import "./util/polyfill.js"; import RawDecoder from "./decoders/raw.js"; import CopyRectDecoder from "./decoders/copyrect.js"; @@ -187,8 +186,6 @@ export default class RFB extends EventTargetMixin { this._canvas.style.margin = 'auto'; // Some browsers add an outline on focus this._canvas.style.outline = 'none'; - // IE miscalculates width without this :( - this._canvas.style.flexShrink = '0'; this._canvas.width = 0; this._canvas.height = 0; this._canvas.tabIndex = -1; @@ -1263,17 +1260,6 @@ export default class RFB extends EventTargetMixin { } _negotiateSecurity() { - // Polyfill since IE and PhantomJS doesn't have - // TypedArray.includes() - function includes(item, array) { - for (let i = 0; i < array.length; i++) { - if (array[i] === item) { - return true; - } - } - return false; - } - if (this._rfbVersion >= 3.7) { // Server sends supported list, client decides const numTypes = this._sock.rQshift8(); @@ -1290,15 +1276,15 @@ export default class RFB extends EventTargetMixin { Log.Debug("Server security types: " + types); // Look for each auth in preferred order - if (includes(1, types)) { + if (types.includes(1)) { this._rfbAuthScheme = 1; // None - } else if (includes(22, types)) { + } else if (types.includes(22)) { this._rfbAuthScheme = 22; // XVP - } else if (includes(16, types)) { + } else if (types.includes(16)) { this._rfbAuthScheme = 16; // Tight - } else if (includes(2, types)) { + } else if (types.includes(2)) { this._rfbAuthScheme = 2; // VNC Auth - } else if (includes(19, types)) { + } else if (types.includes(19)) { this._rfbAuthScheme = 19; // VeNCrypt Auth } else { return this._fail("Unsupported security types (types: " + types + ")"); @@ -2183,15 +2169,7 @@ export default class RFB extends EventTargetMixin { return this._handleCursor(); case encodings.pseudoEncodingQEMUExtendedKeyEvent: - // Old Safari doesn't support creating keyboard events - try { - const keyboardEvent = document.createEvent("keyboardEvent"); - if (keyboardEvent.code !== undefined) { - this._qemuExtKeyEventSupported = true; - } - } catch (err) { - // Do nothing - } + this._qemuExtKeyEventSupported = true; return true; case encodings.pseudoEncodingDesktopName: diff --git a/core/util/browser.js b/core/util/browser.js index 15548014..24b5e960 100644 --- a/core/util/browser.js +++ b/core/util/browser.js @@ -45,15 +45,6 @@ try { export const supportsCursorURIs = _supportsCursorURIs; -let _supportsImageMetadata = false; -try { - new ImageData(new Uint8ClampedArray(4), 1, 1); - _supportsImageMetadata = true; -} catch (ex) { - // ignore failure -} -export const supportsImageMetadata = _supportsImageMetadata; - let _hasScrollbarGutter = true; try { // Create invisible container @@ -106,14 +97,6 @@ export function isSafari() { navigator.userAgent.indexOf('Chrome') === -1); } -export function isIE() { - return navigator && !!(/trident/i).exec(navigator.userAgent); -} - -export function isEdge() { - return navigator && !!(/edge/i).exec(navigator.userAgent); -} - export function isFirefox() { return navigator && !!(/firefox/i).exec(navigator.userAgent); } diff --git a/core/util/cursor.js b/core/util/cursor.js index 4db1dab2..12bcceda 100644 --- a/core/util/cursor.js +++ b/core/util/cursor.js @@ -43,9 +43,6 @@ export default class Cursor { if (useFallback) { document.body.appendChild(this._canvas); - // FIXME: These don't fire properly except for mouse - /// movement in IE. We want to also capture element - // movement, size changes, visibility, etc. const options = { capture: true, passive: true }; this._target.addEventListener('mouseover', this._eventHandlers.mouseover, options); this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options); @@ -90,14 +87,7 @@ export default class Cursor { this._canvas.width = w; this._canvas.height = h; - let img; - try { - // IE doesn't support this - img = new ImageData(new Uint8ClampedArray(rgba), w, h); - } catch (ex) { - img = ctx.createImageData(w, h); - img.data.set(new Uint8ClampedArray(rgba)); - } + let img = new ImageData(new Uint8ClampedArray(rgba), w, h); ctx.clearRect(0, 0, w, h); ctx.putImageData(img, 0, 0); diff --git a/core/util/events.js b/core/util/events.js index 39eefd45..eb09fe1e 100644 --- a/core/util/events.js +++ b/core/util/events.js @@ -65,10 +65,6 @@ export function setCapture(target) { target.setCapture(); document.captureElement = target; - - // IE releases capture on 'click' events which might not trigger - target.addEventListener('mouseup', releaseCapture); - } else { // Release any existing capture in case this method is // called multiple times without coordination diff --git a/core/util/polyfill.js b/core/util/polyfill.js deleted file mode 100644 index 0e458c86..00000000 --- a/core/util/polyfill.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors - * Licensed under MPL 2.0 or any later version (see LICENSE.txt) - */ - -/* Polyfills to provide new APIs in old browsers */ - -/* Object.assign() (taken from MDN) */ -if (typeof Object.assign != 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, varArgs) { // .length of function is 2 - 'use strict'; - if (target == null) { // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - const to = Object(target); - - for (let index = 1; index < arguments.length; index++) { - const nextSource = arguments[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (let nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }, - writable: true, - configurable: true - }); -} - -/* CustomEvent constructor (taken from MDN) */ -(() => { - function CustomEvent(event, params) { - params = params || { bubbles: false, cancelable: false, detail: undefined }; - const evt = document.createEvent( 'CustomEvent' ); - evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); - return evt; - } - - CustomEvent.prototype = window.Event.prototype; - - if (typeof window.CustomEvent !== "function") { - window.CustomEvent = CustomEvent; - } -})(); - -/* Number.isInteger() (taken from MDN) */ -Number.isInteger = Number.isInteger || function isInteger(value) { - return typeof value === 'number' && - isFinite(value) && - Math.floor(value) === value; -}; diff --git a/core/websock.js b/core/websock.js index 3156aed6..8e606bc4 100644 --- a/core/websock.js +++ b/core/websock.js @@ -17,9 +17,6 @@ import * as Log from './util/logging.js'; // this has performance issues in some versions Chromium, and // doesn't gain a tremendous amount of performance increase in Firefox // at the moment. It may be valuable to turn it on in the future. -// Also copyWithin() for TypedArrays is not supported in IE 11 or -// Safari 13 (at the moment we want to support Safari 11). -const ENABLE_COPYWITHIN = false; const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB export default class Websock { @@ -256,11 +253,7 @@ export default class Websock { this._rQ = new Uint8Array(this._rQbufferSize); this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi)); } else { - if (ENABLE_COPYWITHIN) { - this._rQ.copyWithin(0, this._rQi, this._rQlen); - } else { - this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi, this._rQlen - this._rQi)); - } + this._rQ.copyWithin(0, this._rQi, this._rQlen); } this._rQlen = this._rQlen - this._rQi; diff --git a/karma.conf.js b/karma.conf.js index c295b1f9..1ea17475 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -31,16 +31,13 @@ module.exports = (config) => { // list of files / patterns to load in the browser (loaded in order) files: [ - { pattern: 'app/localization.js', included: false }, - { pattern: 'app/webutil.js', included: false }, - { pattern: 'core/**/*.js', included: false }, - { pattern: 'vendor/pako/**/*.js', included: false }, - { pattern: 'vendor/browser-es-module-loader/dist/*.js*', included: false }, - { pattern: 'tests/test.*.js', included: false }, - { pattern: 'tests/fake.*.js', included: false }, - { pattern: 'tests/assertions.js', included: false }, - 'vendor/promise.js', - 'tests/karma-test-main.js', + { pattern: 'app/localization.js', included: false, type: 'module' }, + { pattern: 'app/webutil.js', included: false, type: 'module' }, + { pattern: 'core/**/*.js', included: false, type: 'module' }, + { pattern: 'vendor/pako/**/*.js', included: false, type: 'module' }, + { pattern: 'tests/test.*.js', type: 'module' }, + { pattern: 'tests/fake.*.js', included: false, type: 'module' }, + { pattern: 'tests/assertions.js', type: 'module' }, ], client: { diff --git a/package.json b/package.json index 8fc04e50..660f16e9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "scripts": { "lint": "eslint app core po/po2js po/xgettext-html tests utils", "test": "karma start karma.conf.js", - "prepublish": "node ./utils/use_require.js --as commonjs --clean" + "prepublish": "node ./utils/use_require.js --clean" }, "repository": { "type": "git", @@ -42,10 +42,7 @@ "devDependencies": { "@babel/core": "*", "@babel/plugin-syntax-dynamic-import": "*", - "@babel/plugin-transform-modules-amd": "*", "@babel/plugin-transform-modules-commonjs": "*", - "@babel/plugin-transform-modules-systemjs": "*", - "@babel/plugin-transform-modules-umd": "*", "@babel/preset-env": "*", "@babel/cli": "*", "babel-plugin-import-redirect": "*", diff --git a/tests/assertions.js b/tests/assertions.js index bab932c5..c33c81ec 100644 --- a/tests/assertions.js +++ b/tests/assertions.js @@ -6,10 +6,8 @@ chai.use(function (_chai, utils) { _chai.Assertion.addMethod('displayed', function (targetData, cmp=_equal) { const obj = this._obj; const ctx = obj._target.getContext('2d'); - 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 - const data = new Uint8Array(dataCl); - const len = dataCl.length; + const data = ctx.getImageData(0, 0, obj._target.width, obj._target.height).data; + const len = data.length; new chai.Assertion(len).to.be.equal(targetData.length, "unexpected display size"); let same = true; for (let i = 0; i < len; i++) { diff --git a/tests/fake.websocket.js b/tests/fake.websocket.js index 623b25e4..4db3c590 100644 --- a/tests/fake.websocket.js +++ b/tests/fake.websocket.js @@ -1,17 +1,5 @@ import Base64 from '../core/base64.js'; -// PhantomJS can't create Event objects directly, so we need to use this -function makeEvent(name, props) { - const evt = document.createEvent('Event'); - evt.initEvent(name, true, true); - if (props) { - for (let prop in props) { - evt[prop] = props[prop]; - } - } - return evt; -} - export default class FakeWebSocket { constructor(uri, protocols) { this.url = uri; @@ -35,7 +23,7 @@ export default class FakeWebSocket { close(code, reason) { this.readyState = FakeWebSocket.CLOSED; if (this.onclose) { - this.onclose(makeEvent("close", { 'code': code, 'reason': reason, 'wasClean': true })); + this.onclose(new CloseEvent("close", { 'code': code, 'reason': reason, 'wasClean': true })); } } @@ -58,7 +46,7 @@ export default class FakeWebSocket { _open() { this.readyState = FakeWebSocket.OPEN; if (this.onopen) { - this.onopen(makeEvent('open')); + this.onopen(new Event('open')); } } @@ -67,7 +55,7 @@ export default class FakeWebSocket { // neatly packaged for (let i = 0;i < data.length;i++) { let buf = data.subarray(i, i+1); - this.onmessage(makeEvent("message", { 'data': buf })); + this.onmessage(new MessageEvent("message", { 'data': buf })); } } } diff --git a/tests/karma-test-main.js b/tests/karma-test-main.js deleted file mode 100644 index 28436667..00000000 --- a/tests/karma-test-main.js +++ /dev/null @@ -1,48 +0,0 @@ -const TEST_REGEXP = /test\..*\.js/; -const allTestFiles = []; -const extraFiles = ['/base/tests/assertions.js']; - -Object.keys(window.__karma__.files).forEach(function (file) { - if (TEST_REGEXP.test(file)) { - // TODO: normalize? - allTestFiles.push(file); - } -}); - -// Stub out mocha's start function so we can run it once we're done loading -mocha.origRun = mocha.run; -mocha.run = function () {}; - -let script; - -// Script to import all our tests -script = document.createElement("script"); -script.type = "module"; -script.text = ""; -let allModules = allTestFiles.concat(extraFiles); -allModules.forEach(function (file) { - script.text += "import \"" + file + "\";\n"; -}); -script.text += "\nmocha.origRun();\n"; -document.body.appendChild(script); - -// Fallback code for browsers that don't support modules (IE) -script = document.createElement("script"); -script.type = "module"; -script.text = "window._noVNC_has_module_support = true;\n"; -document.body.appendChild(script); - -function fallback() { - if (!window._noVNC_has_module_support) { - /* eslint-disable no-console */ - if (console) { - console.log("No module support detected. Loading fallback..."); - } - /* eslint-enable no-console */ - let loader = document.createElement("script"); - loader.src = "base/vendor/browser-es-module-loader/dist/browser-es-module-loader.js"; - document.body.appendChild(loader); - } -} - -setTimeout(fallback, 500); diff --git a/tests/test.display.js b/tests/test.display.js index bd5a55f9..0604997c 100644 --- a/tests/test.display.js +++ b/tests/test.display.js @@ -4,28 +4,27 @@ import Base64 from '../core/base64.js'; import Display from '../core/display.js'; describe('Display/Canvas Helper', function () { - const checkedData = new Uint8Array([ + const checkedData = new Uint8ClampedArray([ 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 ]); - const basicData = new Uint8Array([0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255]); + const basicData = new Uint8ClampedArray([0xff, 0x00, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0xff, 0xff, 0xff, 255]); - function makeImageCanvas(inputData) { + function makeImageCanvas(inputData, width, height) { const canvas = document.createElement('canvas'); - canvas.width = 4; - canvas.height = 4; + canvas.width = width; + canvas.height = height; const ctx = canvas.getContext('2d'); - const data = ctx.createImageData(4, 4); - for (let i = 0; i < checkedData.length; i++) { data.data[i] = inputData[i]; } + const data = new ImageData(inputData, width, height); ctx.putImageData(data, 0, 0); return canvas; } - function makeImagePng(inputData) { - const canvas = makeImageCanvas(inputData); + function makeImagePng(inputData, width, height) { + const canvas = makeImageCanvas(inputData, width, height); const url = canvas.toDataURL(); const data = url.split(",")[1]; return Base64.decode(data); @@ -44,7 +43,7 @@ describe('Display/Canvas Helper', function () { it('should take viewport location into consideration when drawing images', function () { display.resize(4, 4); display.viewportChangeSize(2, 2); - display.drawImage(makeImageCanvas(basicData), 1, 1); + display.drawImage(makeImageCanvas(basicData, 4, 1), 1, 1); display.flip(); const expected = new Uint8Array(16); @@ -300,7 +299,7 @@ describe('Display/Canvas Helper', function () { }); it('should support drawing images via #imageRect', function (done) { - display.imageRect(0, 0, 4, 4, "image/png", makeImagePng(checkedData)); + display.imageRect(0, 0, 4, 4, "image/png", makeImagePng(checkedData, 4, 4)); display.flip(); display.onflush = () => { expect(display).to.have.displayed(checkedData); @@ -316,7 +315,7 @@ describe('Display/Canvas Helper', function () { }); it('should support drawing an image object via #drawImage', function () { - const img = makeImageCanvas(checkedData); + const img = makeImageCanvas(checkedData, 4, 4); display.drawImage(img, 0, 0); display.flip(); expect(display).to.have.displayed(checkedData); @@ -361,27 +360,6 @@ describe('Display/Canvas Helper', function () { expect(img.addEventListener).to.have.been.calledOnce; }); - it('should wait if an image is incorrectly loaded', function () { - const img = { complete: true, width: 0, height: 0, addEventListener: sinon.spy() }; - display._renderQ = [{ type: 'img', x: 3, y: 4, width: 4, height: 4, img: img }, - { type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }]; - display.drawImage = sinon.spy(); - display.fillRect = sinon.spy(); - - display._scanRenderQ(); - expect(display.drawImage).to.not.have.been.called; - expect(display.fillRect).to.not.have.been.called; - expect(img.addEventListener).to.have.been.calledOnce; - - display._renderQ[0].img.complete = true; - display._renderQ[0].img.width = 4; - display._renderQ[0].img.height = 4; - display._scanRenderQ(); - expect(display.drawImage).to.have.been.calledOnce; - expect(display.fillRect).to.have.been.calledOnce; - expect(img.addEventListener).to.have.been.calledOnce; - }); - it('should call callback when queue is flushed', function () { display.onflush = sinon.spy(); display.fillRect(0, 0, 4, 4, [0, 0xff, 0]); diff --git a/tests/test.gesturehandler.js b/tests/test.gesturehandler.js index ba2f7991..73356be3 100644 --- a/tests/test.gesturehandler.js +++ b/tests/test.gesturehandler.js @@ -3,7 +3,6 @@ const expect = chai.expect; import EventTargetMixin from '../core/util/eventtarget.js'; import GestureHandler from '../core/input/gesturehandler.js'; -import * as browser from '../core/util/browser.js'; class DummyTarget extends EventTargetMixin { } @@ -23,12 +22,6 @@ describe('Gesture handler', function () { }); beforeEach(function () { - // Touch events and gestures are not supported on IE - if (browser.isIE()) { - this.skip(); - return; - } - target = new DummyTarget(); gestures = sinon.spy(); target.addEventListener('gesturestart', gestures); diff --git a/tests/test.helper.js b/tests/test.helper.js index b1f438ee..5552ec48 100644 --- a/tests/test.helper.js +++ b/tests/test.helper.js @@ -2,7 +2,6 @@ import keysyms from '../core/input/keysymdef.js'; import * as KeyboardUtil from "../core/input/util.js"; -import * as browser from '../core/util/browser.js'; describe('Helpers', function () { "use strict"; @@ -70,11 +69,6 @@ describe('Helpers', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.platform !== undefined) { @@ -102,14 +96,10 @@ describe('Helpers', function () { describe('getKey', function () { it('should prefer key', function () { - if (browser.isIE() || browser.isEdge()) this.skip(); expect(KeyboardUtil.getKey({key: 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal('a'); }); it('should map legacy values', function () { - expect(KeyboardUtil.getKey({key: 'Spacebar'})).to.be.equal(' '); - expect(KeyboardUtil.getKey({key: 'Left'})).to.be.equal('ArrowLeft'); expect(KeyboardUtil.getKey({key: 'OS'})).to.be.equal('Meta'); - expect(KeyboardUtil.getKey({key: 'Win'})).to.be.equal('Meta'); expect(KeyboardUtil.getKey({key: 'UIKeyInputLeftArrow'})).to.be.equal('ArrowLeft'); }); it('should handle broken Delete', function () { @@ -130,60 +120,6 @@ describe('Helpers', function () { it('should return Unidentified when it cannot map the key', function () { expect(KeyboardUtil.getKey({keycode: 0x42})).to.be.equal('Unidentified'); }); - - describe('Broken key AltGraph on IE/Edge', function () { - let origNavigator; - beforeEach(function () { - // window.navigator is a protected read-only property in many - // environments, so we need to redefine it whilst running these - // tests. - origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } - - Object.defineProperty(window, "navigator", {value: {}}); - if (window.navigator.platform !== undefined) { - // Object.defineProperty() doesn't work properly in old - // versions of Chrome - this.skip(); - } - }); - afterEach(function () { - if (origNavigator !== undefined) { - Object.defineProperty(window, "navigator", origNavigator); - } - }); - - it('should ignore printable character key on IE', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"; - expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified'); - }); - it('should ignore printable character key on Edge', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"; - expect(KeyboardUtil.getKey({key: 'a'})).to.be.equal('Unidentified'); - }); - it('should allow non-printable character key on IE', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"; - expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift'); - }); - it('should allow non-printable character key on Edge', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"; - expect(KeyboardUtil.getKey({key: 'Shift'})).to.be.equal('Shift'); - }); - it('should allow printable character key with charCode on IE', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"; - expect(KeyboardUtil.getKey({key: 'a', charCode: 0x61})).to.be.equal('a'); - expect(KeyboardUtil.getKey({key: 'Unidentified', charCode: 0x61})).to.be.equal('a'); - }); - it('should allow printable character key with charCode on Edge', function () { - window.navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"; - expect(KeyboardUtil.getKey({key: 'a', charCode: 0x61})).to.be.equal('a'); - expect(KeyboardUtil.getKey({key: 'Unidentified', charCode: 0x61})).to.be.equal('a'); - }); - }); }); describe('getKeysym', function () { @@ -236,7 +172,6 @@ describe('Helpers', function () { describe('Numpad', function () { it('should handle Numpad numbers', function () { - if (browser.isIE() || browser.isEdge()) this.skip(); expect(KeyboardUtil.getKeysym({code: 'Digit5', key: '5', location: 0})).to.be.equal(0x0035); expect(KeyboardUtil.getKeysym({code: 'Numpad5', key: '5', location: 3})).to.be.equal(0xFFB5); }); @@ -247,7 +182,6 @@ describe('Helpers', function () { expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: 'Delete', location: 3})).to.be.equal(0xFF9F); }); it('should handle Numpad Decimal key', function () { - if (browser.isIE() || browser.isEdge()) this.skip(); expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: '.', location: 3})).to.be.equal(0xFFAE); expect(KeyboardUtil.getKeysym({code: 'NumpadDecimal', key: ',', location: 3})).to.be.equal(0xFFAC); }); diff --git a/tests/test.keyboard.js b/tests/test.keyboard.js index 3571d39c..940769e6 100644 --- a/tests/test.keyboard.js +++ b/tests/test.keyboard.js @@ -1,7 +1,6 @@ const expect = chai.expect; import Keyboard from '../core/input/keyboard.js'; -import * as browser from '../core/util/browser.js'; describe('Key Event Handling', function () { "use strict"; @@ -20,7 +19,6 @@ describe('Key Event Handling', function () { describe('Decode Keyboard Events', function () { it('should decode keydown events', function (done) { - if (browser.isIE() || browser.isEdge()) this.skip(); const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { expect(keysym).to.be.equal(0x61); @@ -31,7 +29,6 @@ describe('Key Event Handling', function () { kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'})); }); it('should decode keyup events', function (done) { - if (browser.isIE() || browser.isEdge()) this.skip(); let calls = 0; const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { @@ -45,118 +42,10 @@ describe('Key Event Handling', function () { kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'})); kbd._handleKeyUp(keyevent('keyup', {code: 'KeyA', key: 'a'})); }); - - describe('Legacy keypress Events', function () { - it('should wait for keypress when needed', function () { - const kbd = new Keyboard(document); - kbd.onkeyevent = sinon.spy(); - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); - expect(kbd.onkeyevent).to.not.have.been.called; - }); - it('should decode keypress events', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0x61); - expect(code).to.be.equal('KeyA'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); - kbd._handleKeyPress(keyevent('keypress', {code: 'KeyA', charCode: 0x61})); - }); - it('should ignore keypress with different code', function () { - const kbd = new Keyboard(document); - kbd.onkeyevent = sinon.spy(); - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); - kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61})); - expect(kbd.onkeyevent).to.not.have.been.called; - }); - it('should handle keypress with missing code', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0x61); - expect(code).to.be.equal('KeyA'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41})); - kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61})); - }); - it('should guess key if no keypress and numeric key', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0x32); - expect(code).to.be.equal('Digit2'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32})); - }); - it('should guess key if no keypress and alpha key', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0x61); - expect(code).to.be.equal('KeyA'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false})); - }); - it('should guess key if no keypress and alpha key (with shift)', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0x41); - expect(code).to.be.equal('KeyA'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true})); - }); - it('should not guess key if no keypress and unknown key', function (done) { - const kbd = new Keyboard(document); - kbd.onkeyevent = (keysym, code, down) => { - expect(keysym).to.be.equal(0); - expect(code).to.be.equal('KeyA'); - expect(down).to.be.equal(true); - done(); - }; - kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x09})); - }); - }); - - describe('suppress the right events at the right time', function () { - beforeEach(function () { - if (browser.isIE() || browser.isEdge()) this.skip(); - }); - it('should suppress anything with a valid key', function () { - const kbd = new Keyboard(document, {}); - const evt1 = keyevent('keydown', {code: 'KeyA', key: 'a'}); - kbd._handleKeyDown(evt1); - expect(evt1.preventDefault).to.have.been.called; - const evt2 = keyevent('keyup', {code: 'KeyA', key: 'a'}); - kbd._handleKeyUp(evt2); - expect(evt2.preventDefault).to.have.been.called; - }); - it('should not suppress keys without key', function () { - const kbd = new Keyboard(document, {}); - const evt = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); - kbd._handleKeyDown(evt); - expect(evt.preventDefault).to.not.have.been.called; - }); - it('should suppress the following keypress event', function () { - const kbd = new Keyboard(document, {}); - const evt1 = keyevent('keydown', {code: 'KeyA', keyCode: 0x41}); - kbd._handleKeyDown(evt1); - const evt2 = keyevent('keypress', {code: 'KeyA', charCode: 0x41}); - kbd._handleKeyPress(evt2); - expect(evt2.preventDefault).to.have.been.called; - }); - }); }); describe('Fake keyup', function () { it('should fake keyup events for virtual keyboards', function (done) { - if (browser.isIE() || browser.isEdge()) this.skip(); let count = 0; const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { @@ -178,9 +67,6 @@ describe('Key Event Handling', function () { }); describe('Track Key State', function () { - beforeEach(function () { - if (browser.isIE() || browser.isEdge()) this.skip(); - }); it('should send release using the same keysym as the press', function (done) { const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { @@ -256,11 +142,6 @@ describe('Key Event Handling', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.platform !== undefined) { @@ -323,11 +204,6 @@ describe('Key Event Handling', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.platform !== undefined) { @@ -399,11 +275,6 @@ describe('Key Event Handling', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.platform !== undefined) { @@ -549,11 +420,6 @@ describe('Key Event Handling', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.platform !== undefined) { diff --git a/tests/test.localization.js b/tests/test.localization.js index 301ab79f..311353a1 100644 --- a/tests/test.localization.js +++ b/tests/test.localization.js @@ -11,11 +11,6 @@ describe('Localization', function () { // environments, so we need to redefine it whilst running these // tests. origNavigator = Object.getOwnPropertyDescriptor(window, "navigator"); - if (origNavigator === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "navigator", {value: {}}); if (window.navigator.languages !== undefined) { diff --git a/tests/test.rfb.js b/tests/test.rfb.js index da3cc9f6..d5a9adc8 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -8,26 +8,9 @@ import { encodings } from '../core/encodings.js'; import { toUnsigned32bit } from '../core/util/int.js'; import { encodeUTF8 } from '../core/util/strings.js'; import KeyTable from '../core/input/keysym.js'; -import * as browser from '../core/util/browser.js'; import FakeWebSocket from './fake.websocket.js'; -/* UIEvent constructor polyfill for IE */ -(() => { - if (typeof window.UIEvent === "function") return; - - function UIEvent( event, params ) { - params = params || { bubbles: false, cancelable: false, view: window, detail: undefined }; - const evt = document.createEvent( 'UIEvent' ); - evt.initUIEvent( event, params.bubbles, params.cancelable, params.view, params.detail ); - return evt; - } - - UIEvent.prototype = window.UIEvent.prototype; - - window.UIEvent = UIEvent; -})(); - function push8(arr, num) { "use strict"; arr.push(num & 0xFF); @@ -2277,12 +2260,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); it('should be able to handle large Provide messages', function () { - // repeat() is not supported in IE so a loop is needed instead - let expectedData = "hello"; - for (let i = 1; i <= 100000; i++) { - expectedData += "hello"; - } - + let expectedData = "hello".repeat(100000); let data = [3, 0, 0, 0]; const flags = [0x10, 0x00, 0x00, 0x01]; @@ -2528,23 +2506,11 @@ describe('Remote Frame Buffer Protocol Client', function () { let pos = elementToClient(x, y); let ev; - try { - ev = new MouseEvent('mousemove', - { 'screenX': pos.x + window.screenX, - 'screenY': pos.y + window.screenY, - 'clientX': pos.x, - 'clientY': pos.y }); - } catch (e) { - ev = document.createEvent('MouseEvent'); - ev.initMouseEvent('mousemove', - true, true, window, 0, - pos.x + window.screenX, - pos.y + window.screenY, - pos.x, pos.y, - false, false, false, false, - 0, null); - } - + ev = new MouseEvent('mousemove', + { 'screenX': pos.x + window.screenX, + 'screenY': pos.y + window.screenY, + 'clientX': pos.x, + 'clientY': pos.y }); client._canvas.dispatchEvent(ev); } @@ -2552,25 +2518,13 @@ describe('Remote Frame Buffer Protocol Client', function () { let pos = elementToClient(x, y); let ev; - try { - ev = new MouseEvent(down ? 'mousedown' : 'mouseup', - { 'screenX': pos.x + window.screenX, - 'screenY': pos.y + window.screenY, - 'clientX': pos.x, - 'clientY': pos.y, - 'button': button, - 'buttons': 1 << button }); - } catch (e) { - ev = document.createEvent('MouseEvent'); - ev.initMouseEvent(down ? 'mousedown' : 'mouseup', - true, true, window, 0, - pos.x + window.screenX, - pos.y + window.screenY, - pos.x, pos.y, - false, false, false, false, - button, null); - } - + ev = new MouseEvent(down ? 'mousedown' : 'mouseup', + { 'screenX': pos.x + window.screenX, + 'screenY': pos.y + window.screenY, + 'clientX': pos.x, + 'clientY': pos.y, + 'button': button, + 'buttons': 1 << button }); client._canvas.dispatchEvent(ev); } @@ -2805,25 +2759,14 @@ describe('Remote Frame Buffer Protocol Client', function () { let pos = elementToClient(x, y); let ev; - try { - ev = new WheelEvent('wheel', - { 'screenX': pos.x + window.screenX, - 'screenY': pos.y + window.screenY, - 'clientX': pos.x, - 'clientY': pos.y, - 'deltaX': dx, - 'deltaY': dy, - 'deltaMode': mode }); - } catch (e) { - ev = document.createEvent('WheelEvent'); - ev.initWheelEvent('wheel', true, true, window, 0, - pos.x + window.screenX, - pos.y + window.screenY, - pos.x, pos.y, - 0, null, "", - dx, dy, 0, mode); - } - + ev = new WheelEvent('wheel', + { 'screenX': pos.x + window.screenX, + 'screenY': pos.y + window.screenY, + 'clientX': pos.x, + 'clientY': pos.y, + 'deltaX': dx, + 'deltaY': dy, + 'deltaMode': mode }); client._canvas.dispatchEvent(ev); } @@ -2938,14 +2881,6 @@ describe('Remote Frame Buffer Protocol Client', function () { }); describe('Gesture event handlers', function () { - beforeEach(function () { - // Touch events and gestures are not supported on IE - if (browser.isIE()) { - this.skip(); - return; - } - }); - function gestureStart(gestureType, x, y, magnitudeX = 0, magnitudeY = 0) { let pos = elementToClient(x, y); diff --git a/tests/test.webutil.js b/tests/test.webutil.js index 2a166ee0..82a9cc6d 100644 --- a/tests/test.webutil.js +++ b/tests/test.webutil.js @@ -22,11 +22,6 @@ describe('WebUtil', function () { let origLocalStorage; beforeEach(function () { origLocalStorage = Object.getOwnPropertyDescriptor(window, "localStorage"); - if (origLocalStorage === undefined) { - // Object.getOwnPropertyDescriptor() doesn't work - // properly in any version of IE - this.skip(); - } Object.defineProperty(window, "localStorage", {value: {}}); if (window.localStorage.setItem !== undefined) { diff --git a/tests/vnc_playback.html b/tests/vnc_playback.html index 4fd74658..ffa69906 100644 --- a/tests/vnc_playback.html +++ b/tests/vnc_playback.html @@ -2,21 +2,6 @@