]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Merge pull request #1319 from wavezhang/patch-2
authorSamuel Mannehed <samuel@cendio.se>
Mon, 11 Nov 2019 15:46:36 +0000 (16:46 +0100)
committerGitHub <noreply@github.com>
Mon, 11 Nov 2019 15:46:36 +0000 (16:46 +0100)
Update zh_CN.po

core/input/keyboard.js
tests/test.keyboard.js
utils/use_require.js
utils/use_require_helpers.js

index 6e41365ec9d41c65f04cbdea0b098d126218919e..9e6af2ac753e98112e8380c69fe2a5ac3a4cdfd4 100644 (file)
@@ -162,7 +162,7 @@ export default class Keyboard {
         // state change events. That gets extra confusing for CapsLock
         // which toggles on each press, but not on release. So pretend
         // it was a quick press and release of the button.
-        if (browser.isMac() && (code === 'CapsLock')) {
+        if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
             stopEvent(e);
@@ -274,7 +274,7 @@ export default class Keyboard {
         }
 
         // See comment in _handleKeyDown()
-        if (browser.isMac() && (code === 'CapsLock')) {
+        if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
             return;
index f5807e92e010e2cdd527a37fef492fcaa4266679..b49312dd6bd670aa74b7700323480d7d477012ff 100644 (file)
@@ -314,6 +314,80 @@ describe('Key Event Handling', function () {
         });
     });
 
+    describe('Caps Lock on iOS and macOS', 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 () {
+            Object.defineProperty(window, "navigator", origNavigator);
+        });
+
+        it('should toggle caps lock on key press on iOS', function (done) {
+            window.navigator.platform = "iPad";
+            const kbd = new Keyboard(document);
+            kbd.onkeyevent = sinon.spy();
+            kbd._handleKeyDown(keyevent('keydown', {code: 'CapsLock', key: 'CapsLock'}));
+
+            expect(kbd.onkeyevent).to.have.been.calledTwice;
+            expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
+            expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
+            done();
+        });
+
+        it('should toggle caps lock on key press on mac', function (done) {
+            window.navigator.platform = "Mac";
+            const kbd = new Keyboard(document);
+            kbd.onkeyevent = sinon.spy();
+            kbd._handleKeyDown(keyevent('keydown', {code: 'CapsLock', key: 'CapsLock'}));
+
+            expect(kbd.onkeyevent).to.have.been.calledTwice;
+            expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
+            expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
+            done();
+        });
+
+        it('should toggle caps lock on key release on iOS', function (done) {
+            window.navigator.platform = "iPad";
+            const kbd = new Keyboard(document);
+            kbd.onkeyevent = sinon.spy();
+            kbd._handleKeyUp(keyevent('keyup', {code: 'CapsLock', key: 'CapsLock'}));
+
+            expect(kbd.onkeyevent).to.have.been.calledTwice;
+            expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
+            expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
+            done();
+        });
+
+        it('should toggle caps lock on key release on mac', function (done) {
+            window.navigator.platform = "Mac";
+            const kbd = new Keyboard(document);
+            kbd.onkeyevent = sinon.spy();
+            kbd._handleKeyUp(keyevent('keyup', {code: 'CapsLock', key: 'CapsLock'}));
+
+            expect(kbd.onkeyevent).to.have.been.calledTwice;
+            expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xFFE5, "CapsLock", true);
+            expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xFFE5, "CapsLock", false);
+            done();
+        });
+    });
+
     describe('Escape AltGraph on Windows', function () {
         let origNavigator;
         beforeEach(function () {
index d6e8d6a58c80c3c911dfdcd2ad96fd09fb23564a..d2d976903f06db1a06f0747c68a2bd535fb4d621 100755 (executable)
@@ -30,10 +30,13 @@ const no_copy_files = new Set([
     // skip these -- they don't belong in the processed application
     path.join(paths.vendor, 'sinon.js'),
     path.join(paths.vendor, 'browser-es-module-loader'),
-    path.join(paths.vendor, 'promise.js'),
     path.join(paths.app, 'images', 'icons', 'Makefile'),
 ]);
 
+const only_legacy_scripts = new Set([
+    path.join(paths.vendor, 'promise.js'),
+]);
+
 const no_transform_files = new Set([
     // don't transform this -- we want it imported as-is to properly catch loading errors
     path.join(paths.app, 'error-handler.js'),
@@ -108,7 +111,7 @@ function transform_html(legacy_scripts, only_legacy) {
                 // Otherwise include both modules and legacy fallbacks
                 new_script += '    <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n';
                 for (let i = 0;i < legacy_scripts.length;i++) {
-                    new_script += '    <script nomodule src="${legacy_scripts[i]}"></script>\n';
+                    new_script += `    <script nomodule src="${legacy_scripts[i]}"></script>\n`;
                 }
             }
 
@@ -158,11 +161,10 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
     const helper = helpers[import_format];
 
     const outFiles = [];
+    const legacyFiles = [];
 
     const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve()
         .then(() => {
-            if (no_copy_files.has(filename)) return;
-
             const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
             const legacy_path = path.join(legacy_path_base, path.relative(in_path_base, filename));
 
@@ -174,9 +176,26 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
                 return;  // skip non-javascript files
             }
 
+            if (no_transform_files.has(filename)) {
+                return ensureDir(path.dirname(out_path))
+                    .then(() => {
+                        console.log(`Writing ${out_path}`);
+                        return copy(filename, out_path);
+                    });
+            }
+
+            if (only_legacy_scripts.has(filename)) {
+                legacyFiles.push(legacy_path);
+                return ensureDir(path.dirname(legacy_path))
+                    .then(() => {
+                        console.log(`Writing ${legacy_path}`);
+                        return copy(filename, legacy_path);
+                    });
+            }
+
             return Promise.resolve()
                 .then(() => {
-                    if (only_legacy && !no_transform_files.has(filename)) {
+                    if (only_legacy) {
                         return;
                     }
                     return ensureDir(path.dirname(out_path))
@@ -187,10 +206,6 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
                 })
                 .then(() => ensureDir(path.dirname(legacy_path)))
                 .then(() => {
-                    if (no_transform_files.has(filename)) {
-                        return;
-                    }
-
                     const opts = babel_opts();
                     if (helper && helpers.optionsOverride) {
                         helper.optionsOverride(opts);
@@ -225,10 +240,6 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
                 });
         });
 
-    if (with_app_dir && helper && helper.noCopyOverride) {
-        helper.noCopyOverride(paths, no_copy_files);
-    }
-
     Promise.resolve()
         .then(() => {
             const handler = handleDir.bind(null, true, false, in_path || paths.main);
@@ -257,8 +268,16 @@ function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
             console.log(`Writing ${out_app_path}`);
             return helper.appWriter(out_path_base, legacy_path_base, out_app_path)
                 .then((extra_scripts) => {
-                    const rel_app_path = path.relative(out_path_base, out_app_path);
-                    const legacy_scripts = extra_scripts.concat([rel_app_path]);
+                    let legacy_scripts = extra_scripts;
+
+                    legacyFiles.forEach((file) => {
+                        let rel_file_path = path.relative(out_path_base, file);
+                        legacy_scripts.push(rel_file_path);
+                    });
+
+                    let rel_app_path = path.relative(out_path_base, out_app_path);
+                    legacy_scripts.push(rel_app_path);
+
                     transform_html(legacy_scripts, only_legacy);
                 })
                 .then(() => {
index a4f99c7045ca504ad1330e9df33fff783c1b315a..ec5da0d1924b16de8070544c23c55982074780d5 100644 (file)
@@ -31,7 +31,6 @@ module.exports = {
                     return [ require_path ];
                 });
         },
-        noCopyOverride: () => {},
     },
     'commonjs': {
         optionsOverride: (opts) => {
@@ -45,7 +44,6 @@ module.exports = {
                 .then(buf => writeFile(out_path, buf))
                 .then(() => []);
         },
-        noCopyOverride: () => {},
         removeModules: true,
     },
     'systemjs': {
@@ -55,17 +53,11 @@ module.exports = {
             return writeFile(out_path, `SystemJS.import("${ui_path}");`)
                 .then(() => {
                     console.log(`Please place SystemJS in ${path.join(script_base_path, 'system-production.js')}`);
-                // FIXME: Should probably be in the legacy directory
-                    const promise_path = path.relative(base_out_path,
-                                                       path.join(base_out_path, 'vendor', 'promise.js'));
                     const systemjs_path = path.relative(base_out_path,
                                                         path.join(script_base_path, 'system-production.js'));
-                    return [ promise_path, systemjs_path ];
+                    return [ systemjs_path ];
                 });
         },
-        noCopyOverride: (paths, no_copy_files) => {
-            no_copy_files.delete(path.join(paths.vendor, 'promise.js'));
-        },
     },
     'umd': {
         optionsOverride: (opts) => {