Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

31 views
Skip to first unread message

luserdroog

unread,
Jan 17, 2022, 10:51:16 PM1/17/22
to
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>

JJ

unread,
Jan 18, 2022, 1:29:17 AM1/18/22
to
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.

luserdroog

unread,
Jan 19, 2022, 1:20:14 PM1/19/22
to
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);
0 new messages