From bf9ce8c1a698837a0f58acecb129be7a623a757f Mon Sep 17 00:00:00 2001 From: jahorton Date: Thu, 26 Mar 2020 09:33:47 +0700 Subject: [PATCH] refactor(web/engine): starts DOM pre-processor fix(web): Ensures dev resources continue working --- web/source/dom/domEventHandlers.ts | 17 +- web/source/dom/preProcessor.ts | 278 +++++++++++++++++++++++++++++ web/source/kmwhotkeys.ts | 2 +- web/source/text/processor.ts | 278 +---------------------------- 4 files changed, 290 insertions(+), 285 deletions(-) create mode 100644 web/source/dom/preProcessor.ts diff --git a/web/source/dom/domEventHandlers.ts b/web/source/dom/domEventHandlers.ts index 9d79fbbe10..2048f8b387 100644 --- a/web/source/dom/domEventHandlers.ts +++ b/web/source/dom/domEventHandlers.ts @@ -1,4 +1,5 @@ /// +/// namespace com.keyman.dom { /* @@ -211,7 +212,7 @@ namespace com.keyman.dom { // Hide the touch device input caret, if applicable I3363 (Build 301) if(dom.Utils.instanceof(DOMEventHandlers.states.activeElement, "TouchAliasElement")) { - let lastAlias = DOMEventHandlers.states.activeElement; + let lastAlias = DOMEventHandlers.states.activeElement; lastAlias.hideCaret(); } @@ -412,7 +413,7 @@ namespace com.keyman.dom { return true; } - return this.keyman.textProcessor.keyDown(e); + return PreProcessor.keyDown(e); }.bind(this); doChangeEvent(_target: HTMLElement|Document) { @@ -445,7 +446,7 @@ namespace com.keyman.dom { return true; } - return this.keyman.textProcessor.keyPress(e); + return PreProcessor.keyPress(e); }.bind(this); /** @@ -454,11 +455,9 @@ namespace com.keyman.dom { * Description Processes keyup event and passes event data to keyboard */ _KeyUp: (e: KeyboardEvent) => boolean = function(this: DOMEventHandlers, e: KeyboardEvent): boolean { - var keyboardManager = this.keyman.keyboardManager; - let processor = this.keyman.textProcessor; var osk = this.keyman.osk; - var Levent = processor._GetKeyEventProperties(e, false); + var Levent = PreProcessor._GetKeyEventProperties(e, false); if(Levent == null || !osk.ready) { return true; } @@ -489,7 +488,7 @@ namespace com.keyman.dom { } } - return processor.keyUp(e); + return PreProcessor.keyUp(e); }.bind(this); } @@ -555,12 +554,12 @@ namespace com.keyman.dom { } // And the actual target element - var target=scroller.parentNode as dom.TouchAliasElement; + var target=scroller.parentNode as TouchAliasElement; // Move the caret and refocus if necessary if(DOMEventHandlers.states.activeElement != target) { // Hide the KMW caret - let prevTarget = DOMEventHandlers.states.activeElement; + let prevTarget = DOMEventHandlers.states.activeElement; if(prevTarget) { prevTarget.hideCaret(); } diff --git a/web/source/dom/preProcessor.ts b/web/source/dom/preProcessor.ts new file mode 100644 index 0000000000..0deb12251d --- /dev/null +++ b/web/source/dom/preProcessor.ts @@ -0,0 +1,278 @@ +namespace com.keyman.dom { + export class PreProcessor { + /** + * Function _GetEventKeyCode + * Scope Private + * @param {Event} e Event object + * Description Finds the key code represented by the event. + */ + static _GetEventKeyCode(e: KeyboardEvent) { + if (e.keyCode) { + return e.keyCode; + } else if (e.which) { + return e.which; + } else { + return null; + } + } + + /** + * Function _GetKeyEventProperties + * Scope Private + * @param {Event} e Event object + * @param {boolean=} keyState true if call results from a keyDown event, false if keyUp, undefined if keyPress + * @return {Object.} KMW keyboard event object: + * Description Get object with target element, key code, shift state, virtual key state + * Ltarg=target element + * Lcode=keyCode + * Lmodifiers=shiftState + * LisVirtualKeyCode e.g. ctrl/alt key + * LisVirtualKey e.g. Virtual key or non-keypress event + */ + static _GetKeyEventProperties(e: KeyboardEvent, keyState?: boolean): text.KeyEvent { + let keyman = com.keyman.singleton; + let processor = keyman.textProcessor; + var s = new text.KeyEvent(); + + e = keyman._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs + if(e.cancelBubble === true) { + return null; // I2457 - Facebook meta-event generation mess -- two events generated for a keydown in Facebook contentEditable divs + } + + let target = keyman.util.eventTarget(e) as HTMLElement; + if (target == null) { + return null; + } else if (target.nodeType == 3) {// defeat Safari bug + target = target.parentNode as HTMLElement; + } + s.Ltarg = text.Processor.getOutputTarget(target); + + s.Lcode = this._GetEventKeyCode(e); + if (s.Lcode == null) { + return null; + } + + // Stage 1 - track the true state of the keyboard's modifiers. + var prevModState = processor.modStateFlags, curModState = 0x0000; + var ctrlEvent = false, altEvent = false; + + let keyCodes = text.Codes.keyCodes; + switch(s.Lcode) { + case keyCodes['K_CTRL']: // The 3 shorter "K_*CTRL" entries exist in some legacy keyboards. + case keyCodes['K_LCTRL']: + case keyCodes['K_RCTRL']: + case keyCodes['K_CONTROL']: + case keyCodes['K_LCONTROL']: + case keyCodes['K_RCONTROL']: + ctrlEvent = true; + break; + case keyCodes['K_LMENU']: // The 2 "K_*MENU" entries exist in some legacy keyboards. + case keyCodes['K_RMENU']: + case keyCodes['K_ALT']: + case keyCodes['K_LALT']: + case keyCodes['K_RALT']: + altEvent = true; + break; + } + + /** + * Two separate conditions exist that should trigger chiral modifier detection. Examples below use CTRL but also work for ALT. + * + * 1. The user literally just pressed CTRL, so the event has a valid `location` property we can utilize. + * Problem: its layer isn't presently activated within the OSK. + * + * 2. CTRL has been held a while, so the OSK layer is valid, but the key event doesn't tell us the chirality of the active CTRL press. + * Bonus issue: RAlt simulation may cause erasure of this location property, but it should ONLY be empty if pressed in this case. + * We default to the 'left' variants since they're more likely to exist and cause less issues with RAlt simulation handling. + * + * In either case, `e.getModifierState("Control")` is set to true, but as a result does nothing to tell us which case is active. + * + * `e.location != 0` if true matches condition 1 and matches condition 2 if false. + */ + + curModState |= (e.getModifierState("Shift") ? 0x10 : 0); + + let modifierCodes = text.Codes.modifierCodes; + if(e.getModifierState("Control")) { + curModState |= ((e.location != 0 && ctrlEvent) ? + (e.location == 1 ? modifierCodes['LCTRL'] : modifierCodes['RCTRL']) : // Condition 1 + prevModState & 0x0003); // Condition 2 + } + if(e.getModifierState("Alt")) { + curModState |= ((e.location != 0 && altEvent) ? + (e.location == 1 ? modifierCodes['LALT'] : modifierCodes['RALT']) : // Condition 1 + prevModState & 0x000C); // Condition 2 + } + + // Stage 2 - detect state key information. It can be looked up per keypress with no issue. + s.Lstates = 0; + + s.Lstates |= e.getModifierState('CapsLock') ? modifierCodes['CAPS'] : modifierCodes['NO_CAPS']; + s.Lstates |= e.getModifierState('NumLock') ? modifierCodes['NUM_LOCK'] : modifierCodes['NO_NUM_LOCK']; + s.Lstates |= (e.getModifierState('ScrollLock') || e.getModifierState("Scroll")) // "Scroll" for IE9. + ? modifierCodes['SCROLL_LOCK'] : modifierCodes['NO_SCROLL_LOCK']; + + // We need these states to be tracked as well for proper OSK updates. + curModState |= s.Lstates; + + // Stage 3 - Set our modifier state tracking variable and perform basic AltGr-related management. + s.LmodifierChange = processor.modStateFlags != curModState; + processor.modStateFlags = curModState; + + // For European keyboards, not all browsers properly send both key-up events for the AltGr combo. + var altGrMask = modifierCodes['RALT'] | modifierCodes['LCTRL']; + if((prevModState & altGrMask) == altGrMask && (curModState & altGrMask) != altGrMask) { + // We just released AltGr - make sure it's all released. + curModState &= ~ altGrMask; + } + // Perform basic filtering for Windows-based ALT_GR emulation on European keyboards. + if(curModState & modifierCodes['RALT']) { + curModState &= ~modifierCodes['LCTRL']; + } + + let modifierBitmasks = text.Codes.modifierBitmasks; + // Stage 4 - map the modifier set to the appropriate keystroke's modifiers. + var activeKeyboard = processor.activeKeyboard; + if(activeKeyboard && activeKeyboard.isChiral) { + s.Lmodifiers = curModState & modifierBitmasks.CHIRAL; + + // Note for future - embedding a kill switch here or in keymanweb.osk.emulatesAltGr would facilitate disabling + // AltGr / Right-alt simulation. + if(osk.Layouts.emulatesAltGr() && (s.Lmodifiers & modifierBitmasks['ALT_GR_SIM']) == modifierBitmasks['ALT_GR_SIM']) { + s.Lmodifiers ^= modifierBitmasks['ALT_GR_SIM']; + s.Lmodifiers |= modifierCodes['RALT']; + } + } else { + // No need to sim AltGr here; we don't need chiral ALTs. + s.Lmodifiers = + (curModState & 0x10) | // SHIFT + ((curModState & (modifierCodes['LCTRL'] | modifierCodes['RCTRL'])) ? 0x20 : 0) | + ((curModState & (modifierCodes['LALT'] | modifierCodes['RALT'])) ? 0x40 : 0); + } + + // Mnemonic handling. + if(activeKeyboard && activeKeyboard.isMnemonic) { + // The following will never set a code corresponding to a modifier key, so it's fine to do this, + // which may change the value of Lcode, here. + text.Processor.setMnemonicCode(s, e.getModifierState("Shift"), e.getModifierState("CapsLock")); + } + + // The 0x6F used to be 0x60 - this adjustment now includes the chiral alt and ctrl modifiers in that check. + var LisVirtualKeyCode = (typeof e.charCode != 'undefined' && e.charCode != null && (e.charCode == 0 || (s.Lmodifiers & 0x6F) != 0)); + s.LisVirtualKey = LisVirtualKeyCode || e.type != 'keypress'; + + // Other minor physical-keyboard adjustments + if(activeKeyboard && !activeKeyboard.isMnemonic) { + // Positional Layout + + /* 13/03/2007 MCD: Swedish: Start mapping of keystroke to US keyboard */ + var Lbase = KeyMapping.languageMap[processor.baseLayout]; + if(Lbase && Lbase['k'+s.Lcode]) { + s.Lcode=Lbase['k'+s.Lcode]; + } + /* 13/03/2007 MCD: Swedish: End mapping of keystroke to US keyboard */ + + if(!activeKeyboard.definesPositionalOrMnemonic && !(s.Lmodifiers & 0x60)) { + // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic + s = { + Lcode: KeyMapping._USKeyCodeToCharCode(s), + Ltarg: s.Ltarg, + Lmodifiers: 0, + LisVirtualKey: false, + vkCode: s.Lcode, // Helps to merge OSK and physical keystroke control paths. + Lstates: s.Lstates, + kName: '' + }; + } + } + + return s; + } + + /** + * Function keyDown + * Scope Public + * Description Processes keydown event and passes data to keyboard. + * + * Note that the test-case oriented 'recorder' stubs this method to facilitate keystroke + * recording for use in test cases. If changing this function, please ensure the recorder is + * not affected. + */ + static keyDown(e: KeyboardEvent): boolean { + let processor = com.keyman.singleton.textProcessor; + processor.swallowKeypress = false; + + // Get event properties + var Levent = this._GetKeyEventProperties(e, true); + if(Levent == null) { + return true; + } + + var LeventMatched = !processor.processKeyEvent(Levent); + + if(LeventMatched) { + if(e && e.preventDefault) { + e.preventDefault(); + e.stopPropagation(); + } + } + + return !LeventMatched; + } + + // KeyUp basically exists for two purposes: + // 1) To detect browser form submissions (handled in kmwdomevents.ts) + // 2) To detect modifier state changes. + static keyUp(e: KeyboardEvent): boolean { + let processor = com.keyman.singleton.textProcessor; + var Levent = this._GetKeyEventProperties(e, false); + if(Levent == null) { + return true; + } + + return processor.doModifierPress(Levent, false); + } + + static keyPress(e: KeyboardEvent): boolean { + let keyman = com.keyman.singleton; + let processor = keyman.textProcessor; + + var Levent = this._GetKeyEventProperties(e); + if(Levent == null || Levent.LisVirtualKey) { + return true; + } + + // _Debug('KeyPress code='+Levent.Lcode+'; Ltarg='+Levent.Ltarg.tagName+'; LisVirtualKey='+Levent.LisVirtualKey+'; _KeyPressToSwallow='+keymanweb._KeyPressToSwallow+'; keyCode='+(e?e.keyCode:'nothing')); + + /* I732 START - 13/03/2007 MCD: Swedish: Start positional keyboard layout code: prevent keystroke */ + if(!processor.activeKeyboard.isMnemonic) { + if(!processor.swallowKeypress) { + return true; + } + if(Levent.Lcode < 0x20 || ((keyman)._BrowserIsSafari && (Levent.Lcode > 0xF700 && Levent.Lcode < 0xF900))) { + return true; + } + + e = keyman._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs + if(e) { + e.returnValue = false; + } + return false; + } + /* I732 END - 13/03/2007 MCD: Swedish: End positional keyboard layout code */ + + // Only reached if it's a mnemonic keyboard. + if(processor.swallowKeypress || processor.keyboardInterface.processKeystroke(keyman.util.physicalDevice, Levent.Ltarg, Levent)) { + processor.swallowKeypress = false; + if(e && e.preventDefault) { + e.preventDefault(); + e.stopPropagation(); + } + return false; + } + + processor.swallowKeypress = false; + return true; + } + } +} \ No newline at end of file diff --git a/web/source/kmwhotkeys.ts b/web/source/kmwhotkeys.ts index 84a1ccabaf..1ac7cee0e9 100644 --- a/web/source/kmwhotkeys.ts +++ b/web/source/kmwhotkeys.ts @@ -72,7 +72,7 @@ namespace com.keyman { e = window.event as KeyboardEvent; } - var _Lcode = this.keyman.textProcessor._GetEventKeyCode(e); + var _Lcode = dom.PreProcessor._GetEventKeyCode(e); if(_Lcode == null) { return false; } diff --git a/web/source/text/processor.ts b/web/source/text/processor.ts index 730b4a08ef..0406e142e0 100644 --- a/web/source/text/processor.ts +++ b/web/source/text/processor.ts @@ -226,7 +226,7 @@ namespace com.keyman.text { if(Lkc.Lcode != Codes.keyCodes['K_SPACE']) { // exception required, March 2013 // Jan 2019 - interesting that 'K_SPACE' also affects the caps-state check... Lkc.vkCode = Lkc.Lcode; - this.setMnemonicCode(Lkc, layer.indexOf('shift') != -1, this.stateKeys['K_CAPS']); + Processor.setMnemonicCode(Lkc, layer.indexOf('shift') != -1, this.stateKeys['K_CAPS']); } } else { Lkc.vkCode=Lkc.Lcode; @@ -282,7 +282,6 @@ namespace com.keyman.text { } var matchBehavior: RuleBehavior; - this.swallowKeypress = false; // Pass this key code and state to the keyboard program if(this.activeKeyboard && keyEvent.Lcode != 0) { @@ -558,7 +557,7 @@ namespace com.keyman.text { } // FIXME: makes some bad assumptions. - setMnemonicCode(Lkc: KeyEvent, shifted: boolean, capsActive: boolean) { + static setMnemonicCode(Lkc: KeyEvent, shifted: boolean, capsActive: boolean) { // K_SPACE is not handled by defaultKeyOutput for physical keystrokes unless using touch-aliased elements. // It's also a "exception required, March 2013" for clickKey, so at least they both have this requirement. if(Lkc.Lcode != Codes.keyCodes['K_SPACE']) { @@ -948,25 +947,9 @@ namespace com.keyman.text { } } - /** - * Function _GetEventKeyCode - * Scope Private - * @param {Event} e Event object - * Description Finds the key code represented by the event. - */ - _GetEventKeyCode(e: KeyboardEvent) { - if (e.keyCode) { - return e.keyCode; - } else if (e.which) { - return e.which; - } else { - return null; - } - } - // Returns true if the key event is a modifier press, allowing keyPress to return selectively // in those cases. - private doModifierPress(Levent: KeyEvent, isKeyDown: boolean): boolean { + doModifierPress(Levent: KeyEvent, isKeyDown: boolean): boolean { let keyman = com.keyman.singleton; let outputTarget = Levent.Ltarg; @@ -1001,260 +984,5 @@ namespace com.keyman.text { // No modifier keypresses detected. return false; } - - /** - * Function _GetKeyEventProperties - * Scope Private - * @param {Event} e Event object - * @param {boolean=} keyState true if call results from a keyDown event, false if keyUp, undefined if keyPress - * @return {Object.} KMW keyboard event object: - * Description Get object with target element, key code, shift state, virtual key state - * Ltarg=target element - * Lcode=keyCode - * Lmodifiers=shiftState - * LisVirtualKeyCode e.g. ctrl/alt key - * LisVirtualKey e.g. Virtual key or non-keypress event - */ - _GetKeyEventProperties(e: KeyboardEvent, keyState?: boolean): KeyEvent { - let keyman = com.keyman.singleton; - var s = new KeyEvent(); - - e = keyman._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs - if(e.cancelBubble === true) { - return null; // I2457 - Facebook meta-event generation mess -- two events generated for a keydown in Facebook contentEditable divs - } - - let target = keyman.util.eventTarget(e) as HTMLElement; - if (target == null) { - return null; - } else if (target.nodeType == 3) {// defeat Safari bug - target = target.parentNode as HTMLElement; - } - s.Ltarg = Processor.getOutputTarget(target); - - s.Lcode = this._GetEventKeyCode(e); - if (s.Lcode == null) { - return null; - } - - // Stage 1 - track the true state of the keyboard's modifiers. - var prevModState = this.modStateFlags, curModState = 0x0000; - var ctrlEvent = false, altEvent = false; - - let keyCodes = Codes.keyCodes; - switch(s.Lcode) { - case keyCodes['K_CTRL']: // The 3 shorter "K_*CTRL" entries exist in some legacy keyboards. - case keyCodes['K_LCTRL']: - case keyCodes['K_RCTRL']: - case keyCodes['K_CONTROL']: - case keyCodes['K_LCONTROL']: - case keyCodes['K_RCONTROL']: - ctrlEvent = true; - break; - case keyCodes['K_LMENU']: // The 2 "K_*MENU" entries exist in some legacy keyboards. - case keyCodes['K_RMENU']: - case keyCodes['K_ALT']: - case keyCodes['K_LALT']: - case keyCodes['K_RALT']: - altEvent = true; - break; - } - - /** - * Two separate conditions exist that should trigger chiral modifier detection. Examples below use CTRL but also work for ALT. - * - * 1. The user literally just pressed CTRL, so the event has a valid `location` property we can utilize. - * Problem: its layer isn't presently activated within the OSK. - * - * 2. CTRL has been held a while, so the OSK layer is valid, but the key event doesn't tell us the chirality of the active CTRL press. - * Bonus issue: RAlt simulation may cause erasure of this location property, but it should ONLY be empty if pressed in this case. - * We default to the 'left' variants since they're more likely to exist and cause less issues with RAlt simulation handling. - * - * In either case, `e.getModifierState("Control")` is set to true, but as a result does nothing to tell us which case is active. - * - * `e.location != 0` if true matches condition 1 and matches condition 2 if false. - */ - - curModState |= (e.getModifierState("Shift") ? 0x10 : 0); - - let modifierCodes = Codes.modifierCodes; - if(e.getModifierState("Control")) { - curModState |= ((e.location != 0 && ctrlEvent) ? - (e.location == 1 ? modifierCodes['LCTRL'] : modifierCodes['RCTRL']) : // Condition 1 - prevModState & 0x0003); // Condition 2 - } - if(e.getModifierState("Alt")) { - curModState |= ((e.location != 0 && altEvent) ? - (e.location == 1 ? modifierCodes['LALT'] : modifierCodes['RALT']) : // Condition 1 - prevModState & 0x000C); // Condition 2 - } - - // Stage 2 - detect state key information. It can be looked up per keypress with no issue. - s.Lstates = 0; - - s.Lstates |= e.getModifierState('CapsLock') ? modifierCodes['CAPS'] : modifierCodes['NO_CAPS']; - s.Lstates |= e.getModifierState('NumLock') ? modifierCodes['NUM_LOCK'] : modifierCodes['NO_NUM_LOCK']; - s.Lstates |= (e.getModifierState('ScrollLock') || e.getModifierState("Scroll")) // "Scroll" for IE9. - ? modifierCodes['SCROLL_LOCK'] : modifierCodes['NO_SCROLL_LOCK']; - - // We need these states to be tracked as well for proper OSK updates. - curModState |= s.Lstates; - - // Stage 3 - Set our modifier state tracking variable and perform basic AltGr-related management. - s.LmodifierChange = this.modStateFlags != curModState; - this.modStateFlags = curModState; - - // For European keyboards, not all browsers properly send both key-up events for the AltGr combo. - var altGrMask = modifierCodes['RALT'] | modifierCodes['LCTRL']; - if((prevModState & altGrMask) == altGrMask && (curModState & altGrMask) != altGrMask) { - // We just released AltGr - make sure it's all released. - curModState &= ~ altGrMask; - } - // Perform basic filtering for Windows-based ALT_GR emulation on European keyboards. - if(curModState & modifierCodes['RALT']) { - curModState &= ~modifierCodes['LCTRL']; - } - - let modifierBitmasks = Codes.modifierBitmasks; - // Stage 4 - map the modifier set to the appropriate keystroke's modifiers. - var activeKeyboard = this.activeKeyboard; - if(activeKeyboard && activeKeyboard.isChiral) { - s.Lmodifiers = curModState & modifierBitmasks.CHIRAL; - - // Note for future - embedding a kill switch here or in keymanweb.osk.emulatesAltGr would facilitate disabling - // AltGr / Right-alt simulation. - if(osk.Layouts.emulatesAltGr() && (s.Lmodifiers & modifierBitmasks['ALT_GR_SIM']) == modifierBitmasks['ALT_GR_SIM']) { - s.Lmodifiers ^= modifierBitmasks['ALT_GR_SIM']; - s.Lmodifiers |= modifierCodes['RALT']; - } - } else { - // No need to sim AltGr here; we don't need chiral ALTs. - s.Lmodifiers = - (curModState & 0x10) | // SHIFT - ((curModState & (modifierCodes['LCTRL'] | modifierCodes['RCTRL'])) ? 0x20 : 0) | - ((curModState & (modifierCodes['LALT'] | modifierCodes['RALT'])) ? 0x40 : 0); - } - - // Mnemonic handling. - if(activeKeyboard && activeKeyboard.isMnemonic) { - // The following will never set a code corresponding to a modifier key, so it's fine to do this, - // which may change the value of Lcode, here. - this.setMnemonicCode(s, e.getModifierState("Shift"), e.getModifierState("CapsLock")); - } - - // The 0x6F used to be 0x60 - this adjustment now includes the chiral alt and ctrl modifiers in that check. - var LisVirtualKeyCode = (typeof e.charCode != 'undefined' && e.charCode != null && (e.charCode == 0 || (s.Lmodifiers & 0x6F) != 0)); - s.LisVirtualKey = LisVirtualKeyCode || e.type != 'keypress'; - - // Other minor physical-keyboard adjustments - if(activeKeyboard && !activeKeyboard.isMnemonic) { - // Positional Layout - - /* 13/03/2007 MCD: Swedish: Start mapping of keystroke to US keyboard */ - var Lbase = KeyMapping.languageMap[this.baseLayout]; - if(Lbase && Lbase['k'+s.Lcode]) { - s.Lcode=Lbase['k'+s.Lcode]; - } - /* 13/03/2007 MCD: Swedish: End mapping of keystroke to US keyboard */ - - if(!activeKeyboard.definesPositionalOrMnemonic && !(s.Lmodifiers & 0x60)) { - // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic - s = { - Lcode: KeyMapping._USKeyCodeToCharCode(s), - Ltarg: s.Ltarg, - Lmodifiers: 0, - LisVirtualKey: false, - vkCode: s.Lcode, // Helps to merge OSK and physical keystroke control paths. - Lstates: s.Lstates, - kName: '' - }; - } - } - - return s; - } - - /** - * Function keyDown - * Scope Public - * Description Processes keydown event and passes data to keyboard. - * - * Note that the test-case oriented 'recorder' stubs this method to facilitate keystroke - * recording for use in test cases. If changing this function, please ensure the recorder is - * not affected. - */ - keyDown(e: KeyboardEvent): boolean { - this.swallowKeypress = false; - - // Get event properties - var Levent = this._GetKeyEventProperties(e, true); - if(Levent == null) { - return true; - } - - var LeventMatched = !this.processKeyEvent(Levent); - - if(LeventMatched) { - if(e && e.preventDefault) { - e.preventDefault(); - e.stopPropagation(); - } - } - - return !LeventMatched; - } - - // KeyUp basically exists for two purposes: - // 1) To detect browser form submissions (handled in kmwdomevents.ts) - // 2) To detect modifier state changes. - keyUp(e: KeyboardEvent): boolean { - var Levent = this._GetKeyEventProperties(e, false); - if(Levent == null) { - return true; - } - - return this.doModifierPress(Levent, false); - } - - keyPress(e: KeyboardEvent): boolean { - let keyman = com.keyman.singleton; - - var Levent = this._GetKeyEventProperties(e); - if(Levent == null || Levent.LisVirtualKey) { - return true; - } - - // _Debug('KeyPress code='+Levent.Lcode+'; Ltarg='+Levent.Ltarg.tagName+'; LisVirtualKey='+Levent.LisVirtualKey+'; _KeyPressToSwallow='+keymanweb._KeyPressToSwallow+'; keyCode='+(e?e.keyCode:'nothing')); - - /* I732 START - 13/03/2007 MCD: Swedish: Start positional keyboard layout code: prevent keystroke */ - if(!this.activeKeyboard.isMnemonic) { - if(!this.swallowKeypress) { - return true; - } - if(Levent.Lcode < 0x20 || ((keyman)._BrowserIsSafari && (Levent.Lcode > 0xF700 && Levent.Lcode < 0xF900))) { - return true; - } - - e = keyman._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs - if(e) { - e.returnValue = false; - } - return false; - } - /* I732 END - 13/03/2007 MCD: Swedish: End positional keyboard layout code */ - - // Only reached if it's a mnemonic keyboard. - if(this.swallowKeypress || this.keyboardInterface.processKeystroke(keyman.util.physicalDevice, Levent.Ltarg, Levent)) { - this.swallowKeypress = false; - if(e && e.preventDefault) { - e.preventDefault(); - e.stopPropagation(); - } - return false; - } - - this.swallowKeypress = false; - return true; - } } } \ No newline at end of file