Hatena::Grouporera

もし高校野球の女子マネージャーがOpera Browserを使ったら

logo
 | 

2009-07-20

Opera UniteでOperaアドオン

03:39

おもしろかったので紹介。

Opera Unite とウェブページで JSONP 通信して、アドオンのようなことを実現するサンプル。


これで使われている JSMigemo というのは、辞書ファイルを複数の XML に分割して、XMLHttpRequest で取りに行っている。ローカルサーバーで走っているのにこれだと効率が悪いので、せっかくなら辞書を1ファイルにしてしまおう、という話を別のブログに書いた。

作ったファイルがこれ。

これを使うように JSMigemo を修正するなら、変更点はこんな感じになる。

% diff -u migemo_orig.js migemo.js
--- migemo_orig.js	2009-07-20 19:58:50.000000000 -0400
+++ migemo.js	2009-07-20 14:23:08.000000000 -0400
@@ -276,79 +276,14 @@
   },
 
 
-  Dictionary: function  () {
-    // Dictionary class
-    this.createIndex = function() {
-      var doc = _migemo.xmlDocument(_migemo.joinPath(_migemo.dictdir_path,
-                                                     "dictindex.xml"));
-      var items = doc.getElementsByTagName("item");
-      for (var i=0; i<items.length; i++) {
-        var values = items[i].getElementsByTagName("value");
-        var pathList = [];
-        for (var j=0; j<values.length; j++) {
-          pathList.push(values[j].firstChild.nodeValue);
-        }
-        this._index[items[i].getAttribute("key")] = pathList;
-      }
-    }
-    
-    this.getLookupTable = function(xmldoc) {
-      var table = [];
-      var items = xmldoc.getElementsByTagName("item");
-      for (var i=0; i<items.length; i++) {
-        var candidates = new Array();
-        var valueElements = items[i].getElementsByTagName("value");
-        for (var j=0; j<valueElements.length; j++) {
-          candidates.push(valueElements[j].firstChild.nodeValue);
-        }
-        table.push({"key":items[i].getAttribute("key"),
-          "candidates": candidates});
-      }
-      table.sort(function(x,y) {return _migemo.compareStrings(x.key,y.key);});
-      return table;
-    }
-    
-    this.seek = function(path, key) {
-      result = new Array();
-      // load dictionary
-      var doc = _migemo.xmlDocument(_migemo.joinPath(_migemo.dictdir_path,
-                                                     path));
-      var dic = doc.getElementsByTagName("dictionary")[0].firstChild;
-      var text = dic.nodeValue;
-      // search matched lines
-      var lines = text.match(RegExp("^"+key+".*\n","mg"));
-      // for each line:
-      if (lines) {
-        for (var i=0; i<lines.length; i++) {
-          // add result to result
-          var values = lines[i].slice(0,-1).split("\t").slice(1);
-          result = result.concat(values);
-        }
-      }
-      // return result
-      return result;
-    }
-    
+  Dictionary: function(){
     this.lookup = function(key) {
-      var paths = this.getDictionaryPaths(key);
-      var values = new Array();
-      for (var i=0; i<paths.length; i++) {
-        values = values.concat(this.seek(paths[i], key));
-      }
-      return values;
-    }
-    
-    this.getDictionaryPaths = function(key) {
-      var paths = this._index[key.substring(0,1)];
-      if (typeof paths == "undefined") {
-        paths = [];
-      }
-      return paths;
+      var initial = key[0];
+      var candidates = migemoDict[initial];
+      var ans = [];
+      for(var word in candidates) if (!word.indexOf(key)) ans = ans.concat(candidates[word]);
+      return ans;
     }
-    
-    // initialization
-    this._index = {};
-    this.createIndex();
   },
 
   Node: function (value, children) {
@@ -394,22 +329,6 @@
     }
   },
 
-  xmlDocument: function (path) {
-    // download XML document located at path
-    var xmldoc;
-    if( window.ActiveXObject && /Win/.test(navigator.userAgent) ) {
-      xmldoc = new ActiveXObject("Microsoft.XMLDOM");
-      xmldoc.async = false;
-      xmldoc.load(path);
-    } else if( document.implementation && 
-             document.implementation.createDocument ) {
-      xmldoc = document.implementation.createDocument("", "", null);
-      xmldoc.async = false;
-      xmldoc.load(path);
-    }
-    return xmldoc;
-  },
-
   compareStrings: function (x, y){
     var result;
     if (x.slice(0,y.length)==y) {

つまり、_migemo.Dictionary を以下のものに変えて、さらに _migemo.xmlDocument を削除する、という意味。

  Dictionary: function(){
    this.lookup = function(key) {
      var initial = key[0];
      var candidates = migemoDict[initial];
      var ans = [];
      for(var word in candidates) if (!word.indexOf(key)) ans = ans.concat(candidates[word]);
      return ans;
    }
  },

それから、index.html のほうで新しい辞書を読んであげる。

  <script type="text/javascript; charset=utf-8" src="migemoDict.js"></script>
  <script type="text/javascript; charset=utf-8" src="migemo.js"></script>

XML ファイルは config.xml 以外全部消す。

ちょっとは速くなるかな? (ちゃんと比べてないのでわからない)


JSMigemo はこれ以外にも精度やパフォーマンスの問題を抱えているので、まだ効率向上の余地はあるはず。一度検索したものをキャッシュしたりなどなど。

(JSMigemo はちょっと古いので、XUL/Migemo の方が参考になる)

トラックバック - http://orera.g.hatena.ne.jp/edvakf/20090720
 |