d.hetima RSSフィード

2010-06-14

終了時の状態を復元するSafari機能拡張 HsRestoreSession 公開

終了時の状態を復元するSafari機能拡張、HsRestoreSession を公開しました。SafariStandのRestore Last Workspaceと似たような機能です。問答無用で復元するのではなく、どのタブを復元するか選択できるページを表示します。

できないこと:

・履歴の復元

・fileプロトコルを表示しているページの復元

この辺はSafari機能拡張からアクセスすることができません。セキュリティはかなり厳しい。

・ページのサムネイルを表示

表示しているページのサムネイルを取得することはできるんだけどかなり大きなpngbase64エンコードした文字列のみ。開いているタブ全部を記録するのは厳しいので見送りました。ローカルにあるキャッシュを使う手もあるけれど、ファイル参照やfileプロトコルを扱えないので駄目。websnapr 系のサービスを使うのは検討中。

・ウィンドウの位置・サイズの復元

これはできそう

・復元前にタブの順番を入れ替える

これはJavaScriptを使いこなせればできるんだが!

結果的に SafariStand から機能を切り出したものになったけれど、すべての機能を移植するのは無理です。いや、ほとんどの機能は移植無理です。SIMBLが劇的ビフォーアフター並みに改造できるのに比べて、Safari機能拡張で出来るのは部屋の模様替えくらい。そのかわり安全性はずっと高いし、Windows版でも動く。

2010-06-12

Safari Extension のクラスリファレンスのようなもの

Safari Extensions Reference を参考に一瞥しやすいようにまとめました。言語仕様を無視したオレオレ表記方法ですみません。

global.html

終了時に body onunload で処理可能(アンインストール時にも呼ばれる)。

SafariExtensionSettings の値は Safari の初期設定ファイルに保存される(com.apple.Safari.plist に ExtensionSettings-extension.bundle.id-DEVELOPERID として)。

safari.application == SafariApplication
safari.extension == SafariExtension
safari.self == SafariExtensionGlobalPage

class SafariExtension{
  (readonly array)bars;
  
  //safari-extension://extension.bundle.id-DEVELOPERID/
  (readonly DOMString)baseURI;
  (readonly array)toolbarItems;
  (readonly SafariExtensionGlobalPage)globalPage;
  (readonly SafariExtensionSecureSettings)secureSettings;
  (readonly SafariExtensionSettings)settings;

  //whitelist と blacklist は optional
  //runAtEnd が true ならページのスクリプトを実行した後、false なら実行前にロード
  //add の返り値は remove するときに使う
  DOMString addContentScript(DOMString source, array whitelist, array blacklist, boolean runAtEnd);
  DOMString addContentScriptFromURL(DOMString url, array whitelist, array blacklist, boolean runAtEnd);
  void removeContentScript(DOMString url);
  void removeContentScripts();
  DOMString addContentStyleSheet(DOMString source, array whitelist, array blacklist);
  DOMString addContentStyleSheetFromURL(DOMString url, array whitelist, array blacklist);
  void removeContentStyleSheet(DOMString url);
  void removeContentStyleSheets();
}

class SafariApplication{
  (readonly array of SafariBrowserWindow)browserWindows;
  (readonly SafariBrowserWindow)activeBrowserWindow;

  SafariBrowserWindow openBrowserWindow();
  void addEventListener(DOMString type, function, boolean useCapture);
  void removeEventListener(DOMString type, function, boolean useCapture);
}

class SafariExtensionGlobalPage{
  (readonly DOMWindow)contentWindow;
}


class SafariBrowserTab{
  (readonly SafariBrowserWindow)browserWindow;
  (readonly SafariWebPageProxy)page;
  (readonly DOMString)title;
  (DOMString)url;

  void activate();
  void close();
  //base-64 でエンコードされた png データ。でかい。
  DOMString visibleContentsAsDataURL();
}

class SafariBrowserWindow{
  (readonly array of SafariBrowserTab)tabs;
  (readonly SafariBrowserTab)activeTab;
  (readonly boolean)visible;

  void activate();
  void close();

  //index がマイナスか大きすぎたら右端に追加
  //visibility = "foreground" or "background"
  SafariBrowserTab openTab (Optional DOMString visibility, Optional long index);
  void insertTab (SafariBrowserTab tab, long index);
}

class SafariWebPageProxy{
	void dispatchMessage (DOMString name, any message);
}
//設定の読み書き
safari.extension.settings.key = value;
var value = safari.extension.settings.key;

//inject.js からの message は target に SafariBrowserTab が入っている
safari.application.addEventListener("message", function(messageEvent) {
  if(messageEvent.name === "hoge") {
    messageEvent.target.page.dispatchMessage("re-hoge", "ok");
  }
},false);

//bundle 内のリソースのURL
var imageUrl = safari.extension.baseURI+"image.png";

inject.js

inject.js はフレームや iframe にもそれぞれ読み込まれる。

スクリプトを開始:」に指定するとページのスクリプトを実行する前に、「スクリプトを終了:」に指定するとページのスクリプトを実行した後にロードされる、と Safari Extensions Development Guide に書いてあった。正確なタイミングはよく分かりません。

safari.extension == SafariContentExtension;
safari.self == SafariContentWebPage;

//global.html の safari.extension と比べるとかなり制限されている。
class SafariContentExtension{
  (readonly DOMString)baseURI;
}

class SafariContentWebPage{
  (readonly SafariContentBrowserTabProxy)tab;
  void addEventListener(DOMString type, function, boolean useCapture);
  void removeEventListener(DOMString type, function, boolean useCapture);
}

class SafariContentBrowserTabProxy{
  //同期メッセージを送る messageEvent.name==="canLoad"
  any canLoad(BeforeLoadEvent event, Optional any message);
  //通常の dispatchMessage は非同期
  void dispatchMessage (DOMString name, Optional any message);
  void setContextMenuEventUserInfo(MouseEvent event, any userInfo);
}

//inject.js はフレームや iframe にもそれぞれ読み込まれる。メインのdocumentだけでやりたい処理は
if(window.top===window){
  
}
//とかするとよい

//上記 global.html のサンプルに対応するコード
safari.self.addEventListener("message", function(messageEvent) {
  if(messageEvent.name === "re-hoge") {
    alert(messageEvent.message);
  }
},false);
safari.self.tab.dispatchMessage("hoge");


extension bar.html

表示していなくてもロードはされる。

safari.extension == SafariExtension;
safari.application == SafariApplication;
safari.self == SafariExtensionBar;

class SafariExtensionBar{
  (readonly SafariBrowserWindow) browserWindow;
  (readonly DOMWindow)contentWindow;
  (readonly DOMString)identifier;
  (DOMString)label;
  (readonly boolean)visible;
  void hide(boolean doNotRemember);
  void show(boolean doNotRemember);
  void addEventListener(DOMString type, function, boolean useCapture);
  void removeEventListener(DOMString type, function, boolean useCapture);
}

2009-10-26

ATOK for Mac 無償試用版をアンインストールしても残ったファイル

ATOKの試用期限が切れそうだったのでアンインストールしたけれど以下のファイル群が削除されないままだった。

/Applications/JustSystems
/Library/Application Support/JustSystems
/Library/JustSystems

の各フォルダと

/Library/LaunchAgents/com.justsystems.launchd.jslmaUI.plist
/Library/LaunchAgents/com.justsystems.launchd.UpdateChecker.plist
/Library/LaunchDaemons/com.justsystems.launchd.jslmad.plist
/Library/LaunchDaemons/com.justsystems.OnlineUpdate.plist

のファイル。他にも ~/Library/Preferences/ などに設定やユーザー辞書も残る。

LaunchAgents と LaunchDaemons が問題で、これが残ったままだとアップデートチェックが稼働し続ける。自己責任で削除しますた。

2009-09-29

ATOKダイレクトプラグインを作ってみたwwwwwwwwww

egbridge の後継「かわせみ」が発表されたこのタイミングで作ってみたよ!

文字の間に「w」を挟み込むプラグイン。ruby で書きました。動作環境は ruby 1.8.7 以上。Snow Leopard は 1.8.7 でした。

f:id:hetima:20090929140051p:image

完全にネタですが、欲しい人は下記からどうぞ(同梱インストーラは Mac 用)。

ダウンロード

ソースはこんなです。

#! /usr/bin/ruby -Ku

module Atok_plugin

  def run_process( a_request_data )

    result_data = Hash.new
    candidate_array = Array.new
    
    # www
    result_a=""
    a_request_data["composition_string"].chars.each{|c|
        result_a+=c+"www"
    }
    candidate_array.push( { 'hyoki' => result_a+"w", 
                            'comment' => "半角" } )

    # www
    result_a=""
    a_request_data["composition_string"].chars.each{|c|
        result_a+=c+"www"
    }
    candidate_array.push( { 'hyoki' => result_a+"", 
                            'comment' => "全角" } )

    # 増えるwww
    result_a=""
    www="ww"
    a_request_data["composition_string"].chars.each{|c|
        www+="w"
        result_a+=c+www
    }
    candidate_array.push( { 'hyoki' => result_a, 
                            'comment' => "半角" } )

    # 増えるww
    result_a=""
    www="ww"
    a_request_data["composition_string"].chars.each{|c|
        www+=""
        result_a+=c+www
    }
    candidate_array.push( { 'hyoki' => result_a, 
                            'comment' => "全角" } )

    # 末尾www
    candidate_array.push( { 'hyoki' => a_request_data["composition_string"]+"wwwwwwwwww", 
                            'comment'=> "半角" } )

    # 末尾www
    candidate_array.push( { 'hyoki' => a_request_data["composition_string"]+"wwwwwwwwww", 
                            'comment' => "全角" } )

    result_data[ 'candidate' ] = candidate_array
    result_data

  end
end

ATOKダイレクトプラグイン、配布するのめんどくさい。個別にインストーラをつける必要があってサイズもでかい。インストーラは Mac と win で別々。

Mac では、

/Library/Application Support/JustSystems/ATOK/ATOK Direct/Plugins

にインストールされる。インストール後はログアウトが必要。いったんインストールしたらスクリプトファイルを書き換えると即座に反映されるので、機能修正はやりやすい。

試用している ATOK 2009 の期限が10月24日までなのでおそらく かわせみ に乗り換えることになるだろう。

2009-09-24

iTunes StoreにユーザーCSSを適用して表示をカスタマイズする

すげーひさしぶりに blog 書くよ!

iTunes 9.0.1 - soundscape out より。

iTunes Store が、WebKit を使用する様になり、フォント指定の先頭に「MS Pゴシック」が指定してあるっぽい。

とのこと。WebKit ということはユーザー定義の CSS が使える可能性があるので試してみる。

 *{
    font-family:"Lucida Grande" !important;
 }

とりあえずこんな感じのCSSを書いてファイル保存。

com.apple.iTunes.plist に WebKitUserStyleSheetEnabledPreferenceKey と WebKitUserStyleSheetLocationPreferenceKey を設定。

defaults write com.apple.iTunes WebKitUserStyleSheetEnabledPreferenceKey -bool true
defaults write com.apple.iTunes WebKitUserStyleSheetLocationPreferenceKey "cssファイルのフルパス"

どうやらユーザー定義の CSS が使えるようです。

f:id:hetima:20090924073856p:image