Home > Latest topics

Latest topics 近況報告

たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。

萌えるふぉくす子さんだば子本制作プロジェクトの動向はもえじら組ブログで。

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

Page 5/243: « 1 2 3 4 5 6 7 8 9 »

Double-click on the empty area of the tab bar doesn't open a new tab anymore! / タブバーの余白をダブルクリックしても新しいタブが開かれなくなった - May 06, 2014

Q

On Firefox 29 (and later), I cannot open a new tab by double-click on the empty area of the tab bar, with Tree Style Tab. Is this a bug?

ツリー型タブを使っているとき、Firefox 29以降のバージョンではタブバー上の余白をダブルクリックしても新しいタブを開けません。これはバグではないですか?

A

No, it's not a bug of Tree Style Tab. In old Firefox (Firefox 28 or older), double-click on the empty area of the tab bar opened a new tab actually, but it was a feature of Firefox itself. The action was available only when you choose "Tabs on Bottom" mode, and Tree Style Tab always chose the mode automatically. In the "Tabs on Top" mode, your actions on the empty area of the tab bar worked as on the title bar - for example, it maximized the window itself on Windows. Because the "Tabs on Bottom" mode has been removed on Firefox 29, now double-click on the empty area always works as on the title bar.

Because it is not a feature related to "tree of tabs", I won't include it to TST in the future. Certainly TST already has some features not related to "tree of tabs", but there is a criterion for those exceptions: is the feature provided by Firefox itself, and does TST break it? Then, now Firefox 29 itself doesn't open a new tab by double-click on the tab bar, so TST also never do it. Sorry, but I have to draw a line somewhere.

Instead, you should use another addon who provides the feature: double-click on the empty area on the tab bar to open a new tab, for Firefox 29 and later. For example, my another addon Tabs on Bottom.

いいえ、それはツリー型タブのバグではありません。古いバージョン(Firefox 28以前)のFirefoxでは確かにタブバーの余白をダブルクリックすると新しいタブが開かれましたが、それは「タブを下部に表示」モードの時だけ使える、Firefox自体の機能です。ツリー型タブは単に、「タブを下部に表示」モードを常時有効にしていただけです。元々、「タブを上部に表示」モードでは、タブバーの余白での操作はタイトルバー上での操作と同等に扱われていました(例えば、ダブルクリックでウィンドウを最大化するなど)。「タブを下部に表示」モードがFirefox 29で削除されてしまったため、タブバーの余白でのダブルクリックは常にタイトルバー上での操作と見なされます。

この機能は「タブのツリー」というコンセプトに直接は関係しないため、今後もツリー型タブにこの機能を含めるつもりはありません。ツリー型タブはFirefox本体に元々備わっている機能をなるべく阻害しないことを目標にしており、そのために実際にツリーと関係無い機能を入れている部分もありますが、この機能については現在はFirefox本体にそもそも含まれていないので、そのような特別な対応をする予定も残念ですがありません。

なので、どうしても必要な場合は、代わりに、タブバーの余白のダブルクリックで新しいタブを開く機能を提供している別のアドオン(例えばTabs on Bottom)を併用してください。

4年越しで溜飲を下げた話 - May 02, 2014

Mozilla Corporationの人から、「なんでツリー型タブはFull Reviewを受けてないんだい? about:addonsからの検索にヒットしないから、ユーザがインストールするのに面倒だよ。You申請しちゃいなよ!(意訳)」的なメールを頂いた。ありがたいことだ。

Mozillaのアドオンポータルサイトである所のMozilla Add-onsでは、アドオンを登録するにあたってPreliminary Review(事前審査)とFull Review(完全審査)という2段階の審査がある。登録したアドオンはまずPreliminary Reviewでセキュリティ面などの大雑把な審査を必ず受けて、通過できなければそのアドオンはAMOへの掲載すらかなわない。ここで問題なしとなれば晴れて「実験的アドオン」としてサイトに掲載されるようになるけど、Firefoxのアドオンマネージャからの検索にはヒットせず、おすすめアドオンとしてもノミネートされないので、これではまだ単に「載っただけ」。そこで一定の支持を得たら、次の段階としてFull Reviewを申請して品質面その他を審査してもらえる。Full Reviewを無事通過すれば、Firefoxのアドオンマネージャからの検索にヒットするようになったり、おすすめとして紹介して貰えたりするようになる。定番アドオンと言われるような物は、代替はこのFull Reviewを通過した状態になってる。

前から見てる人は把握してるかもしれないけど、僕が作ってるアドオンのうちいくつかは、Preliminary Reviewのみ通過していて実験的アドオンのままになっている。新しく作って登録した物は当然なんだけど、それだけでなく、過去にはFull Reviewを通っていた物が、ある時を境に審査にパスしなくなってそれっきりになっている物もある。ツリー型タブもその1つだ。

何故かというと、簡単に言えば、最初のFull Reviewの頃には審査が甘かったから通過できていたのが、その後の審査基準見直しで通らなくなったということ。ただ、僕としてはこの時の裁定にはあまり納得がいってなくて、evalが危険でそれ以外の方法が安全だと思ってる人へ英訳)というエントリでタラタラ不満をぶちまけたりもしてた。

そういう経緯があったから、大人げないオッサンとしては「いやーFull Reviewしたいのは山々なんですけどねーeval()使ってるから駄目っておたくんとこの人達が言うもんですからねー」と嫌味全開で返したくもなったんだけど、そこは我慢して、審査基準に合わないと言われたからFull Reviewしてないんですよ、審査基準が変わったなら再申請するのはやぶさかでないけどそうでないなら多分通過しないと思いますよ、でもまあ確かにeval()使ってるとレビューしにくいだろうししょうがないっすね、と、そんな感じで返信するに留め……られるほどにはやっぱり大人になりきれておらず、嫌みったらしく上記のエントリ(英語の方)のURIを貼り付けてメール送信してしまいました。ああ、なんとも底の浅い人間である事よ……

でもまあ、その時のレビュワーの人とは無関係であるにせよ、公式サイドの人から「Full Reviewに値する」という評価を貰えた事には「やってやったぜ」という胸のすく思いで、4年越しで溜飲を下げたのでした。

Firefox for Androidに仮想的なスクロールバーを導入するScrollbar Like Scrollerを更新した - Nov 13, 2013

Scrollbar Like Scrollerを更新した。

1.0/1.1での大きな変更点として、仮想的な「つまみ」を導入して、それ以外の場所では反応しないようにした。使い勝手が悪くなったと見る向きもあるかもしれないけど、前の挙動に戻すつもりはないです。

というのも、僕が自分で実際に使ってた感想として、何も無いところでスワイプやパンスクロールしようとして急に画面が飛んでしてしまう(スクロールバー風操作の開始と判断して、指があった位置から計算したスクロール位置まで強制的にスクロールしてしまう)という誤爆が何度かあってイラッときてしまったのです。

スクロール位置を示すインジケーター自体はFirefoxも提供してるんだけど、これは注意深く見ないと気がつかないようなさりげなさで表示されているので、UIとしてこれを目印にするのは辛い。と思ったというのもあって、ぶっとい「つまみ」に相当する物を自前で表示するようにした。これをなるべく正確な位置に表示したくてああだこうだと座標をいじくり回した結果、指のある位置からのスクロール位置の算出が前よりグッと正確になったので、そういう意味でも成果はあったと思う。

もう1つの変更として、画面の上端や左端もスクロールバーとして動作するようにした。右手でスマホを持って親指でスクロールしてる時は右にスクロールバーが出てていいんだけど、左手で持って親指でスクロールしてると、右端に出るつまみまで指が届かなかったので。最後にパンスクロールした時のタッチ位置が画面の1/3より左だったら左につまみが出るようになってるけど、つまみが出てない時でも、つまみがあるであろう位置を指で操作すればスクロール操作は開始できます。

Firefox for Android用のアドオンを作った - Nov 08, 2013

Nexus 7を買って以降、Firefox for Androidをエンドユーザとして使うようになってそれなりに経つんだけど、布団の中でWebブラウズする時間がだんだん長くなってきて(病気で……とかじゃなくて、単にPCの前に座って作業するのが億劫になってきたという事です)、触る時間・頻度が増えてくると、色々細かい所で「イラッ」と来るようになってきた。

アドオンを作れば解決できるんだろうなあと思ってはいたんだけど、既に何十とリポジトリを作っていてメンテナンスしきれてない僕がまた新しく抱え込むのは世界に不幸を増やす事になるのではないか……と思って、「他の誰かがやってくれないかなあ」と淡い期待を抱きながら待ってたんだけど、僕の不満が解消されるような物が出てくる気配が一向になかったので、カッとなった勢いで2つほど作ってAMOに登録してみた。ああ、またつまらぬ物を作ってしまった……

Scrollbar Like Scroller(スクロールバー風スクロール)は、いくつかのAndroidアプリ(具体的にはJota Text Editorとか)で実装されていた「基本的にはパンスクロールだけど、必要に応じてスクロールバーも使える」的な挙動を実現する物。はい、どこからどう見てもパクリです。

ビューポートの大きさの解像度とタッチイベントの座標の解像度が違うという点でドツボに填って難儀したけど、タッチイベントの座標を現在のズーム率とかけ算した値がどうやらビューポートのサイズと同じ解像度になるようだったので、どうにかそれらしい動きを実現できた。

縦にクソ長い2chまとめだとかTogetterまとめだとかを見た後で最初の方までスクロールするのにパンスクロールのためのスワイプ操作で画面をひたすらこするのにウンザリしていて、このままじゃ画面か指が削れて無くなっちまうよ!!!という悩みはこれで解消されると思う。

Open Local File(ローカルファイルを開く)は、名前の通りで、なぜかAndroid版Firefoxに標準で付いてない「ローカルファイルを選択して開く」機能を加えるだけの物。一旦ダウンロードして保存したXPIファイルをファイルブラウザからFirefoxを指定して開こうと思ったら、関連付けでJota Text Editor固定になってしまっててどう頑張っても開けず、関連付けを設定し直すのもイヤだったので、作った。

nsIFilePickerでやってるんだけど、modeGetFolderが未実装だったり最後に開いたディレクトリを記録・反映できなかったりと、PC版と同じように作るのはやはり難しいのだなあ。という事を改めて思い知らされた感じです。

あと選択範囲のリンクをまとめて保存する機能なんかも欲しかったんだけどゼロから作るのはさすがに辛かったので、これはSave Link Menusを改造して作った。

デスクトップ版FirefoxとAndroid版FirefoxではAPIが違う部分が多いので(低レベルのAPIは共通でもUIに近い部分は全然違う)、まだまだおぼつかない感じだし、ちょっと凝ったことをやろうとするとドキュメントが無いというかつてのMozilla Application Suite時代のアドオン開発を想起させられる手探りっぷりだけど、必要になったらさっと作れるくらいにはなれるといいなあ。

Why I don't provide "disabe animation of tab dragging operations" feature for Tree Style Tab? - Nov 06, 2013

This is the English translation of my another entry.

I decided to reject a pull request for TST, adding new secret preference to disable animation effects around drag and drop of tabs, because it contradicts the principle of the TST project. This entry describes why I rejected the pull request.

Why I introduced such an animation effect?

Because it is introduced by Firefox itself. After the animation effect is activated on Firefox, I updated TST to follow it. However, it was unwelcome update for some people and I got many requests like "it is hard to operate tabs with drag-and-drop", "I want an option to disable animation effects during tabs are dragged." Actually, I can see two issues on the issue tracker:

The patch of the pull request adds a secret preference to do it. It is enough small and clear. If I added the option, I wrote just same patch.

But I disagree to merge the pull request, because I think that the approach of the patch is similar to a story: "Firefox's Gecko engine is too buggy and less compatibility to WebKit, so why don't you delete all codes of Gecko and introduce WebKit with Firefox-like UI?" In other words, it is very easy to add new option which is requested by people, however, I'm extremely reluctant to do it beacuse it is opposed to my polify on Tree Style Tab project.

Basic premises and my policies.

Basically, this project depends on Mozilla Firefox project --which is very large and uncontrollable by me-- and it is unavoidable to be tossed up and down by the storm of changes in Firefox. Actually, on my another project, I had to rewrite the addon for new versions of Firefox again and again. I learned through the bitter experience that I should have some strict policies on my addon projects:

  • Don't re-implement a feature included in Firefox itself. For example, Tab Mix Plus has its own session management mechanism, because TMP project is started before the session management feature is introduced by Firefox itself. If the TMP project was started after that, they project team didn't implement such a custom session manager. There is no merit to implement a custom feature which conflicts to Firefox's.

    To reduce maintenance cost, and to keep better compatibility with other addons which are developed based on Firefox's APIs, I think I should update and re-construct my addons for new APIs introduced by Firefox. It is better than I struggle to keep old custom implementations against Firefox's changes.

    • However, sometimes I decide to keep my custom implementations, when it is hard to rewrite codes for Firefox's new API for me.

      For example, TST uses a library "JSDeferred" to process asynchronous operations easily. On the other side, lately Firefox uses Promise and Task for the same purpose. I know I should rewrite TST based on them instead of JSDeferred, but I still don't do it because: 1) TST is strongly designed based on JSDeferred. 2) Promise/Task are not available on the current ESR (Firefox 17). (In other words, I'll merge pull requests to do such a reconstruction, if there is no disadvantage about compatibility with other addons.)

    • When the API of Firefox's library is too untrustworthy for me, I decide to use my custom library based on very low stable APIs.

      For example, Firefox has a system named "preference" which can save/restore users' configurations. Because it is not developer-friendly (ex. there are three deferent types --boolean, integer, and string--, and hard to observe changed configurations dynamically), Firefox provides some libraries like FUEL. But, such libraries are untrustworthy and risky for me because Firefox team sometimes changes those APIs despite they promised those APIs are developer-friendly --obviously they should be stable and safe--. I don't want to spend time to update my codes for such unstable APIs, so I actually use my custom library modules/lib/prefs.js which is based only on very stable low APIs. It is one of reasons why I don't update my codes for Promise/Task yet.

      Anyway, I think that FUEL APIs are untrustworthy because Firefox team created FUEL just for third party add-on developers, not themselves. Because Promise/Task are used everywhere in Firefox, Firefox team will keep them stable for themselves.

  • Don't depend on deprecated features. For example, "E4X" became obsolete on lately Firefox. TST used E4X in some cases, so I had to decide that I keep E4X for TST or I give up. Some projects (not mine) decided to re-implement E4X by themselves, but I decided to give up and rewrite codes without E4X.
  • Don't include features not related to the main concept. The basic concept is: what I want to use, one feature per one addon, and, as minimum as possible.

    In my old blog entry (note: written in Japanese), I told that: features which I never use or unrelated to the main concept may satisfy users in the short term, but it will shorten life of the project in the long term. Basically I develop and publish my addons on GitHub because I need it and I want to keep it available for me. So I don't want to introduce changes which can disrupt the concept.

  • Provide higihly compatible, natural look-and-feel for Firefox's built-in features and other addons. For example, Firefox has a feature "auto hide toolbox" for the fullscreen mode started by F11 key. And, TST also provides "auto hide tab bar" feature. Yes, it is not related to "tree" feature. But if TST doesn't have the feature, you'll see unexpected vertical tab bar in the fullscreen mode. You press F11, you expect that the web page becomes fullscreened, then the vertical tab bar should not appear on the scene.

    This is the main reason why I took much time to update TST to support drag-and-drop animation effects. Before the animation effect is introduced to Firefox, I respected behaviors of drag-and-drop around layers and objects on Adobe Illustrator. This behavior is still available when you drag a link to the tab bar.

Reasons why the pull request is unacceptable for me.

Based on the above policies, I disagree to merge this pull request to TST's master, because:

  • Firefox has no option to disable animation effect of dragging tabs.
    • There are different and large codes for both cases: with and without animation.
    • However, animation-less operations in rare cases seem to be inhospitable (for me), contrastively basic operations with animation are developed actively.
    • So I forecast that codes for animation-less operations can be removed from future versions of Firefox. It is risky that I develop TST strongly based on such a disappearing implementation.
  • Because there is no option to enable/disable animation effects, I think that Firefox team basically designs Firefox to do drag-and-drop operations with animations. Then, I should keep TST along the design of Firefox itself.

    • I believe that animation effects in GUI often provide better user experiences. I'm affirmative about such a policy of Firefox project.
    • Actually disabling animation effects by userChrome.css or other ways sometimes break Firefox itself. For example, the internal operation to finalize closed tabs uses "TransitionEnd" DOM event to trigger itself, but it didn't workcorrectly because the event was never fired if the animation efect was disabled by userChrome.css. (I don't kwnow the bug is already fixed or not.)

      I don't think my addon should be specially hospitable for people who live without animation effects, because Firefox itself disfavors them.

  • I disagree to add new option to disable animation effects, for a request like "it is hard to operate tabs with animation effects." Instead, I think I should improve usability of tab operations with animation effects, to reduce frustrations around such operations.
    • If you don't have to operate tabs manually, you won't suffer from animations. If you have to operate tree of tabs manually to put them as you want, then TST should build tree of tabs automatically more intelligently to set you free from stressful manual operations.
    • If it is hard for you to drop the tab to the favorite position with animation effects, then TST should make it easy, instead of disabling animation effects.
  • Currently I have no plan to use Firefox without animation effects. I don't want to maintain codes for a feature I never use.
  • Of course, disabling animation effects is useful for some people who suffer from visual transitions, about accessibility. However, remember, Firefox itself is not providing ability to disable animations, for such people. And, this addon is "Tree Style Tab." I think TST should not include custom accessibility features which is missing on Firefox itself --it should be done by Firefox project--.
    • If you seriously suffer from the problem, you should file a bug for the issue, induce developers to implement ability to disable animation effects. Or, you should create a new addon which is based on a simple concept: disabling animation effects. (Note, I never develop such an addon because I never use it!) The user script zzzz-removeTabMoveAnimation.uc.js for userChrome.js seems to be written for the purpose.

The conclusion: fork this project freely.

This is just my personal, current opinion. Of course I don't think this is the final truth of the topic. If you have information which can solve my worrying, or if you explain compelling reasons that I should do it, then I possibly merge such a change.

Otherwise, I'm sorry but I never merge such pull requests to my master repository. Then please fork this project, extend, maintain, and release it for people who have same distress - it is my stance on this project. To keep my codes forkable -- this is one of reasons why I distribute all codes of TST under OSS licenses.

ツリー型タブにおける、タブのドラッグ時のアニメーション効果についてのポリシー - Sep 13, 2013

English version of this entry is available.

ツリー型タブに頂いたプルリクエストについて、ポリシー上の理由から取り込めないなあと思ったのだけれども、これまで、参照しやすい形でまとまった文章としてポリシーを表明していなかった気がするで、何故この変更を取り込まないか(タブをドラッグ&ドロップするときのアニメーション効果をOFFにできるようにしないのか)の判断理由を頑張って文章にしてみました。アーカイブとして、少し手直し&追記してこちらにも転記しておきます。

Firefox本体の挙動としてタブのドラッグ&ドロップ操作にアニメーション効果が適用されるようになって以後、ツリー型タブにも、その挙動に合わせるための変更を随時行ってきました。

しかしながら、この変更は万人にとって望ましい結果をもたらしたとは言えず、「タブをドラッグ&ドロップで操作しにくい」「タブのドラッグ&ドロップ操作時のアニメーション効果を無効にできるようにして欲しい」といった意見・要望が何度か寄せられています。今すぐにパッと挙げられるだけでも、Issue Tracker上には以下の2つのIssueがありました。

メールを通じて寄せられた意見も合わせると、無視できない数の人がこの件に関心を持っているようだ、という印象を僕は持っています。

冒頭に挙げたプルリクエストは、ドラッグ&ドロップ時のアニメーションを無効化する設定をツリー型タブに加える、という物でした。変更箇所は最小限で、内容もおかしなことをしている部分はなく、コードとしてはそのまま取り込んで全く違和感のないパッチです。

ですが、自分の認識としては、このパッチで示されている方向での対応というのは言わば、「FirefoxのGeckoエンジンはバグだらけだしWebkitと互換性が低いから、Geckoを全部消して、WebkitにFirefox風のUIを付けた物を次のバージョンのFirefoxにしますよ」というような物なのではないか、と考えています。……という例えは極端なのでもう少し普通の言葉で言い直すと、「確かに皆が望む通りに対処することは簡単なのだけれども、プロジェクトの運営ポリシー的に、この点で皆が望む通りの対処の仕方をする事には非常に慎重である」ということになります。

大前提として、このプロジェクト(ツリー型タブというアドオンの開発プロジェクト)は、Mozilla Firefoxという自分には制御のできない別のプロジェクトに依存している・振り回される事を避けられないプロジェクトである、という事をまず押さえておく必要があります。

ツリー型タブ以外も含めた自作のFirefoxアドオン全体で、Firefoxの仕様変更に追従するために大きな変更が必要だったことが過去に何度かあり、その時の苦い経験から、現在のところ、自分はこれらのアドオン開発のプロジェクトにおいて以下のような方針を立てるようにしています。

  • Firefox本体で実装している物と同じ目的の物は、できる限り、アドオン側で独自に実装し直さない。
    例えばTab Mix Plusはタブのセッション管理機能について、Firefox本体にそのような機能が入る前から開発されてきたという経緯から、Firefox本体のセッション管理機能とは全く別のセッション管理機能を持っています。が、今新たにTab Mix Plusを開発するとしたら、独自の仕組みを持つメリットは全くありません。 メンテナンスコストの削減と、「Firefox本体の機能と親和性が高くなるように開発されている」他のアドオンと併用したときの相互運用性を高く保つという、2つの観点から、独自の仕組みをメンテナンスし続けるよりは、Firefox本体で実装された仕組みにうまく載っかるように改修する道を選ぶべきであると、自分は考えています。
    • ただ、アドオン内の各部分が独自の仕組みに強く依存した設計になっており、Firefox本体で採用された新しい仕組みに基づく形に改修するのが非常に難しい(工数が大きい)場合には、独自の仕組みを保ち続ける選択を取る場合があります。
      例えば、TSTでは非同期な処理と非同期な処理の連携をうまく取るために、JSDeferredというライブラリを使用しています。一方で、最近のFirefoxではPromiseTaskといった仕組みが導入されており、本来であれば、JSDeferredではなくこれらに基づく形で全体を作りなおすべきところです。が、ESR版Firefoxではまだこれらが使えないという事情もあって、移行はできていません。
      (逆に言うと、そのような手のかかる変更に現在のところ自分は着手できていないが、問題視はしているということで、この点を解消するプルリクエストであれば、他のアドオンとの互換性などいくつかの懸念が払拭できていれば、是非とも取り込んでいきたいと思っていると言えます。)
    • Firefox本体で提供されているライブラリのAPIの安定性がいまいち信頼できないという場合、そのより低位の、より変更が少ないと予想されるAPIに基づいて、自分でライブラリを作成して使用しているという場合もあります。
      例えば、Firefoxではユーザ設定を保存する機能としてpreferenceという仕組みがありますが、真偽値・整数値・文字列値という型の違いがあったり、設定の変更を監視するのが面倒だったりということで、より簡単に使えるようにするためのライブラリをFirefox自身がいくつか提供しています。FUELもそのひとつです。しかしながら、それらの「シンタックスシュガー」的な用途で作られたライブラリは、ライブラリ自体のAPIが彼らの都合でコロコロ変えられてしまうリスクが結構あり、それで泣かされるのは非常にアホらしいという認識が自分にはあります。なので、僕は自作のアドオン群では、preferenceを扱う最も低いレイヤのAPIであるnsIPrefBranchを直に操作するライブラリ(modules/lib/prefs.js)を自分で作って使っています。
      PromiseやTaskへの移行に踏み切れていない理由の1つとしては、このような懸念もあります。が、FUELのようなライブラリがFirefox内部でほとんど使われていないために捨てられてしまうリスクがある(彼らは、自分が使う物は大事にメンテナンスしますが、「アドオン作者が使うように」といった感じでお仕着せの便利ライブラリとして用意した物については、彼ら自身が使っていないので冷遇しがちという印象が僕にはあります。)のに比べると、PromiseやTaskはFirefoxの中の深い部分で既に多用され始めているので、今更捨てられてしまうリスクはそれほどには高くないかな……という目算もあります。
  • Firefox本体で廃止が決まっている機能、廃止される見込みがある機能には、なるべく依存しない。
    例えば、記憶に新しいところではE4Xの廃止というトピックがありました。文字列のヒアドキュメント代わりにE4Xを使用している箇所が、E4Xの廃止で動かなくなるという事に対して、E4Xを諦めるか、E4Xを使い続けるのか、という2つの道があり得ました。プロジェクトによっては、E4Xを自前で実装し直すことでそれ以外の箇所の変更を最小限に留めるという道を選んだところもあったようですが、自分は、E4Xを捨てる道を選びました。このあたりの判断については過去に会社のブログで詳しく書いていますので、そちらも見てもらえると幸いです。
  • プロジェクトのコンセプトから外れる事は、なるべくしない。
    コンセプトは「自分が使いたいものを、1機能につき1アドオンとして、最小の形で開発する」ということ。
    過去のエントリで詳しく書いていますが、自分が使わない機能や、コンセプトから外れる機能を盛り込むことは、短期的にはユーザの満足度を高める結果に繋がる可能性がありますが、長期的には、プロジェクトの寿命を縮めるリスクを増やす事だと自分は考えています。GitHub上に置いてある僕のアドオンは、基本的にはどれも「自分が使いたいから・使い続けたいから」開発をしているので、自分が使い続けにくくなる可能性が高まる変更は、なるべく取り込みたくないと考えています。
  • 細かい挙動はFirefox本体の本来の挙動に可能な限り合わせる。違和感が無いように作り込む。
    例えばFirefox本体の機能として、F11キーでフルスクリーン表示に切り替えた時に、ツールバーが画面の外に隠れるというものがあります。ツリー型タブには「タブバーを自動的に隠す」機能がありますが、単機能だシンプル化だと言っておきながら一見するとツリーとは関係ないこのような機能を未だに含め続けているのには、このF11でのフルスクリーン表示時の挙動をFirefox本体の挙動に自然にマッチするようにしたいからというのが大きな動機としてあります。
    タブのドラッグ&ドロップ操作のアニメーションに、ツリー型タブでそれなりの労力を割いて対応している最大の理由も、これです。(Firefoxにタブのドラッグ&ドロップのアニメーションが実装されるまでは、UIが似ているAdobe Illustratorのオブジェクトとレイヤーの操作性を参考に作り込んでいました。これは今でも、タブ以外のオブジェクトをタブバー上にドラッグした時に見ることができます。)

以上を踏まえてこのプルリクエストで触れている問題を考えると、自分は以下の理由から、この変更を行わない方が良いという考えを持っています。

  • Firefox本体に、タブのドラッグ&ドロップ時のアニメーションをOFFにする機能が無い。
    • アニメーションするかしないかでFirefox内でのコードパスが大きく異なり、どちらもそれなりに大きな規模である。
    • が、アニメーションのための開発が活発に行われていたのに対して、アニメーション無しのドラッグ&ドロップについては冷遇されている(気が、自分はする)。
    • ということは、今後、アニメーション無しのドラッグ&ドロップは実装が削除される可能性もある(と、自分は見ている)。 削除される可能性がそれなりにある実装に強く依存してしまうのは、リスクが高い。
  • ON/OFFの設定がないという事は、Firefox的には、タブのドラッグ&ドロップは基本的にアニメーションするものであるというスタンスだと考えられる。であれば、Firefoxに依存するプロジェクトは、Firefoxの方針に従っておくのが得策であろう。
    • アニメーション効果を適用することは、見た目のキレイさだけでなく、使い勝手の向上にも関係するので、自分はそのようなスタンスを取ることには肯定的である。
    • アニメーション効果をユーザが無理矢理無効化すると、正しく動かなくなる、という部分がFirefoxの中にすらある。
      具体的には、タブを閉じる処理は内部でのデストラクタを走らせるトリガーとして「アニメーションが完了した」というイベントを使っており、アニメーションが無効化されているとデストラクタが走らないのでタブがきちんと閉じられないという問題があった(今その問題がどうなっているかは把握していない)。
      Firefox本体の側がアニメーションOFFでの利用をここまで冷遇している以上、そのような使い方をこのアドオンで手厚くサポートする必然性を、自分は感じない。
  • 「アニメーションがあるとタブをドラッグ&ドロップで操作しにくい」、という要望に真正面から「アニメーション効果をOFFにできるようにしました」と応えるよりも、そういう要望が出にくくなるような形での解決を図るべきだと考えている。
    • そもそもドラッグ&ドロップで操作する必然性が薄ければ、問題なくなるのではないか。手動でツリーを編集しなければ意図した通りにならない、という状況があるのなら、ユーザに手動でのツリー編集という手間を強いる方向よりは、ツリー編集しなくてもストレスを感じないように、ユーザの意図を汲んで自動的にいい感じにツリーを構築するようにした方が、より望ましいのではないか。
    • アニメーション有りの状態でドラッグ&ドロップすると狙った位置にドロップしにくい、という問題があるのであれば、それは、アニメーションをOFFにすることで対処するのではなく、アニメーション有りでも狙った位置にドロップできるようにするのが、正しい解決ではないのか。
  • 僕自身は、アニメーションをOFFにして使うつもりがない。自分が使わない機能に対するメンテナンスコストを抱え込みたくない。
  • 視覚的に連続した変化を認識しにくい、アニメーションされた方が却って認識しづらくなる、といった性質あるいは障害を持っている人がいる、という事を考慮すると、アニメーションをOFFにできるようにすることは、アクセシビリティ上意義のある事だと思う。
    が、Firefox本体がアニメーションをOFFにできるようになっていない以上、「タブをツリー表示できるようにする」というコンセプトのこのアドオンが、独自にアクセシビリティ上の配慮を盛り込むのはおかしいのではないか。
    • この点を真面目に考えるのであれば、「FirefoxのBugzillaで問題提起して、Firefox本体の側でアニメーション効果のON/OFFをできるようにする」あるいは、「Firefoxのアニメーション効果を無効にするという1つのコンセプトに則ったアドオンを開発する」という道を選ぶべきだと、自分は思う。(アドオンではないが、userChrome.js用のzzzz-removeTabMoveAnimation.uc.jsというスクリプトは、そのための物と言えそう。)

以上の事は、あくまで現時点での自分の考えがそうであるというだけで、絶対普遍の真理であるとは考えていません。ここに挙げた数々の懸念点を払拭できる材料があったり、あるいは、そのような懸念があってもなおこのようにするべきであるという強い動機があって、僕が同意できるのであれば、変更を取り込むことにはやぶさかでないです。

でも、そうでない限りは、この種の変更については「フォーク版を作ってそっちで自由に開発していって下さい。そして、その機能を必要とする人自身の手でメンテナンスしていって下さい。」というのがこのプロジェクトの方針ということになります。僕がこれらのアドオン群にオープンソースライセンスを適用しているのには、そのような自由を保障しておきたかったからという理由もあります。

冷たいようですが、どこで線を引くのか・何を基準に線を引くのかを熟慮した結果、このような線引きに落ち着いたということで、同様の不満を抱いている方々にはどうかご理解を頂ければ幸いです。

RubyのCGIスクリプトでService Hookを受けて実行した外部コマンドの標準出力を文字列として受け取る - Apr 02, 2013

1つ前のエントリで、Rubyでバッククォートで実行した外部コマンドの標準出力を何故か受け取れないと書いてたんだけど、追記した通り、これは「RubyスクリプトがCGIで実行されているせいで標準入出力がCGI用に使われており、バッククォートで起動した子プロセスはその標準入出力を引き継ぐから、子プロセスから標準出力に出した内容が文字列として呼び出し元のスクリプトに返される代わりに、CGI経由でクライアント(GitHubのService Hookのエージェント)に返されてしまっている」ということだった(すとうさんに教えていただいた)。

で、対策として spawn()Process.waitpid() を使うと良いというアドバイスを頂いて、以下のように直してみた。

#!/usr/bin/ruby1.9.1
require "cgi"
require "shellwords"
require "json"
require "logger"
require "stringio"

SYNC_SCRIPT = "/home/piro/shared/or/tools/upload_nightly_xpi.sh"
RELEASE_SCRIPT = "/home/piro/shared/or/tools/release_addon.sh"
SSH_KEY = "/path/to/secret_key"
BASE_DIR = "/home/piro/shared/xul"
USER = "piro"

logger = Logger.new("/home/piro/shared/post-receiver.log")
#logger = Logger.new("/dev/null")
logger.level = Logger::INFO

# 子プロセスの実行結果(標準出力)を常に文字列で受け取るユーティリティ
def run(command_line)
  pipe_in, pipe_out = IO.pipe
  Process.waitpid(spawn(command_line, [:out, :err] => pipe_out))
  pipe_out.close
  pipe_in.read
end

cgi = CGI::new
puts "Content-Type: text/plain\n\n"
begin
  payload, = cgi.params["payload"]
  payload = JSON.parse(payload)
  project = payload["repository"]["name"]

  project_dir = File.join(BASE_DIR, Shellwords.escape(project))
  makefile = File.join(project_dir, "Makefile")
  if File.exist?(project_dir) and File.exist?(makefile)
    logger.info "build #{project}"
    sudo = "sudo -u #{USER} -H"
    command_line = "#{sudo} #{SYNC_SCRIPT} -i #{SSH_KEY} -b #{BASE_DIR} -d #{project_dir}"
    logger.info command_line
    logger.info run(command_line)

    command_line = "cd #{project_dir}; git describe"
    logger.info command_line
    current_commit = run(command_line).strip
    logger.info current_commit
    # 現在のコミットがタグを打ったまさにそのコミットである場合、
    # git describeの結果はタグ名だけになる。
    # なので、それをトリガーにしてリリース処理を走らせる。
    if !current_commit.empty? && !current_commit.match(/\A.+-[0-9]+-g[0-9a-f]+\z/)
      logger.info "=> release commit"
      command_line = "#{sudo} #{RELEASE_SCRIPT} -i #{SSH_KEY} -b #{BASE_DIR} -n #{project}"
      logger.info run(command_line)
    else
      logger.info "=> regular commit"
    end
  end

  logger.info "ok"
  p "ok"
rescue Exception => error
  logger.error error
  logger.info "ng"
  p "ng"
end

run() というのを定義していて、ここでパイプを作って spawn() の子プロセスの標準入出力に設定して、実行が終わるまで待ってパイプから実行結果を文字列として読み出す、ということをしている。(パイプを使う方法もすとうさんに教えていただいた。)

あと、このスクリプトは ~/public_html 以下に置いてるんだけど、apacheユーザで実行されてしまってファイルのアクセス権が……という事にも地味に悩まされていて、それでsudoを使ってたんだけど、suexecというApacheモジュールを使うと良いと教えてもらって sudo a2enmod suexec; sudo service apache2 restart としてみた。でもこの状態で git pull とかさせるとどういうわけか「error: cannot open .git/FETCH_HEAD: Permission denied」と言われてしまって(whoの結果ではapacheユーザじゃなくpublic_htmlがあるユーザになってるのに、何故だ……)、それで結局相変わらずsudoしている。

アドオンの自動ビルドとかリリース手順の自動化とか - Mar 30, 2013

以前、update.rdf関係を半自動生成するために頑張ったことがあって、各アドオンの紹介ページのHTMLからupdate.rdf(未署名)を作るあたりまでは自動化できてたんだけど、そこ止まりになっててまだまだ手動でやらなきゃいけないことが多くて、億劫で余計にリリースが滞る……という状況になっている。

それで、これじゃいかん!と思ってもっと自動化を進めることにして、とりあえずリポジトリのmaster/HEADを元に自動でテスト用ビルドを作るようにはした

で、その知見を元にもう少し頑張って、開発版ではなくリリース版の方ももっと自動化するというチャレンジをしている。

続きを表示する ...

大量肉リリース - Dec 29, 2012

リリースしてない状態が長く続いてる今このタイミングで12月29日、今年最後の肉の日ならこれは肉リリースにかこつけて溜まりに溜まってた物を一斉放出するいい機会だ……と思って、リリースできていなかった物をまとめて更新した。

最後にリリースしてから1年くらい経ってる物もあった。自分で使ってるのは常にmasterのHEADだから、リリースしなくちゃっていう圧力が働きにくくて、つい放置してしまう。それにしてもこれだけの数をまとめてというのは初めてなんじゃないかと思う。

ついでに、だいぶ前に実験的に作ってそれっきり放置していたSuspend Tabも、体裁を整えて一緒に公開した。類似アドオンが既にいくつもある激戦区にわざわざ突っ込んで行かんでも……というのはすごく思うけど、ツリー型タブと併用できる物が他に無いのでは仕方が無い。

1月には早々にFirefox 18が公開される予定になってたと思うし、それより前には公開しておかないと、また「動かないんだけど」の報告の嵐になるだろうなあ……という思いもあって、今を逃す手は無いなと。そういうわけで今年最後の肉リリースに踏み切った次第です。

RestartlessのE4Xレス化 - Dec 26, 2012

再起動の要らないアドオンをAdd-on SDK無しで開発するときの簡易的なテンプレートのような物として作っているRestartlessは、ツールバーボタンの定義や設定ダイアログの定義にE4Xを使う前提で設計してた。静的なXULファイルを別に用意しなくても、JavaScriptで書かれたロジックの中にリテラルとしてXULの定義を埋め込める、ということで重宝してたんだけど、E4Xのデフォルト無効化で完全にハシゴを外された形になってしまった。

E4Xを多用してた方々各方面悲喜こもごもあるようで、自力でスクリプトをパースしてCDATAマーク区間だけでも認識できるようにするとか色々なアプローチが試みられているようなのだけれども、僕はというと、面倒なのでE4Xはスッパリ諦める事にした。元はといえば、従来のやり方に近いやり方で再起動の要らないアドオンをラクに開発したいというのがRestartless開発の動機だったのだから、何か代わりの手段があるのであれば、E4Xにこだわる理由はなかったし。

まずE4Xで定義されたXULのコード片を受け取る部分についてだけど、これらは内部的にはXMLのソースコードの文字列に変換した後、RangeのcreateContextualFragmentでDOMDocumentFragmentにしてたので、インプットはただの文字列でも構わなかった。なのでToolbarItem.jsconfig.jsは以下の点だけ修正して終わりとした。

  • E4X無効の環境でもシンタックスエラーにならないように、E4X固有の書き方をなくした(具体的には、識別子としていきなり「*」が出てこないようにした)。
  • インプットが文字列の時は、それをそのままDOMDocumentFragmentにした後、ホワイトスペースだけのテキストノードをその都度削除するようにした(XBLの定義が手抜きなせいで、こういう場合に初期化エラーになるので)。

ツールバーボタンの定義は、手間だけど文字列リテラルに書き直すことにした(簡単なスクリプトでインデントも含めてそれっぽく置換した)。ちょよんごさんのnode-hereを移植することも考えたんだけど、単に改行込みのコード片を文字列として取得できるだけだと、E4Xの時みたいな「属性値やテキストノードの値にJSの変数の値を入れる」ということが簡単にはできなくて、そこの面倒さの方が気になったので、今回は見送ることにした。

ただ、設定ダイアログくらいの規模となると、一々文字列リテラルにしてたら埒があかないのでそこだけはなんとかしたかった。これについては、Firefox 8くらいから後のバージョンではchrome.manifestでcontentやlocaleのChrome URLを動的に登録・解除できるようになってるので、昔ながらのやり方に戻って静的なXULファイルで書くようにした

ロケールもこの要領でpropertiesファイルからDTDに書き直せばいいんだけど、Fox Splitterみたいにロケールの数が多いとそんなのやってらんないし、Fox Splitterの場合は設定ダイアログとブラウザ上のUIとで同じラベルを使い回したりしていて、どれをpropertiesファイルに残してどれをDTDにするのかとかを考えるのももう無理っぽかったので、逆転の発想で、属性値やテキストノードの値に{{ JavaScriptの文 }}という書き方を許容するようにして、XULドキュメントが開かれたときに自動的に解決するユーティリティを加えて、propertiesファイルをDTD代わりに使うことにしてみた。DOMContentLoadedのタイミングだと遅すぎるようだったので、今の所は待ち無しで実行してるけど、XBLの初期化タイミングが狂うリスクがあるので、将来的には問題が起こるかもしれない。(……と、ここまで書いて気付いたけど、node-hereを移植した上でこれと同じ記法を許容するようにすればよかったかなぁ。もう後の祭りだけど。)

Restartlessベースで作ってた各アドオン(親のタブに戻るFox Splitter、あと開発中で放置してた「Suspend Tab」)も更新済みで、masterベースのXPIはこの間から提供してる自動ビルドが既に利用できる状態になってる。Nightlyで使ってた人がもしいたら、これで動くようになってると思う。

……node-here.jsの移植はやらないでおくって書いたけど、結局やっぱり必要になってしまったので移植した。スタックトレースから列番号を取れないというGecko(SpiderMonkey?)の制限のため、1行の中に2個以上のhere()は書けない。

Page 5/243: « 1 2 3 4 5 6 7 8 9 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき