• Can you capture ctrl- or alt- keys without propagating?

    From luserdroog@21:1/5 to All on Mon Jan 17 19:51:11 2022
    I've started yet another useless project that'll likely never be
    completed. I want to make an APL interpreter where the language
    actually looks like the 1962 APL book. I thought the browser
    would be an easy environment to whip something up given the
    easy access to Unicode characters and complex layout like
    superscripts and subscripts.

    But I can't figure how to reliably capture key strokes using either
    ctrl- or alt- modifiers. Failing that, I thought I could use CapsLock
    or NumLock as an alternative "bucky bit" but I can't seem to get that
    to work either. With ctrl- and alt- most of the alphabet is already
    mapped to browser actions and they're still propagating even
    though I'm returning false which I thought should cancel the event
    propagation.

    Is there a context I can set up to capture Control or Alt keys without triggering the associated built-in browser action?

    My code:

    <html><!-- apl62.html -->
    <head>
    <meta charset="utf-8" />
    <style> </style>
    </head>
    <body>
    <div>
    <span class='log'></span>
    </div>
    </body>
    <script>

    var shift_key = 0;
    var ctrl_key = 0;
    var alt_key = 0;
    var caps_key = 0;
    var num_key = 0;

    const log = document.querySelector( '.log' );
    log.focus();

    document.addEventListener( 'keydown', function (event){
    console.log( event );
    if( event.key == 'Shift' ) shift_key = 1;
    else if( event.key == 'Control' ) ctrl_key = 1;
    else if( event.key == 'Alt' ) alt_key = 1;
    else if( event.key == 'CapsLock' ) caps_key = 1;
    else if( event.key == 'NumLock' ) num_key = 1;
    return false;
    });

    document.addEventListener( 'keyup', function (event){
    console.log( event );
    if( event.key == 'Shift' ) shift_key = 0;
    else if( event.key == 'Control' ) ctrl_key = 0;
    else if( event.key == 'Alt' ) alt_key = 0;
    else if( event.key == 'CapsLock' ) caps_key = 0;
    else if( event.key == 'NumLock' ) num_key = 0;
    else log.textContent += modified( key( event.code ) );
    return false;
    });

    function key( code ){
    const keyboard = {
    KeyQ: 'q', KeyW: 'w', KeyE: 'e', KeyR: 'r', KeyT: 't',
    KeyY: 'y', KeyU: 'u', KeyI: 'i', KeyO: 'o', KeyP: 'p',
    KeyA: 'a', KeyS: 's', KeyD: 'd', KeyF: 'f', KeyG: 'g',
    KeyH: 'h', KeyJ: 'j', KeyK: 'k', KeyL: 'l',
    KeyZ: 'z', KeyX: 'x', KeyC: 'c', KeyV: 'v',
    KeyB: 'b', KeyN: 'n', KeyM: 'm',
    Digit1: '1', Digit2: '2', Digit3: '3',
    Digit4: '4', Digit5: '5', Digit6: '6',
    Digit7: '7', Digit8: '8', Digit9: '9', Digit0: '0',
    Minus: '-', Equal: '=', Period: '.', Comma: ',',
    Plus: '+',
    Slash: '/', Backslash: '\\', BracketLeft: '[', BracketRight: ']'
    };
    if( keyboard.hasOwnProperty( code ) )
    code = keyboard[ code ];
    return code;
    }

    function modified( code ){
    console.log( '' + shift_key + '' + ctrl_key + '' + alt_key + '' + caps_key + '' + num_key); const alphabets = [
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`1234567890/,.-=[]\\",
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*()?<>_+{}|",
    "\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D" +
    "\u039E\u039F\u03A0\u03A1\u03A2\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA" +
    "\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D" +
    "\u039E\u039F\u03A0\u03A1\u03A2\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA",
    ];
    console.log( code );
    const i = alphabets[0].indexOf( code );
    if( i != -1 ){
    if( shift_key ){
    code = String.fromCharCode( alphabets[1].charCodeAt( i ) );
    console.log( code );
    } else if( alt_key ){
    code = String.fromCharCode( alphabets[2].charCodeAt( i ) );
    console.log( code );
    }
    }
    return code;
    }


    const vtypes = [ 'scalar', 'vector', 'matrix', 'tree' ];
    const ftypes = [ 'logical', 'integral', 'numerical', 'arbitrary' ];

    </script>
    </html>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to luserdroog on Tue Jan 18 13:29:09 2022
    On Mon, 17 Jan 2022 19:51:11 -0800 (PST), luserdroog wrote:
    I've started yet another useless project that'll likely never be
    completed. I want to make an APL interpreter where the language
    actually looks like the 1962 APL book. I thought the browser
    would be an easy environment to whip something up given the
    easy access to Unicode characters and complex layout like
    superscripts and subscripts.

    But I can't figure how to reliably capture key strokes using either
    ctrl- or alt- modifiers. Failing that, I thought I could use CapsLock
    or NumLock as an alternative "bucky bit" but I can't seem to get that
    to work either. With ctrl- and alt- most of the alphabet is already
    mapped to browser actions and they're still propagating even
    though I'm returning false which I thought should cancel the event propagation.

    Is there a context I can set up to capture Control or Alt keys without triggering the associated built-in browser action?
    [snip]

    First, make sure to add a capturing event listener (passing `true` as the second argument of `addEventListener()` method).

    In the event handler, it should check for the main key of the keyboard shortcut, not the modifier keys. e.g. for CTRL+P, check for the "P" key (preferrably using the event's `code` property), then check the modifier
    keys using the `ctrlKey` property. Also check other modifier key properties
    to make sure they're not being pressed (otherwise CTRL+SHIFT+P will also matches the condition).

    After the condition is met, call the event's `preventDefault()` method to disable browser's default key handler, in case the pressed key or key combination triggers browser's built in feature.

    Also call the event's `stopImmediatePropagation()` and `stopPropagation()` methods in case page scripts or browser extension scripts also use the same keyboard shortcut. However, it may not have any effect if their event
    listeners are also capturing event listeners, and were added before yours.
    i.e. first come, first serve. So, their event listeners are called first, before yours. Thus, you'll have no chance of preventing the event to be
    passed to their event listeners.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From luserdroog@21:1/5 to All on Wed Jan 19 10:20:09 2022
    On Tuesday, January 18, 2022 at 12:29:17 AM UTC-6, JJ wrote:
    On Mon, 17 Jan 2022 19:51:11 -0800 (PST), luserdroog wrote:

    Is there a context I can set up to capture Control or Alt keys without triggering the associated built-in browser action?
    [snip]

    First, make sure to add a capturing event listener (passing `true` as the second argument of `addEventListener()` method).

    In the event handler, it should check for the main key of the keyboard shortcut, not the modifier keys. e.g. for CTRL+P, check for the "P" key (preferrably using the event's `code` property), then check the modifier keys using the `ctrlKey` property. Also check other modifier key properties to make sure they're not being pressed (otherwise CTRL+SHIFT+P will also matches the condition).

    After the condition is met, call the event's `preventDefault()` method to disable browser's default key handler, in case the pressed key or key combination triggers browser's built in feature.

    Also call the event's `stopImmediatePropagation()` and `stopPropagation()` methods in case page scripts or browser extension scripts also use the same keyboard shortcut. However, it may not have any effect if their event listeners are also capturing event listeners, and were added before yours. i.e. first come, first serve. So, their event listeners are called first, before yours. Thus, you'll have no chance of preventing the event to be passed to their event listeners.

    That's excellent. Thank you. I was able to get the whole keyboard to work
    with Alt- and Alt-Shift-, at least the intersection of the set of glyphs from the prettiest APL keyboard google could find and the list of Unicode points from the wikipedia page. I'll have to do more work for some weird ones
    like Quad+Equal or Circle+Diaeresis.

    But I got all these: ⍺⊥∩⌊ε_∇∆⍳∘'⎕∣⊤○⋆?⍴~↓∪⍵⊃↑⊂⋄¨‾<≤=≥>≠∨∧×÷←→⊢⍎⍕⍝⍀⌿
    ΑΒΓΔ⍷ΖΗΘ⍸ΚΛ⌷ΝΞΟΠΡΣΤΥΦΧΨΩΪΫ ⌶⍫⍒⍋⌽⍉⊖⍟⍱⍲!⌹⍞ ⊣≡ ,⍙:

    With this:
    <html><!-- apl62.html -->
    <head>
    <meta charset="utf-8" />
    <style> </style>
    </head>
    <body>
    <div>
    <span class='log'></span>
    </div>
    </body>
    <script>

    function key( code ){
    const keyboard = {
    Backquote:'`',Digit1:'1',Digit2:'2',Digit3:'3',
    Digit4:'4',Digit5:'5',Digit6:'6',
    Digit7:'7',Digit8:'8',Digit9:'9', Digit0:'0',Minus:'-', Equal:'=',
    KeyQ:'q',KeyW:'w',KeyE:'e',KeyR:'r',KeyT:'t',KeyY:'y',KeyU:'u',KeyI:'i',KeyO:'o',KeyP:'p',
    BracketLeft:'[', BracketRight:']',Backslash:'\\',
    KeyA:'a',KeyS:'s',KeyD:'d',KeyF:'f',KeyG:'g',KeyH:'h',KeyJ:'j',KeyK:'k',KeyL: 'l',
    Semicolon:';',Quote:'\'',
    KeyZ:'z',KeyX:'x',KeyC:'c',KeyV:'v',KeyB:'b',KeyN:'n',KeyM:'m',
    Comma:',',Period:'.',Slash:'/',
    Space:' ',Enter:'\r',Backspace:'\b',Escape:'\u001B'
    };
    if( keyboard.hasOwnProperty( code ) ) code = keyboard[ code ];
    return code;
    }

    function modified( code, event ){
    const alphabets = [
    "abcdef" + "ghijklmnop" + "qrstuvwxyz" + "`1234567890" + "-=,./;\'[]\\",
    "ABCDEF" + "GHIJKLMNOP" + "QRSTUVWXYZ" + "~!@#$%^&*()" + "_+<>?:\"{}|",
    "\u237A\u22A5\u2229\u230A\u03B5_" +
    "\u2207\u2206\u2373\u2218\'\u2395\u2223\u22A4\u25CB\u22C6" +
    "?\u2374\u2308~\u2193\u222A\u2375\u2283\u2191\u2282" +
    "\u22C4\u00A8\u203E<\u2264=\u2265>\u2260\u2228\u2227\u00D7\u00F7" +
    "\u235D\u2340\u233F\u234E\u2355\u2190\u2192\u22A2",
    "\u0391\u0392\u0393\u0394\u2377\u0396" +
    "\u0397\u0398\u2378\u039A\u039B\u2337\u039D\u039E\u039F\u03A0" +
    "\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB" +
    " \u2336\u236B\u2352\u234B\u233D\u2349\u2296\u235F\u2371\u2372" +
    "!\u2339,\u2359:\u2261 \u235E \u22A3",
    ];
    //console.log( code );
    const i = alphabets[0].indexOf( code );
    const a = (event.shiftKey?1:0) + (event.altKey?2:0);
    if( i != -1 ){
    code = String.fromCharCode( alphabets[a].charCodeAt( i ) );
    }
    return [ i != -1 && a < alphabets.length, code ];
    }


    const log = document.querySelector( '.log' );
    document.body.focus();

    document.addEventListener( 'keydown', function (event){
    var [ b, k ] = modified( key( event.code ), event );
    if( b ){
    event.preventDefault();
    }
    return false;
    }, true);

    document.addEventListener( 'keyup', function (event){
    var [ b, k ] = modified( key( event.code ), event );
    if( b ){
    event.preventDefault();
    log.textContent += k;
    }
    return false;
    }, true);


    const vtypes = [ 'scalar', 'vector', 'matrix', 'tree' ];
    const ftypes = [ 'logical', 'integral', 'numerical', 'arbitrary' ];

    </script>
    </html>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)