Archive for 12月, 2010

JavaScriptからメモリ情報を取得する方法

JavaScriptにおいてメモリ管理は基本的にエンジン任せなのであまり意識することは無いかもしれませんが、メモリリークの調査やパフォーマンスの実験のためにメモリ情報をJavaScriptから扱いたいときがあると思います。

Read the rest of this entry »

WebStorm/PhpStormの半額キャンペーンが1月10日まで延長

WebStorm/PhpStormの個人向けライセンスがクリスマスキャンペーンで半額になっていますが、ブログ記事では今年いっぱいの期限となっていましたが、購入ページを見ると2011年1月10日までと延長されていました。

Christmas pricing ends Jan 10, 2011.

WebStorm :: Licensing

という訳で、購入を検討している方は忘れないうちに決めるといいですよ。

LDR上ではてなブックマーク拡張を使ってはてブコメントを見るuserChrome.js

以前書いた、LDRではてなブックマーク拡張を通してはてブのコメントをみるTomblooパッチをuserChrome.jsを使って書き直してもっと使い易くしたものです。
概要的にははてなブックマーク拡張のコメントビューアー機能をuserChrome.jsからよびだしてLDRの記事についてるはてブコメントを表示するものです。(なのではてなブックマーク拡張はインストールしてないと使えません)

記事にフォーカスがあった状態でmを押すとはてなコメントビューアーが開きます。
jを押すと(次の記事に移動ショートカット)コメントビューアーが開いてたときは閉じるようにしてあります。

以下、技術的な話

まず、userChrome.jsをどうデバッグすればいいのか忘れたので、とりあえずFirebugのコンソールへ吐くlog関数を用意した。

// firebugのコンソールに出力
function fbug(x) {
    var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
    var Firebug = windowManager.getMostRecentWindow("navigator:browser").Firebug;
    if (Firebug.Console.isEnabled() && Firebug.toggleBar(true, 'console')) {
        Firebug.Console.logFormatted(Array.slice(arguments));
    }
    return x;
}

もっと手軽に呼べたような気がしたけど…

次はChrome側とContent側でやりとりする方法
Chrome側ってのはuseChrome.jsや拡張機能などのいわゆる特権持ってて何でもできてしまう実行範囲のこと
Content側ってのは通常のWebサイトの実行範囲のこと。

Chrome側からContent側をいじろうとすると、XPCNativeWrapperでラップされているのでそのままではアクセスできません。
wrappedJSObjectを使って回避するのはあまり望ましいやり方ではないと思うので、今回はMessageEventを利用してChromeとContentを行き来してみました。
コードの真ん中ら辺のメイン部分だけ取り出してみると

    // docはchrome側のdocument
    // Chrome側 - 受信
    doc.addEventListener("hatenaPingMessage", function (request) {
        var res = request.data;
        if (res === "hide") {
            hBookmark.CommentViewer.hide();
        } else {
            hBookmark.CommentViewer.toggle(res);
        }
    }, false);
    // Content側 - 送信
    evalInPage(function() {
        window.addEventListener("load", function() {
            window.Keybind.add('m', function(evt) {
                var item = window.get_active_item(true);
                var permalink = item.link.replace(/#/, '%23');
                pingToChrome(permalink);
            });
            var _j = window.Keybind._keyfunc.j;// jを保存してから書き換える
            window.Keybind.add('j', function(evt) {
                _j();
                pingToChrome("hide");
            });
        }, false);
        // Chrome領域へ通知
        function pingToChrome(message) {
            var request = document.createEvent("MessageEvent");
            request.initMessageEvent("hatenaPingMessage", true, false,
                    message,
                    location.protocol + "//" + location.host,
                    "", window);
            document.dispatchEvent(request);// =>hatenaPingMessage
        }
    }, []);
}
function evalInPage(func, args) {
    var argStr = JSON.stringify(args || []);
    safeWindow.location.href = "javascript:void " + func + ".apply(null," + argStr + ")";
}

まずはChrome側のdocumentにイベントを待ち受けるhatenaPingMessageというeventを受け取れるにします。
そして、Content側でスクリプトを実行するためにJavaScript:プロトコルハックを使ってブックマークレット的に実行します。
その中で、hatenaPingMessageというオレオレイベントを発火させるpingToChromeを作って、pingToChromeで発火したイベントをChrome側でキャッチしてChrome権限が必要な処理(はてなコメントビューアーを呼び出す)をしています。
Google Chromeの拡張とかで似たような仕組みになってた気がします。

MessageEventとJavaScript:プロトコルハック

Google Chrome関係のメモ

FirefoxのChromeについてのメモ

pingToChrome

Ustreamの録画済み動画をRSS購読する方法

USTREAMであるユーザーの録画済み動画をRSS購読したいと思ってRSSのURLを探したら存在したのでメモ。

http://www.ustream.tv/user/USERNAME というUSRNAMEの人のRSSは
http://www.ustream.tv/USERNAME-videos.rss というのがRSSになっているみたい。

たとえば、W2C_LIVEならW2C_LIVE の動画というのがRSSになって購読できる。

しかし、なんでこんな隠し要素みたいになってるんだ。

-videos.rss

Post Now browsing to Twitterで設定画面が開かないバグ修正

Post Now browsing to Twitterで設定画面がうまく開かない現象が起きていたみたいで、以前はGM_configというGUI用のライブラリを使っていたのですが、今回usconfigに移行しました。
なので、今まで設定画面が開かないなどの現象が起きていた人はインストールしなおしてください。
(おかしいときは ツール→Greasemonkey(もしくはステータスバーの猿アイコン)→ユーザースクリプトの管理→Post Now browsing to Twitterを選択→✓関連付けられた設定も削除にチェック→アンインストール → インストール)

こっからはGM_configからUSConfigへ移行方法について。

GM_configは前から少し不安定な感じがあったので、同種のライブラリであるUSConfigに変えました。
GM_configとUSConfigの違いを簡単に挙げてみると(移行するに当たっての変更点)

まずはGUIの書き方が別物なので、そこはすべて書き直す必要があります。

GM_configの場合

GM_config.init('Configuration for Post Now browsing to Twitter', {
    'defaultTag': {
        'label': 'Prefix:',
        'type': 'text',
        'default':'Now browsing: '
    },
    'isSelection': {
        'label': 'Use selectionQuote',
        'type': 'checkbox',
        'default':true
    },
    'ShortURL': {
        'label': 'Short URL',
        'type': 'select',
        'options': {
            'bit.ly': 'bit.ly',
            'j.mp': 'j.mp',
            'goo.gl': 'goo.gl',
            'is.gd': 'is.gd',
            'tinyurl.com': 'tinyurl.com'
        },
        'default':'bit.ly'
    },
    'ShortCutKey': {
        'label': 'ShortcutKey:',
        'type': 'text',
        'default':'CS-Enter'
    },
    'PostWithCtrl': {
        'label': 'Post with Ctrl+Enter:',
        'type': 'checkbox',
        'default': false
    },
    'bitlyUserName': {
        'section': ['bit.ly'],
        'label': 'bit.ly Username:',
        'type': 'text',
    'default':
        'remiko'
    },
    'bitlyAPIKey': {
        'label': 'bit.ly APIKey :',
        'type': 'text',
        'default': 'R_fa2240c646c07b2091x'
    }
}, configStyle , {
    open: function () {
        // ショートカットの入力補助
        var iframe = document.getElementById("GM_config");
        var iframeDoc = iframe.contentDocument;
        iframeDoc.getElementById("field_ShortCutKey").addEventListener('keydown', function (evt) {
            evt.preventDefault();
            this.value = shortcut.get(evt);
        }, false);
        // OAuth Setting
        if (TWOauth.isAuthorize()) {
            TWOauth.injectToConfig();
        } else {
            XHRloading.createText(iframeDoc);
            TWOauth.getRequestToken(TWOauth.injectToConfig);
        }
    },
    save: function () {

    } // reload the page when configuration was changed
});

USConfigの場合

Config.define('usc_basic', function() {
	with (this.builder) {
		var shortURL_opt = [
			'bit.ly',
			'j.mp',
			'goo.gl',
			'is.gd',
			'tinyurl.com'
		]
		dialog(
			"Post Now browsing to Twitter Settings",
			{ width: 600, height: 700 },

				section(
						"User options",
						"Behavior/keyboard Preference",
						grid(
								text("Prefix:", 'defaultTag', "Now browsing: ", { size: 20 }), '\n',
								checkbox("Use selection quote", 'isSelection', true), '\n',
								checkbox("Post with Ctrl+Enter", 'PostWithCtrl', false), '\n',
								text("ShortcutKey:", 'ShortCutKey', "CS-Enter", { size: 16 })
								)
						),
				section(
						"Short URL options",
						"select used Short URL service",

						grid(
								select("Short URL Services", 'ShortURL', shortURL_opt, "bit.ly"), '\n',
								text("bit.ly Username:", 'bitlyUserName', "remiko"), '\n',
								text("bit.ly APIKey :", 'bitlyAPIKey', 'R_fa2240c646c07b2091c6bc6d109089ef', { size: 30 })
								)
						),
				section(
						"OAuth Authorization",
						"Sign in with Twitter"
						)
				);
	}
}, {
	saveKey: 'GM_config',
	aftersave: function() {

	},
	afteropen : function() {
		// ショートカットの入力補助
		var iframeDoc = this.frame.contentDocument;
		iframeDoc.getElementById("control_ShortCutKey").addEventListener('keydown', function (evt) {
			evt.preventDefault();
			this.value = shortcut.get(evt);
		}, false);
		// OAuth Setting
		if (TWOauth.isAuthorize()) {
			TWOauth.injectToConfig();
		} else {
			XHRloading.createText(iframeDoc);
			TWOauth.getRequestToken(TWOauth.injectToConfig);
		}
	}
});

二つを見比べると、GM_configはオブジェクトを定義する感じだけど、USConfigはその都度関数を呼び出す感じになってる。レイアウトの自由度はUSConfigの方が上ですが、ちょっとインデント管理が大変で書きにくい。
またUSConfigではselectに連想配列っぽいオブジェクトを使えないので、配列に直す必要があります。
後、Text() のデフォルトサイズが少し小さいので第4引数で属性にsizeを追加してます。
最後の空sectionはafteropen時に書き換えるようにしてるので、本質とはあんまり関係ないです。
USConfigの方がConfig.define()でのコールバック(afteropenなど)が豊富なので、細かい制御がしやすいと思います。
そのコードバックで設定画面のiframeをとるにはthis.frameとすればよいみたいです。

次に設定情報の取り出し方
GM_configがそのつど、keyを指定してvalueを取り出す感じだったのが(GreasemonkeyのGM_getvalueに近い)

GM_config.get(key);// value

USConfigでは設定全部をまとめたオブジェクトを最初にロードする感じになっています

var settings = Config.load();
settings.key;// value

また、設定を保存するキーの初期値はGM_configと違うのでそのまま移行させるためにはsaveKeyを’GM_config’にします。

Config.define('dialog_name', function() { with (this.builder) {
  dialog(...);
}}, {
  saveKey: 'GM_config',
  aftersave: function() {...},
});

後はGM_config.*()がConfig.*()など細かい違いあるので、それを手直しすれば移行できました。
(GM_config.close()がConfig.remove()だったのが少しはまった)

USConfig

im.kayac.comを使って今見ているサイトをFirefoxからiPhoneへ送る

im.kayac.comというiPhoneへの通知を行うサービスがあるので、それを利用してFirefoxから今みているサイトのURLを送ってiPhoneからも簡単に開けるという感じのものを作ってみました。

準備するもの

  1. iPhoneのim.kayac.comアプリをダウンロード
  2. 登録してパスワードを設定する

インストール

Custom Buttonsのアドオンとして作ったので、Custom Buttons(Custom Buttons²)をインストールしておいて、下のボタンをクリックするとインストールできます。

URL to im.kayacURL to im.kayac

インストールしたら、Edit Buttonから

var username = "";
var password = "";

を自分の情報にあわせて入力すれば完了。

iPhoneへ送りたいサイトを開いた状態で、ボタンを押せばiPhoneへプッシュ通知ができます。

im.kayac.comのAPIがシンプルだったので10分ぐらいで作れましたが、かなり適当な作りしてます。

WebStormのコード補完に新しく候補を追加する方法

WebStorm/PhpStormEAP build 98.458でJavaScript Librariesのスコープを決定できる機能が追加されました。

なので、この方法が使えるのはWebStorm & PhpStorm 2.0以上(EAPビルド)の場合のみです。

Read the rest of this entry »

プロフィール: azu(アズ)
Firefoxの事やソフトウェアの紹介や使い道、Greasemonkeyの作成
  • OS:Windows Vista, 7
  • ブラウザ:Firefox
  • Twitterのアカウントはこちら
  • azu_re
  • メールアドレス(Twitterの方が確実)
  • info@ドメイン名
リンク