Now browsing the archives for the 'General' category.

Firefox への Feedly Cloud 用フィードリーダー追加

Google Reader から Feedly Cloud へ乗り換えしたので、 Firefox のブックマークメニューの「このページを購読…」からフィードを追加できるようにした。

手順

(1) Firefox で Feedly Could を開く。

(2) Feedly Could を開いたタブで、スクラッチパッド(「ツール」→「Web 開発」→「スクラッチパッド」)を開く。

(3) 以下のコードを貼り付けて、「実行」する。

navigator.registerContentHandler(
    "application/vnd.mozilla.maybe.feed", 
    "http://cloud.feedly.com/#subscription/feed/%s", 
    "feedly"
);

(4) タブ内の上部に「”feedly” (cloud.feedly.com) をフィードリーダーとして追加しますか?」と通知バーが表示されるので、「フィードリーダーを追加」ボタンをクリックする。

(5) 以降、何らかのフィードを開いてブックマークメニューから「このページを購読…」を選択すると、フィードリーダーの一覧に「feedly」が表示されるようになる。

navigator.registerContentHandler によるフィードリーダーの追加は、現在開いているページと同一ドメインでないと許可されないので、必ず上記(1)の手順で Feedly Could を開いておくことが重要。

別解

エラーコンソールを開いて下記のコードを実行する。この場合、前述のような同一ドメインの制約はない。

Components.classes["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Components.interfaces.nsIWebContentHandlerRegistrar).
registerContentHandler(
    "application/vnd.mozilla.maybe.feed",
    "http://cloud.feedly.com/#subscription/feed/%s",
    "feedly",
    null
);

参考

Firefox へのフィードリーダーの追加 | MDN

TOP

XUL Document をタブで開いたときにタブにアイコンを表示する

アドオンマネージャ(about:addons)をタブで開いたとき、タブにアドオンを示すパズルピース型のアイコンが表示される。これを自分の拡張機能でも実現したい。

まず、XUL Document 内にXHTML名前空間でlinkタグを埋め込む。

<window title="My Add-on"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">

    <xhtml:link rel="shortcut icon" href="chrome://myaddon/skin/icon.png" />

    ...

</window>

これだけだとなぜかXULのレイアウトがバグるので、CSSでlinkタグを非表示にする。

    <xhtml:link rel="shortcut icon" href="chrome://myaddon/skin/icon.png" style="display: none;" />

TOP

Extend Firefox 3.5 Runners-Up 賞品

先日 Extend Firefox 3.5 の賞品が届いた。

またメッセンジャーバッグかよ、と思っていたが、中身はEeePC 1005HA (Seashell)。
なんでも、当初予定されていたメッセンジャーバッグが在庫切れだったらしい。

箱を開けると、真っ黒のEeePCが。

しかし、キーボードは英語配列!

まだ電源は入れていないが、当然OSも英語版Windows XPなんだろうな。
Ubuntuでもインストールして遊ぶか。

TOP

Windows Vista のバックアップと復元センター

Windows Vista のバックアップと復元センターをあらためて試し、バックアップ前と復元後の全ファイルを比較したところ、下記の拡張子を持ったファイルなどがバックアップ対象外となっていたようだ。

asp bak bat cgi chm dll exe ini jar js jsp manifest php pl vbs wsf

ちゃんとしたバックアップツールが無いかと探したところ BunBackup が良さそうなので乗り換えた。

TOP

拡張機能開発の一時休止のお知らせ

PCリカバリに伴い Windows Vista のバックアップと復元機能を使用したところ、「js」を含む特定の拡張子のファイルがごっそり消えたため、拡張機能開発をしばらくの間休止します。

TOP

Software Design 2009年1月号 : Firefox徹底カスタマイズ術

Software Design 2009年1月号

Software Design 2009年1月号|gihyo.jp … 技術評論社
第2特集
~Greasemonkey+α,Ubiquity,Vimperator,Firemacs,FireGestures~ Firefox徹底カスタマイズ術

TOP

Firefox 3ではじめる拡張機能開発|gihyo.jp … 技術評論社

特集:Firefox 3ではじめる拡張機能開発

第1回 最小構成でインストール
第2回 機能を実装する(前編)
第3回 機能を実装する(中編)
第4回 機能を実装する(後編)
第5回 localeパッケージによるローカライズ
第6回 skinパッケージによる装飾
第7回 インストーラの作成
第8回 電子署名済みアップデートマニフェストを用いた拡張機能の配布

TOP

Gmail の設定で Always use https を有効にすると Gmail Notifier で新着チェック不可

Gmail で最近追加されたオプション「Always use https」を有効にすると、 Gmail Notifier v1.0.25.0 にてメールの新着チェックができなくなった。 Gmail Notifier といっても、 Firefox 用のアドオンの方ではなく、 Google が公式に配布している方の話。

「gnotify.exe」をバイナリエディタで開き、「http://」の箇所を無理やり「https://」に変え、x00を一個削って全体のバイト長をそろえたら、無事に新着チェックできるようになった。

と思ったら、すでに Google から対策用パッチが配布されていた。

TOP

[Places] フォルダ内のブックマークを列挙する

Places データベースへの問い合わせ結果から得たブックマークのノードは nsINavHistoryResultNode インタフェースを実装するオブジェクトであるが、ブックマークフォルダは nsINavHistoryContainerResultNode インタフェースも合わせて実装しており、 childCount プロパティで子ノードの数を調べたり、 getChild メソッドで指定したインデックスの子ノードを取得することができる。
例えば、[Places] ビューと nsIPlacesView インタフェース の続きとして、右クリックしたブックマークフォルダ内の子ノードにアクセスするには、以下のようにすればよい。ただし、ビュー上でフォルダが開いていることを前提とする。

// assume that node is instanceof Ci.nsINavHistoryContainerResultNode and is open.
for (var i = 0; i < node.childCount; i++) {
    var childNode = node.getChild(i);
}

一方、ビュー上でフォルダが閉じた状態になっている場合、 childCount プロパティなどを使って子ノードへアクセスしようとすると NS_ERROR_NOT_AVAILABLE 例外がスローされる。そこで、ブックマークフォルダのノードの containerOpen プロパティへ true をセットすることで一時的にフォルダを開いてから子ノードへアクセスし、処理が終わった後に false をセットしてフォルダを閉じるようにする。以下は、引数で指定したブックマークフォルダ内のすべてのブックマークを再帰的に取得し、配列として返す関数である。

function flatChildNodes(aNode) {
    var ret = [];
    var closeOriginally = !aNode.containerOpen;
    if (closeOriginally)
        // if the folder is closed, open it.
        aNode.containerOpen = true;
    for (var i = 0; i < aNode.childCount; i++) {
        var childNode = aNode.getChild(i);
        if (PlacesUtils.nodeIsBookmark(childNode))
            ret.push(childNode);
        else if (PlacesUtils.nodeIsFolder(childNode) && 
                 !PlacesUtils.nodeIsLivemarkContainer(childNode))
        // call this function recursive
        ret = ret.concat(arguments.callee(childNode));
    }
    if (closeOriginally)
        // don't forget to restore the folder's original closed state
        aNode.containerOpen = false;
    return ret;
}

上記の例では、ビュー上に表示されているブックマークフォルダ、つまりデータベースへの問い合わせ結果が取得済みのブックマークフォルダを対象としていた。ビューへの表示が無い場面でフォルダ内のノードへアクセスするには、データベースへ問い合わせを行う必要がある。通常 Places データベースへの問い合わせを行うには、 nsINavHistoryService#getNewQuery でクエリオブジェクトを生成し executeQuery で実行するという手続きが必要であるが、 PlacesUtils.getFolderContents を使えばより単純なコードでフォルダ内のノードへアクセス可能である。

var result = PlacesUtils.getFolderContents(node.itemId);    // nsINavHistoryResult
var parentNode = result.root;
for (var i = 0; i < parentNode.childCount; i++) {
    var childNode = parentNode.getChild(i);
}

以下は、ブックマークフォルダの itemId プロパティを引数に、そのフォルダ内の全ブックマークを再帰的に取得して配列として返す関数である。

function flatChildNodes(aItemId) {
    var ret = [];
    var parentNode = PlacesUtils.getFolderContents(aItemId).root;
    for (var i = 0; i < parentNode.childCount; i++) {
        var childNode = parentNode.getChild(i);
        if (PlacesUtils.nodeIsBookmark(childNode))
            ret.push(childNode);
        else if (PlacesUtils.nodeIsFolder(childNode) && 
                 !PlacesUtils.nodeIsLivemarkContainer(childNode))
            // call this function recursive
            ret = ret.concat(arguments.callee(childNode.itemId));
    }
    return ret;
}

TOP

[Places] nsINavHistoryResultNode からブックマークの各種情報を取得する

[Places] ビューと nsIPlacesView インタフェースから引き続き、 Places データベースからの検索結果 (nsINavHistoryResult オブジェクト) から得たブックマークのノード (nsINavHistoryResultNode オブジェクト) について、各種情報を取得する。

ブックマークの種類

あるノードの種類を調べる、例えばフォルダかどうかを調べるには、 type プロパティを調べる。

if (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER)
    alert("The node is a folder.");

PlacesUtils には nodeIs* メソッドがたくさん用意されているので、こちらを使った方が便利。

if (PlacesUtils.nodeIsFolder(node))
    alert("The node is a folder.");
else if (PlacesUtils.nodeIsLivemarkContainer(node))
    alert("The node is a Live Bookmark.");

ブックマークのタグ

nsINavHistoryResultNode の tags プロパティではすべてのタグが「, 」で連結された文字列として取得できる。

var tags = node.tags;

一方、 nsITaggingService#getTagsForURI ですべてのタグを配列として取得することも可能。なお、 PlacesUtils.tagging は nsITaggingService へのショートカット、 PlacesUtils._uri は URI 文字列から nsIURI オブジェクトを生成する便利メソッドである。

var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(node.uri), {});

ブックマークのアノテーション

Places では、ブックマークの「説明」プロパティなどは、ブックマークアイテムに対するアノテーションのひとつとして管理されている。アノテーションを取得するには nsIAnnotationService#getItemAnnotation を使う。 PlacesUtils.annotations は nsIAnnotationService へのショートカット、 DESCRIPTION_ANNO はアノテーション名 “bookmarkProperties/description” である。

var desc = PlacesUtils.annotations.getItemAnnotation(node.itemId, DESCRIPTION_ANNO);

以下のように PlacesUIUtils の便利メソッドを使ってブックマークの itemId に対応する「説明」プロパティを取得することも可能。

var desc = PlacesUIUtils.getItemDescription(node.itemId);

ブックマークのアイコン

nsINavHistoryResultNode の icon プロパティから nsIURI オブジェクトとして取得可能。

var iconLink = node.icon ? node.icon.spec : null;

取得した URI は「moz-anno:favicon:http://en-us.www.mozilla.com/favicon.ico」のような特殊なプロトコルで示される。この URI をブラウザに直接貼り付けてみればわかるように、「moz-anno:」プロトコルはプロトコルハンドラによって自動的にアイコンの画像データへ変換される。

一方、あるブックマークの URL を引数としてアイコンの URL を取得するには、 nsIFaviconService#getFaviconForPage を使用する。 PlacesUtils.favicons は nsIFaviconService へのショートカットである。

var icon = PlacesUtils.favicons.getFaviconForPage(PlacesUtils._uri(node.uri));

アイコンの MIME 型と画像データを取得するには、 nsIFaviconService#getFaviconData を使用する。

var mimeType = {};
var iconData = PlacesUtils.favicons.getFaviconData(icon, mimeType, {});
mimeType = mimeType.value;

BASE64 形式の data: URI に変換するには以下のようにする。

var dataURI = "data:" + mimeType + ";" + "base64," + btoa(String.fromCharCode.apply(null, iconData));

TOP