SPB Git forge

spb/admin-ka

Public
41commits 1branches 0releases
172.9 MBsize
maindefault branch
19 days agolast push
JavaScript 65.5% Python 17.8% CSS 13% HTML 3.7%
5.9 KB · 192 lines javascript
Raw Blame History
1import KeyTable from "./keysym.js";2import keysyms from "./keysymdef.js";3import vkeys from "./vkeys.js";4import fixedkeys from "./fixedkeys.js";5import DOMKeyTable from "./domkeytable.js";6import * as browser from "../util/browser.js";78// Get 'KeyboardEvent.code', handling legacy browsers9export function getKeycode(evt) {10    // Are we getting proper key identifiers?11    // (unfortunately Firefox and Chrome are crappy here and gives12    // us an empty string on some platforms, rather than leaving it13    // undefined)14    if (evt.code) {15        // Mozilla isn't fully in sync with the spec yet16        switch (evt.code) {17            case 'OSLeft': return 'MetaLeft';18            case 'OSRight': return 'MetaRight';19        }2021        return evt.code;22    }2324    // The de-facto standard is to use Windows Virtual-Key codes25    // in the 'keyCode' field for non-printable characters26    if (evt.keyCode in vkeys) {27        let code = vkeys[evt.keyCode];2829        // macOS has messed up this code for some reason30        if (browser.isMac() && (code === 'ContextMenu')) {31            code = 'MetaRight';32        }3334        // The keyCode doesn't distinguish between left and right35        // for the standard modifiers36        if (evt.location === 2) {37            switch (code) {38                case 'ShiftLeft': return 'ShiftRight';39                case 'ControlLeft': return 'ControlRight';40                case 'AltLeft': return 'AltRight';41            }42        }4344        // Nor a bunch of the numpad keys45        if (evt.location === 3) {46            switch (code) {47                case 'Delete': return 'NumpadDecimal';48                case 'Insert': return 'Numpad0';49                case 'End': return 'Numpad1';50                case 'ArrowDown': return 'Numpad2';51                case 'PageDown': return 'Numpad3';52                case 'ArrowLeft': return 'Numpad4';53                case 'ArrowRight': return 'Numpad6';54                case 'Home': return 'Numpad7';55                case 'ArrowUp': return 'Numpad8';56                case 'PageUp': return 'Numpad9';57                case 'Enter': return 'NumpadEnter';58            }59        }6061        return code;62    }6364    return 'Unidentified';65}6667// Get 'KeyboardEvent.key', handling legacy browsers68export function getKey(evt) {69    // Are we getting a proper key value?70    if ((evt.key !== undefined) && (evt.key !== 'Unidentified')) {71        // Mozilla isn't fully in sync with the spec yet72        switch (evt.key) {73            case 'OS': return 'Meta';74            case 'LaunchMyComputer': return 'LaunchApplication1';75            case 'LaunchCalculator': return 'LaunchApplication2';76        }7778        // iOS leaks some OS names79        switch (evt.key) {80            case 'UIKeyInputUpArrow': return 'ArrowUp';81            case 'UIKeyInputDownArrow': return 'ArrowDown';82            case 'UIKeyInputLeftArrow': return 'ArrowLeft';83            case 'UIKeyInputRightArrow': return 'ArrowRight';84            case 'UIKeyInputEscape': return 'Escape';85        }8687        // Broken behaviour in Chrome88        if ((evt.key === '\x00') && (evt.code === 'NumpadDecimal')) {89            return 'Delete';90        }9192        return evt.key;93    }9495    // Try to deduce it based on the physical key96    const code = getKeycode(evt);97    if (code in fixedkeys) {98        return fixedkeys[code];99    }100101    // If that failed, then see if we have a printable character102    if (evt.charCode) {103        return String.fromCharCode(evt.charCode);104    }105106    // At this point we have nothing left to go on107    return 'Unidentified';108}109110// Get the most reliable keysym value we can get from a key event111export function getKeysym(evt) {112    const key = getKey(evt);113114    if (key === 'Unidentified') {115        return null;116    }117118    // First look up special keys119    if (key in DOMKeyTable) {120        let location = evt.location;121122        // Safari screws up location for the right cmd key123        if ((key === 'Meta') && (location === 0)) {124            location = 2;125        }126127        // And for Clear128        if ((key === 'Clear') && (location === 3)) {129            let code = getKeycode(evt);130            if (code === 'NumLock') {131                location = 0;132            }133        }134135        if ((location === undefined) || (location > 3)) {136            location = 0;137        }138139        // The original Meta key now gets confused with the Windows key140        // https://bugs.chromium.org/p/chromium/issues/detail?id=1020141141        // https://bugzilla.mozilla.org/show_bug.cgi?id=1232918142        if (key === 'Meta') {143            let code = getKeycode(evt);144            if (code === 'AltLeft') {145                return KeyTable.XK_Meta_L;146            } else if (code === 'AltRight') {147                return KeyTable.XK_Meta_R;148            }149        }150151        // macOS has Clear instead of NumLock, but the remote system is152        // probably not macOS, so lying here is probably best...153        if (key === 'Clear') {154            let code = getKeycode(evt);155            if (code === 'NumLock') {156                return KeyTable.XK_Num_Lock;157            }158        }159160        // Windows sends alternating symbols for some keys when using a161        // Japanese layout. We have no way of synchronising with the IM162        // running on the remote system, so we send some combined keysym163        // instead and hope for the best.164        if (browser.isWindows()) {165            switch (key) {166                case 'Zenkaku':167                case 'Hankaku':168                    return KeyTable.XK_Zenkaku_Hankaku;169                case 'Romaji':170                case 'KanaMode':171                    return KeyTable.XK_Romaji;172            }173        }174175        return DOMKeyTable[key][location];176    }177178    // Now we need to look at the Unicode symbol instead179180    // Special key? (FIXME: Should have been caught earlier)181    if (key.length !== 1) {182        return null;183    }184185    const codepoint = key.charCodeAt();186    if (codepoint) {187        return keysyms.lookup(codepoint);188    }189190    return null;191}192