引用:
なので、commandDispatcher をかましてないのが原因かも? と思いました。
controllers = commandDispatcher なんでしょうか?
いいえ、this.controllersは、input,textarea要素についているネイティブ(?)のプロパティで、DOM Inspectorで見ると[object XULControllers]となっています。おそらく、nsIControllersではないかと思います。このオブジェクト配下にはcommandDispatcherもありますが、残念ながらnull値です。
あと、XUL Windowにはdocument.commandDispatcherがあるのですがHTMLドキュメントには存在しないようです。
また、先ほど同じbindingを施したものをchrome://...のURLからアクセスしてみましたが、きちんと動作しました。XBL自体もchrome://...の方においているのですが、Firefox外部のリソースにbindingすると外部リソースと同じく制限を受けてしまうようです。
しかし、通常のキーバインド、
コード:
<handler event="keypress" key="l" command="cmd_charNext"/>
は外部リソースでも動作します。動的にhandlerを追加/削除できれば良いのですが...
ついでなので今現在のソースを晒しておきます。
chrome://hogehoge/content/bindings/vi_input.xbl
コード:
<?xml version="1.0"?>
<bindings id="viInputBindings"
          xmlns="http://www.mozilla.org/xbl"
          xmlns:xbl="http://www.mozilla.org/xbl">
  <binding id="viInputFields">
    <implementation>
      <property name="mode"
                onget="return this.getAttribute('mode')"
                onset="this.setAttribute('mode',val); return val"/>
      <method name="doCommand">
        <parameter name="cmd"/>
          <body><![CDATA[
            var controller = this.controllers.getControllerForCommand(cmd);
            controller.doCommand(cmd);
          ]]></body>
       </method>
       <constructor><![CDATA[
          this.mode = this.hasAttribute('mode') ? this.getAttribute('mode') : 'insert';
          this.addEventListener('keypress',function(e){
            if(this.mode == 'normal'){
              switch(e.charCode){
                case 73: //`I'
                  this.doCommand('cmd_beginLine');
                case 105: //`i'
                  this.mode = 'insert';
                  break;
                case 104: //`h'
                  this.doCommand('cmd_charPrevious');
                  break;
                case 108: //`l'
                  this.doCommand('cmd_charNext');
                  break;
                }
              e.preventDefault();
            } else if(this.mode == 'insert'){
              if(e.keyCode == e.DOM_VK_ESCAPE){
                this.mode = 'normal';
            }
          }
         },true);
       ]]></constructor>
    </implementation>
  </binding>
</binding>
userContent.css
コード:
input {
-moz-binding: url(chrome://hogehoge/content/bindigns/vi_input.xbl#viInputFields);
}