diff --git a/web/source/keymanweb.ts b/web/source/keymanweb.ts
index 01d7c769aa..5e10889dd0 100644
--- a/web/source/keymanweb.ts
+++ b/web/source/keymanweb.ts
@@ -1958,21 +1958,6 @@ if(!window['keyman']['initialized']) {
}
return e;
}
-
- /**
- * Function _push
- * Scope Private
- * @param {Array} Parray Array
- * @param {*} Pval Value to be pushed or appended to array
- * @return {Array} Returns extended array
- * Description Push (if possible) or append a value to an array
- */
- keymanweb._push = function(Parray, Pval)
- {
- if(Parray.push) Parray.push(Pval);
- else Parray=Parray.concat(Pval);
- return Parray;
- }
/**
* Function attachToControl
diff --git a/web/source/kmwapi.ts b/web/source/kmwapi.ts
index b69737c2cc..cffce136ce 100644
--- a/web/source/kmwapi.ts
+++ b/web/source/kmwapi.ts
@@ -1,6 +1,7 @@
///
///
///
+///
// Allows proper minification handling.
///
@@ -17,6 +18,11 @@
// kmwbase.ts
goog.exportProperty(keyman, "build", keyman); // Only works on individual instances.
goog.exportSymbol("KeymanBase.prototype.isFontAvailable", KeymanBase.prototype.isFontAvailable);
+goog.exportSymbol("KeymanBase.prototype.GetLastActiveElement", KeymanBase.prototype.getLastActiveElement);
+goog.exportSymbol("KeymanBase.prototype.FocusLastActiveElement", KeymanBase.prototype.focusLastActiveElement);
+goog.exportSymbol("KeymanBase.prototype.HideHelp", KeymanBase.prototype.hideHelp);
+goog.exportSymbol("KeymanBase.prototype.ShowHelp", KeymanBase.prototype.showHelp);
+goog.exportSymbol("KeymanBase.prototype.ShowPinnedHelp", KeymanBase.prototype.showPinnedHelp);
// Util.ts
@@ -45,4 +51,41 @@ goog.exportSymbol("Util.prototype.saveCookie", Util.prototype.saveCookie);
goog.exportSymbol("Util.prototype.toNumber", Util.prototype.toNumber);
goog.exportSymbol("Util.prototype.toFloat", Util.prototype.toFloat);
goog.exportSymbol("Util.prototype.toNzString", Util.prototype.nzString);
-goog.exportSymbol("Util.prototype.alert", Util.prototype.alert);
\ No newline at end of file
+goog.exportSymbol("Util.prototype.alert", Util.prototype.alert);
+
+// kmwcallback.ts
+(function() {
+ var exportKBCallback = function(miniName: string, longName: string, func:() => any) {
+ goog.exportSymbol("KeyboardInterface.prototype." + longName, func);
+ goog.exportSymbol("KeyboardInterface.prototype." + miniName, func);
+ }
+
+ var exportKBCallbackWithArgs = function(miniName: string, longName: string, func:(...args: any[]) => any) {
+ goog.exportSymbol("KeyboardInterface.prototype." + longName, func);
+ goog.exportSymbol("KeyboardInterface.prototype." + miniName, func);
+ }
+
+ exportKBCallback('KSF', 'saveFocus', KeyboardInterface.prototype.saveFocus);
+ exportKBCallback('KBR', 'beepReset', KeyboardInterface.prototype.beepReset);
+
+ exportKBCallbackWithArgs('KT', 'insertText', KeyboardInterface.prototype.insertText);
+ exportKBCallbackWithArgs('KR', 'registerKeyboard', KeyboardInterface.prototype.registerKeyboard);
+ exportKBCallbackWithArgs('KRS', 'registerStub', KeyboardInterface.prototype.registerStub);
+ exportKBCallbackWithArgs('KC', 'context', KeyboardInterface.prototype.context);
+ exportKBCallbackWithArgs('KN', 'nul', KeyboardInterface.prototype.nul);
+ exportKBCallbackWithArgs('KCM', 'contextMatch', KeyboardInterface.prototype.contextMatch);
+ exportKBCallbackWithArgs('KIK', 'isKeypress', KeyboardInterface.prototype.isKeypress);
+ exportKBCallbackWithArgs('KKM', 'keyMatch', KeyboardInterface.prototype.keyMatch);
+ exportKBCallbackWithArgs('KSM', 'stateMatch', KeyboardInterface.prototype.stateMatch);
+ exportKBCallbackWithArgs('KKI', 'keyInformation', KeyboardInterface.prototype.keyInformation);
+ exportKBCallbackWithArgs('KDM', 'deadkeyMatch', KeyboardInterface.prototype.deadkeyMatch);
+ exportKBCallbackWithArgs('KB', 'beep', KeyboardInterface.prototype.beep);
+ exportKBCallbackWithArgs('KA', 'any', KeyboardInterface.prototype.any);
+ exportKBCallbackWithArgs('KO', 'output', KeyboardInterface.prototype.output);
+ exportKBCallbackWithArgs('KDO', 'deadkeyOutput', KeyboardInterface.prototype.deadkeyOutput);
+ exportKBCallbackWithArgs('KIO', 'indexOutput', KeyboardInterface.prototype.indexOutput);
+ exportKBCallbackWithArgs('KIFS', 'ifStore', KeyboardInterface.prototype.ifStore);
+ exportKBCallbackWithArgs('KSETS', 'setStore', KeyboardInterface.prototype.setStore);
+ exportKBCallbackWithArgs('KLOAD', 'loadStore', KeyboardInterface.prototype.loadStore);
+ exportKBCallbackWithArgs('KSAVE', 'saveStore', KeyboardInterface.prototype.saveStore);
+}());
\ No newline at end of file
diff --git a/web/source/kmwbase.ts b/web/source/kmwbase.ts
index d4ae995e05..8028f6dd25 100644
--- a/web/source/kmwbase.ts
+++ b/web/source/kmwbase.ts
@@ -2,6 +2,7 @@
///
// Includes KMW-added property declaration extensions for HTML elements.
///
+///
/***
KeymanWeb 10.0
@@ -9,6 +10,8 @@
***/
declare var keyman: any
+declare var KeymanWeb: any
+
var keyman = window['keyman'] || {};
window['keyman'] = keyman; // To preserve the name _here_ in case of minification.
@@ -43,7 +46,6 @@ class KeymanBase {
deferredStubs = []; // Array of pending keyboard stubs from addKeyboard(), to register after initialization
deferredKRS = []; // Array of pending keyboard stubs from KRS, to register afterf initialization
deferredKR = []; // Array of pending keyboards, to be installed at end of initialization
- waiting = null; // Element displayed during keyboard load time
warned = false; // Warning flag (to prevent multiple warnings)
baseFont = 'sans-serif'; // Default font for mapped input elements
appliedFont = ''; // Chain of fonts to be applied to mapped input elements
@@ -74,6 +76,7 @@ class KeymanBase {
util: Util;
osk: any;
ui: any;
+ interface: KeyboardInterface;
// Defines option-tracking object as a string map.
options: { [name: string]: string; } = {
@@ -85,24 +88,13 @@ class KeymanBase {
'ui':null
};;
- // Stub functions (defined later in code only if required)
- setDefaultDeviceOptions(opt){}
- getStyleSheetPath(s){return s;}
- getKeyboardPath(f, p){return f;}
- KC_(n, ln, Pelem){return '';}
- handleRotationEvents(){}
- alignInputs(b){}
-
- setInitialized(val: number) {
- this.initialized = this['initialized'] = val;
- }
-
- refreshElementContent = null;
-
// -------------
constructor() {
this.util = this['util'] = new Util(this);
+ window['KeymanWeb'] = this.interface = this['interface'] = new KeyboardInterface(this);
+
+ this.osk = {ready:false}; // Temporary.
// Load properties from their static variants.
this.__BUILD__ = KeymanBase.__BUILD__;
@@ -128,6 +120,62 @@ class KeymanBase {
isFontAvailable(fName: string): boolean {
return this.util.checkFont({'family':fName});
}
+
+ /**
+ * Legacy entry points (non-standard names)- included only to allow existing IME keyboards to continue to be used
+ */
+ getLastActiveElement(): HTMLElement {
+ return this._LastActiveElement;
+ }
+
+ focusLastActiveElement(): void {
+ (this)._FocusLastActiveElement();
+ }
+
+ //The following entry points are defined but should not normally be used in a keyboard, as OSK display is no longer determined by the keyboard
+ hideHelp(): void {
+ this.osk._Hide(true);
+ }
+
+ showHelp(Px: number, Py: number): void {
+ this.osk._Show(Px,Py);
+ }
+
+ showPinnedHelp(): void {
+ this.osk.userPositioned=true;
+ this.osk._Show(-1,-1);
+ }
+
+ // Stub functions (defined later in code only if required)
+ setDefaultDeviceOptions(opt){}
+ getStyleSheetPath(s){return s;}
+ getKeyboardPath(f, p){return f;}
+ KC_(n, ln, Pelem){return '';}
+ handleRotationEvents(){}
+ alignInputs(b){}
+
+ /**
+ * Function _push
+ * Scope Private
+ * @param {Array} Parray Array
+ * @param {*} Pval Value to be pushed or appended to array
+ * @return {Array} Returns extended array
+ * Description Push (if possible) or append a value to an array
+ */
+ _push(Parray: T[], Pval: T) {
+ if(Parray.push) {
+ Parray.push(Pval);
+ } else {
+ Parray=Parray.concat(Pval);
+ }
+ return Parray;
+ }
+
+ setInitialized(val: number) {
+ this.initialized = this['initialized'] = val;
+ }
+
+ refreshElementContent = null;
}
/**
@@ -158,28 +206,19 @@ KeymanBase.__BUILD__ = keyman.__BUILD__;
if(!window['keyman']['loaded']) {
(function() {
+ /* We only recreate the 'keyman' object if it's not been loaded.
+ * As this is the base object, not creating it prevents a KMW system reset.
+ */
+
var keymanweb = window['keyman'] = new KeymanBase();
// Define public OSK, user interface and utility function objects
var osk: any;
- osk = keymanweb['osk'] = {ready:false};
+ osk = keymanweb['osk'];
var ui: any;
ui = keymanweb['ui'] = {};
- var kbdInterface = keymanweb['interface'] = {
- // Cross-reference with /windows/src/global/inc/Compiler.h - these are the Developer codes for the respective system stores.
- // They're named here identically to their use in that header file.
- TSS_LAYER: 33,
- TSS_PLATFORM: 31,
-
- _AnyIndices: [], // AnyIndex - array of any/index match indices
- _BeepObjects: [], // BeepObjects - maintains a list of active 'beep' visual feedback elements
- _BeepTimeout: 0, // BeepTimeout - a flag indicating if there is an active 'beep'.
- // Set to 1 if there is an active 'beep', otherwise leave as '0'.
- _DeadKeys: [] // DeadKeys - array of matched deadkeys
- };
-
osk.highlightSubKeys = function(k,x,y){}
osk.createKeyTip = function(){}
osk.optionKey = function(e,keyName,keyDown){}
diff --git a/web/source/kmwcallback.ts b/web/source/kmwcallback.ts
index 78e70d6f75..affc447446 100644
--- a/web/source/kmwcallback.ts
+++ b/web/source/kmwcallback.ts
@@ -1,53 +1,117 @@
/// // Includes KMW-added property declaration extensions for HTML elements.
/// // Includes type definitions for basic KMW types.
+///
/***
KeymanWeb 10.0
Copyright 2017 SIL International
***/
+/**
+ * Cache of context storing and retrieving return values from KC
+ * Must be reset prior to each keystroke and after any text changes
+ * MCD 3/1/14
+ **/
+class CachedContext {
+ _cache: string[][] = [];
+
+ reset(): void {
+ this._cache = [];
+ }
+
+ get(n: number, ln: number): string {
+ // return null; // uncomment this line to disable context caching
+ if(typeof this._cache[n] == 'undefined') {
+ return null;
+ } else if(typeof this._cache[n][ln] == 'undefined') {
+ return null;
+ }
+ return this._cache[n][ln];
+ }
+
+ set(n: number, ln: number, val: string): void {
+ if(typeof this._cache[n] == 'undefined') {
+ this._cache[n] = [];
+ }
+ this._cache[n][ln] = val;
+ }
+};
+
+// Defines the base Deadkey-tracking object.
+class Deadkey {
+ p: number; // Position of deadkey
+ d: number; // Numerical id of the deadkey
+ matched: number;
+
+ constructor(pos: number, id: number) {
+ this.p = pos;
+ this.d = id;
+ }
+
+ match(p: number, d: number): boolean {
+ var result:boolean = (this.p == p && this.d == d);
+ this.matched = result ? 1 : 0;
+
+ return result;
+ }
+
+ set(): void {
+ this.matched = 1;
+ }
+
+ reset(): void {
+ this.matched = 0;
+ }
+}
+
+class BeepData {
+ e: HTMLElement;
+ c: string;
+
+ constructor(e: HTMLElement) {
+ this.e = e;
+ this.c = e.style.backgroundColor;
+ }
+
+ reset(): void {
+ this.e.style.backgroundColor = this.c;
+ }
+}
+
// If KMW is already initialized, the KMW script has been loaded more than once. We wish to prevent resetting the
// KMW system, so we use the fact that 'initialized' is only 1 / true after all scripts are loaded for the initial
// load of KMW.
-if(!window['keyman']['initialized']) {
- (function() {
- // Declare KeymanWeb and util objects
- var keymanweb=window['keyman'], kbdInterface=window['KeymanWeb']=keymanweb['interface'], KeymanWeb=kbdInterface,
- util=keymanweb['util'], osk=keymanweb['osk'],device=util.device,dbg=keymanweb.debug; //osk defined here, build 350
+//if(!window['keyman']['initialized']) {
+// (function() {
- class Deadkey {
- p: number; // Position of deadkey
- d: number; // Numerical id of the deadkey
- matched: number;
+ class KeyboardInterface {
+ keymanweb: KeymanBase;
+ cachedContext: CachedContext = new CachedContext();
- constructor(pos: number, id: number) {
- this.p = pos;
- this.d = id;
- }
+ TSS_LAYER: number = 33;
+ TSS_PLATFORM: number = 31;
- match(p: number, d: number): boolean {
- var result:boolean = (this.p == p && this.d == d);
- this.matched = result ? 1 : 0;
+ _AnyIndices = []; // AnyIndex - array of any/index match indices
+ _BeepObjects: BeepData[] = []; // BeepObjects - maintains a list of active 'beep' visual feedback elements
+ _BeepTimeout: number = 0; // BeepTimeout - a flag indicating if there is an active 'beep'.
+ // Set to 1 if there is an active 'beep', otherwise leave as '0'.
+ _DeadKeys: Deadkey[] = []; // DeadKeys - array of matched deadkeys
- return result;
- }
-
- set(): void {
- this.matched = 1;
- }
-
- reset(): void {
- this.matched = 0;
- }
+ constructor(kmw: KeymanBase) {
+ this.keymanweb = kmw;
}
+ // // Declare KeymanWeb and util objects
+ // var keymanweb=window['keyman'], kbdInterface=window['KeymanWeb']=keymanweb['interface'], KeymanWeb=kbdInterface,
+ // util=keymanweb['util'], osk=keymanweb['osk'],device=util.device,dbg=keymanweb.debug; //osk defined here, build 350
+
/**
* Function KSF
* Scope Public
* Description Save keyboard focus
*/
- KeymanWeb['KSF'] = kbdInterface['saveFocus'] = kbdInterface.saveFocus = function(): void {
- keymanweb._IgnoreNextSelChange = 1;
+ saveFocus(): void {
+ this.keymanweb._IgnoreNextSelChange = 1;
}
/**
@@ -58,19 +122,19 @@ if(!window['keyman']['initialized']) {
* @return {boolean} true if inserted
* Description Insert text into active control
*/
- KeymanWeb['KT'] = kbdInterface['insertText'] = kbdInterface.insertText = function(Ptext: string, PdeadKey:number): boolean {
- kbdInterface.resetContextCache();
+ insertText(Ptext: string, PdeadKey:number): boolean {
+ this.resetContextCache();
//_DebugEnter('InsertText');
- var Lelem = keymanweb._LastActiveElement, Ls, Le, Lkc, Lsel, Lv=false;
+ var Lelem = this.keymanweb._LastActiveElement, Ls, Le, Lkc, Lsel, Lv=false;
if(Lelem != null) {
Ls=Lelem._KeymanWebSelectionStart;
Le=Lelem._KeymanWebSelectionEnd;
- Lsel=keymanweb._Selection;
+ Lsel=this.keymanweb._Selection;
- keymanweb._IsActivatingKeymanWebUI = 1;
- keymanweb._IgnoreNextSelChange = 100;
- keymanweb._FocusLastActiveElement();
- if(keymanweb._IsMozillaEditableIframe(Lelem,0)) {
+ this.keymanweb._IsActivatingKeymanWebUI = 1;
+ this.keymanweb._IgnoreNextSelChange = 100;
+ (this.keymanweb)._FocusLastActiveElement();
+ if((this.keymanweb)._IsMozillaEditableIframe(Lelem,0)) {
Lelem = Lelem.documentElement; // I3363 (Build 301)
}
if(document.selection && Lsel != null) {
@@ -78,12 +142,12 @@ if(!window['keyman']['initialized']) {
}
Lelem._KeymanWebSelectionStart=Ls;
Lelem._KeymanWebSelectionEnd=Le;
- keymanweb._IgnoreNextSelChange = 0;
+ this.keymanweb._IgnoreNextSelChange = 0;
if(Ptext!=null) {
- kbdInterface.output(0, Lelem, Ptext);
+ this.output(0, Lelem, Ptext);
}
if((typeof(PdeadKey)!=='undefined') && (PdeadKey !== null)) {
- kbdInterface.deadkeyOutput(0, Lelem, PdeadKey);
+ this.deadkeyOutput(0, Lelem, PdeadKey);
}
Lelem._KeymanWebSelectionStart=null;
Lelem._KeymanWebSelectionEnd=null;
@@ -99,49 +163,49 @@ if(!window['keyman']['initialized']) {
* @param {Object} Pk Keyboard object
* Description Register and load the keyboard
*/
- KeymanWeb['KR'] = kbdInterface['registerKeyboard'] = kbdInterface.registerKeyboard = function(Pk): void {
+ registerKeyboard(Pk): void {
// If initialization not yet complete, list the keyboard to be registered on completion of initialization
- if(!keymanweb['initialized']) {
- keymanweb.deferredKR.push(Pk); return;
+ if(!this.keymanweb['initialized']) {
+ this.keymanweb.deferredKR.push(Pk); return;
}
var Li,Lstub;
// Check if the active stub refers to this keyboard, else find applicable stub
- var Ps=keymanweb._ActiveStub, savedActiveStub = keymanweb._ActiveStub;
+ var Ps=this.keymanweb._ActiveStub, savedActiveStub = this.keymanweb._ActiveStub;
if(!Ps || !('KI' in Ps) || (Ps['KI'] != Pk['KI'])) {
// Find the first stub for this keyboard
- for(Lstub=0;Lstub < keymanweb._KeyboardStubs.length; Lstub++) { // I1511 - array prototype extended
- Ps=keymanweb._KeyboardStubs[Lstub];
+ for(Lstub=0;Lstub < this.keymanweb._KeyboardStubs.length; Lstub++) { // I1511 - array prototype extended
+ Ps=this.keymanweb._KeyboardStubs[Lstub];
if(Pk['KI'] == Ps['KI'])break;
Ps=null;
}
}
// Build 369: ensure active stub defined when loading local keyboards
- if(keymanweb._ActiveStub == null && Ps != null) {
- keymanweb._ActiveStub = Ps;
+ if(this.keymanweb._ActiveStub == null && Ps != null) {
+ this.keymanweb._ActiveStub = Ps;
}
// Register the stub for this language (unless it is already registered)
// keymanweb.KRS(Ps?Ps:Pk);
// Test if keyboard already loaded
- for(Li=0; Lithis.keymanweb).doKeyboardLoaded(Pk['KI']);
// Restore the originally-active stub to its prior state. No need to change it permanently.
- keymanweb._ActiveStub = savedActiveStub;
+ this.keymanweb._ActiveStub = savedActiveStub;
}
/**
@@ -154,18 +218,18 @@ if(!window['keyman']['initialized']) {
* @return {?number} 1 if already registered, else null
*/
//var ts0=new Date().toTimeString().substr(3,5);
- KeymanWeb['KRS'] = kbdInterface['registerStub'] = kbdInterface.registerStub = function(Pstub): number {
+ registerStub(Pstub): number {
var Lk;
// In initialization not complete, list the stub to be registered on completion of initialization
- if(!keymanweb['initialized']) {
- keymanweb.deferredKRS.push(Pstub);
+ if(!this.keymanweb['initialized']) {
+ this.keymanweb.deferredKRS.push(Pstub);
return null;
}
// The default stub is always the first keyboard stub loaded [and will be ignored by desktop browsers - not for beta, anyway]
- if(keymanweb.dfltStub == null) {
- keymanweb.dfltStub=Pstub;
+ if(this.keymanweb.dfltStub == null) {
+ this.keymanweb.dfltStub=Pstub;
//if(device.formFactor == 'desktop') return 1; //Needs further thought before release
}
@@ -181,23 +245,23 @@ if(!window['keyman']['initialized']) {
}
// If language code already defined (or not specified in stub), check to see if stub already registered
- for(Lk=0; Lkthis.keymanweb).doKeyboardRegistered(Pstub['KI'],Pstub['KL'],Pstub['KN'],Pstub['KLC'],Pstub['KP']);
return null;
}
@@ -216,14 +280,14 @@ if(!window['keyman']['initialized']) {
* KC(10,10,Pelem) == "abcdef" i.e. return as much as possible of the requested string
*/
- KeymanWeb['KC'] = kbdInterface['context'] = kbdInterface.context = function(n: number, ln:number, Pelem:HTMLElement): string {
- var v = kbdInterface.cachedContext.get(n, ln);
+ context(n: number, ln:number, Pelem:HTMLElement): string {
+ var v = this.cachedContext.get(n, ln);
if(v !== null) {
return v;
}
- var r = keymanweb.KC_(n, ln, Pelem);
- kbdInterface.cachedContext.set(n, ln, r);
+ var r = this.keymanweb.KC_(n, ln, Pelem);
+ this.cachedContext.set(n, ln, r);
return r;
}
@@ -240,8 +304,8 @@ if(!window['keyman']['initialized']) {
* KN(2,Pelem) == FALSE
* KN(4,Pelem) == TRUE
*/
- KeymanWeb['KN'] = kbdInterface['nul'] = kbdInterface.nul = function(n:number, Ptarg:HTMLElement): boolean {
- var cx=kbdInterface.context(n+1, 1, Ptarg);
+ nul(n: number, Ptarg: HTMLElement): boolean {
+ var cx=this.context(n+1, 1, Ptarg);
// With #31, the result will be a replacement character if context is empty.
return cx === "\uFFFE";
@@ -257,14 +321,13 @@ if(!window['keyman']['initialized']) {
* @return {boolean} True if selected context matches val
* Description Test keyboard context for match
*/
- KeymanWeb['KCM'] = kbdInterface['contextMatch'] = kbdInterface.contextMatch =
- function(n:number, Ptarg:HTMLElement, val:string, ln:number): boolean {
+ contextMatch(n: number, Ptarg: HTMLElement, val: string, ln: number): boolean {
//KeymanWeb._Debug('KeymanWeb.KCM(n='+n+', Ptarg, val='+val+', ln='+ln+'): return '+(kbdInterface.context(n,ln,Ptarg)==val));
- var cx=kbdInterface.context(n, ln, Ptarg);
+ var cx=this.context(n, ln, Ptarg);
if(cx === val) {
return true; // I3318
}
- kbdInterface._DeadkeyResetMatched(); // I3318
+ this._DeadkeyResetMatched(); // I3318
return false;
}
@@ -275,11 +338,11 @@ if(!window['keyman']['initialized']) {
* @return {boolean} true if keypress event
* Description Test if event as a keypress event
*/
- KeymanWeb['KIK'] = kbdInterface['isKeypress'] = kbdInterface.isKeypress = function(e: KeyEvent):boolean {
- if(keymanweb._ActiveKeyboard['KM']) { // I1380 - support KIK for positional layouts
+ isKeypress(e: KeyEvent):boolean {
+ if(this.keymanweb._ActiveKeyboard['KM']) { // I1380 - support KIK for positional layouts
return !e.LisVirtualKey; // will now return true for U_xxxx keys, but not for T_xxxx keys
} else {
- return keymanweb._USKeyCodeToCharCode(e) ? true : false; // I1380 - support KIK for positional layouts
+ return (this.keymanweb)._USKeyCodeToCharCode(e) ? true : false; // I1380 - support KIK for positional layouts
}
}
@@ -292,12 +355,11 @@ if(!window['keyman']['initialized']) {
* @return {boolean} True if key matches rule
* Description Test keystroke with modifiers against rule
*/
- KeymanWeb['KKM'] = kbdInterface['keyMatch'] = kbdInterface.keyMatch =
- function(e: KeyEvent, Lruleshift:number, Lrulekey:number): boolean {
+ keyMatch(e: KeyEvent, Lruleshift:number, Lrulekey:number): boolean {
var retVal = false; // I3318
var keyCode = (e.Lcode == 173 ? 189 : e.Lcode); //I3555 (Firefox hyphen issue)
- var bitmask = keymanweb.getKeyboardModifierBitmask();
+ var bitmask = (this.keymanweb).getKeyboardModifierBitmask();
if(e.vkCode > 255) {
keyCode = e.vkCode; // added to support extended (touch-hold) keys for mnemonic layouts
@@ -311,7 +373,7 @@ if(!window['keyman']['initialized']) {
retVal = (keyCode == Lrulekey); // I3318, I3555
}
if(!retVal) {
- kbdInterface._DeadkeyResetMatched(); // I3318
+ this._DeadkeyResetMatched(); // I3318
}
return retVal; // I3318
};
@@ -323,7 +385,7 @@ if(!window['keyman']['initialized']) {
* @param {number} Lstate
* Description Test keystroke against state key rules
*/
- KeymanWeb['KSM'] = kbdInterface['stateMatch'] = kbdInterface.stateMatch = function(e: KeyEvent, Lstate:number) {
+ stateMatch(e: KeyEvent, Lstate: number) {
return ((Lstate & e.Lstates) == Lstate);
}
@@ -334,7 +396,7 @@ if(!window['keyman']['initialized']) {
* @return {Object} Object with event's virtual key flag, key code, and modifiers
* Description Get object with extended key event information
*/
- KeymanWeb['KKI'] = kbdInterface['keyInformation'] = kbdInterface.keyInformation = function(e: KeyEvent): KeyInformation {
+ keyInformation(e: KeyEvent): KeyInformation {
var ei = new KeyInformation();
ei['vk'] = e.LisVirtualKey;
ei['code'] = e.Lcode;
@@ -351,21 +413,20 @@ if(!window['keyman']['initialized']) {
* @return {boolean} True if deadkey found selected context matches val
* Description Match deadkey at current cursor position
*/
- KeymanWeb['KDM'] = kbdInterface['deadkeyMatch'] = kbdInterface.deadkeyMatch =
- function(n: number, Ptarg: HTMLElement, d: number): boolean {
- if(kbdInterface._DeadKeys.length == 0) {
+ deadkeyMatch(n: number, Ptarg: HTMLElement, d: number): boolean {
+ if(this._DeadKeys.length == 0) {
return false; // I3318
}
- var sp=keymanweb._SelPos(Ptarg);
+ var sp=(this.keymanweb)._SelPos(Ptarg);
n = sp - n;
- for(var i = 0; i < kbdInterface._DeadKeys.length; i++) {
- if(kbdInterface._DeadKeys[i].match(n, d)) {
- kbdInterface._DeadKeys[i].set();
+ for(var i = 0; i < this._DeadKeys.length; i++) {
+ if(this._DeadKeys[i].match(n, d)) {
+ this._DeadKeys[i].set();
return true; // I3318
}
}
- kbdInterface._DeadkeyResetMatched(); // I3318
+ this._DeadkeyResetMatched(); // I3318
return false;
}
@@ -375,15 +436,15 @@ if(!window['keyman']['initialized']) {
* Scope Public
* Description Reset/terminate beep or flash (not currently used: Aug 2011)
*/
- KeymanWeb['KBR'] = kbdInterface['beepReset'] = kbdInterface.beepReset = function(): void {
- kbdInterface.resetContextCache();
+ beepReset(): void {
+ this.resetContextCache();
var Lbo;
- kbdInterface._BeepTimeout = 0;
- for(Lbo=0;Lbo= 0;
}
@@ -444,12 +505,12 @@ if(!window['keyman']['initialized']) {
* @param {string} s string to output
* Description Keyboard output
*/
- KeymanWeb['KO'] = kbdInterface['output'] = kbdInterface.output = function(dn: number, Pelem, s:string): void {
- kbdInterface.resetContextCache();
+ output(dn: number, Pelem, s:string): void {
+ this.resetContextCache();
// KeymanTouch for Android uses direct insertion of the character string
- if('oninserttext' in keymanweb) {
- keymanweb['oninserttext'](dn,s);
+ if('oninserttext' in this.keymanweb) {
+ this.keymanweb['oninserttext'](dn,s);
}
if(Pelem.body) {
@@ -460,13 +521,13 @@ if(!window['keyman']['initialized']) {
var Li, Ldv;
if(Pelem.className.indexOf('keymanweb-input') >= 0) {
- var t=keymanweb.getTextBeforeCaret(Pelem);
+ var t=(this.keymanweb).getTextBeforeCaret(Pelem);
if(dn > 0) {
t=t._kmwSubstr(0,t._kmwLength()-dn)+s;
} else {
t=t+s;
}
- keymanweb.setTextBeforeCaret(Pelem,t);
+ (this.keymanweb).setTextBeforeCaret(Pelem,t);
return;
}
@@ -476,7 +537,7 @@ if(!window['keyman']['initialized']) {
/* Editable iframe and contentEditable elements for mozilla */
var _IsEditableIframe = Ldoc.designMode.toLowerCase() == 'on';
if(_IsEditableIframe) {
- var _CacheableCommands = kbdInterface._CacheCommands(Ldoc);
+ var _CacheableCommands = this._CacheCommands(Ldoc);
}
var Lsel = Ldv.getSelection();
@@ -520,19 +581,19 @@ if(!window['keyman']['initialized']) {
}
if(_IsEditableIframe) {
- kbdInterface._CacheCommandsReset(Ldoc, _CacheableCommands, null);// I2457 - support contentEditable elements in mozilla, webkit
+ this._CacheCommandsReset(Ldoc, _CacheableCommands, null);// I2457 - support contentEditable elements in mozilla, webkit
}
Lsel.collapseToEnd();
// Adjust deadkey positions
if(dn >= 0) {
- kbdInterface._DeadkeyDeleteMatched(); // I3318
- kbdInterface._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318
+ this._DeadkeyDeleteMatched(); // I3318
+ this._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318
} // Internet Explorer (including IE9)
} else if(Ldoc && (Ldv=Ldoc.selection)) { // build 77 - use elem.ownerDocument.selection
if(Ldoc.body.isContentEditable || Ldoc.designMode.toLowerCase()=='on') { // I1295 - isContentEditable
- var _CacheableCommands = kbdInterface._CacheCommands(Ldoc);
+ var _CacheableCommands = this._CacheCommands(Ldoc);
}
var Lrange = Ldv.createRange(), Ls1;
@@ -557,7 +618,7 @@ if(!window['keyman']['initialized']) {
if(Ldoc.body.isContentEditable || Ldoc.designMode.toLowerCase()=='on') { // I1295 - isContentEditable
Lrange.moveStart('character',-s.length);
- kbdInterface._CacheCommandsReset(Ldoc, _CacheableCommands,Lrange.select);
+ this._CacheCommandsReset(Ldoc, _CacheableCommands,Lrange.select);
Lrange.moveStart('character',s.length);
Lrange.select();
}
@@ -571,13 +632,13 @@ if(!window['keyman']['initialized']) {
LselectionStart = Pelem.value._kmwCodeUnitToCodePoint(Pelem.selectionStart); // I3319
}
- kbdInterface._DeadkeyDeleteMatched(); // I3318
- kbdInterface._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318
+ this._DeadkeyDeleteMatched(); // I3318
+ this._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318
}
- keymanweb._Selection = Ldv.createRange();
- keymanweb._Selection.select();
- keymanweb._Selection.scrollIntoView();
+ this.keymanweb._Selection = Ldv.createRange();
+ this.keymanweb._Selection.select();
+ this.keymanweb._Selection.scrollIntoView();
// Mozilla et al; IE9+ also recognizes setSelectionRange, but does not seem to work in exactly the same way as Mozilla
} else if (Pelem.setSelectionRange) {
var LselectionStart, LselectionEnd;
@@ -606,8 +667,8 @@ if(!window['keyman']['initialized']) {
// Adjust deadkey positions
if(dn >= 0) {
- kbdInterface._DeadkeyDeleteMatched(); // I3318
- kbdInterface._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318,I3319
+ this._DeadkeyDeleteMatched(); // I3318
+ this._DeadkeyAdjustPos(LselectionStart, -dn + s._kmwLength()); // I3318,I3319
}
if (typeof(LscrollTop) != 'undefined') {
@@ -622,8 +683,8 @@ if(!window['keyman']['initialized']) {
}
// Refresh element content after change (if needed)
- if(typeof(keymanweb.refreshElementContent) == 'function') {
- keymanweb.refreshElementContent(Pelem);
+ if(typeof(this.keymanweb.refreshElementContent) == 'function') {
+ this.keymanweb.refreshElementContent(Pelem);
}
}
@@ -635,16 +696,16 @@ if(!window['keyman']['initialized']) {
* @param {number} Pd deadkey id
* Description Record a deadkey at current cursor position, deleting Pdn characters first
*/
- KeymanWeb['KDO'] = kbdInterface['deadkeyOutput'] = kbdInterface.deadkeyOutput = function(Pdn: number, Pelem: HTMLElement, Pd: number): void {
- kbdInterface.resetContextCache();
+ deadkeyOutput(Pdn: number, Pelem: HTMLElement, Pd: number): void {
+ this.resetContextCache();
if(Pdn >= 0) {
- kbdInterface.output(Pdn,Pelem,""); //I3318 corrected to >=
+ this.output(Pdn,Pelem,""); //I3318 corrected to >=
}
- var Lc: Deadkey = new Deadkey(keymanweb._SelPos(Pelem), Pd);
+ var Lc: Deadkey = new Deadkey((this.keymanweb)._SelPos(Pelem), Pd);
- kbdInterface._DeadKeys=keymanweb._push(kbdInterface._DeadKeys,Lc);
+ this._DeadKeys=this.keymanweb._push(this._DeadKeys,Lc);
// _DebugDeadKeys(Pelem, 'KDeadKeyOutput: dn='+Pdn+'; deadKey='+Pd);
}
@@ -657,11 +718,10 @@ if(!window['keyman']['initialized']) {
* @param {Object} Pelem element to output to
* Description Output a character selected from the string according to the offset in the index array
*/
- KeymanWeb['KIO'] = kbdInterface['indexOutput'] = kbdInterface.indexOutput =
- function(Pdn:number, Ps:string, Pn:number, Pelem:HTMLElement): void {
- kbdInterface.resetContextCache();
- if(kbdInterface._AnyIndices[Pn-1] < Ps._kmwLength()) { //I3319
- kbdInterface.output(Pdn,Pelem,Ps._kmwCharAt(kbdInterface._AnyIndices[Pn-1])); //I3319
+ indexOutput(Pdn: number, Ps: string, Pn: number, Pelem: HTMLElement): void {
+ this.resetContextCache();
+ if(this._AnyIndices[Pn-1] < Ps._kmwLength()) { //I3319
+ this.output(Pdn,Pelem,Ps._kmwCharAt(this._AnyIndices[Pn-1])); //I3319
}
}
@@ -672,7 +732,7 @@ if(!window['keyman']['initialized']) {
* @return {Array.} List of style commands that are cacheable
* Description Build reate list of styles that can be applied in iframes
*/
- kbdInterface._CacheCommands = function(_Document: Document): StyleCommand[] { // I1204 - style application in IFRAMEs, I2192, I2134, I2192
+ private _CacheCommands = function(_Document: Document): StyleCommand[] { // I1204 - style application in IFRAMEs, I2192, I2134, I2192
//var _CacheableBackColor=(_Document.selection?'hilitecolor':'backcolor');
var _CacheableCommands=[
@@ -682,12 +742,12 @@ if(!window['keyman']['initialized']) {
new StyleCommand('superscript',0), new StyleCommand('underline',0)
];
if(_Document.defaultView) {
- keymanweb._push(_CacheableCommands,['hilitecolor',1]);
+ this.keymanweb._push(_CacheableCommands,['hilitecolor',1]);
}
for(var n=0;n < _CacheableCommands.length; n++) { // I1511 - array prototype extended
//KeymanWeb._Debug('Command:'+_CacheableCommands[n][0]);
- keymanweb._push(_CacheableCommands[n], _CacheableCommands[n][1] ?
+ this.keymanweb._push(_CacheableCommands[n], _CacheableCommands[n][1] ?
_Document.queryCommandValue(_CacheableCommands[n][0]) :
_Document.queryCommandState(_CacheableCommands[n][0]));
}
@@ -702,7 +762,7 @@ if(!window['keyman']['initialized']) {
* _func
* Description Restore styles in IFRAMEs (??)
*/
- kbdInterface._CacheCommandsReset = function(_Document: HTMLDocument, _CacheableCommands: StyleCommand[], _func: () => void): void {
+ private _CacheCommandsReset = function(_Document: HTMLDocument, _CacheableCommands: StyleCommand[], _func: () => void): void {
for(var n=0;n < _CacheableCommands.length; n++) { // I1511 - array prototype extended
//KeymanWeb._Debug('ResetCacheCommand:'+_CacheableCommands[n][0]+'='+_CacheableCommands[n][2]);
if(_CacheableCommands[n][1]) {
@@ -730,19 +790,18 @@ if(!window['keyman']['initialized']) {
* @param {Object} Pelem Currently active element (may be needed by future tests)
* @return {boolean} True if the test succeeds
*/
- KeymanWeb['KIFS'] = kbdInterface['ifStore'] = kbdInterface.ifStore =
- function(systemId: number, strValue:string, Pelem: HTMLElement): boolean {
+ ifStore(systemId: number, strValue: string, Pelem: HTMLElement): boolean {
var result=true;
- if(systemId == kbdInterface.TSS_LAYER) {
- result = (osk.layerId === strValue);
- } else if(systemId == kbdInterface.TSS_PLATFORM) {
+ if(systemId == this.TSS_LAYER) {
+ result = (this.keymanweb.osk.layerId === strValue);
+ } else if(systemId == this.TSS_PLATFORM) {
var i,constraint,constraints=strValue.split(' ');
for(i=0; i_Dk[Li]).reset();
}
@@ -923,8 +925,8 @@ if(!window['keyman']['initialized']) {
* Scope Private
* Description Delete matched deadkeys from context
*/
- kbdInterface._DeadkeyDeleteMatched = function(): void {
- var Li, _Dk = kbdInterface._DeadKeys;
+ _DeadkeyDeleteMatched(): void {
+ var Li, _Dk = this._DeadKeys;
for(Li = 0; Li < _Dk.length; Li++) {
if(_Dk[Li].matched) {
_Dk.splice(Li,1);
@@ -939,8 +941,8 @@ if(!window['keyman']['initialized']) {
* @param {number} Ldelta characters to adjust by
* Description Adjust saved positions of deadkeys in context
*/
- kbdInterface._DeadkeyAdjustPos = function(Lstart: number, Ldelta: number): void {
- var Li, _Dk = kbdInterface._DeadKeys;
+ _DeadkeyAdjustPos(Lstart: number, Ldelta: number): void {
+ var Li, _Dk = this._DeadKeys;
for(Li = 0; Li < _Dk.length; Li++) {
if(_Dk[Li].p > Lstart) {
_Dk[Li].p += Ldelta;
@@ -948,8 +950,8 @@ if(!window['keyman']['initialized']) {
}
}
- kbdInterface.clearDeadkeys = function(): void {
- kbdInterface._DeadKeys = [];
+ clearDeadkeys = function(): void {
+ this._DeadKeys = [];
}
// I3318 - deadkey changes END
@@ -962,19 +964,20 @@ if(!window['keyman']['initialized']) {
* Description Encapsulates calls to keyboard input processing.
* @returns {number} 0 if no match is made, otherwise 1.
*/
- kbdInterface.processKeystroke = function(device, element: HTMLElement, keystroke:KeyEvent) {
+ processKeystroke = function(device, element: HTMLElement, keystroke:KeyEvent) {
// Clear internal state tracking data from prior keystrokes.
- keymanweb._CachedSelectionStart = null; // I3319
- kbdInterface._DeadkeyResetMatched(); // I3318
- kbdInterface.resetContextCache();
+ this.keymanweb._CachedSelectionStart = null; // I3319
+ this._DeadkeyResetMatched(); // I3318
+ this.resetContextCache();
// Ensure the settings are in place so that KIFS/ifState activates and deactivates
// the appropriate rule(s) for the modeled device.
- util.activeDevice = device;
+ this.keymanweb.util.activeDevice = device;
// Calls the start-group of the active keyboard.
- return keymanweb._ActiveKeyboard['gs'](element, keystroke);
+ return this.keymanweb._ActiveKeyboard['gs'](element, keystroke);
}
-
- })();
-}
+
+ }
+// })();
+//}
diff --git a/web/source/kmwnative.ts b/web/source/kmwnative.ts
index dbf97cb04b..2326f1cf4f 100644
--- a/web/source/kmwnative.ts
+++ b/web/source/kmwnative.ts
@@ -40,7 +40,7 @@ if(!window['keyman']['initialized']) {
// Keyboards loaded with page are initialized before the page is ready,
// so cannot use the wait indicater (and don't need it, anyway)
// Do not display if a blocking cloud server error has occurred (to prevent multiple errors)
- var bg=keymanweb.waiting;
+ var bg=this.waiting;
if(typeof(bg) == 'undefined' || bg == null || keymanweb.warned) {
return;
}
diff --git a/web/source/kmwutils.ts b/web/source/kmwutils.ts
index 19a859550d..74d6a4bba0 100644
--- a/web/source/kmwutils.ts
+++ b/web/source/kmwutils.ts
@@ -108,8 +108,11 @@ class Device {
class Util {
// Generalized component event registration
device: Device;
+ activeDevice: Device;
physicalDevice: Device;
+ waiting: HTMLDivElement; // The element displayed for util.wait and util.alert.
+
// An object mapping event names to individual event lists. Maps strings to arrays.
private events: { [name: string]: ((Object) => boolean)[];} = {};
private currentEvents: string[] = []; // The event messaging call stack.
@@ -129,6 +132,7 @@ class Util {
initDevices(): void {
this.device = new Device();
this.physicalDevice = new Device();
+ this.activeDevice = this.device;
// Initialize the true device values.
this.device.detect(this._GetIEVersion());
@@ -1108,11 +1112,12 @@ class Util {
* @param {function()=} fn function to call when alert dismissed
*/
alert(s: string, fn: () => void): void {
- var bg = this.keyman.waiting, nn=bg.firstChild.childNodes;
- nn[0].style.display='block';
- nn[1].className='kmw-alert-text';
- nn[1].innerHTML=s;
- nn[2].style.display='none';
+ var bg = this.waiting;
+ var nn=bg.firstChild.childNodes;
+ (nn[0]).style.display='block';
+ (nn[1]).className='kmw-alert-text';
+ (nn[1]).innerHTML=s;
+ (nn[2]).style.display='none';
bg.style.display='block';
if(arguments.length > 1) {
bg.dismiss=fn;
@@ -1126,7 +1131,7 @@ class Util {
* Should not be called before options are defined during initialization
**/
prepareWait(): void {
- var bg=document.createElement('DIV'),
+ var bg: HTMLDivElement = document.createElement('DIV'),
lb=document.createElement('DIV'),
lt=document.createElement('DIV'),
gr=document.createElement('DIV'),
@@ -1162,7 +1167,7 @@ class Util {
lb.appendChild(gr);
bg.appendChild(lb);
document.body.appendChild(bg);
- this.keyman.waiting=bg;
+ this.waiting=bg;
}
/**
diff --git a/web/source/tsconfig.embedded.json b/web/source/tsconfig.embedded.json
index 5de062ac51..02c0155189 100644
--- a/web/source/tsconfig.embedded.json
+++ b/web/source/tsconfig.embedded.json
@@ -11,6 +11,7 @@
"kmwcallback.ts",
"kmwkeymaps.ts",
"kmwlayout.ts",
- "kmwinit.ts"
+ "kmwinit.ts",
+ "kmwapi.ts"
]
}