まめ畑

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

Jetpack Settiongs JEPを使ってみた

Jetpack Ver0.6から取り込まれる予定のSettiongs JEPを使ってみました。
このJEPは、今までFeatureで使用する情報(IDなど)はFeature内でユーザに情報を登録させるようにコードを書いて、Jetpackのストレージに登録しないといけませんでしたが、Settiongs JEPが取り込まれることで簡単なmanifestを書くだけで設定フォームが自動生成されます。
Settings JEPの詳細は: Labs/Jetpack/JEP/24 - MozillaWikiを参照して下さい。
ユーザに入力させる値の型などが指定でき、それに応じてフォームが自動生成されます。
また将来的には、ユーザが準備したHTMLファイルをテンプレートにしてCSSもユーザで指定出来るようになり、好みのフォームが作成出来るようになるそうです。
将来追加されるかもしれないものとしては他に、バリデーションや設定の依存関係の項目があります。


今回は、Jetpack 0.6 pre3+Fx3.5.4を使用して試してみました。
Jetpackの最新β版のDLは: https://ubiquity.mozilla.com/jetpack-xpi/jetpack-latest-beta.xpi

以前作成した、見てるページをTwitterにポストする「見てるNow!」を少しいじってみました。
今までは、IDとPASSが未入力の際はプロンプトを表示していましたが、今回の変更で設定ページから登録が行えるようになりました。
DLは: http://userscripts.org/jetpacks/250から可能です。バージョンアップではなくベータ版として公開していますので、今まで使用されている方などで試して見たい方は、Jetpack 0.6 pre3をインストールし、現在の「見てるNow!」を削除後にインストールを行って下さい。


各Featureの設定ページを作成するには

var manifest = {
  settings: [
	{
	  name: "miterunow",
	  type: "group",
	  label: "Twitter Account",
	  settings: [
		{ name: "twitterId", type: "text", label: "Username" },
		{ name: "twitterPass", type: "password", label: "Password" }
	  ]
	}
  ]
};

の様に記述します。
Settings JEPのページに仕様の詳細が書かれていますが、様々な設定の記述方法が選べます。
複数のアカウントを管理する場合には、1つのmanifestに複数記述する事も可能です。
設定情報はJetpackのStorage APIを介して保存されます。ブラウザを閉じても保存されています。
しかし、typeにPasswordを指定するとpassword managerに登録されますが、呼び出しの方法は同じです。
password managerにマスターパスワードを設定していると、ブラウザを起動し初めてpassword manager内の情報を参照する際にマスターパスワードを求めるプロンプトが出ます。設定していない場合は表示されません。
また、プライバシーの設定でFirefox終了時にパスワード情報を削除するようにしていると、password manager内の情報が削除されてしまうので、ブラウザを起動する度に設定が必要になります。


呼び出す方法は

jetpack.storage.settings.miterunow.twitterId
jetpack.storage.settings.miterunow.twitterPass

といった感じです。
未入力時などに、設定ページを表示する

jetpack.settings.open();

というメソッドもあるのですが、上手く動作しませんでした。


設定ページは、「about:jetpack」ページの「Installed Featuresタブ」内の設定したいFeature→settingsのボタンをクリックすると表示されます。

このフォームに入力するとすぐに保存されます。
フォームを閉じるには、右上にカーソルを持っていくと、

のようなマークが表示されるので、これをクリックします。


簡単ですね。
1つだけ現状で注意しないといけない事は、設定情報はFeatureをPurgeしても自動的に削除されないという事です。この部分は自動的に削除するように改善して欲しいところです。
削除されるようになりました。
今まで設定をどうしようか悩んでたところが解決します。しかし、まだ不具合があるので正式リリースまで使いながら不具合を見つけていきたいと思います。


コード

/*
   @author: con_mame
   @url: http://d.hatena.ne.jp/con_mame/
   @title: Miteru Now!
   @description: POST Watching Site's Title, URL and Short Comment to Twitter
   @version: 0.9.1
*/


var manifest = {
  settings: [
    {
      name: "miterunow",
      type: "group",
      label: "Twitter Account",
      settings: [
        { name: "twitterId", type: "text", label: "Username" },
        { name: "twitterPass", type: "password", label: "Password" }
      ]
    }
  ]
};

(function(){
    jetpack.future.import("storage.settings");


   const TWITTER_ICON = "data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATExMG5mZmnjJysy/4eLm1u7w89ru8PPa7/D02+Hi5dasrK2iNDQzKwAAAAAAAAAAAAAAAAAAAAAAAAAAYWFhNN/f4cb///////7y///22f//89P///PU///z0///+OH//////8jIybkgICAVAAAAAAAAAAAAAAAAZmZmJOvs7c7///3//+u4//3Ygf/81HP//NRz//zUc//81HH//NV1///wyP/6/P/6fHx8TwAAAAAAAAAAAAAAAMnJypT//////uar//zSbP/8027//NNu//zSbf/80m3//NJt//zQZP//5af/+/z9/5ycnV4AAAAAAAAAAHJyciP4+f3h//TW//zTcv/803D//NNx//3YgP/93Iz//dyL//3bif/93ZL///jf//n6/edvb28xAAAAAAAAAACkpaVK+vr8+f/or//80mz//NNu//3dkf//9+f///34///89v///Pb///35//r7/O7FxsZuAAAAAAAAAAAAAAAAsrO0Vvn5+fz/5qb//NJs//zSbf/96rn////////////////////////////BwcKvNDQ0FwAAAAAAAAAAAAAAALCxsVb5+fr8/+an//zSbP/8027//eeu//767//++Ov//vjq//746v///PP/+fn6+6Kio5kTExMLAAAAAAAAAACwsbFW+fn6/P/mp//80m3//NRy//zWef/82ID//Nh///zYf//8133//dqF///22P/3+Pvzb29vRAAAAAAAAAAAsLGxVvn5+vz/5qf//NJt//zUc//81HH//NNu//zTbv/8027//NNu//zPZP//5aX//Pz9/5eXmGAAAAAAAAAAALCxsVb5+fr8/+an//zSbf/81HP//NV1//zWeP/81nj//NZ4//zVdv/8133///PQ//n6/fKGhoY/AAAAAAAAAACwsbFW+fn6/P/mp//80mz//NNu//zkqP//9uH///jh///23///9t7///vs///////S0tOTW1tbBAAAAAAAAAAAsrO0V/r6+v3/5aX//NFp//zRav/+6rn//P7//e7w88T19vmv8/T3s+zt767Y2Nltg4ODDQAAAAAAAAAAAAAAAKampj79/v/z/+/H//zUc//81nv///bb//P0+OSHh4gsAAAAAODg4AbFxcUEAAAAAAAAAAAAAAAAAAAAAAAAAABTU1MI7e3upf//////99////nk///////Dw8OFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJOTkxfW19eI5+nszujp7Mnb29t1dnZ2DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AMAwOABAMDAAWxpwAE+CoABICCAAyAggAMgIIABICCAASAggAEgIIABICCAASAggAMgIIBPICCA/yAgwP8gIA==";

   function getPageInfo(){
      var url = jetpack.tabs.focused.url;
      var title = jetpack.tabs.focused.contentDocument.title;
      var status = title + " " + url;
      return status;
   }

   function postToTwitter(){
      var cWindow =  jetpack.tabs.focused.contentWindow;
      var sStorage = jetpack.storage.settings.miterunow;

      if(!sStorage.twitterId || !sStorage.twitterPass){
        cWindow.alert("Set Your Twitter account.");
        return;
      }

      var tId = sStorage.twitterId;
      var tPass = sStorage.twitterPass;

      var status = "\u898B\u3066\u308B\u004E\u006F\u0077\u0021\u0020";
      var comment = cWindow.prompt("Input Short Comment", " ");
      if(!comment) return;
      comment = (comment != " ") ? comment : "";

      status = status + encodeURIComponent(comment+ " " + getPageInfo());
      var status = "status=" + status;

      $.ajax({
         type: "POST",
         url: "http://twitter.com/statuses/update.xml",
         username: tId,
         password: tPass,
         processData: false,
         data: status,
         success: function(msg){
            jetpack.notifications.show({
                                 title: "Update!",
                                 body: "Update Success",
                                 icon: TWITTER_ICON
            });
         },
         error: function(xtr, status, thrown){
            if(xtr.readyState == 4 && xtr.status == 401){
               sStorage.twitterId = "";
               sStorage.twitterPass = "";
            }
            jetpack.notifications.show({
                                 title: "Error!",
                                 body: status,
                                 icon: TWITTER_ICON
            });
         }
      });
   }

   jetpack.statusBar.append({
      html: <>
         <div id="message">
         <img src={TWITTER_ICON} />Miteru Now!!
         </div>
      </>,
      onReady: function(doc){
         $(doc).click(function(e){
            if(e.button == 2) return;
            postToTwitter();
         });

         $("#message", doc).css({
            position: "absolute",
            fontSize: "10pt",
            fontWeight: "bold",
            cursor: "pointer"
         });
      },
      width: 110
   });
})();