貼り付けて送信
(function() { var mi = document.createElement('menuitem'); mi.setAttribute('label', '\u8cbc\u308a\u4ed8\u3051\u3066\u9001\u4fe1'); mi.setAttribute('accesskey', 's'); mi.setAttribute('id', 'context-pasteandsubmit'); mi.setAttribute('oncommand', 'gContextMenu.pasteAndSubmit(event)'); var pm = document.getElementById('context-paste'); var cm = pm.parentNode; cm.insertBefore(mi, pm.nextSibling); cm.addEventListener('popupshown', function(aEvent) { mi.hidden = pm.hidden || !document.popupNode.form; mi.disabled = pm.disabled; }, false); nsContextMenu.prototype.pasteAndSubmit = function(aEvent) { var node = this.target || document.popupNode; if (node instanceof HTMLTextAreaElement && !window.confirm('\u672c\u5f53\u306b\u9001\u4fe1\u3057\u307e\u3059\u304b\uff1f')) return; goDoCommand('cmd_paste'); Components.lookupMethod(node.form, "submit").call(node.form); setTimeout(function() { document.getElementById('PopupAutoComplete').hidePopup(); }, 100); }; })();
Visual C++ 2005 Express Edition で Firefox をビルドする
Linux で Firefox をビルドするのはわりと簡単で、Linux Prerequisites - Mozilla | MDN に書かれている必要なものをインストールすれば特に問題なくビルドできたのですが、Windows では何回かやってみたもののうまくいかず断念していました。ですが今回めでたくビルドできたので、備忘録もかねて行程を記そうと思います。
ビルド環境の構築
基本的には Building Firefox for Windows - Mozilla | MDN に書いてあることに従います。
Visual C++ 2005 Express Edition のインストール
VC2005EEは以前インストール済みだったので詳しいオプションとかは忘れてしまいました。標準インストールでたぶん問題ないと思います。
Microsoft Windows Vista SDK のインストール
すべてのバージョンの Visual Studio で必須になったらしいです。ディスク容量を節約したければ Sample Code や Documentation はインストールしなくても問題ありません。
Microsoft Windows Server 2003 R2 Platform SDK のインストール
Firefox をビルドするには最低限 "Windows Core SDK" と "Web Workshop (IE) SDK" と "Data Access Services (MDAC) SDK" があればいいとのこと。ディスク容量を節約したければ Sample Code や(略
MozillaBuildのインストール
ビルドに必要なさまざまなツールが入った MozillaBuild というパッケージをインストールします。標準のディレクトリ (c:\mozilla-build
) にインストールした方がいいらしいです。
Express Edition 用のバッチファイル
MDC によると、Express Edition でビルドするには標準のバッチファイルでは駄目らしいです。guess-msvc-v2.bat と start-msvc8-v2.bat をそれぞれダウンロードし、C:\mozilla-build
に置きます。元の guess-msvc.bat
と start-msvc8.bat
を削除する必要はありません。また、ダウンロードした guess-msvc-v2.bat
と start-msvc8-v2.bat
はともにファイル名を変えずにそのまま置いてください。リネームするとエラーが出て起動しません。
profile-sshagent.sh のアップデート
この状態で start-msvc8-v2.bat
を実行すると、
bash: ${SSH_ENV}: ambiguous redirect
chmod: cannot access `/c/Documents': No such file or directory
chmod: cannot access `and': No such file or directory
chmod: cannot access `Settings//.ssh/environment': No such file or directory
bash: /c/Documents: No such file or directory
Could not open a connection to your authentication agent.
とかいうエラーメッセージが出ます。
エラーメッセージで検索してみるとGoogle グループが引っかかりました。どうやら profile-sshagent.sh を最新のものにするとエラーが出なくなるようです。最新の profile-sshagent.sh をダウンロードして、C:\mozilla-build\msys\etc\profile.d
にあるものと置き換えます。
cvs.exe のアップデート
検索しても同じトラブルに会った人がいないようなので環境依存なのかもしれませんが、うちの環境ではこの後 start-msvc8-v2.bat を実行して CVS でチェックアウトしようとしても
cvs [checkout aborted]: reading from server: Connection reset by peer
といったメッセージとともにタイムアウトしてしまいました。以前 Windows でのビルドを断念したのもこれが原因だったのですが、調べてみると CVS のバージョンが古い (1.11) せいで起きる現象らしかったので、http://ftp.gnu.org/non-gnu/cvs/binary/feature/x86-woe/ から新しい CVS をダウンロードしました。今回はとりあえず最新の 1.12.13a にしてみましたが、どのバージョンが安定しているのかはわかりません。ダウンロードした zip ファイルの中の cvs.exe を、C:\mozilla-build\msys\bin
にあるものと置き換えます。
コンソールウィンドウの起動
C:\mozilla-build\
にある start-msvc8-v2.bat をダブルクリックで起動すると、白い背景のコンソールが起動します。以降はこのコンソールにコマンドを打ち込んでいきます。
カレントディレクトリの移動
コンソールが起動した初期状態では、カレントディレクトリは C:\Documents and Settings\<ユーザ名> になっています。長いし深いしスペースが入っていてなんか嫌なので、カレントディレクトリを移動します。今回は D:\source
にしました。
cd d:/source
チェックアウトするとこのフォルダの下に mozilla というフォルダができ、そこに大量のソースコードがダウンロードされることになります。チェックアウトしてビルドしてパッケージングした時点でフォルダ容量が 1 GB 近くになったので、余裕のあるパーティションを選択しましょう。
チェックアウト
まずは他のファイルをチェックアウトするのに必要な client.mk ファイルをチェックアウトします。
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/client.mk
client.mk を落としたら次は他のソースファイルをチェックアウトすればいいのですが、それをやろうとすると
client.mk:480: *** This source tree appears to have Windows-style line endings. To convert it to Unix-style line endings, run "python mozilla/build/win32/mozilla-dos2unix.py". Stop.
と怒られてしまいました。
仕方ないのでまず mozilla/build/win32/mozilla-dos2unix.py
を落とします。
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/build/win32/mozilla-dos2unix.py
それから実行します。
python mozilla/build/win32/mozilla-dos2unix.py
すると
This command will convert the source tree at
d:\source\mozilla
to an MSYS-compatible (unix mode) source tree. You can run this
command multiple times safely. Are you sure you want to continue (Y/N)?
と聞かれるので y
と入力して Enter を押します。
なにやら処理が完了したら、カレントディレクトリを mozilla/ に移動します。
cd mozilla/
残りのソースファイルをチェックアウトします。
make -f client.mk checkout MOZ_CO_PROJECT=browser
browser
のところを変えると Thunderbird や SeaMonkey をチェックアウトできるらしいです。詳しくはGetting Mozilla Source Code Using CVS - Mozilla | MDNを見てください。
すべてのファイルをチェックアウトするにはしばらく時間がかかるので、何か他のことをして時間をつぶしましょう。コンソールを眺めていると時々
cvs.exe [checkout aborted]: reading from server: Connection reset by peer
とか表示されてドキッとしますが、後でビルドしたら特に問題なくビルドできたのでスルーして構わないと思います。
ビルドオプションの設定
ビルドオプションは mozilla
ディレクトリに .mozconfig
というファイルを作成してそこに記載します。いろんなオプションがあるのですが今回はとりあえずビルドするのが目的だったので必要な最小限 (多分) のオプションだけ指定して後はデフォルト設定にしました。詳しいオプションの種類や設定の仕方はビルドオプションの設定 - Mozilla | MDNを見てください。
. $topsrcdir/browser/config/mozconfig mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-@CONFIG_GUESS@
mozilla
ディレクトリに .mozconfig
というファイルを作り、その中に上記の内容をコピペして保存します。
ビルド
いよいよビルドです。
make -f client.mk build
を実行するとビルドが開始されます。ビルドにはチェックアウトよりもさらに時間がかかるはずなので、外出するなりご飯を食べるなり風呂に入るなり寝るなりして終わるのを待ちましょう。
パッケージング
ビルドが終了すると、mozilla
ディレクトリに obj-
で始まるディレクトリができているはずです。このディレクトリはオブジェクトディレクトリとか Objdir とか言ったりするらしいです。うちの場合は obj-i686-pc-mingw32
という名前でした。ビルドしてできたバイナリなどはここに格納されます。
カレントディレクトリをこのフォルダに移動
cd obj-i686-pc-mingw32/
して、
make package
とすると、オブジェクトディレクトリの dist
フォルダに firefox-3.0pre.en-US.win32.zip
のような ZIP パッケージが、
make installer
とするとオブジェクトディレクトリの dist\install\sea
フォルダに firefox-3.0pre.en-US.win32.installer.exe
のようなインストーラが作成されます。
まとめ
Windowsでビルドできた勢いで書いたエントリなので、間違いとかもっと効率的にやる方法とかあるかもしれません。もしあったらコメントとかで教えてくれると幸いです。バッチファイルの書き方とかも勉強しなきゃいけないと思いました。まる。
Firefox3beta4のバグを回避するためのAutoPagerize0.0.25用パッチ
--- autopagerize.user.js.orig 2008-03-15 03:19:35.270184000 +0900 +++ autopagerize.user.js 2008-03-15 21:54:38.877256000 +0900 @@ -473,11 +473,16 @@ // utility functions. function createHTMLDocumentByString(str) { var html = str.replace(/<!DOCTYPE.*?>/, '').replace(/<html.*?>/, '').replace(/<\/html>.*/, '') var htmlDoc = document.implementation.createDocument(null, 'html', null) var fragment = createDocumentFragmentByString(html) - htmlDoc.documentElement.appendChild(htmlDoc.importNode(fragment, true)) + try { + fragment = htmlDoc.adoptNode(fragment) + } catch(e) { + fragment = htmlDoc.importNode(fragment, true) + } + htmlDoc.documentElement.appendChild(fragment) return htmlDoc } function getElementsByXPath(xpath, node) { var node = node || document
とりあえず。
Firefox3beta4とAutoPagerize0.0.24で起きる問題の修正patch - ZeroMemoryのでもいいけど、clear cache したときとかに変なことになると思います。
無事修正されました。
Bug 420700 – Calling createContextualFragment affects subsequent setting of innerHTML
Status: RESOLVED FIXED
Beta 5 では直ってるはず。
めでたしめでたし
昨日の続き。
どうやらこのバグのregressionっぽい。
Bug 386769 – Make setting innerHTML faster
C++はぜんぜんわからんけど。
このバグはキャッシュを利用してCreateContextualFragmentを高速化しようとしてるみたいだけど、初期化処理がうまくいってないのかな?createContextualFragmentするたびにその内容が蓄積されていってる。
var range = document.createRange(); range.setStartAfter(document.body); var df = range.createContextualFragment("<h1>h1</h1>"); var df2 = range.createContextualFragment("<h2>h2</h2>");
とかやると、df2のchildNodesにはh1とh2の両方が入ってしまっている。で、innerHTMLに値を設定する時には実は内部でCreateContextualFragmentを呼び出している。それでなんかのinnerHTMLに文字列を代入するといままでにcreateContextualFragmentされた分がまとめてその中に入っちゃう。
DeaRさんのコメントにもあるように、一度innerHTMLに何らかの値を設定すればこの状態はクリアされるようなので、こんな感じにすればいいかも。
// copied from Pagerization (c) id:ofk function parseHTML(str) { str = str.replace(/^([\n\r]|.)*?<html.*?>|<\/html>([\n\r]|.)*$/ig, '') var res = document.implementation.createDocument(null, 'html', null) var range = document.createRange(); range.setStartAfter(document.body); res.documentElement.appendChild( res.importNode(range.createContextualFragment(str), true) ); document.createElement('span').innerHTML = ''; return res; }
なんか気持ち悪いですが。
Firefox3はまだ不安定ですね。そろそろ移行しなきゃなとは思ってるんですが。
なんかimportNodeをadoptNodeにするだけでも回避できた。こっちのほうがいいかも
// copied from Pagerization (c) id:ofk function parseHTML(str) { str = str.replace(/^([\n\r]|.)*?<html.*?>|<\/html>([\n\r]|.)*$/ig, '') var res = document.implementation.createDocument(null, 'html', null) var range = res.createRange(); range.setStartAfter(document.body); res.documentElement.appendChild( res.adoptNode(range.createContextualFragment(str)) ); return res; }
とおもったらadoptNodeはFirefox2が対応していないのでした。
// copied from Pagerization (c) id:ofk function parseHTML(str) { str = str.replace(/^([\n\r]|.)*?<html.*?>|<\/html>([\n\r]|.)*$/ig, '') var res = document.implementation.createDocument(null, 'html', null) var range = document.createRange(); range.setStartAfter(document.body); var df = range.createContextualFragment(str); var dfc; try { dfc = res.adoptNode(df); } catch (e) { dfc = res.importNode(df, true); } res.documentElement.appendChild(dfc); return res; }
■
d:id:Constellation:20080302:1204467538
どうもrange.createContextualFragmentしたあとに要素のinnerHTMLに何か代入するとその要素にdocumentfragmentが入ってしまうようです。Firefox3のバグでしょうか?
とりあえずcreateContextualFragmentを使わないようにすれば回避できると思います。