まめ畑

ゆるゆると書いていきます

Jetpack0.5でComponents.classesを使用するには

以前、Jetpack 0.5に更新した時の注意メモ - まめ畑Jetpackを0.5に更新するとセキュリティ強化の影響でComponents.classesなどの特権が必要な機能にアクセス出来ないと書きましたが、アクセス可能な方法がありました。
フォーラムで質問が出ていて、それを読むまで忘れていましたがtabオブジェクトにrawというプロパティがあり、その説明に

The underlying XUL tab element that this tab represents. Access this as a last resort, since anything done with this object is subject to changes in the Mozilla platform.

と書かれている通り、JetpackのSandBoxの規制で触れないところも色々いじれるわけです。
しかし、いつ使えなくなるかわからないのであくまでどうしてもという時だけ使うという感じでしょうか。


という事で、Components.classesやComponents.interfacesを使いたい場合は以下の様に書きます。

var Cc = jetpack.tabs[0].raw.ownerDocument.defaultView.Cc;
var Ci = jetpack.tabs[0].raw.ownerDocument.defaultView.Ci;

//以下の様にも書けます
//jetpack.tabs.focused.raw.ownerDocument.defaultView.Cc
//jetpack.tabs.focused.raw.ownerDocument.defaultView.Cc

これらをFireFoxの起動と同時に起動するFeatureに使用する場合、tab中のページが読込まれていないとrawがnullになってしまっているため注意が必要です。
statusBarのonReady関数の様なDOMの構築が完了してから呼び出される箇所で使用する場合には問題ありません。


という事で、NicoDLを修正しました。
こちらからインストール出来ます: Nico DL

/*
   @author: con_mame
   @url: http://d.hatena.ne.jp/con_mame/
   @title: Nico DL
   @description: Download Movie File from NicoNico Douga
   @version: 0.2
*/

(function(){

   const ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAG5JREFUOE+tU+0OABAI5Jl6/2dDtjNaJR+34UdcXZdcGtILmAAgosLLghZP2mV50SNWCaIVdfm8IcPpuRCYwo0AejUq+ELgOSATXFeAh9cEs0PbJnr+byuQln7rgSnhdIgWCZjG6CzMdrt/IUJYAffFJ2uA33mhAAAAAElFTkSuQmCC";

   function getFlv(videoAddr){
	  try{
		 var Cc = jetpack.tabs[0].raw.ownerDocument.defaultView.Cc;
		 var Ci = jetpack.tabs[0].raw.ownerDocument.defaultView.Ci;
		 var saveFile = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
		 saveFile.init(jetpack.tabs.focused.contentWindow, "Save Nico Vide", Ci.nsIFilePicker.modeSave);
		 saveFile.defaultExtension = "flv";
		 saveFile.appendFilters(Ci.nsIFilePicker.filterAll);

		 var ret = saveFile.show();
		 if(ret == Ci.nsIFilePicker.returnCancel) return;
		 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
		 var url = ios.newURI(videoAddr, null, null);

		 var iwp = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(Ci.nsIWebBrowserPersist);
		 var trans = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer);
		 trans.init(url, saveFile.fileURL, videoAddr, null, null, null, iwp);
		 iwp.progressListener = trans;
		 iwp.saveURI(url, null, null, null, null, saveFile.file);
	  }catch(e){
		 console.log(e);
	  }
   }

   function showMessege(title, message){
	  jetpack.notifications.show({
		 title: title,
		 body: message,
		 icon: ICON
	  });
   }

   function doDownload(videoId){
	  $.ajax({
		 type: "GET",
		 url: "http://www.nicovideo.jp/api/getflv/" + videoId,
		 cache: false,
		 success: function(info){
			if(/&url=(.+?)&/.test(decodeURIComponent(info))){
			   getFlv(RegExp.$1);
			}else{
			   showMessege("Error", "Check Login");
			}
		 },
		 error: function(xtr, status, thrown){
			showMessege("Error", status);
		 }
	  });
   }

   jetpack.statusBar.append({
	  html: <>
		 <div id="dl"><img src={ICON}/>DL!</div>
	  </>,
	  onReady: function(doc){
		 $(doc).click(function(){
			var watchPage = jetpack.tabs.focused.url;
			if(/http:\/\/www.nicovideo.jp\/watch\/(.+)$/.test(watchPage)){
			   doDownload(RegExp.$1);
			}else{
			   return;
			}
		 });
		 $("#dl", doc).css({
			position: "absolute",
			paddingTop: "5px",
			fontSize: "12pt",
			fontWeight: "bold",
			cursor: "pointer"
		 });
	  },
	  width: 50
   });
})()