From ca666ca9c1cb081b1b932342c6360228862d579b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 23 Mar 2026 09:41:59 +0100 Subject: [PATCH 01/18] chore: purge irrelevant old content --- TODO.md | 62 + account/home/cloud/index.php | 4 - account/home/index.php | 4 - account/home/profile/index.php | 4 - account/index.php | 4 - customer/2014-11-ephrem/geez9-1.0.js | 1846 -------- customer/2014-11-ephrem/geez9-1.0.json | 17 - customer/2014-11-ephrem/index.html | 106 - .../2014-11-ephrem/keymanweb/keymanweb.js | 3994 ----------------- customer/2014-11-ephrem/keymanweb/kmwbase.js | 1299 ------ .../2014-11-ephrem/keymanweb/kmwcallback.js | 897 ---- customer/2014-11-ephrem/keymanweb/kmwdebug.js | 249 - .../2014-11-ephrem/keymanweb/kmwdebugstub.js | 28 - customer/2014-11-ephrem/keymanweb/kmwinit.js | 44 - .../2014-11-ephrem/keymanweb/kmwkeymaps.js | 172 - .../2014-11-ephrem/keymanweb/kmwlayout.js | 307 -- .../2014-11-ephrem/keymanweb/kmwlegacy.js | 877 ---- .../2014-11-ephrem/keymanweb/kmwnative.js | 458 -- customer/2014-11-ephrem/keymanweb/kmwosk.js | 3745 ---------------- .../keymanweb/kmwreleasestub.js | 213 - .../2014-11-ephrem/keymanweb/kmwstring.js | 439 -- .../2014-11-ephrem/keymanweb/kmwuibutton.js | 585 --- .../2014-11-ephrem/keymanweb/kmwuifloat.js | 553 --- .../2014-11-ephrem/keymanweb/kmwuitoggle.js | 743 --- .../2014-11-ephrem/keymanweb/kmwuitoolbar.js | 1149 ----- .../keymanweb/resources/osk/ajax-loader.gif | Bin 10819 -> 0 bytes .../keymanweb/resources/osk/keymanweb-osk.eot | Bin 23807 -> 0 bytes .../keymanweb/resources/osk/keymanweb-osk.ttf | Bin 25644 -> 0 bytes .../resources/osk/keymanweb-osk.woff | Bin 17944 -> 0 bytes .../keymanweb/resources/osk/kmwosk.css | 198 - .../keymanweb/resources/ui/button/kbdicon.gif | Bin 1036 -> 0 bytes .../resources/ui/button/kmw_button.gif | Bin 1093 -> 0 bytes .../keymanweb/resources/ui/float/kbdicon.gif | Bin 1036 -> 0 bytes .../keymanweb/resources/ui/float/kmicon.gif | Bin 976 -> 0 bytes .../keymanweb/resources/ui/ios/kbdicon.png | Bin 180 -> 0 bytes .../keymanweb/resources/ui/toggle/kbdicon.gif | Bin 1036 -> 0 bytes .../resources/ui/toggle/kmw_logo_16.gif | Bin 1077 -> 0 bytes .../resources/ui/toggle/kmw_logo_16_down.gif | Bin 1105 -> 0 bytes .../resources/ui/toggle/kmw_osk_16.gif | Bin 932 -> 0 bytes .../resources/ui/toggle/kmwcontroller2.gif | Bin 1053 -> 0 bytes .../resources/ui/toggle/kmwcontroller2x.gif | Bin 1074 -> 0 bytes .../keymanweb/resources/ui/toolbar/blank.gif | Bin 807 -> 0 bytes .../resources/ui/toolbar/kmwuitoolbar.css | 521 --- .../resources/ui/toolbar/toolbar.gif | Bin 3250 -> 0 bytes .../keymanweb/resources/ui/toolbar/world.png | Bin 49366 -> 0 bytes fb/index.php | 4 - prog/jira.php | 33 - prog/test-uninstall.php | 47 - prog/uninstall.php | 45 - prog/uninstall2.php | 50 - uninstall/index.php | 68 - 51 files changed, 62 insertions(+), 18703 deletions(-) create mode 100644 TODO.md delete mode 100644 account/home/cloud/index.php delete mode 100644 account/home/index.php delete mode 100644 account/home/profile/index.php delete mode 100644 account/index.php delete mode 100644 customer/2014-11-ephrem/geez9-1.0.js delete mode 100644 customer/2014-11-ephrem/geez9-1.0.json delete mode 100644 customer/2014-11-ephrem/index.html delete mode 100644 customer/2014-11-ephrem/keymanweb/keymanweb.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwbase.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwcallback.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwdebug.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwdebugstub.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwinit.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwkeymaps.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwlayout.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwlegacy.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwnative.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwosk.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwreleasestub.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwstring.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwuibutton.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwuifloat.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwuitoggle.js delete mode 100644 customer/2014-11-ephrem/keymanweb/kmwuitoolbar.js delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/osk/ajax-loader.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/osk/keymanweb-osk.eot delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/osk/keymanweb-osk.ttf delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/osk/keymanweb-osk.woff delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/osk/kmwosk.css delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/button/kbdicon.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/button/kmw_button.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/float/kbdicon.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/float/kmicon.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/ios/kbdicon.png delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kbdicon.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kmw_logo_16.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kmw_logo_16_down.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kmw_osk_16.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kmwcontroller2.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toggle/kmwcontroller2x.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toolbar/blank.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toolbar/kmwuitoolbar.css delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toolbar/toolbar.gif delete mode 100644 customer/2014-11-ephrem/keymanweb/resources/ui/toolbar/world.png delete mode 100644 fb/index.php delete mode 100644 prog/jira.php delete mode 100644 prog/test-uninstall.php delete mode 100644 prog/uninstall.php delete mode 100644 prog/uninstall2.php delete mode 100644 uninstall/index.php diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..c2ba0a5c --- /dev/null +++ b/TODO.md @@ -0,0 +1,62 @@ +Other tasks: + +* PHP upgrade to 8.x +* localizing markdown files + + +Questions for url scheme: + +* URL scheme - very little overlap with langtags (/cdn) +* How do we lay out files in the repo? +* How do we manage relative links? + + +keyman.com/windows --> has link to /linux + +keyman.com/en/windows --> /en/linux +keyman.com/de/windows --> /de/linux + +navigate to keyman.com/linux ->> keyman.com/de/linux (based on geography or by browser lang tag info, by default) + +keyman.com/km/linux --> selects 'km' language, stays there. + + +Fallback? + keyman.com/de/windows --> if no fallback available, use en content, and maybe have a banner saying 'content not yet available in German, please help us translate this!' + + +* transition from existing links? must ensure we have redirections (e.g. /windows --> /en/windows) +* canonical links? +* links embedded in pages on keyman.com: + * should be using relative rather than absolute links (i.e. ../windows rather than /windows) + * Link types: + * dynamic by Javascript + * dynamic links from api.keyman.com data + * dynamic by PHP script / static in HTML (91 .php files) + * static in Markdown (39 files) + * .htaccess redirects and rewrites (16 files) +* external links from other keyman.com sites +* external links from other sites --> should be handled by redirections + + +One plan: +* Move all content pages into a subfolder, including root index.php, e.g. '_content'. All folders except `_common`, `_...`, `.github`, `.well-known`, `cdn`, and `go`, (`resources` and others!) as a starting point. +* In the top-level .htaccess, split out redirects from markdown/php/file extension handling +* Add rewrites for all content pages, to, e.g.: + 1. redirect /windows -> //windows (initially, always redirect to /en/windows) + This could be a static redirect map for the known pages (similar to # per-language landing pages in /.htaccess) + 2. rewrite //windows to /_content/windows?lang= --> redesigning the PHP and Markdown rewriting section of .htaccess to work with localization. + + PSEUDOCODE: + + # Rewrite //... + RewriteCond "$1" !-f + RewriteCond "$1" !-d + RewriteRule "^/([a-z][a-z])/(.+)$/" "/_content/$2?lang=$1" [??? include query string, last] + + Perhaps `([a-z][a-z])` should be a better quality match, e.g. exclude known strings such as cdn,web,go,...? + + 3. rewrite for .md would embed the lang parameter and the appropriate _content path also. + +* Fixup absolute links in _content/ files to relative links +* Fixup absolute links in header files to relative links (make a helper function?) diff --git a/account/home/cloud/index.php b/account/home/cloud/index.php deleted file mode 100644 index cd8b83bf..00000000 --- a/account/home/cloud/index.php +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/account/home/index.php b/account/home/index.php deleted file mode 100644 index fe3cc2a3..00000000 --- a/account/home/index.php +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/account/home/profile/index.php b/account/home/profile/index.php deleted file mode 100644 index 63fa02d4..00000000 --- a/account/home/profile/index.php +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/account/index.php b/account/index.php deleted file mode 100644 index c512c157..00000000 --- a/account/index.php +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/customer/2014-11-ephrem/geez9-1.0.js b/customer/2014-11-ephrem/geez9-1.0.js deleted file mode 100644 index 909a5cb7..00000000 --- a/customer/2014-11-ephrem/geez9-1.0.js +++ /dev/null @@ -1,1846 +0,0 @@ -KeymanWeb.KR(new Keyboard_geez9()); -function Keyboard_geez9() -{ - this.KI="Keyboard_geez9"; - this.KN="Geez"; - this.KV={F:' 1em "Arial"',K102:0,BK:new Array("","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","")};this.KDU=1; - this.KH=''; - this.KM=0; - this.KBVER="1.0"; - this.KVKD="T_WORDSPACE T_2 T_3 T_4 T_5 T_6 T_7 T_8"; - this.KVKL={ - "tablet": { - "font": "Tahoma", - "layer": [ - { - "id": "default", - "row": [ - { - "id": 1, - "key": [ - { - "id": "K_1", - "text": "1" - }, - { - "id": "K_2", - "text": "2" - }, - { - "id": "K_3", - "text": "3" - }, - { - "id": "K_4", - "text": "4" - }, - { - "id": "K_5", - "text": "5" - }, - { - "id": "K_6", - "text": "6" - }, - { - "id": "K_7", - "text": "7" - }, - { - "id": "K_8", - "text": "8" - }, - { - "id": "K_9", - "text": "9" - }, - { - "id": "K_0", - "text": "0" - }, - { - "id": "K_HYPHEN", - "text": "-" - }, - { - "id": "K_EQUAL", - "text": "=" - }, - { - "id": "K_BKSP", - "text": "*BkSp*", - "width": "100", - "sp": "1" - } - ] - }, - { - "id": 2, - "key": [ - { - "id": "K_TAB", - "text": "*Tab*", - "width": "70", - "sp": "1" - }, - { - "id": "K_Q", - "text": "ሀ" - }, - { - "id": "K_W", - "text": "ለ" - }, - { - "id": "T_2", - "text": "2" - }, - { - "id": "T_3", - "text": "3" - }, - { - "id": "T_4", - "text": "4" - }, - { - "id": "T_5", - "text": "5" - }, - { - "id": "T_6", - "text": "6" - }, - { - "id": "T_7", - "text": "7" - }, - { - "id": "K_O", - "text": "መ" - }, - { - "id": "K_P", - "text": "ሰ" - }, - { - "id": "K_LBRKT", - "text": "[" - }, - { - "id": "K_RBRKT", - "text": "]" - }, - { - "id": "T_new_27", - "text": "", - "width": "10", - "sp": "10" - } - ] - }, - { - "id": 3, - "key": [ - { - "id": "K_BKQUOTE", - "text": "`" - }, - { - "id": "K_A", - "text": "ረ" - }, - { - "id": "K_S", - "text": "ሸ" - }, - { - "id": "K_D", - "text": "ቀ" - }, - { - "id": "K_F", - "text": "በ" - }, - { - "id": "K_G", - "text": "ተ" - }, - { - "id": "K_H", - "text": "ነ" - }, - { - "id": "K_J", - "text": "አ" - }, - { - "id": "K_K", - "text": "ገ" - }, - { - "id": "K_L", - "text": "ከ" - }, - { - "id": "K_COLON", - "text": ":" - }, - { - "id": "K_QUOTE", - "text": "'" - }, - { - "id": "K_BKSLASH", - "text": "\\" - } - ] - }, - { - "id": 4, - "key": [ - { - "id": "K_SHIFT", - "text": "*Shift*", - "width": "160", - "sp": "1", - "nextlayer": "shift" - }, - { - "id": "K_Z", - "text": "ወ" - }, - { - "id": "K_X", - "text": "ዘ" - }, - { - "id": "K_C", - "text": "የ" - }, - { - "id": "K_V", - "text": "ደ" - }, - { - "id": "K_B", - "text": "ጠ" - }, - { - "id": "K_N", - "text": "ጸ" - }, - { - "id": "T_8", - "text": "8" - }, - { - "id": "K_COMMA", - "text": "," - }, - { - "id": "K_PERIOD", - "text": "." - }, - { - "id": "K_SLASH", - "text": "/" - }, - { - "id": "K_SHIFT", - "text": "*Shift*", - "width": "145", - "sp": "1" - } - ] - }, - { - "id": 5, - "key": [ - { - "id": "K_LOPT", - "text": "*Menu*", - "width": "140", - "sp": "1" - }, - { - "id": "K_SPACE", - "text": "", - "width": "1030", - "sp": "0" - }, - { - "id": "K_ENTER", - "text": "*Enter*", - "width": "180", - "sp": "1" - } - ] - } - ] - }, - { - "id": "shift", - "row": [ - { - "id": 1, - "key": [ - { - "id": "K_1", - "text": "!" - }, - { - "id": "K_2", - "text": "@" - }, - { - "id": "K_3", - "text": "፧" - }, - { - "id": "K_4", - "text": "፣" - }, - { - "id": "K_5", - "text": "፤" - }, - { - "id": "K_6", - "text": "^" - }, - { - "id": "K_7", - "text": "&" - }, - { - "id": "K_8", - "text": "*" - }, - { - "id": "K_9", - "text": "(" - }, - { - "id": "K_0", - "text": ")" - }, - { - "id": "K_HYPHEN", - "text": "_" - }, - { - "id": "K_EQUAL", - "text": "+" - }, - { - "id": "K_BKSP", - "text": "*BkSp*", - "width": "100", - "sp": "1" - } - ] - }, - { - "id": 2, - "key": [ - { - "id": "K_TAB", - "text": "*Tab*", - "width": "70", - "sp": "1" - }, - { - "id": "K_Q", - "text": "ሐ", - "nextlayer": "default" - }, - { - "id": "K_W", - "text": "ቐ", - "nextlayer": "default" - }, - { - "id": "K_E", - "text": "ⶓ", - "nextlayer": "default" - }, - { - "id": "K_R", - "text": "", - "sp": "9" - }, - { - "id": "K_T", - "text": "", - "sp": "9" - }, - { - "id": "K_Y", - "text": "", - "sp": "9" - }, - { - "id": "K_U", - "text": "ጐ", - "nextlayer": "default" - }, - { - "id": "K_I", - "text": "ቈ", - "nextlayer": "default" - }, - { - "id": "K_O", - "text": "ዐ", - "nextlayer": "default" - }, - { - "id": "K_P", - "text": "ሠ", - "nextlayer": "default" - }, - { - "id": "K_LBRKT", - "text": "{" - }, - { - "id": "K_RBRKT", - "text": "}" - }, - { - "id": "T_new_2277", - "text": "", - "width": "10", - "sp": "10" - } - ] - }, - { - "id": 3, - "key": [ - { - "id": "K_BKQUOTE", - "text": "~" - }, - { - "id": "K_A", - "text": "ኀ", - "nextlayer": "default" - }, - { - "id": "K_S", - "text": "ኘ", - "nextlayer": "default" - }, - { - "id": "K_D", - "text": "ቘ", - "nextlayer": "default" - }, - { - "id": "K_F", - "text": "ቨ", - "nextlayer": "default" - }, - { - "id": "K_G", - "text": "ቸ", - "nextlayer": "default" - }, - { - "id": "K_H", - "text": "ፐ", - "nextlayer": "default" - }, - { - "id": "K_J", - "text": "ጘ", - "nextlayer": "default" - }, - { - "id": "K_K", - "text": "ዀ", - "nextlayer": "default" - }, - { - "id": "K_L", - "text": "ኸ", - "nextlayer": "default" - }, - { - "id": "K_COLON", - "text": ":" - }, - { - "id": "K_QUOTE", - "text": "\"" - }, - { - "id": "K_BKSLASH", - "text": "|" - } - ] - }, - { - "id": 4, - "key": [ - { - "id": "K_SHIFT", - "text": "*Shift*", - "width": "160", - "sp": "2", - "nextlayer": "default" - }, - { - "id": "K_Z", - "text": "ፈ", - "nextlayer": "default" - }, - { - "id": "K_X", - "text": "ዠ", - "nextlayer": "default" - }, - { - "id": "K_C", - "text": "ጰ", - "nextlayer": "default" - }, - { - "id": "K_V", - "text": "ጀ", - "nextlayer": "default" - }, - { - "id": "K_B", - "text": "ጨ", - "nextlayer": "default" - }, - { - "id": "K_N", - "text": "ፀ", - "nextlayer": "default" - }, - { - "id": "K_M", - "text": "ኰ", - "nextlayer": "default" - }, - { - "id": "K_COMMA", - "text": "<" - }, - { - "id": "K_PERIOD", - "text": ">" - }, - { - "id": "K_SLASH", - "text": "?" - }, - { - "id": "K_SHIFT", - "text": "*Shift*", - "width": "145", - "sp": "2" - } - ] - }, - { - "id": 5, - "key": [ - { - "id": "K_LOPT", - "text": "*Menu*", - "width": "140", - "sp": "1" - }, - { - "id": "K_SPACE", - "text": "፡", - "width": "1030", - "sp": "0" - }, - { - "id": "K_ENTER", - "text": "*Enter*", - "width": "180", - "sp": "1" - } - ] - } - ] - } - ] - }, - "phone": { - "font": "Tahoma", - "layer": [ - { - "id": "default", - "row": [ - { - "id": 1, - "key": [ - { - "id": "K_Q", - "text": "ሀ" - }, - { - "id": "K_W", - "text": "ለ" - }, - { - "id": "T_2", - "text": "2" - }, - { - "id": "T_3", - "text": "3" - }, - { - "id": "T_4", - "text": "4" - }, - { - "id": "T_5", - "text": "5" - }, - { - "id": "T_6", - "text": "6" - }, - { - "id": "T_7", - "text": "7" - }, - { - "id": "K_O", - "text": "መ" - }, - { - "id": "K_P", - "text": "ሰ" - } - ] - }, - { - "id": 2, - "key": [ - { - "id": "K_A", - "text": "ረ", - "pad": "50" - }, - { - "id": "K_S", - "text": "ሸ" - }, - { - "id": "K_D", - "text": "ቀ" - }, - { - "id": "K_F", - "text": "በ" - }, - { - "id": "K_G", - "text": "ተ" - }, - { - "id": "K_H", - "text": "ነ" - }, - { - "id": "K_J", - "text": "አ" - }, - { - "id": "K_K", - "text": "ገ" - }, - { - "id": "K_L", - "text": "ከ" - }, - { - "id": "T_new_114", - "text": "", - "width": "10", - "sp": "10" - } - ] - }, - { - "id": 3, - "key": [ - { - "id": "K_SHIFT", - "text": "*Shift*", - "sp": "1", - "nextlayer": "shift" - }, - { - "id": "K_Z", - "text": "ወ" - }, - { - "id": "K_X", - "text": "ዘ" - }, - { - "id": "K_C", - "text": "የ" - }, - { - "id": "K_V", - "text": "ደ" - }, - { - "id": "K_B", - "text": "ጠ" - }, - { - "id": "K_N", - "text": "ጸ" - }, - { - "id": "T_8", - "text": "8" - }, - { - "id": "K_PERIOD", - "text": "." - }, - { - "id": "K_BKSP", - "text": "*BkSp*", - "width": "100", - "sp": "1" - } - ] - }, - { - "id": 4, - "key": [ - { - "id": "K_NUMLOCK", - "text": "*123*", - "width": "150", - "sp": "1", - "nextlayer": "numeric" - }, - { - "id": "K_LOPT", - "text": "*Menu*", - "width": "120", - "sp": "1" - }, - { - "id": "K_SPACE", - "text": "", - "width": "380", - "sp": "0" - }, - { - "id": "T_WORDSPACE", - "text": "፡" - }, - { - "id": "K_ROPT", - "text": "*Hide*", - "width": "120", - "sp": "1" - }, - { - "id": "K_ENTER", - "text": "*Enter*", - "width": "150", - "sp": "1" - } - ] - } - ] - }, - { - "id": "shift", - "row": [ - { - "id": 1, - "key": [ - { - "id": "K_Q", - "text": "ሐ", - "nextlayer": "default" - }, - { - "id": "K_W", - "text": "ቐ", - "nextlayer": "default" - }, - { - "id": "K_E", - "text": "ⶓ", - "nextlayer": "default" - }, - { - "id": "K_R", - "text": "", - "sp": "9" - }, - { - "id": "K_T", - "text": "", - "sp": "9" - }, - { - "id": "K_Y", - "text": "", - "sp": "9" - }, - { - "id": "K_U", - "text": "ጐ", - "nextlayer": "default" - }, - { - "id": "K_I", - "text": "ቈ", - "nextlayer": "default" - }, - { - "id": "K_O", - "text": "ዐ", - "nextlayer": "default" - }, - { - "id": "K_P", - "text": "ሠ", - "nextlayer": "default" - } - ] - }, - { - "id": 2, - "key": [ - { - "id": "K_A", - "text": "ኀ", - "pad": "50", - "nextlayer": "default" - }, - { - "id": "K_S", - "text": "ኘ", - "nextlayer": "default" - }, - { - "id": "K_D", - "text": "ቘ", - "nextlayer": "default" - }, - { - "id": "K_F", - "text": "ቨ", - "nextlayer": "default" - }, - { - "id": "K_G", - "text": "ቸ", - "nextlayer": "default" - }, - { - "id": "K_H", - "text": "ፐ", - "nextlayer": "default" - }, - { - "id": "K_J", - "text": "ጘ", - "nextlayer": "default" - }, - { - "id": "K_K", - "text": "ዀ", - "nextlayer": "default" - }, - { - "id": "K_L", - "text": "ኸ", - "nextlayer": "default" - }, - { - "id": "T_new_114", - "text": "", - "width": "10", - "sp": "10" - } - ] - }, - { - "id": 3, - "key": [ - { - "id": "K_SHIFT", - "text": "*Shift*", - "sp": "2", - "nextlayer": "default" - }, - { - "id": "K_Z", - "text": "ፈ", - "nextlayer": "default" - }, - { - "id": "K_X", - "text": "ዠ", - "nextlayer": "default" - }, - { - "id": "K_C", - "text": "ጰ", - "nextlayer": "default" - }, - { - "id": "K_V", - "text": "ጀ", - "nextlayer": "default" - }, - { - "id": "K_B", - "text": "ጨ", - "nextlayer": "default" - }, - { - "id": "K_N", - "text": "ፀ", - "nextlayer": "default" - }, - { - "id": "K_M", - "text": "ኰ", - "nextlayer": "default" - }, - { - "id": "K_PERIOD", - "text": ".", - "sk": [ - { - "text": ",", - "id": "K_COMMA", - "layer": "default" - }, - { - "text": "!", - "id": "K_1", - "layer": "shift" - }, - { - "text": "?", - "id": "K_SLASH", - "layer": "shift" - }, - { - "text": "'", - "id": "K_QUOTE", - "layer": "default" - }, - { - "text": "\"", - "id": "K_QUOTE", - "layer": "shift" - }, - { - "text": "\\", - "id": "K_BKSLASH", - "layer": "default" - }, - { - "text": ":", - "id": "K_COLON", - "layer": "shift" - }, - { - "text": ";", - "id": "K_COLON", - "layer": "default" - } - ] - }, - { - "id": "K_BKSP", - "text": "*BkSp*", - "sp": "1" - } - ] - }, - { - "id": 4, - "key": [ - { - "id": "K_NUMLOCK", - "text": "*123*", - "width": "150", - "sp": "1", - "nextlayer": "numeric" - }, - { - "id": "K_LOPT", - "text": "*Menu*", - "width": "120", - "sp": "1" - }, - { - "id": "K_SPACE", - "text": "", - "width": "380", - "sp": "0", - "layer": "default" - }, - { - "id": "T_WORDSPACE", - "text": "፡", - "layer": "default" - }, - { - "id": "K_ROPT", - "text": "*Hide*", - "width": "120", - "sp": "1" - }, - { - "id": "K_ENTER", - "text": "*Enter*", - "width": "150", - "sp": "1" - } - ] - } - ] - }, - { - "id": "numeric", - "row": [ - { - "id": 1, - "key": [ - { - "id": "K_1", - "text": "1" - }, - { - "id": "K_2", - "text": "2" - }, - { - "id": "K_3", - "text": "3" - }, - { - "id": "K_4", - "text": "4" - }, - { - "id": "K_5", - "text": "5" - }, - { - "id": "K_6", - "text": "6" - }, - { - "id": "K_7", - "text": "7" - }, - { - "id": "K_8", - "text": "8" - }, - { - "id": "K_9", - "text": "9" - }, - { - "id": "K_0", - "text": "0" - } - ] - }, - { - "id": 2, - "key": [ - { - "id": "K_4", - "text": "፣", - "pad": "50", - "layer": "shift" - }, - { - "id": "K_2", - "text": "@", - "layer": "shift" - }, - { - "id": "K_3", - "text": "፧", - "layer": "shift" - }, - { - "id": "K_5", - "text": "፤", - "layer": "shift" - }, - { - "id": "K_6", - "text": "^", - "layer": "shift" - }, - { - "id": "K_HYPHEN", - "text": "_", - "layer": "shift" - }, - { - "id": "K_EQUAL", - "text": "=", - "layer": "default" - }, - { - "id": "K_BKSLASH", - "text": "|", - "layer": "shift" - }, - { - "id": "K_BKSLASH", - "text": "\\", - "layer": "default" - }, - { - "id": "T_new_410", - "text": "", - "width": "10", - "sp": "10" - } - ] - }, - { - "id": 3, - "key": [ - { - "id": "K_LBRKT", - "text": "[", - "pad": "110", - "sk": [ - { - "id": "U_00AB", - "text": "«" - }, - { - "id": "K_COMMA", - "text": "<", - "layer": "shift" - }, - { - "id": "K_LBRKT", - "text": "{", - "layer": "shift" - } - ] - }, - { - "id": "K_9", - "text": "(", - "layer": "shift" - }, - { - "id": "K_0", - "text": ")", - "layer": "shift" - }, - { - "id": "K_RBRKT", - "text": "]", - "sk": [ - { - "id": "U_00BB", - "text": "»" - }, - { - "id": "K_PERIOD", - "text": ">", - "layer": "shift" - }, - { - "id": "K_RBRKT", - "text": "}", - "layer": "shift" - } - ] - }, - { - "id": "K_EQUAL", - "text": "+", - "layer": "shift" - }, - { - "id": "K_HYPHEN", - "text": "-" - }, - { - "id": "K_8", - "text": "*", - "layer": "shift" - }, - { - "id": "K_SLASH", - "text": "/" - }, - { - "id": "K_BKSP", - "text": "*BkSp*", - "width": "100", - "sp": "1" - } - ] - }, - { - "id": 4, - "key": [ - { - "id": "K_LOWER", - "text": "*abc*", - "width": "150", - "sp": "1", - "nextlayer": "default" - }, - { - "id": "K_LOPT", - "text": "*Menu*", - "width": "120", - "sp": "1" - }, - { - "id": "K_SPACE", - "text": "", - "width": "485", - "sp": "0" - }, - { - "id": "K_ROPT", - "text": "*Hide*", - "width": "120", - "sp": "1" - }, - { - "id": "K_ENTER", - "text": "*Enter*", - "width": "150", - "sp": "1" - } - ] - } - ] - } - ] - } -} -; - this.KCSS=".phone > .kmw-keyboard-geez9 #default-T_2,\n .phone > .kmw-keyboard-geez9 #default-T_3,\n .phone > .kmw-keyboard-geez9 #default-T_4,\n .phone > .kmw-keyboard-geez9 #default-T_5,\n .phone > .kmw-keyboard-geez9 #default-T_6,\n .phone > .kmw-keyboard-geez9 #default-T_7 {\n color: blue;\n font-weight: bold;\n }\n .phone > .kmw-keyboard-geez9 #default-T_8 {\n color: red;\n font-weight: bold;\n } \n \n \n .tablet > .kmw-keyboard-geez9 #default-T_2,\n .tablet > .kmw-keyboard-geez9 #default-T_3,\n .tablet > .kmw-keyboard-geez9 #default-T_4,\n .tablet > .kmw-keyboard-geez9 #default-T_5,\n .tablet > .kmw-keyboard-geez9 #default-T_6,\n .tablet > .kmw-keyboard-geez9 #default-T_7 {\n color: blue;\n font-weight: bold;\n }\n .tablet > .kmw-keyboard-geez9 #default-T_8 {\n color: red;\n font-weight: bold;\n }\n "; - this.s_baseLatin="qwopasdfghjklzxcvbn"; - this.s_baseGeez="ሀለመሰረሸቀበተነአገከወዘየደጠጸ"; - this.s_geez2="ሁሉመሱሩሹቁቡቱኑኡጉኩዉዙዩዱጡጹ"; - this.s_geez3="ሂሊሚሲሪሺቂቢቲኒኢጊኪዊዚዪዲጢጺ"; - this.s_geez4="ሃላማሳራሻቃባታናኣጋካዋዛያዳጣጻ"; - this.s_geez5="ሄሌሜሴሬሼቄቤቴኔኤጌኬዌዜዬዴጤጼ"; - this.s_geez6="ህልምስርሽቅብትንእግክውዝይድጥጽ"; - this.s_geez7="ሆሎሞሶሮሾቆቦቶኖኦጎኮዎዞዮዶጦጾ"; - this.s_geez8="_ሏሟሷሯሿ_ቧቷኗ____ዟ_ዷጧጿ"; - this.s_geez8Illegal="ሀቀአገከወየ"; - this.s_baseLatinU="QPWGASLOXVJBCNZHFMDUKEI"; - this.s_baseGeezU="ሐሠቐቸኀኘኸዐዠጀጘጨጰፀፈፐቨኰቘጐዀⶓቈ"; - this.s_geez2U="ሑሡቑቹኁኙኹዑዡጁጙጩጱፁፉፑቩ______"; - this.s_geez3U="ሒሢቒቺኂኚኺዒዢጂጚጪጲፂፊፒቪኲቚጒዂⶔቊ"; - this.s_geez4U="ሓሣቓቻኃኛኻዓዣጃጛጫጳፃፋፓቫኳቛጓዃጟቋ"; - this.s_geez5U="ሔሤቔቼኄኜኼዔዤጄጔጬጴፄፌፔቬኴቜጔዄⶕቌ"; - this.s_geez6U="ሕሥቕችኅኝኽዕዥጅጝጭጵፅፍፕቭኵቝ_ዅⶖ_"; - this.s_geez7U="ሖሦቖቾኆኞኾዖዦጆጞጮጶፆፎፖቮ__ጕ___"; - this.s_geez8U="ሗሧ_ቿሯኟ__ዧጇ_ጯጷ_ፏፗቯ______"; - this.s_geez8IllegalU="ቐኸዐጘፀኰቘጐዀⶓቈ"; - this.s_geez2IllegalU="ኰቘጐዀⶓቈ"; - this.s_geez6IllegalU="ጐቈ"; - this.s_geez7IllegalU="ኰቘዀⶓቈ"; - this.s36="desktop"; - this.s38="desktop"; - this.s39="desktop"; - this.s40="desktop"; - this.s41="desktop"; - this.s42="desktop"; - this.s43="desktop"; - this.s44="desktop"; - this.KVER="9.0.475.0"; - this.gs=function(t,e) { - return this.g_platform(t,e); - }; - this.g_platform=function(t,e) { - var k=KeymanWeb,r=1,m=0; - if(k.KIFS(31,this.s36,t)) { // Line 11 - m=1; - r=this.g_main(t,e); - } - if(!m) { - - r=this.g_touch(t,e); - } - return r; - }; - this.g_main=function(t,e) { - var k=KeymanWeb,r=0,m=0; - if(k.KKM(e,16400,32)&&k.KIFS(31,this.s38,t)) { // Line 68 - r=m=1; - k.KO(0,t,"፡"); - } - else if(k.KKM(e,16384,50)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 29 - r=m=1; - k.KIO(1,this.s_geez2,1,t); - } - else if(k.KKM(e,16384,50)&&k.KA(0,k.KC(1,1,t),this.s_geez2IllegalU)) { // Line 54 - r=m=1; - k.KIO(1,this.s_geez2IllegalU,1,t); - } - else if(k.KKM(e,16384,50)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 55 - r=m=1; - k.KIO(1,this.s_geez2U,1,t); - } - else if(k.KKM(e,16384,51)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 30 - r=m=1; - k.KIO(1,this.s_geez3,1,t); - } - else if(k.KKM(e,16384,51)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 56 - r=m=1; - k.KIO(1,this.s_geez3U,1,t); - } - else if(k.KKM(e,16400,51)&&k.KIFS(31,this.s41,t)) { // Line 76 - r=m=1; - k.KO(0,t,"፧"); - } - else if(k.KKM(e,16384,52)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 31 - r=m=1; - k.KIO(1,this.s_geez4,1,t); - } - else if(k.KKM(e,16384,52)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 57 - r=m=1; - k.KIO(1,this.s_geez4U,1,t); - } - else if(k.KKM(e,16400,52)&&k.KIFS(31,this.s42,t)) { // Line 77 - r=m=1; - k.KO(0,t,"፣"); - } - else if(k.KKM(e,16384,53)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 32 - r=m=1; - k.KIO(1,this.s_geez5,1,t); - } - else if(k.KKM(e,16384,53)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 58 - r=m=1; - k.KIO(1,this.s_geez5U,1,t); - } - else if(k.KKM(e,16400,53)&&k.KIFS(31,this.s43,t)) { // Line 78 - r=m=1; - k.KO(0,t,"፤"); - } - else if(k.KKM(e,16384,54)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 33 - r=m=1; - k.KIO(1,this.s_geez6,1,t); - } - else if(k.KKM(e,16384,54)&&k.KA(0,k.KC(1,1,t),this.s_geez6IllegalU)) { // Line 59 - r=m=1; - k.KIO(1,this.s_geez6IllegalU,1,t); - } - else if(k.KKM(e,16384,54)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 60 - r=m=1; - k.KIO(1,this.s_geez6U,1,t); - } - else if(k.KKM(e,16384,55)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 34 - r=m=1; - k.KIO(1,this.s_geez7,1,t); - } - else if(k.KKM(e,16384,55)&&k.KA(0,k.KC(1,1,t),this.s_geez7IllegalU)) { // Line 61 - r=m=1; - k.KIO(1,this.s_geez7IllegalU,1,t); - } - else if(k.KKM(e,16384,55)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 62 - r=m=1; - k.KIO(1,this.s_geez7U,1,t); - } - else if(k.KKM(e,16384,56)&&k.KA(0,k.KC(1,1,t),this.s_geez8Illegal)) { // Line 35 - r=m=1; - k.KIO(1,this.s_geez8Illegal,1,t); - } - else if(k.KKM(e,16384,56)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 36 - r=m=1; - k.KIO(1,this.s_geez8,1,t); - } - else if(k.KKM(e,16384,56)&&k.KA(0,k.KC(1,1,t),this.s_geez8IllegalU)) { // Line 63 - r=m=1; - k.KIO(1,this.s_geez8IllegalU,1,t); - } - else if(k.KKM(e,16384,56)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 64 - r=m=1; - k.KIO(1,this.s_geez8U,1,t); - } - else if(k.KKM(e,16400,56)&&k.KIFS(31,this.s44,t)) { // Line 79 - r=m=1; - k.KO(0,t,"ኰ"); - } - else if(k.KKM(e,16400,65)) { // Line 53 - r=m=1; - k.KO(0,t,"ኀ"); - } - else if(k.KKM(e,16400,66)) { // Line 53 - r=m=1; - k.KO(0,t,"ጨ"); - } - else if(k.KKM(e,16400,67)) { // Line 53 - r=m=1; - k.KO(0,t,"ጰ"); - } - else if(k.KKM(e,16400,68)) { // Line 53 - r=m=1; - k.KO(0,t,"ቘ"); - } - else if(k.KKM(e,16400,69)) { // Line 53 - r=m=1; - k.KO(0,t,"ⶓ"); - } - else if(k.KKM(e,16400,70)) { // Line 53 - r=m=1; - k.KO(0,t,"ቨ"); - } - else if(k.KKM(e,16400,71)) { // Line 53 - r=m=1; - k.KO(0,t,"ቸ"); - } - else if(k.KKM(e,16400,72)) { // Line 53 - r=m=1; - k.KO(0,t,"ፐ"); - } - else if(k.KKM(e,16400,73)) { // Line 53 - r=m=1; - k.KO(0,t,"ቈ"); - } - else if(k.KKM(e,16400,74)) { // Line 53 - r=m=1; - k.KO(0,t,"ጘ"); - } - else if(k.KKM(e,16400,75)) { // Line 53 - r=m=1; - k.KO(0,t,"ዀ"); - } - else if(k.KKM(e,16400,76)) { // Line 53 - r=m=1; - k.KO(0,t,"ኸ"); - } - else if(k.KKM(e,16400,77)) { // Line 53 - r=m=1; - k.KO(0,t,"ኰ"); - } - else if(k.KKM(e,16400,78)) { // Line 53 - r=m=1; - k.KO(0,t,"ፀ"); - } - else if(k.KKM(e,16400,79)) { // Line 53 - r=m=1; - k.KO(0,t,"ዐ"); - } - else if(k.KKM(e,16400,80)) { // Line 53 - r=m=1; - k.KO(0,t,"ሠ"); - } - else if(k.KKM(e,16400,81)) { // Line 53 - r=m=1; - k.KO(0,t,"ሐ"); - } - else if(k.KKM(e,16400,83)) { // Line 53 - r=m=1; - k.KO(0,t,"ኘ"); - } - else if(k.KKM(e,16400,85)) { // Line 53 - r=m=1; - k.KO(0,t,"ጐ"); - } - else if(k.KKM(e,16400,86)) { // Line 53 - r=m=1; - k.KO(0,t,"ጀ"); - } - else if(k.KKM(e,16400,87)) { // Line 53 - r=m=1; - k.KO(0,t,"ቐ"); - } - else if(k.KKM(e,16400,88)) { // Line 53 - r=m=1; - k.KO(0,t,"ዠ"); - } - else if(k.KKM(e,16400,90)) { // Line 53 - r=m=1; - k.KO(0,t,"ፈ"); - } - else if(k.KKM(e,16384,65)) { // Line 28 - r=m=1; - k.KO(0,t,"ረ"); - } - else if(k.KKM(e,16384,66)) { // Line 28 - r=m=1; - k.KO(0,t,"ጠ"); - } - else if(k.KKM(e,16384,67)) { // Line 28 - r=m=1; - k.KO(0,t,"የ"); - } - else if(k.KKM(e,16384,68)) { // Line 28 - r=m=1; - k.KO(0,t,"ቀ"); - } - else if(k.KKM(e,16384,70)) { // Line 28 - r=m=1; - k.KO(0,t,"በ"); - } - else if(k.KKM(e,16384,71)) { // Line 28 - r=m=1; - k.KO(0,t,"ተ"); - } - else if(k.KKM(e,16384,72)) { // Line 28 - r=m=1; - k.KO(0,t,"ነ"); - } - else if(k.KKM(e,16384,74)) { // Line 28 - r=m=1; - k.KO(0,t,"አ"); - } - else if(k.KKM(e,16384,75)) { // Line 28 - r=m=1; - k.KO(0,t,"ገ"); - } - else if(k.KKM(e,16384,76)) { // Line 28 - r=m=1; - k.KO(0,t,"ከ"); - } - else if(k.KKM(e,16384,78)) { // Line 28 - r=m=1; - k.KO(0,t,"ጸ"); - } - else if(k.KKM(e,16384,79)) { // Line 28 - r=m=1; - k.KO(0,t,"መ"); - } - else if(k.KKM(e,16384,80)) { // Line 28 - r=m=1; - k.KO(0,t,"ሰ"); - } - else if(k.KKM(e,16384,81)) { // Line 28 - r=m=1; - k.KO(0,t,"ሀ"); - } - else if(k.KKM(e,16384,83)) { // Line 28 - r=m=1; - k.KO(0,t,"ሸ"); - } - else if(k.KKM(e,16384,86)) { // Line 28 - r=m=1; - k.KO(0,t,"ደ"); - } - else if(k.KKM(e,16384,87)) { // Line 28 - r=m=1; - k.KO(0,t,"ለ"); - } - else if(k.KKM(e,16384,88)) { // Line 28 - r=m=1; - k.KO(0,t,"ዘ"); - } - else if(k.KKM(e,16384,90)) { // Line 28 - r=m=1; - k.KO(0,t,"ወ"); - } - else if(k.KKM(e,16384,256)&&k.KIFS(31,this.s39,t)&&k.KCM(1,t,"፡",1)) { // Line 69 - r=m=1; - k.KO(1,t,"።"); - } - else if(k.KKM(e,16384,256)&&k.KIFS(31,this.s40,t)&&k.KCM(1,t,"።",1)) { // Line 70 - r=m=1; - k.KO(1,t,"። "); - } - else if(k.KKM(e,16384,256)&&k.KCM(1,t,"፡",1)) { // Line 73 - r=m=1; - k.KO(1,t,"።"); - } - else if(k.KKM(e,16384,256)&&k.KCM(1,t,"።",1)) { // Line 74 - r=m=1; - k.KO(1,t,"። "); - } - else if(k.KKM(e,16384,256)) { // Line 72 - r=m=1; - k.KO(0,t,"፡"); - } - return r; - }; - this.g_touch=function(t,e) { - var k=KeymanWeb,r=0,m=0; - if(k.KKM(e,16400,65)) { // Line 98 - r=m=1; - k.KO(0,t,"ኀ"); - } - else if(k.KKM(e,16400,66)) { // Line 98 - r=m=1; - k.KO(0,t,"ጨ"); - } - else if(k.KKM(e,16400,67)) { // Line 98 - r=m=1; - k.KO(0,t,"ጰ"); - } - else if(k.KKM(e,16400,68)) { // Line 98 - r=m=1; - k.KO(0,t,"ቘ"); - } - else if(k.KKM(e,16400,69)) { // Line 98 - r=m=1; - k.KO(0,t,"ⶓ"); - } - else if(k.KKM(e,16400,70)) { // Line 98 - r=m=1; - k.KO(0,t,"ቨ"); - } - else if(k.KKM(e,16400,71)) { // Line 98 - r=m=1; - k.KO(0,t,"ቸ"); - } - else if(k.KKM(e,16400,72)) { // Line 98 - r=m=1; - k.KO(0,t,"ፐ"); - } - else if(k.KKM(e,16400,73)) { // Line 98 - r=m=1; - k.KO(0,t,"ቈ"); - } - else if(k.KKM(e,16400,74)) { // Line 98 - r=m=1; - k.KO(0,t,"ጘ"); - } - else if(k.KKM(e,16400,75)) { // Line 98 - r=m=1; - k.KO(0,t,"ዀ"); - } - else if(k.KKM(e,16400,76)) { // Line 98 - r=m=1; - k.KO(0,t,"ኸ"); - } - else if(k.KKM(e,16400,77)) { // Line 98 - r=m=1; - k.KO(0,t,"ኰ"); - } - else if(k.KKM(e,16400,78)) { // Line 98 - r=m=1; - k.KO(0,t,"ፀ"); - } - else if(k.KKM(e,16400,79)) { // Line 98 - r=m=1; - k.KO(0,t,"ዐ"); - } - else if(k.KKM(e,16400,80)) { // Line 98 - r=m=1; - k.KO(0,t,"ሠ"); - } - else if(k.KKM(e,16400,81)) { // Line 98 - r=m=1; - k.KO(0,t,"ሐ"); - } - else if(k.KKM(e,16400,83)) { // Line 98 - r=m=1; - k.KO(0,t,"ኘ"); - } - else if(k.KKM(e,16400,85)) { // Line 98 - r=m=1; - k.KO(0,t,"ጐ"); - } - else if(k.KKM(e,16400,86)) { // Line 98 - r=m=1; - k.KO(0,t,"ጀ"); - } - else if(k.KKM(e,16400,87)) { // Line 98 - r=m=1; - k.KO(0,t,"ቐ"); - } - else if(k.KKM(e,16400,88)) { // Line 98 - r=m=1; - k.KO(0,t,"ዠ"); - } - else if(k.KKM(e,16400,90)) { // Line 98 - r=m=1; - k.KO(0,t,"ፈ"); - } - else if(k.KKM(e,16384,65)) { // Line 86 - r=m=1; - k.KO(0,t,"ረ"); - } - else if(k.KKM(e,16384,66)) { // Line 86 - r=m=1; - k.KO(0,t,"ጠ"); - } - else if(k.KKM(e,16384,67)) { // Line 86 - r=m=1; - k.KO(0,t,"የ"); - } - else if(k.KKM(e,16384,68)) { // Line 86 - r=m=1; - k.KO(0,t,"ቀ"); - } - else if(k.KKM(e,16384,70)) { // Line 86 - r=m=1; - k.KO(0,t,"በ"); - } - else if(k.KKM(e,16384,71)) { // Line 86 - r=m=1; - k.KO(0,t,"ተ"); - } - else if(k.KKM(e,16384,72)) { // Line 86 - r=m=1; - k.KO(0,t,"ነ"); - } - else if(k.KKM(e,16384,74)) { // Line 86 - r=m=1; - k.KO(0,t,"አ"); - } - else if(k.KKM(e,16384,75)) { // Line 86 - r=m=1; - k.KO(0,t,"ገ"); - } - else if(k.KKM(e,16384,76)) { // Line 86 - r=m=1; - k.KO(0,t,"ከ"); - } - else if(k.KKM(e,16384,78)) { // Line 86 - r=m=1; - k.KO(0,t,"ጸ"); - } - else if(k.KKM(e,16384,79)) { // Line 86 - r=m=1; - k.KO(0,t,"መ"); - } - else if(k.KKM(e,16384,80)) { // Line 86 - r=m=1; - k.KO(0,t,"ሰ"); - } - else if(k.KKM(e,16384,81)) { // Line 86 - r=m=1; - k.KO(0,t,"ሀ"); - } - else if(k.KKM(e,16384,83)) { // Line 86 - r=m=1; - k.KO(0,t,"ሸ"); - } - else if(k.KKM(e,16384,86)) { // Line 86 - r=m=1; - k.KO(0,t,"ደ"); - } - else if(k.KKM(e,16384,87)) { // Line 86 - r=m=1; - k.KO(0,t,"ለ"); - } - else if(k.KKM(e,16384,88)) { // Line 86 - r=m=1; - k.KO(0,t,"ዘ"); - } - else if(k.KKM(e,16384,90)) { // Line 86 - r=m=1; - k.KO(0,t,"ወ"); - } - else if(k.KKM(e,16384,256)&&k.KCM(1,t,"፡",1)) { // Line 114 - r=m=1; - k.KO(1,t,"።"); - } - else if(k.KKM(e,16384,256)&&k.KCM(1,t,"።",1)) { // Line 115 - r=m=1; - k.KO(1,t,"። "); - } - else if(k.KKM(e,16384,256)) { // Line 113 - r=m=1; - k.KO(0,t,"፡"); - } - else if(k.KKM(e,16384,257)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 87 - r=m=1; - k.KIO(1,this.s_geez2,1,t); - } - else if(k.KKM(e,16384,257)&&k.KA(0,k.KC(1,1,t),this.s_geez2IllegalU)) { // Line 99 - r=m=1; - k.KIO(1,this.s_geez2IllegalU,1,t); - } - else if(k.KKM(e,16384,257)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 100 - r=m=1; - k.KIO(1,this.s_geez2U,1,t); - } - else if(k.KKM(e,16384,258)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 88 - r=m=1; - k.KIO(1,this.s_geez3,1,t); - } - else if(k.KKM(e,16384,258)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 101 - r=m=1; - k.KIO(1,this.s_geez3U,1,t); - } - else if(k.KKM(e,16384,259)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 89 - r=m=1; - k.KIO(1,this.s_geez4,1,t); - } - else if(k.KKM(e,16384,259)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 102 - r=m=1; - k.KIO(1,this.s_geez4U,1,t); - } - else if(k.KKM(e,16384,260)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 90 - r=m=1; - k.KIO(1,this.s_geez5,1,t); - } - else if(k.KKM(e,16384,260)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 103 - r=m=1; - k.KIO(1,this.s_geez5U,1,t); - } - else if(k.KKM(e,16384,261)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 91 - r=m=1; - k.KIO(1,this.s_geez6,1,t); - } - else if(k.KKM(e,16384,261)&&k.KA(0,k.KC(1,1,t),this.s_geez6IllegalU)) { // Line 104 - r=m=1; - k.KIO(1,this.s_geez6IllegalU,1,t); - } - else if(k.KKM(e,16384,261)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 105 - r=m=1; - k.KIO(1,this.s_geez6U,1,t); - } - else if(k.KKM(e,16384,262)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 92 - r=m=1; - k.KIO(1,this.s_geez7,1,t); - } - else if(k.KKM(e,16384,262)&&k.KA(0,k.KC(1,1,t),this.s_geez7IllegalU)) { // Line 106 - r=m=1; - k.KIO(1,this.s_geez7IllegalU,1,t); - } - else if(k.KKM(e,16384,262)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 107 - r=m=1; - k.KIO(1,this.s_geez7U,1,t); - } - else if(k.KKM(e,16384,263)&&k.KA(0,k.KC(1,1,t),this.s_geez8Illegal)) { // Line 93 - r=m=1; - k.KIO(1,this.s_geez8Illegal,1,t); - } - else if(k.KKM(e,16384,263)&&k.KA(0,k.KC(1,1,t),this.s_baseGeez)) { // Line 94 - r=m=1; - k.KIO(1,this.s_geez8,1,t); - } - else if(k.KKM(e,16384,263)&&k.KA(0,k.KC(1,1,t),this.s_geez8IllegalU)) { // Line 108 - r=m=1; - k.KIO(1,this.s_geez8IllegalU,1,t); - } - else if(k.KKM(e,16384,263)&&k.KA(0,k.KC(1,1,t),this.s_baseGeezU)) { // Line 109 - r=m=1; - k.KIO(1,this.s_geez8U,1,t); - } - return r; - }; -} diff --git a/customer/2014-11-ephrem/geez9-1.0.json b/customer/2014-11-ephrem/geez9-1.0.json deleted file mode 100644 index 1f03854d..00000000 --- a/customer/2014-11-ephrem/geez9-1.0.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "options":{ - "device":"any", - "keyboardBaseUri":"http://keyman.com/customer/2014-11-ephrem/", - "fontBaseUri":"http://s.keyman.com/font/deploy/" - }, - "keyboard":{ - "id":"geez9", - "name":"Geez", - "filename":"geez9-1.0.js", - "version":"1.0", - "lastModified":"2014-10-24T13:38:01+00:00", - "font":{"family":"Wookianos","filename":"wookianos.ttf"}, - "oskFont":{"family":"Wookianos","filename":"wookianos.ttf"}, - "languages":[{"id":"amh","name":"Amharic"}] - } -} diff --git a/customer/2014-11-ephrem/index.html b/customer/2014-11-ephrem/index.html deleted file mode 100644 index 1df48c56..00000000 --- a/customer/2014-11-ephrem/index.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - KeymanWeb Sample Page - Uncompiled Source - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Amharic Sample Keyboard -- Online Test

- -
- -

Type in Amharic in this text area:

- - -

Install Amharic Geez keyboard into Keyman on this device

- -
- - - - - diff --git a/customer/2014-11-ephrem/keymanweb/keymanweb.js b/customer/2014-11-ephrem/keymanweb/keymanweb.js deleted file mode 100644 index 12c404c1..00000000 --- a/customer/2014-11-ephrem/keymanweb/keymanweb.js +++ /dev/null @@ -1,3994 +0,0 @@ -/*** - KeymanWeb 2.0 - Copyright 2014 Tavultesoft Pty Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -***/ - - -/****************************************************************** - * Main Keyman Web Module - * - * Code enclosed as an anonymous function to protect name space - * - ******************************************************************/ - -(function() -{ - // Declare KeymanWeb, OnScreen Keyboard and Util objects - var keymanweb=window['tavultesoft']['keymanweb'],osk=keymanweb['osk'],util=keymanweb['util'],device=util.device; - - /** - * Function debug - * Scope Private - * @param {(string|Object)} s string (or object) to print - * Description Simple debug display (upper right of screen) - */ - keymanweb['debug']=keymanweb.debug=function(s){ - var p;//=document.getElementById('debug_output'); - if(keymanweb.debugElement == null) - { - var d=document.createElement('DIV'),ds=d.style; - ds.position='absolute';ds.width='30%';ds.maxHeight='50%';ds.top='0';ds.right='0'; - ds.minHeight='50px'; ds.border='1px solid blue'; ds.whiteSpace='pre-line';ds.overflowY='scroll'; - p=document.createElement('P'); p.id='debug_output';p.style.margin='2px'; - d.appendChild(p); - document.body.appendChild(d); - keymanweb.debugElement=p; - } - if((p=document.getElementById('debug_output')) == null) return; - - if(arguments.length == 0) - if(typeof p.textContent != 'undefined') p.textContent=''; else p.innerHTML=''; - else - { - var ts=new Date().toTimeString().substr(3,5),t=s,m; - if(typeof s == 'object') - { - if(s == null) - { - t='null'; - } - else - { - t='{'; - for(m in s) - { - t=t+m+':'; - switch(typeof s[m]) - { - case 'string': - case 'number': - case 'boolean': - t=t+s[m]; break; - default: - t=t+typeof s[m]; break; - } - t=t+'; '; - } - if(t.length > 2) t=t.substr(0,t.length-2); //drop final semi-colon - t+='}'; - } - } - if(typeof p.textContent != 'undefined') - p.textContent=ts+' '+t+'\n'+p.textContent; - else - p.innerHTML=ts+' '+t+'
'+p.innerHTML; - - } - } - keymanweb.debugElement=null; - var dbg=keymanweb.debug; - - /** - * Function addEventListener - * Scope Public - * @param {string} event event to handle - * @param {function(Event)} func event handler function - * @return {boolean} value returned by util.addEventListener - * Description Wrapper function to add and identify KeymanWeb-specific event handlers - */ - keymanweb['addEventListener'] = keymanweb.addEventListener = function(event, func) - { - return util.addEventListener('kmw.'+event, func); - } - - /** - * Function setUpTouchDevice - * Scope Private - * Description Initialize event handling and duplicate input fields for touch-input devices - */ - keymanweb.setupTouchDevice = function() - { - /** - * Ideally, OSK behaviour should emulate internal keyboard, but - * it is not possible to do that while allowing native scrolling. - * The compromise adopted is that a touchstart or touchmove event - * on any part of the page other than an input element or the OSK - * itself will temporarily hide the OSK until the touchend or - * window.scroll event is fired. Hiding the OSK in this way seems - * less disturbing than having it move as the page is scrolled. - * - * All of this may be better if we can reliably get the y-offset - * from the CSS transform and apply that to repositioning the OSK - * using a timed event loop. - */ - - /** - * Close OSK and remove simulated caret on losing focus - */ - keymanweb.cancelInput = function() - { - keymanweb._ActiveElement=null; - keymanweb.hideCaret(); - osk.hideNow(); - } - - /** - * Handle losing focus from simulated input field - * - * @param {Event} e event - */ - keymanweb.setBlur = function(e) - { - // This works OK for iOS, but may need something else for other platforms - if(('relatedTarget' in e) && e.relatedTarget) - { - if(e.relatedTarget.nodeName != 'DIV' || e.relatedTarget.className.indexOf('keymanweb-input') == -1) - { - keymanweb.cancelInput(); return; - } - } - //Hide the OSK - if(!keymanweb.focusing) keymanweb.cancelInput(); - } - - /** - * Handle receiving focus by simulated input field - * - * @param {Event=} e event - */ - keymanweb.setFocus=function(e) - { - //e.stopPropagation(); // not doing anything useful, no child elements - //e.preventDefault(); // prevents user selection or scrolling, may be better if they are allowed? - - keymanweb.focusing=true; - keymanweb.focusTimer=window.setTimeout(function(){keymanweb.focusing=false;},1000); - - var tEvent=e; - if(e) - { - if(typeof e.touches == 'object') tEvent=e.touches[0]; - } - - // Allow external code to set focus and thus display the OSK on touch devices if required (KMEW-123) - else - { - tEvent={clientX:0,clientY:0} - // Will usually be called from setActiveElement, which should define _LastActiveElement - if(keymanweb._LastActiveElement) - tEvent.target = keymanweb._LastActiveElement['kmw_ip']; - // but will default to first input or text area on page if _LastActiveElement is null - else - tEvent.target = keymanweb.sortedInputs[0]['kmw_ip']; - } - - var touchX=tEvent.clientX,touchY=tEvent.clientY,tTarg=tEvent.target,scroller; - - // Identify the scroller element - if(tTarg.nodeName == 'SPAN') - scroller=tTarg.parentNode; - else if(tTarg.className != null && tTarg.className.indexOf('keymanweb-input') >= 0) - scroller=tTarg.firstChild; - else - scroller=tTarg; - - // And the actual target element - var target=scroller.parentNode; - - // Move the caret and refocus if necessary - if(keymanweb._ActiveElement != target) - { - // Hide the KMW caret - keymanweb.hideCaret(); - keymanweb._ActiveElement=target; - // The issue here is that touching a DIV does not actually set the focus for iOS, even when enabled to accept focus (by setting tabIndex=0) - // We must explicitly set the focus in order to remove focus from any non-KMW input - target.focus(); //Android native browsers may not like this, but it is needed for Chrome, Safari - } - - // What we really want to do is to blur any active element that is not a KMW input, - // but the following line does not work as might be expected, even though the correct element is referenced. - // It is as though blur is ignored if focus is supposed to have been moved, even if it has not in fact been moved? - //if(document.activeElement.nodeName != 'DIV' && document.activeElement.nodeName != 'BODY') document.activeElement.blur(); - - // Refresh the internal keyboard flag state - keymanweb.useInternalKeyboard=false; - - // And display the OSK if not already visible - if(osk.ready && !osk._Visible) osk._Show(); - - // If clicked on DIV, set caret to end of text - if(tTarg.nodeName == 'DIV' ) - { - var x,cp; - x=util._GetAbsoluteX(scroller.firstChild); - if(target.dir == 'rtl') - { - x += scroller.firstChild.offsetWidth; - cp=(touchX > x ? 0 : 100000); - } - else - cp=(touchX touchY && cp > cpMin && cp != cpMax) {cpMax=cp; cp=Math.round((cp+cpMin)/2);} - else if(y < touchY-yRow && cp < cpMax && cp != cpMin) {cpMin=cp; cp=Math.round((cp+cpMax)/2);} - else break; - keymanweb.setTextCaret(target,cp); - } - while(util._GetAbsoluteY(caret)-dy > touchY && cp > cpMin)keymanweb.setTextCaret(target,--cp); - while(util._GetAbsoluteY(caret)-dy < touchY-yRow && cp < cpMax) keymanweb.setTextCaret(target,++cp); - } - // Caret repositioning for horizontal scrolling of RTL text - if(target.dir == 'rtl') - { - for(iLoop=0; iLoop<16; iLoop++) - { - x=util._GetAbsoluteX(caret); //left of caret - if(x < touchX && cp > cpMin && cp != cpMax) {cpMax=cp; cp=Math.round((cp+cpMin)/2);} - else if(x > touchX && cp < cpMax && cp != cpMin) {cpMin=cp; cp=Math.round((cp+cpMax)/2);} - else break; - keymanweb.setTextCaret(target,cp); - } - while(util._GetAbsoluteX(caret) < touchX && cp > cpMin) keymanweb.setTextCaret(target,--cp); - while(util._GetAbsoluteX(caret) > touchX && cp < cpMax) keymanweb.setTextCaret(target,++cp); - } - // Caret repositioning for horizontal scrolling of standard (LTR) text - else - { - for(iLoop=0; iLoop<16; iLoop++) // assumes fields shorter than 2**16 characters - { - x=util._GetAbsoluteX(caret); //left of caret - if(x > touchX && cp > cpMin && cp != cpMax) - { - cpMax=cp; cp=Math.round((cp+cpMin)/2); - } - else if(x < touchX && cp < cpMax && cp != cpMin) - { - cpMin=cp; cp=Math.round((cp+cpMax)/2); - } - else break; - keymanweb.setTextCaret(target,cp); - } - while(util._GetAbsoluteX(caret) > touchX && cp > cpMin) keymanweb.setTextCaret(target,--cp); - while(util._GetAbsoluteX(caret) < touchX && cp < cpMax) keymanweb.setTextCaret(target,++cp); - } - } - - // TODO: The following is copied from old control focus... not sure how much is needed - - keymanweb._ActiveControl = null; - keymanweb._LastActiveElement = target; - for(var Ln=0; Ln < keymanweb._Controls.length; Ln++) // I1511 - array prototype extended - if(keymanweb._Controls[Ln].LControl == target) - { - keymanweb._ActiveControl = keymanweb._Controls[Ln]; - break; - } - - if(keymanweb._ActiveControl != null && keymanweb._ActiveControl.LDefaultInternalName != null) - { - if(!keymanweb._JustActivatedKeymanWebUI) - { - keymanweb._SetActiveKeyboard(keymanweb._ActiveControl.LDefaultInternalName,'',true); - } - else - keymanweb._ActiveControl.LDefaultInternalName = keymanweb._ActiveKeyboard == null ? '' : keymanweb._ActiveKeyboard['KI']; - } - - //TODO: the logic of the following line doesn't look right!! Both variables are true, but that doesn't make sense! - //_Debug(keymanweb._IsIEEditableIframe(Ltarg,1) + '...' +keymanweb._IsMozillaEditableIframe(Ltarg,1)); - if(!keymanweb._IsIEEditableIframe(target,1) || !keymanweb._IsMozillaEditableIframe(target,1)) - { - keymanweb._DisableInput = 1; return; - } - keymanweb._DisableInput = 0; - - if(!keymanweb._JustActivatedKeymanWebUI) - { - keymanweb._DeadKeys = []; - keymanweb._NotifyKeyboard(0,target,1); // I2187 - } - - if(!keymanweb._JustActivatedKeymanWebUI && keymanweb._SelectionControl != target) - keymanweb._IsActivatingKeymanWebUI = 0; - keymanweb._JustActivatedKeymanWebUI = 0; - - keymanweb._SelectionControl = target; - } - - /** - * Create a caret to be appended to the scroller of the focussed input field. - * The caret is appended to the scroller so that it will automatically be clipped - * when the user manually scrolls it outside the element boundaries. - * It is positioned exactly over the hidden span that is inserted between the - * text spans before and after the insertion point. - */ - keymanweb.caret=document.createElement('DIV'); - var cs=keymanweb.caret.style; - cs.position='absolute'; - cs.height='16px'; // default height, actual height set from element properties - cs.width='2px'; - cs.backgroundColor='blue'; - cs.border='none'; - cs.left=cs.top=0; // actual position set relative to parent when displayed - cs.display='block'; - cs.visibility='hidden'; - cs.zIndex='9998'; // immediately below the OSK - - /** - * Position the caret at the start of the second span within the scroller - * - * @param {Object} e input DIV element (copy of INPUT or TEXTAREA) - */ - keymanweb.showCaret=function(e) - { - if(!e || !e.firstChild || (e.firstChild.childNodes.length<3)) return; - - var scroller=e.firstChild,cs=keymanweb.caret.style,sp2=scroller.childNodes[1]; - - // Attach the caret to this scroller and position it over the caret span - if(keymanweb.caret.parentNode != scroller) scroller.appendChild(keymanweb.caret); - cs.left=sp2.offsetLeft+'px'; - cs.top=sp2.offsetTop+'px'; - cs.height=(sp2.offsetHeight-1)+'px'; - cs.visibility='hidden'; // best to wait for timer to display caret - - // Scroll into view if required - keymanweb.scrollBody(e); - - // Display and position the scrollbar if necessary - keymanweb.setScrollBar(e); - } - - /** - * Display and position a scrollbar in the input field if needed - * - * @param {Object} e input DIV element (copy of INPUT or TEXTAREA) - */ - keymanweb.setScrollBar=function(e) - { - // Display the scrollbar if necessary. Added TEXTAREA condition to correct rotation issue KMW-5. Fixed for 310 beta. - var scroller=e.childNodes[0],sbs=e.childNodes[1].style; - if((scroller.offsetWidth > e.offsetWidth || scroller.offsetLeft < 0) && (e.base.nodeName != 'TEXTAREA')) - { - sbs.height='4px'; - sbs.width=100*(e.offsetWidth/scroller.offsetWidth)+'%'; - sbs.left=100*(-scroller.offsetLeft/scroller.offsetWidth)+'%'; - sbs.top='0'; - sbs.visibility='visible'; - } - else if(scroller.offsetHeight > e.offsetHeight || scroller.offsetTop < 0) - { - sbs.width='4px'; - sbs.height=100*(e.offsetHeight/scroller.offsetHeight)+'%'; - sbs.top=100*(-scroller.offsetTop/scroller.offsetHeight)+'%'; - sbs.left='0'; - sbs.visibility='visible'; - } - else - { - sbs.visibility='hidden'; - } - } - - /** - * Description Toggle state of caret in simulated input field - */ - keymanweb.flashCaret = function() - { - if(device.touchable && keymanweb._ActiveElement != null) - { - var cs=keymanweb.caret.style; - if(cs.visibility != 'visible') cs.visibility='visible'; else cs.visibility='hidden'; - } - } - - /** - * Hide caret in simulated input field, update underlying INPUT or TEXTAREA - */ - keymanweb.hideCaret = function() - { - var e=keymanweb._LastActiveElement,s=null; - if(e && e.className != null && e.className.indexOf('keymanweb-input') >= 0) - { - // Always copy text back to underlying field on blur - e.base.value = keymanweb.getText(e); - - // And set the scroller caret to the end of the element content - keymanweb.setText(e,null,100000); - - // Set the element scroll to zero (or max for RTL INPUT) - var ss=e.firstChild.style; - if(e.base.nodeName == 'TEXTAREA') - ss.top='0'; - else - { - if(e.base.dir == 'rtl') ss.left=(e.offsetWidth-e.firstChild.offsetWidth-8)+'px'; - else ss.left='0'; - } - - - // And hide the caret and scrollbar - if(keymanweb.caret.parentNode) keymanweb.caret.parentNode.removeChild(keymanweb.caret); - keymanweb.caret.style.visibility='hidden'; - if(e.childNodes.length > 1 ) e.childNodes[1].style.visibility='hidden'; - } - } - - // Start the caret flash timer - keymanweb.timerId = window.setInterval(keymanweb.flashCaret,500); - - /** - * Insert text into simulated input field at indicated character position - * - * @param {Object} e simulated input field DIV - * @param {?string} t text to insert in element - * @param {?number} cp caret position (characters) - */ - keymanweb.setText = function(e,t,cp) - { - if(e && e.childNodes.length > 0) - { - var d=e.firstChild,tLen=0; - if(d.childNodes.length >= 3) - { - var s1=d.childNodes[0],s2=d.childNodes[2],t1,t2; - - // Read current text if null passed (for caret positioning) - if(t === null) - { - t1=(typeof(s1.textContent) == 'string' ? s1.textContent : s1.innerText); - t2=(typeof(s2.textContent) == 'string' ? s2.textContent : s2.innerText); - t=t1+t2; - } - if(cp < 0) cp = 0; //if(typeof t._kmwLength == 'undefined') return; - tLen=t._kmwLength(); - - if(cp === null || cp > tLen) cp=tLen; - t1=t._kmwSubstr(0,cp); t2=t._kmwSubstr(cp); - - if(typeof(s1.textContent) == 'string') s1.textContent=t1; else s1.innerText=t1; - if(typeof(s2.textContent) == 'string') s2.textContent=t2; else s2.innerText=t2; - } - } - keymanweb.updateBaseElement(e,tLen); // KMW-3, KMW-29 - } - - /** - * Set content, visibility, background and borders of input and base elements (KMW-3,KMW-29) - * - * @param {Object} e input element - * @param {number} n length of text in field - */ - keymanweb.updateBaseElement=function(e,n) - { - e.base.value=keymanweb.getText(e); //KMW-29 - e.style.backgroundColor=(n==0?'transparent':window.getComputedStyle(e.base,null).backgroundColor); - if(device.OS == 'iOS') - { - e.base.style.visibility=(n==0?'visible':'hidden'); - } - } - - /** - * Get simulated input field content - * - * @param {Object} e simulated input field DIV - * @return {string} entire text in simulated input field - */ - keymanweb.getText=function(e) - { - if(e == null) return ''; - return (typeof(e.textContent) == 'string' ? e.textContent : e.innerText); - } - - /** - * Get text up to the caret from simulated input field - * - * @param {Object} e simulated input field DIV - * @return {string} Context for simulated input field - */ - keymanweb.getTextBeforeCaret=function(e) - { - if(e && e.childNodes.length > 1) - { - var d=e.firstChild; - if(d.childNodes.length > 0) - { - var s1=d.childNodes[0]; - if('textContent' in s1) - return s1.textContent; - if('innerText' in s1) - return s1.innerText; - } - } - return ''; - } - - /** - * Replace text up to the caret in the simulated input field - * - * @param {Object} e simulated input field DIV - * @param {string} t string to insert - */ - keymanweb.setTextBeforeCaret=function(e,t) - { - if(e && e.childNodes.length > 0) - { - var d=e.firstChild,tLen=0; - if(d.childNodes.length > 1) - { - var s1=d.childNodes[0],s2=d.childNodes[2]; - // Collapse (trailing) whitespace to a single space for INPUT fields (also prevents wrapping) - if(e.base.nodeName != 'TEXTAREA') t=t.replace(/\s+$/,' '); - if('textContent' in s1) s1.textContent=t; - else if('innerText' in s1) s1.innerText=t; - // Test total length in order to control base element visibility - tLen=t.length; - if('textContent' in s2) tLen=tLen+s2.textContent.length; - else if('innerText' in s2) tLen=tLen+s2.innerText.length; - } - } - - // Update the base element then scroll into view if necessary - keymanweb.updateBaseElement(e,tLen); //KMW-3, KMW-29 - keymanweb.scrollInput(e); - - } - - /** - * Description Get current position of caret in simulated input field - * - * @param {Object} e simulated input field DIV - * @return {number} caret character position in simulated input field - */ - keymanweb.getTextCaret=function(e) - { - return keymanweb.getTextBeforeCaret(e)._kmwLength(); - } - - /** - * Set current position of caret in simulated input field then display the caret - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @param {number} cp caret position (character index) - */ - keymanweb.setTextCaret=function(e,cp) - { - keymanweb.setText(e,null,cp); - keymanweb.showCaret(e); - } - - /** - * Handle the touch move event for an input element - * - * @param {Event} e touchmove event - */ - keymanweb.dragInput=function(e) - { - // Prevent dragging window - e.preventDefault(); e.stopPropagation(); - - // Identify the target from the touch list or the event argument (IE 10 only) - var target=(typeof e.targetTouches == 'object' ? e.targetTouches[0].target : e.target); - if(target == null) return; - - // Identify the input element from the touch event target (touched element may be contained by input) - if(target.className == null || target.className.indexOf('keymanweb-input') < 0) target=target.parentNode; - if(target.className == null || target.className.indexOf('keymanweb-input') < 0) target=target.parentNode; - if(target.className == null || target.className.indexOf('keymanweb-input') < 0) return; - - var x=(typeof e.touches == 'object' ? e.touches[0].screenX : e.screenX), - y=(typeof e.touches == 'object' ? e.touches[0].screenY : e.screenY); - - // Allow content of input elements to be dragged horizontally or vertically - if(typeof keymanweb.firstTouch == 'undefined' || keymanweb.firstTouch == null) - keymanweb.firstTouch={x:x,y:y}; - else - { - var x0=keymanweb.firstTouch.x,y0=keymanweb.firstTouch.y, - scroller=target.firstChild,dx,dy,x1; - - if(target.base.nodeName == 'TEXTAREA') - { - var yOffset=parseInt(scroller.style.top,10); - if(isNaN(yOffset)) yOffset=0; - dy=y0-y; - if(dy < -4 || dy > 4) - { - scroller.style.top=(yOffset 4) - { - // Limit dragging beyond the defined text (to avoid dragging the text completely out of view) - var xMin=0,xMax=util._GetAbsoluteX(target)+target.offsetWidth-scroller.offsetWidth-32; - if(target.base.dir == 'rtl')xMin=16; else xMax=xMax-24; - x1=xOffset-dx; - if(x1 > xMin) x1=xMin; - if(x1 < xMax) x1=xMax; - scroller.style.left=x1+'px'; - keymanweb.firstTouch.x=x; - } - } - } - keymanweb.setScrollBar(target); - } - - /** - * Scroll the input field horizontally (INPUT base element) or - * vertically (TEXTAREA base element) to bring the caret into view - * as text is entered or deleted form an element - * - * @param {Object} e simulated input field object with focus - */ - keymanweb.scrollInput=function(e) - { - if(!e || !e.firstChild || e.className == null || e.className.indexOf('keymanweb-input') < 0 ) return; - - var scroller=e.firstChild; - if(scroller.childNodes.length < 3) return; - - // Get the actual absolute position of the caret and the element - var s2=scroller.childNodes[1], - cx=util._GetAbsoluteX(s2),cy=util._GetAbsoluteY(s2), - ex=util._GetAbsoluteX(e),ey=util._GetAbsoluteY(e), - x=parseInt(scroller.style.left,10), - y=parseInt(scroller.style.top,10), - dx=0,dy=0; - - // Scroller offsets must default to zero - if(isNaN(x)) x=0; if(isNaN(y)) y=0; - - // Scroll input field vertically if necessary - if(e.base.nodeName == 'TEXTAREA') - { - var rowHeight=Math.round(e.offsetHeight/e.base.rows); - if(cy < ey) dy=cy-ey; - if(cy > ey+e.offsetHeight-rowHeight) dy=cy-ey-e.offsetHeight+rowHeight; - if(dy != 0)scroller.style.top=(y ex+e.offsetWidth-12) dx=cx-ex-e.offsetWidth+12; - if(dx != 0)scroller.style.left=(x x.base.rows+1) x.base.rows=calcRows; - } - ds.width=xs.width; ds.minHeight=xs.height; - } - else - { - ds.minWidth=xs.width; ds.height=xs.height; - } - x.base.style.visibility='hidden'; // hide by default: KMW-3 - - // Add an explicit event listener to allow the duplicated input element - // to be adjusted for any changes in base element location or size - // This will be called for each element after any rotation, as well as after user-initiated changes - // It has to be wrapped in an anonymous function to preserve scope and be applied to each element. - (function(xx){xx.base.addEventListener('resize',function(e){keymanweb.updateInput(xx);},false);})(x); - - // And copy the text content - keymanweb.setText(x,x.base.value,null); - } - } - - /********************************************************* - * - * End of main touch-device initialization. - * - *********************************************************/ - - /** - * Function setupDesktopPage - * Scope Private - * Description Save list of inputs for non-touch devices (desktop browsers) - */ - keymanweb.setupDesktopPage = function() - { - for(var k=0; k<2; k++) - { - var ipList=document.getElementsByTagName(k==0?'INPUT':'TEXTAREA'); - for(var n=0;n 0 && ipTextArea.length == 0) n=1; - else if(ipInput.length == 0 && ipTextArea.length > 0) n=2; - else if(ipInput[0].offsetTop < ipTextArea[0].offsetTop) n=1; - else if(ipInput[0].offsetTop > ipTextArea[0].offsetTop) n=2; - else if(ipInput[0].offsetLeft < ipTextArea[0].offsetLeft) n=1; - else if(ipInput[0].offsetLeft > ipTextArea[0].offsetLeft) n=2; - - switch(n) - { - case 0: - fs=fsDefault; - case 1: - fs=util.getStyleValue(ipInput[0],'font-family'); - case 2: - fs=util.getStyleValue(ipTextArea[0],'font-family'); - } - if(typeof(fs) == 'undefined' || fs == 'monospace') fs=fsDefault; - - return fs; - } - - /** - * Input element stub functions, redefined when a touch device is initialized - */ - - /** - * Function stub, for desktop browsers - * - * @param {Event=} e event - */ - keymanweb.setFocus = function(e){}; - keymanweb.timerID = null; - - /** - * Function stub, for desktop browsers - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @return {string} entire text in simulated input field - */ - keymanweb.getText = function(e){return '';}; - - /** - * Function stub, for desktop browsers - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @param {?string} t text to insert in element - * @param {?number} cp caret position (characters) - */ - keymanweb.setText = function(e,t,cp){}; - - /** - * Function stub, for desktop browsers - * - * @return {string} - */ - keymanweb.getTextBeforeCaret = function(){return '';}; - - /** - * Function stub, for desktop browsers - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @return {string} Context for simulated input field - */ - keymanweb.setTextBeforeCaret = function(e){}; - - /** - * Function stub, for desktop browsers - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @return {number} caret character position in simulated input field - */ - keymanweb.getTextCaret = function(e){return 0;}; - - /** - * Function stub, for desktop browsers - * - * @param {Object} e element (object) or element id (string) of simulated input field - * @param {number} cp caret character position in simulated input field - */ - keymanweb.setTextCaret = function(e,cp){}; - - /** - * Function stub, for desktop browser - */ - keymanweb.hideCaret = function(){}; - - /** - * Function stub, for desktop browsers - */ - keymanweb.flashCaret = function(){}; - - /** - * Function stub, for desktop browsers - * - * @param {Object} x element - */ - keymanweb.updateInput=function(x){}; - - // End of I3363 (Build 301) additions - - /** - * Exposed function to load keyboards by name. One or more arguments may be used - * - * @param {string|Object} x keyboard name string or keyboard metadata JSON object - * - */ - keymanweb['addKeyboards'] = function(x) - { - if(arguments.length == 0) - keymanweb.keymanCloudRequest('',false); - else - keymanweb.addKeyboardArray(arguments); - } - - /** - * Build 362: addKeyboardArray() link to Cloud. One or more arguments may be used - * - * @param {string|Object} x keyboard name string or keyboard metadata JSON object - * - */ - keymanweb.addKeyboardArray = function(x) - { - // Store all keyboard meta-data for registering later if called before initialization - if(!keymanweb['initialized']) - { - for(var k=0; k 0) - { - var pList=x[i].split('@'),lList=[''],tEntry; - if(pList[0].toLowerCase() == 'english') pList[0] = 'us'; - if(pList.length > 1) - { - lList=pList[1].split(','); - } - for(j=0; j 2) tEntry['version']=pList[2]; - keymanweb.cloudList.push(tEntry); - } - } - if(typeof(x[i]) == 'object' && x[i] != null) - { - // Register any local keyboards immediately: - // - must specify filename, keyboard name, language codes, region codes - // - no request will be sent to cloud - if(typeof(x[i]['filename']) == 'string') - { - if(!keymanweb.addStub(x[i])) - alert('To use a custom keyboard, you must specify file name, keyboard name, language, language code and region code.'); - } - else - { - lList=x[i]['language']; - - //Array or single entry? - if(typeof(lList.length) == 'number') { - for(j=0; j 1) && byLanguage ? 'languages' : 'keyboards') - +'?jsonp=tavultesoft.keymanweb.register'; - - // Set callback timer - tFlag='&timerid='+window.setTimeout( - function(){keymanweb.serverUnavailable(cmd);} - ,10000); - - Lscript.charset="UTF-8"; - Lscript.src = URL+cmd+tFlag; - Lscript.type = 'text/javascript'; - try { - document.body.appendChild(Lscript); - } - catch(ex) { - document.getElementsByTagName('head')[0].appendChild(Lscript); - } - } - - /** - * Add default or all keyboards for a given language - * - * @param {string} arg Language name (multiple arguments allowed) - **/ - keymanweb['addKeyboardsForLanguage'] = function(arg) - { - keymanweb.addLanguageKeyboards(arguments); - } - - /** - * Add default or all keyboards for a given language - * - * @param {Object} languages Array of language names - **/ - keymanweb.addLanguageKeyboards = function(languages) - { - var i,j,lgName,ll=keymanweb.languageList,cmd,first,addAll; - - // Defer registering keyboards by language until the language list has been loaded - if(ll == null) - { - first = (keymanweb.languagesPending.length == 0); - for(i=0; i 9) rIndex = 0; else rIndex = region-1; - } - else if(typeof(region) == 'string') - { - var list = (region.length == 2 ? keymanweb.regionCodes : keymanweb.regions); - for(var i=0; i=0; j--) - { - if('Keyboard_'+arguments[i] == ss[j]['KI'] && ss.length > 1) - { - ss.splice(j,1); break; - } - } - } - // Always reset to the first remaining keyboard - keymanweb._SetActiveKeyboard(ss[0]['KI'],ss[0]['KLC'],true); - - // then update the UI keyboard menu - keymanweb.doKeyboardUnregistered(); - } - - - - /** - * Browser dependent initialization - */ - if(document.selection) // only defined for IE - { - var appVer=navigator.appVersion; - // Legacy support variables - if(typeof(document.createEventObject)=='undefined' && (appVer.indexOf('MSIE 5.0') >= 0 - || appVer.indexOf('MSIE 4.0') >= 0 || appVer.indexOf('MSIE 3.0') >= 0)) keymanweb.legacy=1; - else if(appVer.indexOf('MSIE 6.0') >= 0) keymanweb._IE = 6; - else if(appVer.indexOf('MSIE 7.0') >= 0) keymanweb._IE = 7; - else if(appVer.indexOf('MSIE 8.0') >= 0) keymanweb._IE = 8; - if(keymanweb._IE && document.compatMode=='BackCompat') keymanweb._IE = 6; - } - - // I732 START - Support for European underlying keyboards #1 - if(typeof(window['KeymanWeb_BaseLayout']) !== 'undefined') - osk._BaseLayout = window['KeymanWeb_BaseLayout']; - else - osk._BaseLayout = 'us'; - - - keymanweb._BrowserIsSafari = (navigator.userAgent.indexOf('AppleWebKit') >= 0); // I732 END - Support for European underlying keyboards #1 - - /** - * Function _GetEventObject - * Scope Private - * @param {Event=} e Event object if passed by browser - * @return Event object - * Description Gets the event object from the window when using Internet Explorer - * and handles getting the event correctly in frames - */ - keymanweb._GetEventObject=function(e) // I2404 - Attach to controls in IFRAMEs - { - if (!e) - { - e = window.event; - if(!e) - { - e = keymanweb._GetLastActiveElement(); - if(e) - { - e = e.ownerDocument; - if(e) e = e.parentWindow; - if(!e) return null; - e = e.event; - } - } - } - 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 _IsAttached - * Scope Private - * @param {Object} Pelem Element to be tested - * @return {number} Returns 1 if attached, else 0 - * Description Tests whether or not KeymanWeb is attached to element - */ - keymanweb._IsAttached = function(Pelem) - { - for(var i = 0; i < keymanweb._AttachedElements.length; i++) - if(keymanweb._AttachedElements[i] == Pelem) return 1; - return 0; - } - - /** - * Function attachToControl - * Scope Public - * @param {Object} Pelem Element to which KMW will be attached - * Description Attaches KMW to control (or IFrame) - */ - keymanweb['attachToControl'] = keymanweb.attachToControl = function(Pelem) - { - // Check that the element is neither readonly nor disabled for KeymanWeb - var ro=Pelem.attributes['readonly'],cn=Pelem.className; - if(typeof ro == 'object' && ro.value != 'false' ) return; - if(typeof cn == 'string' && cn.indexOf('kmw-disabled') >= 0) return; - - if(Pelem.tagName.toLowerCase() == 'iframe') - keymanweb._AttachToIframe(Pelem); - else - { - util.attachDOMEvent(Pelem,'focus', keymanweb._ControlFocus); - util.attachDOMEvent(Pelem,'blur', keymanweb._ControlBlur); - Pelem.onkeypress = keymanweb._KeyPress; - Pelem.onkeydown = keymanweb._KeyDown; - Pelem.onkeyup = keymanweb._KeyUp; - } - // I1596 - attach to controls dynamically - if(!keymanweb._IsAttached(Pelem)) keymanweb._AttachedElements.push(Pelem); - } - - /** - * Function _AttachToIframe - * Scope Private - * @param {Object} Pelem IFrame to which KMW will be attached - * Description Attaches KeymanWeb to IFrame - */ - keymanweb._AttachToIframe = function(Pelem) - { - try - { - var Lelem=Pelem.contentWindow.document; - /* editable Iframe */ - if(Lelem) - { - if(Lelem.parentWindow) - { - // Internet Explorer - if(Lelem.designMode.toLowerCase() == 'on' || Lelem.body.isContentEditable) // I1295 - fix non-attachment for some forms of IFRAMEs - { - // I1480 - Attach to IFRAME instead of document - util.attachDOMEvent(Pelem,'focus', keymanweb._ControlFocus); - util.attachDOMEvent(Pelem,'blur', keymanweb._ControlBlur); - util.attachDOMEvent(Lelem,'keydown', keymanweb._KeyDown); // I2404 - Update for attaching to elements within IFRAMEs, don't attach to read-only IFRAMEs - util.attachDOMEvent(Lelem,'keypress', keymanweb._KeyPress); - util.attachDOMEvent(Lelem,'keyup', keymanweb._KeyUp); - - if(!keymanweb.legacy) - { // I1481 - Attach to the selectionchange in the iframe (and do a selchange to get the new selection) - /* IE: call _SelectionChange when the user changes the selection */ - util.attachDOMEvent(Lelem, 'selectionchange', keymanweb._SelectionChange); - keymanweb._SelectionChange(); - } - } - } - else - { - if(Lelem.designMode.toLowerCase() == 'on') - { - // Mozilla // I2404 - Attach to IFRAMEs child objects, only editable IFRAMEs here - util.attachDOMEvent(Lelem,'focus', keymanweb._ControlFocus); - util.attachDOMEvent(Lelem,'blur', keymanweb._ControlBlur); - util.attachDOMEvent(Lelem,'keydown', keymanweb._KeyDown); - util.attachDOMEvent(Lelem,'keypress', keymanweb._KeyPress); - util.attachDOMEvent(Lelem,'keyup', keymanweb._KeyUp); - } - else - { - keymanweb._AttachToControls(Lelem); // I2404 - Manage IE events in IFRAMEs - } - } - } - } - catch(err) - { - // do not attempt to attach to the iframe as it is from another domain - XSS denied! - } - } - - /** - * Function GetEnabled - * Scope Private - * @return {boolean} True if KMW enabled - * Description Test if KMW enabled - */ - keymanweb.GetEnabled = function() - { - return keymanweb._Enabled; - } - - /** - * Function SetEnabled - * Scope Private - * @param {(boolean|number)} Pvalue True to enable KMW - * Description Enable or disable KMW - */ - keymanweb.SetEnabled = function(Pvalue) - { - if(Pvalue) Pvalue=1; else Pvalue=0; - if(keymanweb._Enabled != Pvalue) - { - keymanweb._Enabled = Pvalue; - if((!Pvalue) && keymanweb['HideInterface']) keymanweb['HideInterface'](); //JMD 3/9/10 - } - } - - /** - * Function DisableControl - * Scope Private - * @param {Object} Pelem Element to be disabled - * Description Disable KMW control element - */ - keymanweb.DisableControl = function(Pelem) - { - var Ln, Lc; - for(Ln=0; Ln 1 && setFocus) - { - if(device.touchable) keymanweb.setFocus(); - else keymanweb['focusLastActiveElement'](); - } - } - - /** - * Function getUIState - * Scope Public - * @return {Object.} - * Description Return object with activation state of UI: - * activationPending (bool): KMW being activated - * activated (bool): KMW active - */ - keymanweb['getUIState'] = keymanweb.getUIState = function() - { - var p={}; - p['activationPending'] = p.activationPending = keymanweb._IsActivatingKeymanWebUI; - p['activated'] = p.activated = keymanweb._JustActivatedKeymanWebUI; - return p; - } - - /** - * Set or clear the IsActivatingKeymanWebUI flag (exposed function) - * - * @param {(boolean|number)} state Activate (true,false) - */ - keymanweb['activatingUI'] = function(state) - { - keymanweb._IsActivatingKeymanWebUI = (state ? 1 : 0); - } - -//TODO: add more complete description of what ControlFocus really does - - /** - * Respond to KeymanWeb-aware input element receiving focus - * - * @param {Event} e Event object - * @return {boolean} always true (?) - */ - keymanweb._ControlFocus = function(e) - { - var Ltarg, Ln; - if(!keymanweb._Enabled) return true; - e = keymanweb._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs - if(!e) return true; - if (e.target) Ltarg = e.target; - else if (e.srcElement) Ltarg = e.srcElement; - else return true; - - // Prevent any action if a protected input field - if(device.touchable && (Ltarg.className == null || Ltarg.className.indexOf('keymanweb-input') < 0)) return true; - - // Or if not a remappable input field - var en=Ltarg.nodeName.toLowerCase(); - if(en == 'input') - { - var et=Ltarg.type.toLowerCase(); - if(!(et == 'text' || et == 'search')) return true; - } - else if(en != 'textarea') return true; - - keymanweb._ActiveElement=Ltarg; // I3363 (Build 301) - - if (Ltarg.nodeType == 3) // defeat Safari bug - Ltarg = Ltarg.parentNode; - - var LfocusTarg = Ltarg; - - // Ensure that focussed element is visible above the keyboard - if(device.touchable && (Ltarg.className == null || Ltarg.className.indexOf('keymanweb-input') < 0)) keymanweb.scrollBody(Ltarg); - - if(Ltarg.tagName=='IFRAME') //**TODO: check case reference - { - keymanweb._AttachToIframe(Ltarg); - Ltarg=Ltarg.contentWindow.document; - } - - //??keymanweb._Selection = null; - keymanweb._ActiveControl = null; - keymanweb._LastActiveElement = Ltarg; - for(Ln=0; Ln < keymanweb._Controls.length; Ln++) // I1511 - array prototype extended - if(keymanweb._Controls[Ln].LControl == Ltarg) - { - keymanweb._ActiveControl = keymanweb._Controls[Ln]; - break; - } - - if(keymanweb._ActiveControl != null && keymanweb._ActiveControl.LDefaultInternalName != null) - { - if(!keymanweb._JustActivatedKeymanWebUI) - { - keymanweb._SetActiveKeyboard(keymanweb._ActiveControl.LDefaultInternalName,'',true); - } - else - keymanweb._ActiveControl.LDefaultInternalName = keymanweb._ActiveKeyboard == null ? '' : keymanweb._ActiveKeyboard['KI']; - } - - //TODO: the logic of the following line doesn't look right!! Both variables are true, but that doesn't make sense! - //_Debug(keymanweb._IsIEEditableIframe(Ltarg,1) + '...' +keymanweb._IsMozillaEditableIframe(Ltarg,1)); - if(!keymanweb._IsIEEditableIframe(Ltarg,1) || !keymanweb._IsMozillaEditableIframe(Ltarg,1)) - { - keymanweb._DisableInput = 1; - return true; - } - keymanweb._DisableInput = 0; - - if(!keymanweb._JustActivatedKeymanWebUI) - { - keymanweb._DeadKeys = []; - keymanweb._NotifyKeyboard(0,Ltarg,1); // I2187 - } - - if(!keymanweb._JustActivatedKeymanWebUI && keymanweb._SelectionControl != Ltarg) - keymanweb._IsActivatingKeymanWebUI = 0; - keymanweb._JustActivatedKeymanWebUI = 0; - - keymanweb._SelectionControl = Ltarg; - Ltarg._KeymanWebSelectionStart = Ltarg._KeymanWebSelectionEnd = null; // I3363 (Build 301) - - // Set element directionality (but only if element is empty) - keymanweb._SetTargDir(Ltarg); - - //Execute external (UI) code needed on focus if required - keymanweb.doControlFocused(LfocusTarg,keymanweb._ActiveControl); - - // Force display of OSK for touch input device, or if a CJK keyboard, to ensure visibility of pick list - if(device.touchable) - { - osk._Enabled=1; - } - else - { - // Conditionally show the OSK when control receives the focus - if(osk.ready) - { - if(keymanweb.isCJK()) osk._Enabled=1; - if(osk._Enabled) osk._Show(); else osk._Hide(false); - } - } - // TODO: This is possibly the main sequencing issue, as ControlFocus may get called before other elements - // are ready, or keyboards downloaded. Need some way to ensure that the OSK is displayed when everything is ready. - - - // We have slightly different focus management on IE to other browsers. This is because - // IE has problems with loss of focus when clicking on another element. This can probably - // be resolved in the future by using MouseDown and MouseUp events instead of Click events - // on the VK elements but for now we just use the smoother interaction on Firefox and Chrome, - // and let IE do the focus dance. This means some careful management of the - // IsActivatingKeymanWebUI and LastActiveElement variables, so be careful with any changes - // to these. - // if(keymanweb._IE) keymanweb._LastActiveElement = null; // I2498 - KeymanWeb OSK does not accept clicks in FF when using automatic UI - - return true; - } - - /** - * Function _IsIEEditableIframe - * Scope Private - * @param {Object} Pelem Iframe element - * {boolean|number} PtestOn 1 to test if frame content is editable (TODO: unclear exactly what this is doing!) - * @return {boolean} - * Description Test if element is an IE editable IFrame - */ - keymanweb._IsIEEditableIframe = function(Pelem,PtestOn) - { - var Ldv, Lvalid = Pelem && (Ldv=Pelem.tagName) && Ldv.toLowerCase() == 'body' && (Ldv=Pelem.ownerDocument) && Ldv.parentWindow; - return (!PtestOn && Lvalid) || (PtestOn && (!Lvalid || Pelem.isContentEditable)); - } - - /** - * Function _IsMozillaEditableIframe - * Scope Private - * @param {Object} Pelem Iframe element - * @param {boolean|number} PtestOn 1 to test if 'designMode' is 'ON' - * @return {boolean} - * Description Test if element is a Mozilla editable IFrame - */ - keymanweb._IsMozillaEditableIframe = function(Pelem,PtestOn) - { - var Ldv, Lvalid = Pelem && (Ldv=Pelem.defaultView) && Ldv.frameElement; - return (!PtestOn && Lvalid) || (PtestOn && (!Lvalid || Ldv.document.designMode.toLowerCase()=='on')); - } - - /** - * Respond to KMW losing focus on event - * - * @param {Event} e Event object - * @return {boolean} Always true (?) - */ - keymanweb._ControlBlur = function(e) - { - var Ltarg; - - if(!keymanweb._Enabled) return true; - - e = keymanweb._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs - if(!e) return true; - if (e.target) Ltarg = e.target; - else if (e.srcElement) Ltarg = e.srcElement; - else return true; - - keymanweb._ActiveElement = null; // I3363 (Build 301) - - // Hide the touch device input caret, if applicable I3363 (Build 301) - if(device.touchable) keymanweb.hideCaret(); - - if (Ltarg.nodeType == 3) // defeat Safari bug - Ltarg = Ltarg.parentNode; - - if(Ltarg.tagName=='IFRAME') - Ltarg=Ltarg.contentWindow.document; - - if (Ltarg.setSelectionRange) - { - //Ltarg._KeymanWebSelectionStart = Ltarg.selectionStart; - //Ltarg._KeymanWebSelectionEnd = Ltarg.selectionEnd; - Ltarg._KeymanWebSelectionStart = Ltarg.value._kmwCodeUnitToCodePoint(Ltarg.selectionStart); //I3319 - Ltarg._KeymanWebSelectionEnd = Ltarg.value._kmwCodeUnitToCodePoint(Ltarg.selectionEnd); //I3319 - - } - - ////keymanweb._SelectionControl = null; - - keymanweb._LastActiveElement = Ltarg; - - if(keymanweb._ActiveControl != null && keymanweb._ActiveControl.LDefaultInternalName != null) - if(keymanweb._ActiveKeyboard == null) - keymanweb._ActiveControl.LDefaultInternalName = ''; - else - keymanweb._ActiveControl.LDefaultInternalName = keymanweb._ActiveKeyboard['KI']; - - keymanweb._ActiveControl = null; - - if(!keymanweb._IsActivatingKeymanWebUI) keymanweb._NotifyKeyboard(0,Ltarg,0); // I2187 - - e = keymanweb._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs //TODO: is this really needed again???? - keymanweb.doControlBlurred(Ltarg,e,keymanweb._IsActivatingKeymanWebUI); - - // Hide the OSK when the control is blurred, unless the UI is being temporarily selected - if(osk.ready && !keymanweb._IsActivatingKeymanWebUI) osk._Hide(false); - - return true; - } - - /**************************************************************** - * - * Provide for external processing on events - * - ***************************************************************/ - - /** - * Function doControlBlurred - * Scope Private - * @param {Object} _target element losing focus - * @param {Event} _event event object - * @param {(boolean|number)} _isActivating activation state - * @return {boolean} - * Description Execute external (UI) code needed on blur - */ - keymanweb.doControlBlurred = function(_target,_event,_isActivating) - { - var p={}; p['target']=_target; p['event']=_event; p['isActivating']=_isActivating; - return util.callEvent('kmw.controlblurred',p); - } - - /** - * Function doControlFocused - * Scope Private - * @param {Object} _target element gaining focus - * @param {Object} _activeControl currently active control - * @return {boolean} - * Description Execute external (UI) code needed on focus - */ - keymanweb.doControlFocused = function(_target,_activeControl) - { - var p={}; p['target']=_target; p['activeControl']=_activeControl; - return util.callEvent('kmw.controlfocused',p); - } - - /** - * Execute external (UI) code needed on registering keyboard, used - * to update each UIs language menu - * - * Note that the argument object is not at present used by any UI, - * since the menu is always fully recreated when needed, but the arguments - * remain defined to allow for possible use in future (Aug 2014) - * - * @param {string} _internalName - * @param {string} _language - * @param {string} _keyboardName - * @param {string} _languageCode - * @return {boolean} - */ - keymanweb.doKeyboardRegistered = function(_internalName,_language,_keyboardName,_languageCode) - { - var p={'internalName':_internalName,'language':_language,'keyboardName':_keyboardName,'languageCode':_languageCode}; - return util.callEvent('kmw.keyboardregistered',p); - } - - /** - * Execute external (UI) code to rebuild menu when deregistering keyboard - * - * @return {boolean} - */ - - keymanweb.doKeyboardUnregistered = function() - { - var p={}; - return util.callEvent('kmw.keyboardregistered',p); - } - - /** - * Execute external (UI) code needed on laoding keyboard - * - * @param {string} _internalName - * @return {boolean} - */ - keymanweb.doKeyboardLoaded = function(_internalName) - { - var p={}; p['keyboardName']=_internalName; - return util.callEvent('kmw.keyboardloaded',p); - } - - /** - * Function doBeforeKeyboardChange - * Scope Private - * @param {string} _internalName - * @param {string} _languageCode - * @return {boolean} - * Description Execute external (UI) code needed before changing keyboard - */ - keymanweb.doBeforeKeyboardChange = function(_internalName,_languageCode) - { - var p={}; p['internalName']=_internalName; p['languageCode']=_languageCode; - return util.callEvent('kmw.beforekeyboardchange',p); - } - - /** - * Execute external (UI) code needed *after* changing keyboard - * - * @param {string} _internalName - * @param {string} _languageCode - * @param {boolean=} _indirect - * @return {boolean} - */ - keymanweb.doKeyboardChange = function(_internalName,_languageCode,_indirect) - { - var p={}; p['internalName']=_internalName; p['languageCode']=_languageCode; - p['indirect']=(arguments.length > 2 ? _indirect : false); - return util.callEvent('kmw.keyboardchange',p); - } - - /** - * Function doUnloadOSK - * Scope Private - * @return {boolean} - * Description Execute external (UI) code if any needed after unloading OSK (probably not required) - */ - keymanweb.doUnloadOSK = function() - { - var p={}; - return util.callEvent('kmw.unloadosk',p); - } - - /** - * Function doLoadUI - * Scope Private - * @return {boolean} - * Description Execute UI initialization code after loading the UI - */ - keymanweb.doLoadUI = function() - { - var p={}; - return util.callEvent('kmw.loaduserinterface',p); - } - - /** - * Function doUnloadUI - * Scope Private - * @return {boolean} - * Description Execute UI cleanup code before unloading the UI (may not be required?) - */ - keymanweb.doUnloadUI = function() - { - var p={}; - return util.callEvent('kmw.unloaduserinterface',p); - } - - /***************************************************************************** - * - * Provide for handling the initial focus event differently - * The first focus event can happen before we get the WindowLoad, - * e.g. if the page activates a control on WindowLoad itself, - * so trap that and run it through to the page - * - *****************************************************************************/ - - /** - * Function _BubbledFocus - * Scope Private - * @param {Event} e Event object - * Description Respond to KMW receiving bubbled focus on event (TODO: may not be needed, not currently doing anything) - */ - keymanweb._BubbledFocus = function(e) { /*KeymanWeb._WindowLoad(e);*/ } - - if (window.addEventListener) - window.addEventListener('focus', keymanweb._BubbledFocus, true); - - /** - * Function _GetKeyEventProperties - * Scope Private - * @param {Event} e Event object - * @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 - */ - keymanweb._GetKeyEventProperties = function(e) - { - var s = new Object(); - e = keymanweb._GetEventObject(e); // I2404 - Manage IE events in IFRAMEs - if(!e) return null; - - if(e.cancelBubble === true) return null; // I2457 - Facebook meta-event generation mess -- two events generated for a keydown in Facebook contentEditable divs - - if (e.target) s.Ltarg = e.target; - else if (e.srcElement) s.Ltarg = e.srcElement; - else return null; - if (s.Ltarg.nodeType == 3) // defeat Safari bug - s.Ltarg = s.Ltarg.parentNode; - - if (e.keyCode) s.Lcode = e.keyCode; - else if (e.which) s.Lcode = e.which; - else return null; - - s.Lmodifiers = - (e.shiftKey ? 0x10 : 0) | - (e.ctrlKey ? (e.ctrlLeft ? 0x20 : 0x20) : 0) | - (e.altKey ? (e.altLeft ? 0x40 : 0x40) : 0); // I3363 (Build 301) - - //s.LisVirtualKey = (e.charCode != null && (e.charCode == 0 || (s.Lmodifiers & 0x60) != 0)) || e.type != 'keypress'; - //s.LisVirtualKeyCode = false; - s.LisVirtualKeyCode = (typeof e.charCode != 'undefined' && e.charCode != null && (e.charCode == 0 || (s.Lmodifiers & 0x60) != 0)); - s.LisVirtualKey = s.LisVirtualKeyCode || e.type != 'keypress'; - - return s; - } - - /** - * Function _SelectionChange - * Scope Private - * @return {boolean} - * Description Respond to selection change event - */ - keymanweb._SelectionChange = function() - { - if(keymanweb._IgnoreNextSelChange) - { - keymanweb._IgnoreNextSelChange--; - } - else - { - var Ls=document.selection; - if(Ls.type.toLowerCase()!='control') // && document.selection.createRange().parentElement() == keymanweb._SelectionControl) // && window.event.srcElement == keymanweb._SelectionControl) - { - var Lrange=Ls.createRange(); - if(!keymanweb._Selection || !keymanweb._Selection.isEqual(Lrange)) - { - keymanweb._Selection = Lrange; - - /* Delete deadkeys for IE when certain keys pressed */ - keymanweb._DeadKeys = []; - } - } - } - return true; - } - -// TODO: find out if _FindCaret is still needed for current FireFox, delete if not - - /** - * Function _FindCaret - * Scope Private - * @param {Object} Pelem element - * Description Work around a problem with scrolling text boxes and input boxes in Firefox, not needed for other browsers - */ - keymanweb._FindCaret = function(Pelem) // I779 - { - if(!Pelem.createTextRange && Pelem.selectionStart) - { - var Levent=document.createEvent('KeyboardEvent'); - if(Levent.initKeyEvent) - { - Levent.initKeyEvent('keypress',true,true,null,false,false,false,false,0,32); - var LkeyPress = keymanweb._KeyPress; - - /** - * Function _KeyPress - * Scope Private - * @param {Event} e event - * Description Temporarily disable keypress event handling TODO: does this really work??? objects are passed by reference so should be OK - */ - keymanweb._KeyPress = function(e) {}; - Pelem.dispatchEvent(Levent); - Levent=document.createEvent('KeyboardEvent'); - Levent.initKeyEvent('keypress',true,true,null,false,false,false,false,8,0); - Pelem.dispatchEvent(Levent); - keymanweb._KeyPress = LkeyPress; - } - } - } - - /** - * Function _NotifyKeyboard - * Scope Private - * @param {number} _PCommand event code (16,17,18) or 0 - * @param {Object} _PTarget target element - * @param {number} _PData 1 or 0 - * Description Notifies keyboard of keystroke or other event - */ - keymanweb._NotifyKeyboard = function(_PCommand,_PTarget,_PData) // I2187 - { - if(keymanweb._ActiveKeyboard != null && typeof(keymanweb._ActiveKeyboard['KNS']) == 'function') keymanweb._ActiveKeyboard['KNS'](_PCommand,_PTarget,_PData); - } - - /** - * Function _KeyDown - * Scope Private - * @param {Event} e event - * @return {boolean} - * Description Processes keydown event and passes data to keyboard - */ - keymanweb._KeyDown = function(e) - { - var Ldv,eClass=''; - - keymanweb._KeyPressToSwallow = 0; - if(!keymanweb._Enabled || keymanweb._DisableInput || keymanweb._ActiveKeyboard == null || - (keymanweb._ActiveControl != null && !keymanweb._ActiveControl.LEnabled)) return true; - - // Prevent mapping element is readonly or tagged as kmw-disabled - var el=util.eventTarget(e); - if(device.touchable) - { - if(el && typeof el.kmwInput != 'undefined' && el.kmwInput == false) return true; - } - else if(el && el.className.indexOf('kmw-disabled') >= 0) return true; - - // Or if OSK not yet ready (for any reason) - if(!osk.ready) return true; - - // Get event properties - var Levent = keymanweb._GetKeyEventProperties(e); - if(Levent == null) return true; - switch(Levent.Lcode) - { - case 8: - keymanweb._DeadKeys = []; - break; // I3318 (always clear deadkeys after backspace) - case 16: - case 17: - case 18: - keymanweb._NotifyKeyboard(Levent.Lcode,Levent.Ltarg,1); - return osk._UpdateVKShift(Levent, Levent.Lcode-15, 1); // I2187 - } - - // I1207 - if((Ldv=Levent.Ltarg.ownerDocument) && (Ldv=Ldv.selection) && (Levent.Lcode<33 || Levent.Lcode>40)) - { - Ldv.createRange().select(); - } - - if(!window.event) - { - // I1466 - Convert the - keycode on mnemonic as well as positional layouts - // FireFox, Mozilla Suite - if(keymanweb._VKMap_FF_IE['k'+Levent.Lcode]) Levent.Lcode=keymanweb._VKMap_FF_IE['k'+Levent.Lcode]; - } - //else - //{ - // Safari, IE, Opera? - //} - - if(!keymanweb._ActiveKeyboard['KM']) - { - // Positional Layout - - var LeventMatched=0; - /* 13/03/2007 MCD: Swedish: Start mapping of keystroke to US keyboard */ - var Lbase=keymanweb._VKMap[osk._BaseLayout]; - if(Lbase && Lbase['k'+Levent.Lcode]) Levent.Lcode=Lbase['k'+Levent.Lcode]; - /* 13/03/2007 MCD: Swedish: End mapping of keystroke to US keyboard */ - - if(typeof(keymanweb._ActiveKeyboard['KM'])=='undefined' && !(Levent.Lmodifiers & 0x60)) - { - // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic - var Levent2={Lcode:keymanweb._USKeyCodeToCharCode(Levent),Ltarg:Levent.Ltarg,Lmodifiers:0,LisVirtualKey:0}; - if(keymanweb.callKeyboardStartGroup(Levent2.Ltarg,Levent2)) LeventMatched=1; - } - - LeventMatched = LeventMatched || keymanweb.callKeyboardStartGroup(Levent.Ltarg,Levent); - - // Support backspace in simulated input DIV from physical keyboard where not matched in rule I3363 (Build 301) - if(Levent.Lcode == 8 && !LeventMatched && Levent.Ltarg.className != null && Levent.Ltarg.className.indexOf('keymanweb-input') >= 0) - keymanweb.KO(1,keymanweb._LastActiveElement,""); - } - else - { - // Mnemonic layout - if(Levent.Lcode == 8) // I1595 - Backspace for mnemonic - { - keymanweb._KeyPressToSwallow = 1; - if(!keymanweb.callKeyboardStartGroup(Levent.Ltarg,Levent)) - keymanweb.KO(1,keymanweb._LastActiveElement,""); // I3363 (Build 301) - return false; //added 16/3/13 to fix double backspace on mnemonic layouts on desktop - } - else - keymanweb._KeyPressToSwallow = 0; - } - - if(!LeventMatched && Levent.Lcode >= 96 && Levent.Lcode <= 111) - { - // Number pad, numlock on -// _Debug('KeyPress NumPad code='+Levent.Lcode+'; Ltarg='+Levent.Ltarg.tagName+'; LisVirtualKey='+Levent.LisVirtualKey+'; _KeyPressToSwallow='+keymanweb._KeyPressToSwallow+'; keyCode='+(e?e.keyCode:'nothing')); - - if(Levent.Lcode < 106) var Lch = Levent.Lcode-48; - else Lch = Levent.Lcode-64; - keymanweb.KO(0, Levent.Ltarg, String._kmwFromCharCode(Lch)); //I3319 - - LeventMatched = 1; - } - - if(LeventMatched) - { - keymanweb._FindCaret(Levent.Ltarg); //I779 - if(e && e.preventDefault) e.preventDefault(); - keymanweb._KeyPressToSwallow = (e?e.keyCode:0); - return false; - } - else keymanweb._KeyPressToSwallow = 0; - - if(Levent.Lcode == 8) - { - /* Backspace - delete deadkeys, also special rule if desired? */ - // This is needed to prevent jumping to previous page, but why??? // I3363 (Build 301) - if(Levent.Ltarg.className != null && Levent.Ltarg.className.indexOf('keymanweb-input') >= 0) return false; - } - return true; - } - - keymanweb.callKeyboardStartGroup = function(Ltarg, Levent) { - keymanweb._CachedSelectionStart = null; // I3319 - keymanweb._DeadkeyResetMatched(); // I3318 - keymanweb.cachedContext.reset(); - return keymanweb._ActiveKeyboard['gs'](Ltarg, Levent); - } - - /** - * Function _KeyPress - * Scope Private - * @param {Event} e event - * @return {boolean} - * Description Processes keypress event (does not pass data to keyboard) - */ - keymanweb._KeyPress = function(e) - { - var Levent; - if(!keymanweb._Enabled || keymanweb._DisableInput || keymanweb._ActiveKeyboard == null || - (keymanweb._ActiveControl != null && !keymanweb._ActiveControl.LEnabled)) return true; - - Levent = keymanweb._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(!keymanweb._ActiveKeyboard['KM']) - { - if(!keymanweb._KeyPressToSwallow) return true; - if(Levent.Lcode < 0x20 || (keymanweb._BrowserIsSafari && (Levent.Lcode > 0xF700 && Levent.Lcode < 0xF900))) return true; - e = keymanweb._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 */ - - if(keymanweb._KeyPressToSwallow || keymanweb.callKeyboardStartGroup(Levent.Ltarg,Levent)) - { - keymanweb._KeyPressToSwallow=0; - if(e && e.preventDefault) e.preventDefault(); - keymanweb._FindCaret(Levent.Ltarg); // I779 - return false; - } - keymanweb._KeyPressToSwallow=0; - return true; - } - - /** - * Function _KeyUp - * Scope Private - * @param {Event} e event - * @return {boolean} - * Description Processes keyup event and passes event data to keyboard - */ - keymanweb._KeyUp = function(e) - { - var Levent = keymanweb._GetKeyEventProperties(e); - if(Levent == null || !osk.ready) return true; - - switch(Levent.Lcode) - { - case 13: - if(Levent.Ltarg.nodeName == 'TEXTAREA') break; - - // For input fields, move to next input element - if(Levent.Ltarg.type == 'search' || Levent.Ltarg.type == 'submit') - Levent.Ltarg.form.submit(); - else - keymanweb.moveToNext(false); - return true; - - case 16: - case 17: - case 18: keymanweb._NotifyKeyboard(Levent.Lcode,Levent.Ltarg,0); return osk._UpdateVKShift(Levent, Levent.Lcode-15, 1); // I2187 - } - - // I736 start - var Ldv; - if((Ldv=Levent.Ltarg.ownerDocument) && (Ldv=Ldv.selection) && Ldv.type != 'control') // I1479 - avoid createRange on controls - { - Ldv=Ldv.createRange(); - //if(Ldv.parentElement()==Levent.Ltarg) //I1505 - keymanweb._Selection = Ldv; - } - // I736 end - - //if(document.selection && document.selection.type=='Text') keymanweb._Selection=document.selection.createRange(); - //if(!KeymanWeb._Enabled) return true; - //if (!e) e = window.event; - return false; - } - -//TODO: check return of _KeyUp - what happens if returning true or false ?? what if null returned? - - /** - * Move focus to next (or previous) input or text area element on TAB - * Uses list of actual input elements - * - * Note that _ActiveElement on touch devices returns the DIV that overlays - * the input element, not the element itself. - * - * @param {number|boolean} bBack Direction to move (0 or 1) - */ - keymanweb.moveToNext=function(bBack) - { - var i,t=keymanweb.sortedInputs, - activeBase=keymanweb._ActiveElement; - - // For touchable devices, get the base element of the DIV - if(device.touchable) activeBase=activeBase.base; - - // Identify the active element in the list of inputs ordered by position - for(i=0; i= t.length) i=i-t.length; - if(i < 0) i=i+t.length; - - // Move to the selected element - if(device.touchable) - { - // Set focusing flag to prevent OSK disappearing - keymanweb.focusing=true; - var target=t[i]['kmw_ip']; - - // Focus if next element is non-mapped - if(typeof(target) == 'undefined') - { - t[i].focus(); - } - - // Or reposition the caret on the input DIV if mapped - else - { - keymanweb._ActiveElement=keymanweb._LastActiveElement=target; - keymanweb.setTextCaret(target,10000); - keymanweb.scrollInput(target); - } - } - // Behaviour for desktop browsers - else - { - t[i].focus(); - } - } - - /** - * Move focus to user-specified element - * - * @param {string|Object} e element or element id - * - **/ - keymanweb['moveToElement'] = function(e) - { - var i; - - if(typeof(e) == 'string') e=document.getElementById(e); - - if(device.touchable && e['kmw_ip']) - e['kmw_ip'].focus(); - else - e.focus(); - } - - /** - * Change active keyboard to keyboard selected by (internal) name and language code - * - * Test if selected keyboard already loaded, and simply update active stub if so. - * Otherwise, insert a script to download and insert the keyboard from the repository - * or user-indicated file location. - * - * @param {string} PInternalName - * @param {string=} PLgCode - * @param {boolean=} saveCookie - */ - keymanweb._SetActiveKeyboard = function(PInternalName,PLgCode,saveCookie) - { - var n,Ln,lgCode; - - // Set default language code - if(arguments.length < 2 || (!PLgCode)) lgCode='---'; else lgCode=PLgCode; - - // Check that the saved keyboard is currently registered - for(n=0; n= keymanweb._KeyboardStubs.length)) - { - PInternalName=keymanweb._KeyboardStubs[0]['KI']; lgCode=keymanweb._KeyboardStubs[0]['KLC']; - } - - // Save name of keyboard (with language code) as a cookie - if(arguments.length > 2 && saveCookie) keymanweb.saveCurrentKeyboard(PInternalName,lgCode); - - // Check if requested keyboard and stub are currently active - if(keymanweb._ActiveStub && keymanweb._ActiveKeyboard - && keymanweb._ActiveKeyboard['KI'] == PInternalName - && keymanweb._ActiveStub['KI'] == PInternalName //this part of test should not be necessary, but keep anyway - && keymanweb._ActiveStub['KLC'] == PLgCode - && !keymanweb.mustReloadKeyboard - ) return; - - // Check if current keyboard matches requested keyboard, but not stub - if(keymanweb._ActiveKeyboard && (keymanweb._ActiveKeyboard['KI'] == PInternalName)) - { - // If so, simply update the active stub - for(Ln=0; Ln 0) k = k0; - - if(k) - { - if(typeof(k['KLC']) != 'undefined') lg = k['KLC']; - else if(typeof(k['LanguageCode']) != 'undefined') lg = k['LanguageCode']; - } - - return ((lg == 'cmn') || (lg == 'jpn') || (lg == 'kor')); - } - keymanweb.isCJK = keymanweb['isCJK']; // I3363 (Build 301) - - /** - * Allow to change active keyboard by (internal) keyboard name - * - * @param {string} PInternalName Internal name - * @param {string} PLgCode Language code - */ - keymanweb['setActiveKeyboard'] = function(PInternalName,PLgCode) - { - //TODO: This does not make sense: the callbacks should be in _SetActiveKeyboard, not here, - // since this is always called FROM the UI, which should not need notification. - // If UI callbacks are needed at all, they should be within _SetActiveKeyboard - keymanweb.doBeforeKeyboardChange(PInternalName,PLgCode); - keymanweb._SetActiveKeyboard(PInternalName,PLgCode,true); - if(keymanweb._LastActiveElement != null) keymanweb._FocusLastActiveElement(); - keymanweb.doKeyboardChange(PInternalName,PLgCode); - } - - /** - * Function getActiveKeyboard - * Scope Public - * @return {string} Name of active keyboard - * Description Return internal name of currently active keyboard - */ - keymanweb['getActiveKeyboard'] = function() - { - if(keymanweb._ActiveKeyboard == null) return ''; - return keymanweb._ActiveKeyboard['KI']; - } - - /** - * Function getActiveLanguage - * Scope Public - * @return {string} language code - * Description Return language code for currently selected language - */ - keymanweb['getActiveLanguage'] = function() - { - if(keymanweb._ActiveStub == null) return ''; - return keymanweb._ActiveStub['KLC']; - } - -//TODO: find all references to next three routines and disambiguate!! - - /** - * Get keyboard meta data for the selected keyboard and language - * - * @param {string} PInternalName Internal name of keyboard - * @param {string=} PlgCode language code - * @return {Object} Details of named keyboard - * - **/ - keymanweb['getKeyboard'] = function(PInternalName,PlgCode) - { - var Ln, Lrn; - for(Ln=0; Ln 0 && typeof(arg)=='object' && arg != null) - { - for(var p in opt) - { - if(arg.hasOwnProperty(p)) opt[p] = arg[p]; - } - } - - // Get default root path and device options - if(opt['root'] == '') opt['root'] = keymanweb.rootPath; - - // Use root-relative paths for resources and keyboards unless set by page source - if(opt['resources'] == '') opt['resources']=opt['root']; - if(opt['keyboards'] == '') opt['keyboards']=opt['root']+'kbd/'; - if(opt['fonts'] == '') opt['fonts']=opt['root']+'font/'; - */ - - // Set default device options - keymanweb.setDefaultDeviceOptions(opt); - - // Only do remainder of initialization once! - if(keymanweb['initialized']) return; - - // Do not initialize until the document has been fully loaded - if(document.readyState !== 'complete') - { - window.setTimeout(function(){keymanweb.init(arg);},50); - return; - } - - keymanweb._MasterDocument = window.document; - - // Initialize and protect input elements for touch-screen devices (but never for apps) - // NB: now set disabled=true rather than readonly, since readonly does not always - // prevent element from getting focus, e.g. within a LABEL element. - // c.f. http://kreotekdev.wordpress.com/2007/11/08/disabled-vs-readonly-form-fields/ - if(device.touchable) - { - eTextArea=document.getElementsByTagName("textarea"); - eInput=document.getElementsByTagName("input"); - for(i=0; i