全プロファイル共通の拡張機能をインストールする方法

別に変なHackでも何でもなく一般的な方法だと思うが、DOM Inspector等の様に全プロファイル共通の拡張機能を入れる方法を今更発見したので記事にしておく。

昨日Ubuntuをマシンに入れて遊んでいたのだが、面白いことにapt-getからFirefox拡張機能をインストールできる。

例えば、

sudo apt-get install firefox-greasemonkey
sudo apt-get install firefox-dom-inspector

で、前者はgreasemonkey、後者はDOM Inspectorが共通の拡張機能としてインストールされる。

インストールすると/usr/share/firefox-extensionsディレクトリにxpiファイルの中身が展開されていて、/usr/lib/firefox/extensions/GUIDからリンクが張られている。
まぁ要するに、Firefoxがインストールされているディレクトリ下のextensionsディレクトリにxpiファイルを展開した奴を突っ込んであげれば、全プロファイル共通の拡張機能を入れることが可能なのだ。どのプロファイルでも使いたい拡張機能を入れておけば、新たにプロファイルを作る度に拡張機能を入れ直す手間が省ける。

この方法はWindowsでも可能だ。WindowsにはシボリックリンクがないのでFirefoxインストールディレクトリに直接入れることになるが...。NTFSならシンボリックリンクが使えるみたい、というかCygwinで何気なくln -sを使ってたっけ...。nyiyonさん指摘ありがとう。

注意点

Firefoxインストールディレクト/extensions下のディレクトリ名はその拡張機能ID(GUIDまたはextensionName@organization.tldのような形式)でなければならない。これはxpiファイル内のinstall.rdfに記載されている。

IDの抜き取り方法

install.rdfはだいたい以下のようになっている。

install.rdfの例

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <Description about="urn:mozilla:install-manifest">
        <em:id>GUID または name@organization.tld</em:id><!-- ここを抜き取る -->
        <em:name>拡張名</em:name>
        <em:version>バージョン</em:version>
        <em:description>概要</em:description>
        <em:creator>作成者名</em:creator>
        <em:homepageURL>URL</em:homepageURL>
        <em:iconURL>アイコンのURL</em:iconURL>
        <em:targetApplication>
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>2.0</em:minVersion>
                <em:maxVersion>2.0.0.*</em:maxVersion>
            </Description>
        </em:targetApplication>
    </Description>
</RDF>

<!-- ここを抜き取る -->の部分がIDだ。

UNIX系OSなら以下のコマンドで抜き取ることができるだろう。

unzip -p <xpiFile> install.rdf | \
sed -ne '/em:targetApplication/,/\/em:targetApplication/d' \
    -e 's/.*\(em:id="\|<em:id>\)\(.*\)\("\|<\/em:id>\)/\2/p'

インストールスクリプト(For *nix)

他のディストリビューション等を使っている人はSHARE_DIR,FIREFOX_DIRを適時書き換えてほしい。
また、sudoまたはrootユーザで実行することを前提にしている*1

install_xpi.sh

#!/bin/sh

SHARE_DIR=/usr/share/firefox-extensions
FIREFOX_DIR=/usr/lib/firefox
#DEBUG=echo

usage() {
    echo "$0 <xpiFile>"
    exit 0
}
[ $# -lt 1 ] && usage

XPI_FILE=$1

getGUID() {
    unzip -p "${XPI_FILE}" install.rdf | \
    sed -ne '/em:targetApplication/,/\/em:targetApplication/d' \
        -e 's/.*\(em:id="\|<em:id>\)\(.*\)\("\|<\/em:id>\)/\2/p'
}

getName(){
    unzip -p "${XPI_FILE}" install.rdf | \
    sed -ne '/<em:localized>/,/<\/em:localized>/d' \
        -e 's/.*\(em:name="\|<em:name>\)\(.*\)\("\|<\/em:name>\)/\2/p' | \
    tr '[A-Z]' '[a-z]' | \
    sed 's/\s//g'
}

GUID=`getGUID`
EXTENSION_NAME=`getName`

echo "Extract \`${XPI_FILE}' to: \`${SHARE_DIR}/${EXTENSION_NAME}'"
echo "And Link \`${FIREFOX_DIR}/extensions/${GUID}' to the extract directory."
echo ""
echo "Install [y/N]?: "
read FLAG

if [ "$FLAG" = 'y' ] || [ "$FLAG" = 'Y' ]
then
    umask 0022
    $DEBUG unzip "${XPI_FILE}" -d "${SHARE_DIR}/${EXTENSION_NAME}"
    $DEBUG ln -s  "${SHARE_DIR}/${EXTENSION_NAME}" "${FIREFOX_DIR}/extensions/${GUID}"
else
    echo "Didn't install ${XPI_FILE}."
fi

インストールスクリプト(For Cygwin)

Cygwin(Windows)用にも作ってみた。シンボリックリンクを張らないのでコードはちょっと短くなっている。

install_xpi_cygwin.sh

#!/bin/sh

FIREFOX_DIR=`cygpath -ua "C:\Program Files\Mozilla Firefox"`
#DEBUG=echo

usage() {
    echo "$0 <xpiFile>"
    exit 0
}
[ $# -lt 1 ] && usage

XPI_FILE=$1

getGUID() {
    unzip -p "${XPI_FILE}" install.rdf | \
    sed -ne '/em:targetApplication/,/\/em:targetApplication/d' \
        -e 's/.*\(em:id="\|<em:id>\)\(.*\)\("\|<\/em:id>\)/\2/p'
}

GUID=`getGUID`

echo "Extract \`${XPI_FILE}' to: \`${FIREFOX_DIR}/extensions/${GUID}'"
echo ""
echo -n "Install [y/N]?: "
read FLAG

if [ "$FLAG" = 'y' ] || [ "$FLAG" = 'Y' ]
then
    $DEBUG unzip "${XPI_FILE}" -d "${FIREFOX_DIR}/extensions/${GUID}"
else
    echo "Didn't install ${XPI_FILE}."
fi

*1:でないとディレクトリに書き込めないよね