﻿
テキスト入力欄(TextArea, Input[type=text])で、
    キーボードの(英字)直接入力時に、チベット文字を入れるスクリプト。

● キー入力の仕方
    IME が効いている時は、無効！。
    またフォーカスが、テキスト入力欄に無いと、無効。
    ローマ字(英字)と、チベット文字の対応は、Wylie方式だが、
        母音以外の下接結合する文字を入れる時は、(基字であっても)、
            [Shift] + 文字キー とする。母音に[Shift]は不要。
  
  ▽ １文字の入力
      英字２～３文字で、チベット文字１字を表すものがあるので、
        キーを１つ押しただけでは決定できない場合がある。
      
      キー１つ目に [K][C][T][P][S][N][D] などが押された時は、次の入力を待つ。
          キー２つ目でも、１つ目が[T] →２つ目[S] なら、３文字目を待つ。
          これらは次に h が入るかも知れないので (他、d は z を、n は g, y を待つ)。
      
      例えば、[K] を押し、次に [H] を押せば、U+0F41(kh)を入れる(確定する)が、
          他のキーなら、U+0F40(k)を入れて(確定して)から、そのキーの処理へ進む。
        
        次の文字を入力しないで、U+0F40(k)を決めるには、
            [.]ドット または [Ctrl] または [Enter] を押す。
              [.]は、未決ある時は、未決定の文字を入れる。未決ない時は、空白文字を入れる。
              [Enter] は、未決ある時、TextArea(複数行入力欄)では改行しない。
                input[type=text](１行入力欄)では、要素の keypress を止める。
                  keyup も止めるが、それが出来ないHTA,IE では、
                    設定用object に cancelEnter という名前を作って、
                    true の値を入れるので、使う側でこれを判断する必要あり。
              [Ctrl] は、[Ctrl]キーで拡張的入力を行う設定の時は使えない。
      
      未決定である時に、[Esc]や [Delete]を押すと、保留していた文字を捨てる。
          またフォーカスを、この入力欄から離す事でも、未決定であった事は忘れる。
  
  ▽ 下接する字
      母音を除く下接するチベット文字( 頭を持つ時の基字と、下接字 y,r,l,w 
          (直前の文字位置へ戻り、その下に垂直に結合する文字)) を入れる時は、
      [Shift]キーと伴に英字キーを押すか、[+] を入れてから英字キーを押す。
          例えば、下接kh(U+0F91)は [Shift]+[K]→[H] か、[+]→[K]→[H]。
      
      但し ['] では、その前に [+] を押すことで、下接字と取るが、
          [Shift]キーではその判断はしない。(英字キーでないので、[Shift]のある無しで
              別の文字であるし、[Shift]が必要かはキーボードのレイアウトにより違うので)　
          またこの時は殆ど使われないらしい U+0FB0 でなく、小さい字形の U+0F71 を入れる。
      [A]キーは、[Shift]キーなしでは、無音価の基字の a U+0F68 が入るが、
          [Shift]キーある時は、その下接形ではなく、大文字 A に転写される
            下接の小さい ' U+0F71 (長母音を示す) を入れる。
            ( [+]→['] でも同じ符号が入るので、しつこいかも知れない。
              下接の ' U+0FB0 と、下接の a U+0FB8 は、[-]を使って入力(後述))　
      母音は、下接字と同様に結合する文字であるが、i,u,e,o を入れる時、
          [Shift]キーは使わない。 [Shift]を使った場合は、長母音などになる→拡張
  
  ▽ 区切りや符号
      音節区切りの点 Tsek(tsheg) U+0F0B は [  ](Space)キー。
      文や句の区切り Shey(shad) U+0F0D は [/]キー。 
      
      空白(Ascii \x20)は、[Shift]+[  ](Space)、または
          設定によるが、未決定の文字がない時の[.](dot)。
          (ブラウザによっては、[Ctrl]+[  ]でも、空白が入る。)　
      
      THLの拡張Wylie方式で、単純に1文字に転写されるものは、
          それが入るようにキーを押せば、(多分ほぼ)入る。例：
          [!] ->U+0F08, [*] ->U+0F0C, [;] ->U+0F0F, [|] ->U+0F11, [:] ->U+0F14,　
          など、記号キーはキーにより [Shift]+ が必要だったりはするが。
      少し難しいもの、
          // に転写される U+0F0E (nyi-shey)は、
              [-]→[/] と、先に [-] を一回押す方式とした。
          2文字に転写されるものでも続けて入れれば良いものは、例えば、
              ~X: ([Shift]+)[~]→[Shift]+[X] ->U+0F35  
                  # 下接する符号なので、[Shift]+[文字キー] なのだが、
                  #   この場合の[X]の[Shift]+は省略可能にしている。
                  #   X: [Shift]+[X] ->U+0F37 の [Shift]+ は省略できるようには
                  #     してない。小文字 x は使われていないようではあるが。
              oM: は、[-]→[o] で入る。
                  # 省略ではなく、これを文字通りに打つようにする方が難しい為。
          転写文字が無いものは、次のコード入力で。
  
  ▽ コード入力
      [\]キーを押すと次に、16進数字[0-9A-F]が続けて２つ押されるとし、
        チベット文字のコード U+0F?? の下2桁の指定とする。
        [\]の次、１つ目に [0-9A-F]以外が押されたら、[\]はキャンセルする。
        ２つ目にそれら以外が来た場合は、１つ目の数を U+0F0? の下１桁の指定と決めて進む。
  
  ▽ 拡張的入力
      [-]キーを押すと次のキー入力は、拡張的入力とする。
          転写の綴りの通りにキーを押せば、というようには出来ない所がある。
            下接の指示に[Shift]+を使った為、大文字に転写されるものに、
                [Shift]+を使えなので、[-]を押してから、文字キーを押す。
            THLの拡張Wylieの転写には、g+h といったものがあるが、Unicode には、
                これを(そのコード上で)、2文字で表すのと、1文字で表すのがある。
                この 1文字のものにも、[-]を使う。
            THLの拡張Wylieの転写には、母音類で、- が入るものがあり、
                -i(U+0F80)などは、転写の通りにキーを押すが、r-i(U+0F76) などは、
                [R]キーを押した時、未決とするのは煩わしいので、[-]を最初に
                入れるようにした。
            [-]を使わない拡張例： 転写 A,I,U は [Shift]+[A/I/U]。
                転写 ai, au については、転写綴りと全く異なるが、
                  [Shift]+[E], [Shift]+[O] と、使われてない E,O を用いた。
          ##以下で、他に使われてないなら最後まで文字を入れなくても、途中で決定する
          ##  ようにしてしまったのだが、これはまずかった。最後まで入れれて、
          ##  設定によって短縮可能にするように書き変えるべきと思う。
      
      反転字：[-]→[T] の次に [H]で Th(\u0F4B)、[H]以外で T(\u0F4A)が入る。
              [Shift]+で、[T]か[H]を押すと その下接字を入れる(以下同様に)。
          [-]→[D] の次に [H]以外で D(\u0F4C)が、[H]では D+h(\u0F4D)。
          [-]→[N] は N(\u0F4E)。 [-]→[S] で Sh(\u0F65)。
              拡張で S を使う字は他にないので、Sh に [H]は不要、[S]で決まる。
      重層字：[-]→[G]、[-]→[B] で g+h(\u0F43), b+h(\u0F57)が入る。
              拡張で g, b を使う字は他にないので、[G],[B]で決まる。
          d+h(\u0F52)は、[D]→[-]→[H]。 dz+h(\u0F5C)は、[D]→[-]→[Z]。
              先に[-]を押すと大文字 D から始まる転写字としてしまう。
              dz+h については、[H]は不要。
          k+Sh(\u0F69)は、[K]→[-]→[S]。[H]は不要。
          ※転写は + が入るのに、[-]を使うのはどうかとも思うが。
              例えば、d+h [D]→[+]→[H]とすると、下接の h が入って、\u0F51\u0FB7 の
              ２文字になり、[D]→[-]→[H] では、形は同じだが \u0F52 の１文字になる。
      全形： 上接 R+(\u0F6A)は、[-]→[R]→[.]　
             [-]→[R] では r-i, r-I かの判断を待ち、その→[I]以外で R+ とする。
          下接 +R(\u0FBC),+Y(\u0FBB),+W(\u0FBA)は、[-]→[Shift]+[R/Y/W]　
             +Y,+W については、[Shift]+ を使わなくても入る。
          下接の大きい '(\u0FB0)は [-]→['] ## [+]→['] は小さい方になる　
          下接の a(\u0FB8)は [-]→[Shift]+[A]　
      母音： 反転の -i(\u0F80)は [-]→[I]、 -I(\u0F81)は [-]→[Shift]+[I]　
          r-i(\u0F76)は [-]→[R]→[I]、 r-I(\u0F77)は [-]→[R]→[Shift]+[I]　
          l-i(\u0F78)は [-]→[L]→[I]、 l-I(\u0F79)は [-]→[L]→[Shift]+[I]　
          ※拡張入力に [-]を使う事にしたのは、母音の転写で - が使われる所から。
      修飾符号類： M(\u0F7E)は [-]→[M]、 H(\u0F7F)は [-]→[H]　
          # [-]→が不要なのは、[Shift]+[X]->X(\u0F37)、
          #   [^]->^(\u0F39)、(Shift+)[?]->?(\u0F84)、など
      他： [-]→[/] では、//(\u0F0E)を入れる。
           oM(\u0F00)は [-]→[O](英)、([\]→[0](数)→[0](数)でも入る。)　
    
    拡張入力で、[-]キーを使わないもの。
        母音： [Shift]+[A/I/U/E/O] で、A(\u0F71)(小さい')、I(\u0F73)、U(\u0F75)、
                  E は ai(\u0F7B)(ee)、  O は au(\u0F7D)(oo)
        先に[~]を押してからが、３つあり、
            ~X(\u0F35)は [~]→[X]、 ~M(\u0F83)は [~]→[M]、
                ~M`(\u0F82)は [~]→[`] で、[M]キーは使わない。
        X(\u0F37)(下接符)は、[Shift]+[X] 。
        [F]キーは ph^(\u0F55\u0F39)、[V]キーは b^(\u0F56\u0F39) に。
            これら[F/V]には、[Shift]+ はない。
        他、記号類は、記号キーを押せば入る。
  
  ▽ キーの種別には
    [A]～[Z]の文字キーと [']は、(非拡張の方式での) チベット文字の指定。
    [Shift]キー： [Shift]+英字キーは (英大文字でなく)、下接の字を指定する。
    [+]： 次に入力する英字キーを、下接の字の指定とする。
            ( + を入れるには多くの場合、多分、[Shift]が必要。)　
          垂直配置は上の様に指定するが、水平配置の指定は無い。何も指定しなければ、
            水平配置になるので、[-] や [.] については、次のように使う事にした。
    [-]： 次に入力する英字キーは、拡張入力の指定になる。
            [-]キーの後に、関係ない(拡張で使わない)キーを押した場合、
               [-]キーは消え、押されたキーの文字が入力される。
    [.]： 未決の文字ある時は、その文字を入れる。未決ない時は、空白文字を入れる。
            (設定で、未決を処理する以外は、何もしないようにもできる)。
    [  ](Spaceキー)： 音節区切り tsheg(Tsek)を入れる (設定で変更可能)。
          [Shift]+[  ] では、Space を入れる。
    [Ctrl]: 未決の文字ある時に押されたら、決定。
            設定によっては、拡張入力に使用(この場合は未決の決定はしない)。
    [Enter]: 未決の文字ある時は、その決定に使って、[Enter]の動作をなるべくさせない
            ようにした。
    [/]： 区切り shad(Shey) を入れる。
    [\]： 2桁コード入力、\u0F?? の下2桁を続けて入れる。
    [0]～[9]: チベット文字の数字を入れる。[\]を押した後はコード入力。
    
    チベット文字の入力に関係ないキーには、[Q]["][,][_] や []{}の括弧などがある。
          ( 非拡張のWylie方式ではもっと多く、[F][Q][V][X] の文字は使われない、
            記号では、['][/][ ][.] 以外は使われない。)
        その内、[,] と [Q] を次のように使う事にした。
    [,]： ['](U+0F60) を入れるか、空白(Space)を入れるか、設定(変数)で決める様にした。
          デフォルトは、['](U+0F60) にしてある。これはキーボードのレイアウトで、
             [Shift]+[7] が ['] なら便利だが、['] を直接入れられる場合は無意味かと思う。
    [Q]： キーからのチベット文字入力を止める(キーを押すと普通にローマ字が入る)。
          逆に切っている時に [Q] を押すと、チベット文字入力モードにする。
          なので欄へ、ローマ字(小文字) q を入れる事はできない。

  ▽ [Ctrl]+の拡張入力
      設定によって、拡張入力に、[-]→ の代わりに [Ctrl]キーが使えるようにできる。
      但し、[Ctrl]キーはアプリケーションやシステムが使うので問題あるかも知れない。
          コピペなどの編集操作の [Ctrl]+[A/Z/X/C/V/Y]などは使用不能になる。
              # [Ctrl]+[+/-/0] などはそのまま。
          という事で、これは使わないようにして、[Ctrl]+ を、[-]→ に置き換えた。
      一部、[-]→ と挙動の異なるもの(バグも含め)あり、
          R+ は [Ctrl]+[R] で入る。が、 r-i, r-I が入れられない。
          k+Sh が、[K]→[Ctrl]+[S] の他、[Ctrl]+[K] でも入る。
          [Ctrl]+[^] で、^(\u0F39) が入らない。
    
    その拡張入力の仕方、
      N,Sh: [Ctrl]+[N/S] 、下接は [Ctrl]+[Shift]+[N/S]　
      T,D: [Ctrl]+[T/D]→[.] (＝H以外の他キーで決定)　
          ## [Ctrl]+で拡張の時は、[Ctrl]は決定に使ってない。
      Th,D+h,g+h,b+h: [Ctrl]+[T/D/G/B]→[H] 、# [G/B] は [H]入力せず決定とした。
          下接は [Ctrl]+[T/D/G/B]→[Shift]+[H] 、[Ctrl]+[Shift]+[T/D/G/B]→[H]　
      d+h: [D]→[Ctrl]+[H] 、下接は [D]→[Ctrl]+[Shift]+[H]　
          ## [Ctrl]+[D]→[H] は、既に D+h としたので。
          ## [D]→[H]では、d の横に h が入る。[D]は、dz があるので、次の入力を待つが、
          ##    [H]は想定してなかった。d の横に h は見ない並びなので、[D]→[H]で、
          ##    d+h としても良いのかも知れない？。これは、g+h, b+h についても。
          ## [D]→[Shift]+[H] は、d.+h 、字形は d+h と同じだがコードは2文字。
      dz+h: [D]→[Ctrl]+[Z] 、[D]→[-]→[Z]  # →[H] は不要とした
      k+Sh: [K]→[Ctrl]+[S]  # →[H] は不要とした

      R+: [Ctrl]+[R]  
      +R,+W,+Y: [Ctrl]+[Shift]+[R/W/Y]、[Ctrl]+[W/Y] # +W,+Y は [Shift]無しも可。
          ## [Ctrl]+[R] で R+ を入れるようにした為、r-i, r-I が入れられなくなっていた。
          ## [-]→[R] の方は、これでは未決としているので、
          ##     [-]→[R]→[I] => r-i 、[-]→[R]→[Shift]+[I] => r-I
          ## [Ctrl]+[R]→[-]→[I] などは、見た形は同じだが、コードは2文字。
      [Ctrl]+[Shift]+[R] => +R  
          ## [-]→では2通り、[-]→[Shift]+[R] => +R  又は [-]→[+]→[R] => +R

      M(xF7E,結合文字): [Ctrl]+[M], ~M: [~]→[M], ~M`: [~]→[`], 
      X(xF37,結合文字): [Ctrl/Shift]+[X], ~X: [~]→[X] 
      oM: [Ctrl]+[O]
      ?(xF84): これは、[Ctrl]+[?](Shift+/) では入らない。文字キーとは異なり、
          [Ctrl]と共に押された記号キーのコードが良く分からないので扱えない。
          ## [-]→では、[-]→[?] # [?]は [Shift]+[/] 

      A,I,U: [Shift]+[A/I/U] 、
      -i: [-]→[I] 、 -I: [-]→[Shift]+[I]
          r-i,r-I,l-i,l+I: [-]→[R/L]→ [I]/[Shift]+[I] 
          ## この - が入った転写の処理から、[Ctrl]+ を [-]→ に
          ##   置き換える事を思いついた。

      下接全形の a: [Ctrl]+[Shift]+[A]
      下接全形の ': [-]→[']   ## [+]→['] は、小さい下接 ' とした。
          ## [Ctrl]+では記号キーの扱いは難しい。


● (関数の)使用法
    $set_key_evt_ipt_tib() 
        英字キーの直接入力から、入力欄へ、チベット文字を入れる様にセットする。
        １つのテキスト入力欄に、これを、一度だけ呼び出す。
      
      設定用object = $set_key_evt_ipt_tib( 要素, 関数1, 関数2, 設定用object )
          引数１つ目に、テキスト入力欄(TextArea, Input[type=text])の
              要素オブジェクトを指定。これ以外の引数は無くてもよい。
          以降の引数の関数は、コールバックする通知用。
          引数の設定用object は、初期状態の設定用。
          戻り値: 設定用object。これの下の変数の値を変更する事で、
              実行時の動作を変えられる。
          詳しくは、以下
  
  $set_key_evt_ipt_tib( elmIptTxt, fnGuide, fnOnChgEffect, oSetting ): oSetting
      引数：
      elmIptTxt: テキスト入力欄 TextArea, input[type=text] などの、
          要素object または id。
      
      fnGuide: 関数、コールバック用、(option)。
          待機状態の文字がある事を知らせ、引数には文字を渡す。
          待機状態の文字が無くなった時も呼び、引数には空文字。
      
      fnOnChgEffect: 関数、コールバック用、(option)。
          キーから入力の受け付けの開始時、中止時に これを呼び出す、
          開始時は true、中止時は false の引数とする。
      
      oSetting: object 設定用。(option)。{ 
               ccX2CKey: num, ccX2EKey: num, ccX20Key: num,
               swtchQ: num, swtchIME: num,
               keyExt: bool, ctrlExt: bool, effect: bool
            }
        設定用の object。引数であるが、戻り値でもある。
            引数としては初期設定に、戻り値では実行中の動作変更に用いる。
        
        effect: boolean 
            その入力欄で、チベット文字の直接入力が、有効か無効かの状態。
        
        ccX2CKey: number 0x27 or 0x20
            キー入力、[,] コンマで、何を入力するか。無指定(初期値)は 0x27。
            0x27(39)で、[']と同じく \u0F60 を入れる。
            0x20(32) で、空白文字を入れる。 (それら以外の値は無効)
        ccX2EKey: number //初期値 0x20(32)
            未決の文字が無い時に、[.] ドットキーで入れる文字。
              0x20(32) で、空白文字(\x20)を入れる。
              0x0B(11) で、Tsek(\u0F0B)を入れる。(それら以外の値は無効)
            [.]キーは、未決の文字がある時は、それを決めるのみ。
        ccX20Key: number //初期値 undefined
            この値が 0x20(32) なら、空白(space)キーが押され時、空白(\x20)を
              入れる。それ以外なら、Tsek(\u0F0B)を入れる。
        
        swtchQ: number //初期値 1
            trueなら [Ctrl]+[Q]キーを、スイッチ(入/切)に使う。
            1: [Ctrl]+[Q]で on/off する。使用中は [Ctrl]無しの[Q]でも off する。
            2: 非使用中にも、[Ctrl]無しの[Q]で入る。が小文字 q が入力出来なくなる。
               チベット文字専用なら 2 が便利、そうでないなら 1 が良い？。
            (実際は true なら使用、更にビットが & 2 なら非使用中にも[Q]のみで。)
            キーを使えるのは、その入力欄にフォーカスがある時のみ。
        swtchIME: number //初期値 0
            trueなら [Ctrl|Alt]+[全角/半角]キーを、スイッチ(入/切)に使う。
            true: [Ctrl]+ または [Alt]+ で on/off する。
            & 2: [Ctrl]+ は使わない。 & 4: [Alt]+ は使わない。
            キーを使えるのは、その入力欄にフォーカスがある時のみ。
        
        keyExt: boolean //初期値 true
            true で、[-]キーによる Wylie拡張(THLの方式)の入力を可能にする。
            false なら、基本的な Wylie のみ入力可能。
        ctrlExt: boolean //初期値 false
            true で、[Ctrl]キーを使っての拡張的入力を行う。
            これを使うのは、ブラウザのCtrlキーの使用と衝突するので問題ある。
    
        swtch: function //戻り値にのみ存在する、こちら側の関数。
           名前が switch では(古いブラウザで？)問題あるので、i を抜いた。
           戻り値.swtch( boolean ) の実行で、チベット文字の直接入力を
               開始したり、中断できる。
           直接、effect 変数の変更も出来るが、処理上問題あるかも知れないので。
               また、これで変更すれば、fnOnChgEffect() に通知が行く。
    
    戻り値: 
        戻り値は、上の設定用の object。引数に無ければ作り、あれば補正加筆して返す。
            引数に渡した場合には、戻り値はそれを指している。
        これの各変数の値を変更すると、動作を変更できる。
        また、有効無効の変更は、これに加えた、swtch メソッドの呼び出しでも可能。
    
    1行欄で、[Enter] 押されたたら、何か実行するコードについて、
        未決の文字がある時に、[Enter] 押された時、
            未決の文字を決定して、[Enter] の動作はキャンセルするようにしたつもりだが、
        要素.onkeyup については、やや問題あり。( keypress は長押してしまうと
            リピートするが、onkeyup は１度なのでこちらを使いたいと思うが)。
        addEventListener が無い、HTA(IE)では、この時、
            設定用object.cancelEnter = true とセットする事にした。
            要素.onkeyup では、これが true なら、実行しないように書いた方が良いと思う。
        addEventListener があるブラウザでは、keyup イベントの初期(キャプチャ)段階で
            捕まえて、要素.onkeyup 以降を止めるようにしたつもり。


● 使用法
    単純な使用例
    
    <script src="key_ipt_tib.js"></script>
    
    <textArea id="textArea01"></textArea>
    
    <script>
        oStt = $set_key_evt_ipt_tib( textArea01 )
    </script>


