コマンドラインでaddonsのアップデート

3.5になってから、:addons で 開いて更新ボタンを押してもエラーになるんで作ろうとしてみた。
(途中で、気づいたのですが、タブに開くのではなく
メニュから開いたり

:js BrowserOpenAddonsMgr()

で開いてあげれば、問題ないようです)


updateaddon list で 一覧表示
updateaddon check で 更新の確認
updateaddon update で 更新実行


updateは、かなり微妙です。
終了状態の取得が上手くいかなくて結果報告を完全に放置中ですorz
一応実装しました


addInstallListener か addDownloads の 第3引数のnsIObserver のどちらかで取得するんだと思うのですが、
適当に実装すると全く動かなくなる(;´д`)


DOM の addEventListener と 大分勝手が違うなぁ


あと、e4xを html作成に使ってみましたが便利ですねぇ


// vim:fdm=marker:
(function(){
	
  var T=//{{{ addonmanager
	{
    get extensions() T.extensionManager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION,{}),
    get plugins() T.pluginHost.getPluginTags({}),
    createTable:function(items,gene_body,gene_head){
      var table = <table class="update-addons"></table>;
      if(gene_head){
        let head = <thead></thead>;
        head.* += gene_head();
        table.* += head;
      }
      let body = <tbody></tbody>;
      for([,item] in Iterator(items)){
        body.* += gene_body(item);
      }
      table.* += body;
      return <>
        <style><![CDATA[
          .update-addons thead td{
            font-weight:bold;
            border-bottom: 1px dotted black
          }
          .update-addons tbody tr:nth-child(odd){
            background-color: #eee;
          }
          .update-addons td{
            padding: 0 0.5em;
          }
        ]]></style>
        {table}
      </>;
		}, 
		subcommand:{ ///{{{
			list:{
				desc: "show addon list" ,
				action:function(){
					const attrs = ["name","version", "minAppVersion","maxAppVersion"];

          var xml=T.createTable(T.extensions,function(item){
            var tr = <tr>
              <td>{template.icon({icon:item.iconURL},"")}</td>
            </tr>;
						for(let [,a] in Iterator(attrs)){
							tr.* += <td>{item[a]}</td>;
						}
            return tr;
          },function(){
            let tr = <tr>
              <td>icon</td>
            </tr>;
            for(let [,a] in Iterator(attrs)){
              tr.* += <td>{a}</td>;
            }
            return tr;
          });
					liberator.echo(xml);
				}
			},
			check:{
				desc: "check addon update" ,
				action :function(){
					checkes = {};
					var exts = T.extensions;
					T.extensionManager.update(exts , exts.length
						,Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION,{
						onUpdateEnded:function(){
              liberator.echo(T.createTable(T.extensions
              ,function(item) <tr>
                <td>{template.icon({icon:item.iconURL},"")}</td>
                <td>{item.name}</td>
                <td>{item.version}</td>
                <td>{T.state_msg[checkes[item.id]]}</td>
              </tr>
              ));
						},onUpdateStarted:function(){
						},onAddonUpdateEnded:function(addon,state){
							checkes[addon.id] = state;
						},onAddonUpdateStarted:function(){}
					});
				}
			},
			update:{
				desc: "download updated addon" ,
				action:function(){
					var ext = [ ex for([,ex] in Iterator(T.extensions)) if(ex.xpiURL)];
					if(ext.length > 0){
            addonInstallListener.showResult = true;
						T.extensionManager.addDownloads(ext, ext.length, null);
					}
				}
			}, 
			plugins:{
        desc:"plugin list",
				action:function(){
          var chk = {
            "false":<input type="checkbox" checked="true"/>
            ,"true":<input type="checkbox" disabled="true"/>
          };
          var x = T.createTable(T.plugins
            ,function(o) <tr>
              <td>{chk[o.disabled]}</td>
              <td>{o.name}</td>
              <td>{o.version}</td>
              <td>{o.description}</td>
            </tr>);
          liberator.echo(x);
        }
      }
    }, //}}}
		names:["updateaddon"],
    desc: "update addons",
    action:function(args){
			var command = T.subcommand[args[0]];
			if(command) command.action();
    },
		option:{
			completer:function(context,args){
				if(args.length <= 1){
					context.completions = [ [a, b.desc] for([a,b] in Iterator(T.subcommand))];
				}
			}
		},
		index:-1,
		removeInstallListener:function(){
			if(T.index >= 0){
				T.extensionManager.removeInstallListenerAt(T.index);
				T.index = -1;
			}
		},
  };//}}}

  T.state_msg = {};
  for(let a in Ci.nsIAddonUpdateCheckListener){
    let v = Ci.nsIAddonUpdateCheckListener[a];
    T.state_msg[v] = a.replace(/^STATUS_/,"");
  }

  T.extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
  T.pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);

	let addonInstallListener=//{{{
	{
		addons:[],
    showResult:false,
		//{{{ download event
		onDownloadStarted:function(addon){
		},
		onDownloadProgress:function(addon,value,maxValue){
		},
		onDownloadEnded:function(addon){
		},
		//}}}
		// {{{ install event
		onInstallStarted:function(addon){
		},
		onInstallEnded:function(addon){
			this.addons.push(addon);
		},
		onInstallsCompleted:function(){
      if(!this.showResult) return;
			liberator.echo(T.createTable(this.addons,function(item){
				return <tr>
					<td>{template.icon({icon:item.iconURL},"")}</td>
					<td>{item.name}</td>
					<td>{item.version}</td>
				</tr>;
			}));
			this.addons = [];
      this.showResult = false;
		},//}}}
	};//}}}
  T.index=T.extensionManager.addInstallListener(addonInstallListener);

  commands.addUserCommand(T.names, T.desc, T.action, T.option, true);
})();