*** empty log message ***
[m17n/m17n-lib-js.git] / mim.js
diff --git a/mim.js b/mim.js
index 733d5d1..dc1fab8 100644 (file)
--- a/mim.js
+++ b/mim.js
@@ -23,6 +23,9 @@
 
 // Please note that the code is not yet matured.
 
+// Known bugs:
+// * MIM.get_preedit_pos () returns incorrect position sometimes.
+
 var MIM = {
   // URL of the input method server.
   server: "http://www.m17n.org/common/mim-js",
@@ -76,8 +79,8 @@ var MIM = {
   }
 };
   
-if (window.location.hostname == 'localhost')
-  MIM.server = 'http://localhost/mim';
+//if (window.location.hostname == 'localhost')
+//  MIM.server = 'http://localhost/mim';
 
 (function () {
   var keysyms = new Array ();
@@ -1010,7 +1013,7 @@ MIM.im_domain.DefType (MIM.State.prototype);
     if (node.nodeName != 'tags')
       return null;
     
-    var lang = null, name = null, extra = null;
+    var lang = null, name = null, extra = null, im;
     for (node = node.firstElement (); node; node = node.nextElement ())
       {
        if (node.nodeName == 'language')
@@ -1032,9 +1035,13 @@ MIM.im_domain.DefType (MIM.State.prototype);
        if (! (im = MIM.imextra[lang][extra]))
          return null;
       }
-    if (im.load_status != MIM.LoadStatus.Loaded
-       && (im.load_status != MIM.LoadStatus.NotLoaded || ! im.Load ()))
-      return null;
+    if (im.load_status != MIM.LoadStatus.Loaded)
+      {
+       if (im.load_status == MIM.LoadStatus.NotLoaded)
+         im.Load ();
+       if (im.load_status != MIM.LoadStatus.Loading)
+         return null;
+      }
     return im;
   }
 
@@ -1043,6 +1050,7 @@ MIM.im_domain.DefType (MIM.State.prototype);
   parsers['description'] = function (node)
   {
     this.description = node.firstChild.nodeValue;
+    return true;
   }
   parsers['variable-list'] = function (node)
   {
@@ -1057,9 +1065,11 @@ MIM.im_domain.DefType (MIM.State.prototype);
          }
        vname = Xex.Term.Parse (this.domain, node)
       }
+    return true;
   }
   parsers['command-list'] = function (node)
   {
+    return true;
   }
   parsers['macro-list'] = function (node)
   {
@@ -1068,22 +1078,28 @@ MIM.im_domain.DefType (MIM.State.prototype);
        {
          var im = include (n);
          if (! im)
-           alert ('inclusion fail');
-         else
-           for (var macro in im.domain.functions)
-             {
-               var func = im.domain.functions[macro];
-               if (func instanceof Xex.Macro)
-                 im.domain.CopyFunc (this.domain, macro);
-             }
+           {
+             alert ('inclusion fail');
+             throw new Xex.ErrTerm (MIM.Error.ParseError, "inclusion fail: ");
+           }
+         if (im.load_status == MIM.LoadStatus.Loading)
+           return false;       // force reloading
+         for (var macro in im.domain.functions)
+           {
+             var func = im.domain.functions[macro];
+             if (func instanceof Xex.Macro)
+               im.domain.CopyFunc (this.domain, macro);
+           }
          n = n.previousSibling;
          node.removeChild (n.nextSibling);
        }
     Xex.Term.Parse (this.domain, node.firstElement (), null);
+    return true;
   }
   parsers['title'] = function (node)
   {
     this.title = node.firstChild.nodeValue;
+    return true;
   }
   parsers['map-list'] = function (node)
   {
@@ -1095,8 +1111,10 @@ MIM.im_domain.DefType (MIM.State.prototype);
            if (! im)
              {
                alert ('inclusion fail');
-               continue;
+               throw new Xex.ErrTerm (MIM.Error.ParseError, "inclusion fail: ");
              }
+           else if (im.load_status == MIM.LoadStatus.Loading)
+             return false;
            for (var mname in im.map_list)
              this.map_list[mname] = im.map_list[mname];
          }
@@ -1106,6 +1124,7 @@ MIM.im_domain.DefType (MIM.State.prototype);
            this.map_list[map.name] = map;
          }
       }
+    return true;
   }
   parsers['state-list'] = function (node)
   {
@@ -1116,7 +1135,12 @@ MIM.im_domain.DefType (MIM.State.prototype);
          {
            var im = include (node);
            if (! im)
-             alert ('inclusion fail');
+             {
+               alert ('inclusion fail');
+               throw new Xex.ErrTerm (MIM.Error.ParseError, "inclusion fail: ");
+             }
+           else if (im.load_status == MIM.LoadStatus.Loading)
+             return false;
            for (var sname in im.state_list)
              {
                state = im.state_list[sname];
@@ -1136,6 +1160,7 @@ MIM.im_domain.DefType (MIM.State.prototype);
          }
       }
     delete this.domain.map_list;
+    return true;
   }
 
   MIM.IM = function (lang, name, extra_id, file)
@@ -1149,33 +1174,35 @@ MIM.im_domain.DefType (MIM.State.prototype);
                                  + (this.name != 'nil'
                                     ? this.name : this.extra_id),
                                  MIM.im_domain, null);
+  };
+
+  function load_im (node, im)
+  {
+    //alert ('Loading IM (' + im + ':' + im.lang + '-' + im.name + ')');
+    im.map_list = {};
+    im.initial_state = null;
+    im.state_list = {};
+    for (node = node.firstElement (); node; node = node.nextElement ())
+      {
+       var name = node.nodeName;
+       var parser = parsers[name];
+       if (parser && ! parser.call (im, node))
+         {
+           im.Load ();
+           return;
+         }
+      }
+    //alert ('initial state = ' + im.initial_state);
+    im.load_status = MIM.LoadStatus.Loaded;
   }
 
-  var proto = {
+  MIM.IM.prototype = {
     Load: function ()
     {
-      var node = Xex.Load (MIM.server, this.file);
-      if (! node)
-       {
-         this.load_status = MIM.LoadStatus.Error;
-         return false;
-       }
-      this.map_list = {};
-      this.initial_state = null;
-      this.state_list = {};
-      for (node = node.firstElement (); node; node = node.nextElement ())
-        {
-         var name = node.nodeName;
-         var parser = parsers[name];
-         if (parser)
-           parser.call (this, node);
-       }
-      this.load_status = MIM.LoadStatus.Loaded;
-      return true;
+      this.load_status = MIM.LoadStatus.Loading;
+      Xex.Load (MIM.server, this.file, load_im, this);
     }
-  }
-
-  MIM.IM.prototype = proto;
+  };
 
   MIM.IC = function (im, target)
   {
@@ -1686,47 +1713,56 @@ MIM.im_domain.DefType (MIM.State.prototype);
       return (! this.key_unhandled
              && this.produced.length == 0);
     }
-  }
+  };
 
-  // Load the list of input methods.
-  var node = Xex.Load (MIM.server, "imlist.xml");
-  for (node = node.firstChild; node; node = node.nextSibling)
-    if (node.nodeName == 'input-method')
-      {
-       var lang = null, name = null, extra_id = null, file = null;
+  MIM.create_list = function (node)
+  {
+    // Load the list of input methods.
+    for (node = node.firstChild; node; node = node.nextSibling)
+      if (node.nodeName == 'input-method')
+       {
+         var lang = null, name = null, extra_id = null, file = null;
 
-       for (var n = node.firstChild; n; n = n.nextSibling)
-         {
-           if (n.nodeName == 'language')
-             lang = n.firstChild.nodeValue;
-           else if (n.nodeName == 'name')
-             name = n.firstChild.nodeValue;
-           else if (n.nodeName == 'extra-id')
-             extra_id = n.firstChild.nodeValue;
-           else if (n.nodeName == 'filename')
-             file = n.firstChild.nodeValue;
-         }
-       if (name && name != 'nil')
-         {
-           if (! MIM.imlist[lang])
-             MIM.imlist[lang] = {};
-           MIM.imlist[lang][name] = new MIM.IM (lang, name, extra_id, file);
-         }
-       else if (extra_id && extra_id != 'nil')
-         {
-           if (! MIM.imextra[lang])
-             MIM.imextra[lang] = {};
-           MIM.imextra[lang][extra_id] = new MIM.IM (lang, name, extra_id, file);
-         }
+         for (var n = node.firstChild; n; n = n.nextSibling)
+           {
+             if (n.nodeName == 'language')
+               lang = n.firstChild.nodeValue;
+             else if (n.nodeName == 'name')
+               name = n.firstChild.nodeValue;
+             else if (n.nodeName == 'extra-id')
+               extra_id = n.firstChild.nodeValue;
+             else if (n.nodeName == 'filename')
+               file = n.firstChild.nodeValue;
+           }
+         if ((lang == 'ja' && name == 'anthy')
+             || (lang == 'en' && name == 'ispell'))
+           continue;
+         if (name && name != 'nil')
+           {
+             if (! MIM.imlist[lang])
+               MIM.imlist[lang] = {};
+             MIM.imlist[lang][name] = new MIM.IM (lang, name, extra_id, file);
+           }
+         else if (extra_id && extra_id != 'nil')
+           {
+             if (! MIM.imextra[lang])
+               MIM.imextra[lang] = {};
+             MIM.imextra[lang][extra_id] = new MIM.IM (lang, name, extra_id, file);
+           }
+       }
+    if (MIM.imextra.t && MIM.imextra.t.global)
+      {
+       MIM.im_global = MIM.imextra.t.global;
+       MIM.im_global.Load ();
       }
-  if (MIM.imextra.t && MIM.imextra.t.global)
-    MIM.im_global = MIM.imextra.t.global;
-  else
-    {
-      MIM.im_global = new MIM.IM ('t', 'nil', 'global', null);
-      MIM.im_global.load_status = MIM.LoadStatus.Error;
-    }
-  node = undefined;
+    else
+      {
+       MIM.im_global = new MIM.IM ('t', 'nil', 'global', null);
+       MIM.im_global.load_status = MIM.LoadStatus.Error;
+      }
+    MIM.current = MIM.imlist['t']['latn-post'];
+    MIM.current.Load ();
+  }
 }) ();
 
 (function () {
@@ -2110,7 +2146,7 @@ MIM.keydown = function (event)
   if (! ic || ic.im != MIM.current)
     {
       target.mim_ic = null;
-      Xex.Log ('creating IC');
+      Xex.Log ('creating IC for ' + MIM.current.lang + '-' + MIM.current.name);
       ic = new MIM.IC (MIM.current, target);
       if (ic.im.load_status != MIM.LoadStatus.Loaded)
        return true;
@@ -2284,6 +2320,9 @@ MIM.keypress = function (event)
        var nodes = target.getElementsByTagName ('ul');
        for (var i = 0; i < nodes.length; i++)
          nodes[i].style.visibility = 'hidden';
+       nodes = target.getElementsByTagName ('pre');
+       for (var i = 0; i < nodes.length; i++)
+         nodes[i].style.visibility = 'hidden';
        document.getElementsByTagName ('body')[0].removeChild (target);
       }
   }    
@@ -2311,21 +2350,37 @@ MIM.keypress = function (event)
     if (last_target && target.parentLi != last_target)
       {
        last_target.style.backgroundColor = 'white';
-       if (target.menu_level < last_target.menu_level)
+       while (target.menu_level < last_target.menu_level)
          {
            last_target = last_target.parentLi;
            last_target.style.backgroundColor = 'white';
          }
-       var uls = last_target.getElementsByTagName ('ul');
-       for (var i = 0; i < uls.length; i++)
-         uls[i].style.visibility = 'hidden';
+       var nodes = last_target.getElementsByTagName ('ul');
+       for (var i = 0; i < nodes.length; i++)
+         nodes[i].style.visibility = 'hidden';
+       nodes = last_target.getElementsByTagName ('pre');
+       for (var i = 0; i < nodes.length; i++)
+         nodes[i].style.visibility = 'hidden';
       }
     last_target = target;
     target.style.backgroundColor = 'yellow';
     if (target.menu_level < 3)
       {
-       target.lastChild.style.visibility = 'visible';
-       target.lastChild.style.left = target.clientWidth + 'px';
+       if (false)
+         {
+           target.lastChild.style.visibility = 'visible';
+           target.lastChild.style.left = target.clientWidth + 'px';
+         }
+       else
+         {
+       var left = target.clientWidth;
+       for (var n = target.firstElement ().nextElement (); n; n = n.nextElement ()) 
+         {
+           n.style.visibility = 'visible';
+           n.style.left = left + 'px';
+           left += n.clientWidth;
+         }
+         }
       }
     event.preventDefault ();   
   }
@@ -2345,6 +2400,7 @@ MIM.keypress = function (event)
     if (target.im)
       {
        MIM.current = target.im;
+       MIM.current.Load ();
        destroy ();
       }
     event.preventDefault ();
@@ -2353,6 +2409,7 @@ MIM.keypress = function (event)
   function create_ul (visibility)
   {
     var ul = document.createElement ('ul');
+    ul.name = 'elm';
     ul.style.position = 'absolute';
     ul.style.margin = '0px';
     ul.style.padding = '0px';
@@ -2380,6 +2437,21 @@ MIM.keypress = function (event)
     return li;
   }
 
+  function create_sep ()
+  {
+    var sep = document.createElement ('pre');
+    sep.name = 'elm';
+    sep.innerHTML = ' ';
+    sep.style.position = 'absolute';
+    sep.style.margin = '0px';
+    sep.style.padding = '2px';
+    sep.style.border = '2px solid black';
+    sep.style.top = '-1px';
+    sep.style.backgroundColor = 'black';
+    sep.style.visibility = 'hidden';
+    return sep;
+  }
+
   var menu;
 
   function create_menu (event)
@@ -2403,6 +2475,7 @@ MIM.keypress = function (event)
          {
            var cat = lang_category[catname];
            var li = create_li (1, catname);
+           li.appendChild (create_sep ());
            var sub = create_ul ('hidden');
            for (var langname in cat)
              {
@@ -2411,6 +2484,7 @@ MIM.keypress = function (event)
                  continue;
                var sub_li = create_li (2, lang.name);
                sub_li.parentLi = li;
+               sub_li.appendChild (create_sep ());
                var subsub = create_ul ('hidden');
                for (var name in lang.list)
                  {
@@ -2438,6 +2512,6 @@ MIM.keypress = function (event)
     MIM.add_event_listener (window, 'keydown', MIM.keydown);
     MIM.add_event_listener (window, 'keypress', MIM.keypress);
     MIM.add_event_listener (window, 'mousedown', create_menu);
-    MIM.current = MIM.imlist['t']['latn-post'];
+    Xex.Load (MIM.server, "imlist.xml", MIM.create_list);
   };
 }) ();