Safari の WYSIWYG モードで Shift-Enter が効かないのに対処する

tracwysiwyg を Safari から使っていて気付いたのですが、SafariWYSIWYG モードでは Shift-Enter を入力しても改行(<br>)が入りません。これ自体は Safari のバグの模様。

Bug 16973 - Shift+Return doesn't produce BR elements in a contentEditable area.

じゃあ…と思って、ツールバーの一番右にある改行挿入するアイコンで入れようとしたら、これも挙動がおかしい。生成されている html を見ると ↓ みたいなのが生成されていた。

<p>first</p>
<br>
<p></p>

SafaricontentDocument.execCommand('inserthtml', false, '<br>') を実行すると paragraph を2つに分離してしまうようです。

全然期待通りに動かないので困ったな…と思いながら webkit.org でソースを眺めていたら inserthtml の近くに insertlinebreak というコマンドがあるのを発見(/trunk/WebCore/editing/EditorCommand.cpp @ 34682 - WebKit - Trac)。そのまま使えそうなので keypress イベントで Shift-Enter をハンドリングして insertlinebreak を実行するように変更したところ、無事に <br> が入るようになりました。

TracWysiwyg.prototype.execCommand = function(name, arg) {
    return this.contentDocument.execCommand(name, false, arg);
};
TracWysiwyg.prototype.insertLineBreak = function() {
    this.execCommand("insertlinebreak");
};

SafariWYSIWYG を使う場合、このバグを回避するために自前で insertlinebreak を呼ぶようにしたほうがよさそうです。

これを踏まえて tracwysiwyg を修正、Changeset 4135 - Trac Hacks - Plugins Macros etc. - Trac になりました。ツールバーの改行アイコンからも insertlinebreak を呼ぶように修正しています。

subversion 1.5 で checkout した Trac plugin を setup.py bdist_egg したらエラーになった…の続きの続き

前回で結局うまくいかなかったわけで。

checkout しているのは http://svn.python.org/projects/sandbox/branches/setuptools-0.6@r65197

調べると setuptools/command/sdist.py には subversion 1.5 用のコードがあるけど、setuptools/command/egg_info.py はそのままになっている。

Index: setuptools/command/egg_info.py
===================================================================
--- setuptools/command/egg_info.py      (revision 65196)
+++ setuptools/command/egg_info.py      (working copy)
@@ -217,7 +217,7 @@
             data = f.read()
             f.close()

-            if data.startswith('8'):
+            if data.startswith('9') or data.startswith('8'):
                 data = map(str.splitlines,data.split('\n\x0c\n'))
                 del data[0][0]  # get rid of the '8'
                 dirurl = data[0][3]

このパッチをあてると bdist_egg でリビジョン番号が扱えるようになった。

参考: issue2770: Subversion 1.5 Working Copies Break Setuptools

subversion 1.5 で checkout した Trac plugin を setup.py bdist_egg したらエラーになった…の続き

前回 subversion 1.5 working copy 上で setuptools がこける…というのを書いたわけですが、このことを忘れてまた plugin のビルドでこけた…。

いいかげん修正されてるだろ…と思って branches/setuptools-0.6 を覗いてみたら subversion 1.5 用のコードが追加されていた。早速 setuptools をビルド。

いつも rpm にしてインストールしているので bdist_rpm を実行。

$ svn co http://svn.python.org/projects/sandbox/branches/setuptools-0.6
$ /usr/lib/subversion/tools/client-side/change-svn-wc-format.py . 1.4
$ python setup.py bdist_rpm
....
moving build/bdist.linux-i686/rpm/SRPMS/setuptools-0.6c9dev_r65015-1.src.rpm -> dist
$ ls dist
setuptools-0.6c9dev_r65015-1.src.rpm  setuptools-0.6c9dev-r65015.tar.gz

*.src.rpm しかない…。こういうもんだっけ? まあ rpmbuild すればいいか。

$ rpmbuild --rebuild dist/setuptools-0.6c9dev_r65015-1.src.rpm
....
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.50274
+ umask 022
+ cd /home/jun66j5/rpm/BUILD
+ rm -rf setuptools-0.6c9dev-r65015
+ exit 0

このままインストール。

$ sudo rpm -Uvh rpm/RPMS/noarch/setuptools-0.6c9dev_r65015-1.noarch.rpm

それじゃ適当な plugin でビルドできるか試してみる。

$ head -1 .svn/entries
9
$ python setup.py bdist_egg
running bdist_egg
unrecognized .svn/entries format; skipping .
running egg_info
....
zip_safe flag not set; analyzing archive contents...
creating 'dist/TracWysiwyg-0.2_r0-py2.3.egg' and adding 'build/bdist.linux-i686/egg' to it
removing 'build/bdist.linux-i686/egg' (and everything under it)

んんんん。ビルドはできるけど unrecognized .svn/entries format; skipping . とか言われてるし *.egg ファイル名中のリビジョン番号が 0 になってる…。

subversion 1.5 で checkout した IniAdminPlugin を setup.py bdist_egg したらエラーになった

0.11 用の IniAdminPlugin の egg ファイルを作成しようとして python setup.py bdist_egg するといきなりエラーになった。

$ python setup.py bdist_egg
running bdist_egg
running egg_info
creating IniAdmin.egg-info
writing IniAdmin.egg-info/PKG-INFO
writing top-level names to IniAdmin.egg-info/top_level.txt
writing dependency_links to IniAdmin.egg-info/dependency_links.txt
writing entry points to IniAdmin.egg-info/entry_points.txt
writing manifest file 'IniAdmin.egg-info/SOURCES.txt'
Traceback (most recent call last):
  File "setup.py", line 11, in ?
    package_data={'iniadmin' : ['htdocs/css/*.css', 'templates/*.html', ]})
  File "/usr/lib/python2.3/distutils/core.py", line 149, in setup
    dist.run_commands()
  File "/usr/lib/python2.3/distutils/dist.py", line 907, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python2.3/distutils/dist.py", line 927, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.3/site-packages/setuptools/command/bdist_egg.py", line 167, in run
    self.run_command("egg_info")
  File "/usr/lib/python2.3/distutils/cmd.py", line 333, in run_command
    self.distribution.run_command(command)
  File "/usr/lib/python2.3/distutils/dist.py", line 927, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.3/site-packages/setuptools/command/egg_info.py", line 171, in run
    self.find_sources()
  File "/usr/lib/python2.3/site-packages/setuptools/command/egg_info.py", line 252, in find_sources
    mm.run()
  File "/usr/lib/python2.3/site-packages/setuptools/command/egg_info.py", line 306, in run
    self.add_defaults()
  File "/usr/lib/python2.3/site-packages/setuptools/command/egg_info.py", line 333, in add_defaults
    rcfiles = list(walk_revctrl())
  File "/usr/lib/python2.3/site-packages/setuptools/command/sdist.py", line 45, in walk_revctrl
    for item in ep.load()(dirname):
  File "/usr/lib/python2.3/site-packages/setuptools/command/sdist.py", line 52, in _default_revctrl
    for path in finder(dirname,path):
  File "/usr/lib/python2.3/site-packages/setuptools/command/sdist.py", line 98, in entries_finder
    log.warn("unrecognized .svn/entries format in %s", dirname)
NameError: global name 'log' is not defined

どうも subversion 1.5 working copy のフォーマットが変更になったので setuptools が .svn/entries からリビジョン番号を取り出そうとして失敗している模様。(NameError: global name 'log' is not defined になっているのはまた別の問題だとは思うがとりあえず今はムシ)

$ head -1 .svn/entries
9

setuptools のページから repository を確認したけど branches/setuptools-0.6trunksubversion 1.5 用の処理はまだない。

svn export すればいけるだろうげとそれもなんか癪なので別の方法を。
ここで working copy フォーマットを変更するツールがあるのを思い出したのでそれを使ってみる。

$ /usr/lib/subversion/tools/client-side/change-svn-wc-format.py
usage: change-svn-wc-format.py WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format]
       change-svn-wc-format.py --help

Change the format of a Subversion working copy to that of SVN_VERSION.

  --skip-unknown-format    : skip directories with unknown working copy
                             format and continue the update

第1引数には working copy のディレクトリを指定して、第2引数には subversion のバージョンを指定するらしい。今は 1.4 相当にしたいので 1.4 を指定。

$ /usr/lib/subversion/tools/client-side/change-svn-wc-format.py . 1.4
Converted WC at '.' into format 8 for Subversion 1.4
$ head -1 .svn/entries
8

いちおう 8 になっている。気を取り直して bdist_egg してみる。

$ python setup.py bdist_egg
running bdist_egg
running egg_info
writing IniAdmin.egg-info/PKG-INFO
....
creating dist
creating 'dist/IniAdmin-0.2-py2.3.egg' and adding 'build/bdist.linux-i686/egg' to it
removing 'build/bdist.linux-i686/egg' (and everything under it)

できた。
あれ。egg ファイルの名前 IniAdmin-0.2-py2.3.egg にリビジョン番号入ってないよ…。setuptools は working copy にいたら常にリビジョン番号を取り出そうとするのね…。

CodeRepos の Trac みたいに browser ページに repository へのリンクをつける

CodeReposTrac みたいに browser ページのメニューに repository へのリンクをつけたくなったのでやってみる。

Trac 0.10 限定です。

template (clearsilver) で参照しているページが browser ページなのか判断するようにして、メニューにリンクを追加するのは javascript でやるようにしました。(CtxtnavAddPlugin というメニューにリンクを追加するための plugin があるがあえて使わない)

次のようなのを {TRACENV}/templates/site_footer.cs に書いておきます。svn_base の部分は個々の環境に合わせて変えてください。

<?cs if:browser.path || log.path || ticket.id ?>
<script type="text/javascript">//<![CDATA[
(function() {
    var svn_base = 'http://example.com/svn/';   // repository の URL

    function add_ctxtnav(label, url) {
        var d = document;
        var element = d.getElementById('ctxtnav');
        var ul = element.getElementsByTagName('ul');
        if (ul.length == 0) {
            ul = d.createElement('ul');
            element.appendChild(ul);
        }
        else {
            ul = ul[0];
        }
        var lists = ul.getElementsByTagName('li');
        var list;
        if (lists.length != 0) {
            list = lists[lists.length - 1];
            list.className = list.className.replace(/\blast\b/g, '');
        }
        list = d.createElement('li');
        list.className = lists.length == 0 ? 'first last' : 'last';
        var anchor = d.createElement('a');
        anchor.href = url;
        anchor.appendChild(d.createTextNode(label));
        list.appendChild(anchor);
        ul.appendChild(list);
    }
<?cs if:browser.path || log.path ?>
    add_ctxtnav('Repository Location', encodeURI(svn_base + "<?cs
        var:js_escape(project.shortname) ?><?cs var:js_escape(args.path) ?>"));
<?cs /if ?>
<?cs if:ticket.id ?>
    if (document.referrer.indexOf(location.protocol + '//' + location.host) == 0
        && /\/report\/\d+/.exec(document.referrer))
    {
        add_ctxtnav('Back to Report', document.referrer);
    }
<?cs /if ?>
})();
//]]></script>
<?cs /if ?>

これで browser ページとついでに log ページを見たときに Repository Location というリンクが表示されるようになります。

さらに report ページから ticket ページを見たときに、元の report ページに戻るためのリンクも追加。

Trac プロジェクトの各ディレクトリごとに templates/site_footer.cs を書くのはだるいので、デフォルトの template ディレクトリにだけ site_footer.cs を置くようにして各々の Trac プロジェクトにある templates/site_footer.cs は削除しています。

デフォルトの template ディレクトリは次のような感じで確認できます。

$ python -c 'from trac.config import default_dir; print default_dir("templates")'
/usr/share/trac/templates

0.11 の環境では、SvnUrlsPlugin - Trac Hacks - Plugins Macros etc. - Trac というのがあり、少し毛色が違いますが似たようなのがありますのでこちらをどうぞ (使ったことないのですが)。

Trac で使っているプラグイン

うちの環境で使っている Tracプラグインをリストしてみる。他にもごちゃごちゃ入っているけど実際に使っていると言えるのは以下のものぐらい。
Trac 本体は 0.10-stable を使ってます。

WebAdmin

まずは WebAdmin。ブラウザから trac.ini が変更できるようになります。

IniAdminPlugin

WebAdmin を入れるなら当然 IniAdminPlugin も。trac.ini のすべて項目が変更できます。

CustomFieldAdminPlugin

カスタムフィールドをブラウザから変更できるようになるプラグイン

TicketDeletePlugin

チケットやチケットに対するコメントを削除できるようになります。削除には TICKET_ADMIN 権限が必要。

WikiRenamePlugin

Wiki ページ名を変更できるようにするプラグインWIKI_RENAME 権限が必要。
名前変更時に Wiki ページの中身まで変更してくれます。

ただ、日本語の添付ファイルをつけたページで名前を変更するとエラーになったり、正規表現のメタ文字({, }, [, ] など)をページ名に使っているとエラーになったりします。エラーにならないように修正してパッチを trac-hacks #2253, trac-hacks #2254 として登録してます。

あと TagsPlugin でのタグの面倒までは見てくれないらしい。

S5Plugin

TracWiki 書式で書いた内容を S5 のスライドとして表示できるようにするプラグイン

ちなみにヘッダを # 付きで書いてスライドを見るとそのヘッダが無視されてしまいます

StractisticsPlugin

プロジェクトの活動状況をチャートで表示してくれるプラグイン

TracWysiwygPlugin

TracWiki を WYSIWYG エディタで編集できるようにするプラグイン