mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-24 08:37:42 +00:00
refactor(web/engine): moves CJK, RTL, chiral checks to Keyboard wrapper
This commit is contained in:
parent
135993773c
commit
69b309104a
11 changed files with 89 additions and 100 deletions
|
|
@ -64,6 +64,37 @@ namespace com.keyman.keyboards {
|
|||
return this.scriptObject['KCSS'];
|
||||
}
|
||||
|
||||
/**
|
||||
* true if this keyboard uses a (legacy) pick list (Chinese, Japanese, Korean, etc.)
|
||||
*/
|
||||
get isCJK(): boolean { // I3363 (Build 301)
|
||||
var lg: string;
|
||||
if(typeof(this.scriptObject['KLC']) != 'undefined') {
|
||||
lg = this.scriptObject['KLC'];
|
||||
} else if(typeof(this.scriptObject['LanguageCode']) != 'undefined') {
|
||||
lg = this.scriptObject['LanguageCode'];
|
||||
}
|
||||
|
||||
// While some of these aren't proper BCP-47 language codes, the CJK keyboards predate our use of BCP-47.
|
||||
// So, we preserve the old ISO 639-3 codes, as that's what the keyboards are matching against.
|
||||
return ((lg == 'cmn') || (lg == 'jpn') || (lg == 'kor'));
|
||||
}
|
||||
|
||||
get isRTL(): boolean {
|
||||
return !!this.scriptObject['KRTL'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the currently-active modifier bitmask for the active keyboard.
|
||||
*/
|
||||
get modifierBitmask(): number {
|
||||
return this.scriptObject['KMBM'] || text.Codes.modifierBitmasks['NON_CHIRAL'];
|
||||
}
|
||||
|
||||
get isChiral(): boolean {
|
||||
return !!(this.modifierBitmask & text.Codes.modifierBitmasks['IS_CHIRAL']);
|
||||
}
|
||||
|
||||
// TODO: Provide public property-retrieving methods on this class, rather than as part of
|
||||
// the KeyboardManager object.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -796,85 +796,20 @@ namespace com.keyman.keyboards {
|
|||
* Scope Public
|
||||
* @param {Object=} k0
|
||||
* @return {boolean}
|
||||
* Description Tests if active keyboard (or optional argument) uses a pick list (Chinese, Japanese, Korean, etc.)
|
||||
* Description Tests if the keyboard stub uses a pick list (Chinese, Japanese, Korean, etc.)
|
||||
* (This function accepts either keyboard structure.)
|
||||
*/
|
||||
isCJK(k0?: any|KeyboardStub) { // I3363 (Build 301)
|
||||
let textProcessor = com.keyman.singleton.textProcessor;
|
||||
var k;
|
||||
if(textProcessor.activeKeyboard) {
|
||||
k = textProcessor.activeKeyboard.scriptObject;
|
||||
}
|
||||
var lg='';
|
||||
|
||||
if(arguments.length > 0) {
|
||||
k = k0;
|
||||
}
|
||||
|
||||
if(k) {
|
||||
if(typeof(k['KLC']) != 'undefined') {
|
||||
lg = k['KLC'];
|
||||
} else if(typeof(k['LanguageCode']) != 'undefined') {
|
||||
lg = k['LanguageCode'];
|
||||
}
|
||||
isCJK(k: KeyboardStub) { // I3363 (Build 301)
|
||||
var lg: string;
|
||||
if(typeof(k['KLC']) != 'undefined') {
|
||||
lg = k['KLC'];
|
||||
} else if(typeof(k['LanguageCode']) != 'undefined') {
|
||||
lg = k['LanguageCode'];
|
||||
}
|
||||
|
||||
return ((lg == 'cmn') || (lg == 'jpn') || (lg == 'kor'));
|
||||
}
|
||||
|
||||
isRTL(k0?): boolean {
|
||||
let textProcessor = com.keyman.singleton.textProcessor
|
||||
var k = k0;
|
||||
if(!k && textProcessor.activeKeyboard) {
|
||||
k = textProcessor.activeKeyboard.scriptObject;
|
||||
}
|
||||
return (k != null) && (k['KRTL']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function isChiral
|
||||
* Scope Public
|
||||
* @param {string|Object=} k0
|
||||
* @return {boolean}
|
||||
* Description Tests if the active keyboard (or optional argument) uses chiral modifiers.
|
||||
*/
|
||||
isChiral(k0?) {
|
||||
if(typeof(k0) == "string") {
|
||||
k0 = this.getKeyboardByID(k0);
|
||||
}
|
||||
|
||||
return !!(this.getKeyboardModifierBitmask(k0) & text.Codes.modifierBitmasks.IS_CHIRAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function getKeyboardModifierBitmask
|
||||
* Scope Private
|
||||
* @param {Object=} k0
|
||||
* @return {number}
|
||||
* Description Obtains the currently-active modifier bitmask for the active keyboard.
|
||||
*/
|
||||
getKeyboardModifierBitmask(k0?) {
|
||||
let textProcessor = com.keyman.singleton.textProcessor
|
||||
var k=textProcessor.activeKeyboard;
|
||||
if(k) {
|
||||
k = k.scriptObject;
|
||||
}
|
||||
|
||||
if(arguments.length > 0 && typeof k0 != 'undefined') {
|
||||
k = k0;
|
||||
}
|
||||
|
||||
if(!k) {
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
if(k['KMBM']) {
|
||||
return k['KMBM'];
|
||||
}
|
||||
|
||||
return text.Codes.modifierBitmasks['NON_CHIRAL'];
|
||||
}
|
||||
|
||||
getFont(k0?) {
|
||||
let textProcessor = com.keyman.singleton.textProcessor
|
||||
var k = k0;
|
||||
|
|
|
|||
|
|
@ -343,11 +343,19 @@ namespace com.keyman {
|
|||
* Scope Public
|
||||
* @param {Object=} k0
|
||||
* @return {boolean}
|
||||
* Description Tests if active keyboard (or optional argument) uses a pick list (Chinese, Japanese, Korean, etc.)
|
||||
* Description Tests if active keyboard (or specified keyboard script object, as optional argument)
|
||||
* uses a pick list (Chinese, Japanese, Korean, etc.)
|
||||
* (This function accepts either keyboard structure.)
|
||||
*/
|
||||
['isCJK'](k0) {
|
||||
return this.keyboardManager.isCJK(k0);
|
||||
['isCJK'](k0?) {
|
||||
var kbd: keyboards.Keyboard;
|
||||
if(k0) {
|
||||
kbd = new keyboards.Keyboard(kbd);
|
||||
} else {
|
||||
kbd = this.textProcessor.activeKeyboard;
|
||||
}
|
||||
|
||||
return kbd && kbd.isCJK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -358,7 +366,13 @@ namespace com.keyman {
|
|||
* Description Tests if the active keyboard (or optional argument) uses chiral modifiers.
|
||||
*/
|
||||
['isChiral'](k0?) {
|
||||
return this.keyboardManager.isChiral(k0);
|
||||
var kbd: keyboards.Keyboard;
|
||||
if(k0) {
|
||||
kbd = new keyboards.Keyboard(k0);
|
||||
} else {
|
||||
kbd = this.textProcessor.activeKeyboard;
|
||||
}
|
||||
return kbd.isChiral;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -774,8 +774,9 @@ namespace com.keyman {
|
|||
*
|
||||
* @param {Object} Ptarg Target element
|
||||
*/
|
||||
_SetTargDir(Ptarg: HTMLElement) {
|
||||
var elDir=(this.keyman.keyboardManager.isRTL()) ? 'rtl' : 'ltr';
|
||||
_SetTargDir(Ptarg: HTMLElement) {
|
||||
let activeKeyboard = com.keyman.singleton.textProcessor.activeKeyboard;
|
||||
var elDir=(activeKeyboard && activeKeyboard.isRTL) ? 'rtl' : 'ltr';
|
||||
|
||||
if(Ptarg) {
|
||||
if(this.keyman.util.device.touchable) {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ namespace com.keyman {
|
|||
} else {
|
||||
// Conditionally show the OSK when control receives the focus
|
||||
if(osk.ready) {
|
||||
if(this.keyman.keyboardManager.isCJK()) {
|
||||
if(this.keyman.isCJK()) {
|
||||
osk._Enabled = true;
|
||||
}
|
||||
if(osk._Enabled) {
|
||||
|
|
|
|||
|
|
@ -324,7 +324,8 @@ namespace com.keyman.osk {
|
|||
suggestionText = '\xa0'; // default: nbsp.
|
||||
} else {
|
||||
// Default the LTR ordering to match that of the active keyboard.
|
||||
let rtl = keyman.keyboardManager.isRTL();
|
||||
let activeKeyboard = keyman.textProcessor.activeKeyboard;
|
||||
let rtl = activeKeyboard && activeKeyboard.isRTL;
|
||||
let orderCode = rtl ? 0x202e /* RTL */ : 0x202d /* LTR */;
|
||||
suggestionText = String.fromCharCode(orderCode) + suggestion.displayAs;
|
||||
}
|
||||
|
|
@ -372,7 +373,8 @@ namespace com.keyman.osk {
|
|||
* the elements are inserted for RTL. This allows the banner to be RTL
|
||||
* for visuals/UI while still being internally LTR.
|
||||
*/
|
||||
let rtl = com.keyman.singleton.keyboardManager.isRTL();
|
||||
let activeKeyboard = com.keyman.singleton.textProcessor.activeKeyboard;
|
||||
let rtl = activeKeyboard && activeKeyboard.isRTL;
|
||||
for (var i=0; i<SuggestionBanner.SUGGESTION_LIMIT; i++) {
|
||||
let indexToInsert = rtl ? SuggestionBanner.SUGGESTION_LIMIT - i -1 : i;
|
||||
this.getDiv().appendChild(this.options[indexToInsert].div);
|
||||
|
|
|
|||
|
|
@ -365,16 +365,21 @@ namespace com.keyman.osk {
|
|||
static emulatesAltGr(keyLabels?: KLS): boolean { // TODO: typing for keyLabels (corresponds to KLS)
|
||||
var layers;
|
||||
let keyman = <KeymanBase> window['keyman'];
|
||||
var activeKeyboard = keyman.textProcessor.activeKeyboard;
|
||||
let modifierCodes = Codes.modifierCodes;
|
||||
|
||||
if(!activeKeyboard) {
|
||||
// No Alt-Gr emulation if there's not actually a keyboard loaded.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're not chiral, we're not emulating.
|
||||
if(!keyman.keyboardManager.isChiral()) {
|
||||
if(!activeKeyboard.isChiral) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!keyLabels) {
|
||||
var activeKeyboard = keyman.textProcessor.activeKeyboard;
|
||||
if(activeKeyboard == null || activeKeyboard.legacyLayoutSpec == null) {
|
||||
if(activeKeyboard.legacyLayoutSpec == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +407,7 @@ namespace com.keyman.osk {
|
|||
|
||||
// It's technically possible for the OSK to not specify anything while allowing chiral input. A last-ditch catch:
|
||||
|
||||
var bitmask = keyman.keyboardManager.getKeyboardModifierBitmask();
|
||||
var bitmask = activeKeyboard.modifierBitmask;
|
||||
if((bitmask & emulationMask) != emulationMask) {
|
||||
// At least one of the emulation modifiers is never used by the keyboard! We can confirm everything's safe.
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ namespace com.keyman.osk {
|
|||
Lviskbd={'F':'Tahoma', 'BK': Layouts.dfltText}; //DDOSK
|
||||
}
|
||||
|
||||
this._GenerateVisualKeyboard(Lviskbd, Lhelp, layout, keymanweb.keyboardManager.getKeyboardModifierBitmask());
|
||||
this._GenerateVisualKeyboard(Lviskbd, Lhelp, layout, activeKeyboard.modifierBitmask);
|
||||
} else { //The following code applies only to preformatted 'help' such as European Latin
|
||||
//osk.ddOSK = false;
|
||||
Ldiv=util._CreateElement('div');
|
||||
|
|
@ -779,7 +779,7 @@ namespace com.keyman.osk {
|
|||
this._VMoveX = Lposx - this._Box.offsetLeft;
|
||||
this._VMoveY = Lposy - this._Box.offsetTop;
|
||||
|
||||
if(keymanweb.keyboardManager.isCJK()) {
|
||||
if(keymanweb.isCJK()) {
|
||||
this.pinImg.style.left='15px';
|
||||
}
|
||||
|
||||
|
|
@ -1402,7 +1402,7 @@ namespace com.keyman.osk {
|
|||
|
||||
if(hiddenByUser) {
|
||||
//osk.loadCookie(); // preserve current offset and userlocated state
|
||||
this._Enabled = ((keymanweb.keyboardManager.isCJK() || device.touchable)? true : false); // I3363 (Build 301)
|
||||
this._Enabled = ((keymanweb.isCJK() || device.touchable)? true : false); // I3363 (Build 301)
|
||||
this.saveCookie(); // Save current OSK state, size and position (desktop only)
|
||||
} else if(device.formFactor == 'desktop') {
|
||||
//Allow desktop OSK to remain visible on blur if body class set
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ namespace com.keyman.osk {
|
|||
ts.fontSize=spec['fontsize'];
|
||||
}
|
||||
|
||||
let keyboardManager = (<KeymanBase>window['keyman']).keyboardManager;
|
||||
let activeKeyboard = com.keyman.singleton.textProcessor.activeKeyboard;
|
||||
|
||||
// For some reason, fonts will sometimes 'bug out' for the embedded iOS page if we
|
||||
// instead assign fontFamily to the existing style 'ts'. (Occurs in iOS 12.)
|
||||
|
|
@ -228,7 +228,7 @@ namespace com.keyman.osk {
|
|||
// Add the Unicode 'empty circle' as a base support for needy diacritics.
|
||||
keyText = '\u25cc' + keyText;
|
||||
|
||||
if(keyboardManager.isRTL()) {
|
||||
if(activeKeyboard && activeKeyboard.isRTL) {
|
||||
// Add the RTL marker to ensure it displays properly.
|
||||
keyText = '\u200f' + keyText;
|
||||
}
|
||||
|
|
@ -2216,7 +2216,7 @@ namespace com.keyman.osk {
|
|||
// Else get a default layout for the device for this keyboard
|
||||
if(layout == null && PVK != null) {
|
||||
let kbdDevVersion = PKbd.compilerVersion;
|
||||
layout=Layouts.buildDefaultLayout(PVK, kbdDevVersion, keymanweb.keyboardManager.getKeyboardModifierBitmask(PKbd),formFactor);
|
||||
layout=Layouts.buildDefaultLayout(PVK, kbdDevVersion, PKbd.modifierBitmask, formFactor);
|
||||
}
|
||||
|
||||
// Cannot create an OSK if no layout defined, just return empty DIV
|
||||
|
|
@ -2228,7 +2228,7 @@ namespace com.keyman.osk {
|
|||
}
|
||||
}
|
||||
|
||||
let kbdObj = new VisualKeyboard(PVK, null, layout, keymanweb.keyboardManager.getKeyboardModifierBitmask(), device, true);
|
||||
let kbdObj = new VisualKeyboard(PVK, null, layout, PKbd.modifierBitmask, device, true);
|
||||
let kbd = kbdObj.kbdDiv.childNodes[0] as HTMLDivElement; // Gets the layer group.
|
||||
|
||||
// Select the layer to display, and adjust sizes
|
||||
|
|
|
|||
|
|
@ -600,8 +600,7 @@ namespace com.keyman.text {
|
|||
var retVal = false; // I3318
|
||||
var keyCode = (e.Lcode == 173 ? 189 : e.Lcode); //I3555 (Firefox hyphen issue)
|
||||
|
||||
let keyman = com.keyman.singleton;
|
||||
let bitmask = keyman.keyboardManager.getKeyboardModifierBitmask();
|
||||
let bitmask = this.activeKeyboard.modifierBitmask;
|
||||
let Codes = com.keyman.text.Codes;
|
||||
var modifierBitmask = bitmask & Codes.modifierBitmasks["ALL"];
|
||||
var stateBitmask = bitmask & Codes.stateBitmasks["ALL"];
|
||||
|
|
|
|||
|
|
@ -712,13 +712,17 @@ namespace com.keyman.text {
|
|||
var lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'];
|
||||
var lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'];
|
||||
|
||||
if(!this.activeKeyboard) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(e) {
|
||||
// read shift states from Pevent
|
||||
keyShiftState = e.Lmodifiers;
|
||||
lockStates = e.Lstates;
|
||||
|
||||
// Are we simulating AltGr? If it's a simulation and not real, time to un-simulate for the OSK.
|
||||
if(keyman.keyboardManager.isChiral() && osk.Layouts.emulatesAltGr() &&
|
||||
if(this.activeKeyboard.isChiral && osk.Layouts.emulatesAltGr() &&
|
||||
(this.modStateFlags & Codes.modifierBitmasks['ALT_GR_SIM']) == Codes.modifierBitmasks['ALT_GR_SIM']) {
|
||||
keyShiftState |= Codes.modifierBitmasks['ALT_GR_SIM'];
|
||||
keyShiftState &= ~Codes.modifierCodes['RALT'];
|
||||
|
|
@ -774,8 +778,7 @@ namespace com.keyman.text {
|
|||
*/
|
||||
selectLayer(keyName: string, nextLayerIn?: number | string): boolean {
|
||||
var nextLayer = arguments.length < 2 ? null : nextLayerIn;
|
||||
let keyman = com.keyman.singleton;
|
||||
var isChiral = keyman.keyboardManager.isChiral();
|
||||
var isChiral = this.activeKeyboard && this.activeKeyboard.isChiral;
|
||||
|
||||
// Layer must be identified by name, not number (27/08/2015)
|
||||
if(typeof nextLayer == 'number') {
|
||||
|
|
@ -1125,7 +1128,8 @@ namespace com.keyman.text {
|
|||
|
||||
let modifierBitmasks = Codes.modifierBitmasks;
|
||||
// Stage 4 - map the modifier set to the appropriate keystroke's modifiers.
|
||||
if(keyman.keyboardManager.isChiral()) {
|
||||
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
|
||||
|
|
@ -1143,8 +1147,6 @@ namespace com.keyman.text {
|
|||
}
|
||||
|
||||
// Mnemonic handling.
|
||||
var activeKeyboard = this.activeKeyboard;
|
||||
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue