この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2013年4月)

2013年4月15日

Bug-org 855916 Needs a debug pref for testing moz gesture events 初回投稿日時: 2013年04月15日14時33分58秒
カテゴリ: Events Mozilla Core Mozilla22 バグ修正
固定リンク: id=2013041500
SNS: (list)

Bug-org 851128のレビューを頼まれたので、実際の挙動を確認するために、テストを書いてみたところ、一切イベントが発生しない、という不思議な現象が発生していたので、レビューをリクエストしてきた人に聞いてみたところ、Moz*Gestureイベントはbrowser/がchromeで、キャプチャフェイズで捕まえ、stopPropagation()を呼び出しているため、contentでは一切発生しないようにしている、とのことでした。

これではテストに不便なので、dom.debug.propagate_gesture_events_through_contentという設定値を新規に追加し、これをtrueにしておけば、stopPropagation()が呼ばれないように修正しました。

Bug-org 851128 Double-tap gestures are not recognized on OS X 初回投稿日時: 2013年04月15日14時42分28秒
最終更新日時: 2013年04月15日14時42分50秒
カテゴリ: Events Mac Mozilla Core Mozilla23 バグ修正
固定リンク: id=2013041501
SNS: (list)

私が修正した訳では無いんですが、かなり深く関わることになったので紹介しておきます。

私はよく知らないのですが、MacのSafariは、二本指のダブルタップでズームのような特殊なアクションが行われるんだとかなんとか。そこで、Windows版Geckoとは操作方法が違うものの、Mac版Geckoでは、MozTapGestureをこの操作に割り当てて、chromeで利用できるようにしよう、というバグです。

このイベントは、Bug-org 855916の解説にあるように、Webコンテンツは利用できません。あくまで、chrome権限で動く、アプリのみ利用できます。

意図せずに発生してしまわないように、さんざんテストを重ねた結果、最終的には割とシンプルなパッチになっていますので、興味のある方は読んでみてください。

Bug-org 857829 Backout the patch for bug 849647 from Aurora 初回投稿日時: 2013年04月15日14時51分56秒
カテゴリ: Mozilla Core Mozilla22 Windows バグ修正
固定リンク: id=2013041502
SNS: (list)

Bug-org 849647の修正時からシナリオに入っていましたが、とてつもない影響範囲なのにmozilla-centralで一週間しかテストできていないのはリスキーなので、Mozilla 22からバックアウトし、より長期間、テスタがテストを行うことができるようにしました。

TSFモードを利用している、ATOKユーザの方は、もう6週間、我慢してください。

Bug-org 857820 Drop only blink effect from text-decoration: blink; and completely remove <blink> element 初回投稿日時: 2013年04月15日15時08分54秒
カテゴリ: CSS HTML Mozilla Core Mozilla23 バグ修正
固定リンク: id=2013041503
SNS: (list)

もう、色んな意味でうざいので、blink指定による点滅処理を削除しようよ、というバグです。

Google ChromeのWebKitを、Blinkとしてフォークするというニュースを見てて、『そーいや、OperaもChromiumベースなんだから、Blink陣営になるんだろうな』とぼんやり考えていたところ、『blinkの点滅効果って、OperaのPrestoと、Geckoしかサポートしてないんだから、Operaが、blinkの点滅効果をサポートしない、Blinkエンジンに移行し終わればGeckoだけが孤立するんで、サポートをやめたら、コードがざっくりと削除できていいんじゃないか?』って思いつきました。

そこで、削除を提案してみたところ、すんなりとコアメンバーが賛成してくれたので、他のバグで煮詰まってた気晴らしに作業することにしました。

当初は、text-decoration: blink;自体のサポートを中止することでスタイルシステムが食っているメモリを多少削減できるので良いと思っていたのですが、えむけいさんが、それはCSS仕様に違反する上、他のブラウザとの互換性も損なうと忠告してくれたので、まずは点滅処理の削除だけを行うことにしました。

ちなみに、もし、text-decoration: blink;自体のサポートを中止すると、text-decoration: underline blink;のような指定があった場合、このスタイル指定全体が無視され、下線が引かれなくなってしまいます。ですが、値のサポートは継続していますので、下線は引かれるものの、点滅はしない、という形になります。これは、他のブラウザと全く同じ動作です。

また、単にCSSのパーサでのみ、blinkキーワードをサポートしている訳ではありませんので、DOM APIを用いて、算出値等を取得した際には、blinkが指定されている場合には、きちんと、blink値が返ってきます。

つまり、Webアプリから見ると、CSSのtext-decoration: blink;に関しては、何ら、変化がなかったように見えます。

そして、もうひとつ、<blink>タグのサポートを中止するかどうか、という課題がありました。色々とややこしいことになってコメントが伸びてしまっていますが、こちらもえむけいさんの尽力により、HTMLパーサや、HTMLエディタで、<blink>タグは未知のタグとして扱うように修正しました。

このため、DOM APIで<blink>要素のノードを作成すると、未知のHTML要素としてオブジェクトが生成されるようになっています。

まとめると、変更点は以下のようになります。

  • text-decoration: blink;は、スタイルシステムでは引き続きサポートされる
  • 点滅はしなくなる
  • <blink>要素は未知の要素になった

2013年4月24日

<ruby>関連要素って駄目駄目 初回投稿日時: 2013年04月24日08時50分50秒
最終更新日時: 2015年02月21日15時45分29秒
カテゴリ: HTML XHTML 雑談
固定リンク: id=2013042400
SNS: (list)

<ruby>関連要素の仕様について色々と思うところが多いので、この日記にまとめておこうと思います。

私の結論を先に述べておくと、一言、酷い仕様、です。

歴史

まず、<ruby>関連要素の歴史を振り返ってみましょう。

まず、<ruby>関連要素はIE5で独自拡張として実装されました。ルビを振りたい日本人に一定の支持を受けていた印象があります。ですが、独自に暴走して仕様を決めてしまっているため、他のブラウザベンダ等との協議を経て、ブラッシュアップされたものでないのは当然と言えます。これが第一の不幸です。

そして、Microsoft在籍のエディタを中心に、XHTML 1.1の拡張モジュールとして、2001年に、Ruby Annotationが勧告されました。その内容はIEの実装内容を基に、より複雑なルビをマークアップできるように、仕様も複雑化していました。ですが、IEをはじめ、この仕様を全て実装したブラウザは存在しません。ですが、標準仕様の策定になったという既成事実がこの時に成立してしまいました。これが第二の不幸です。

その後、WebKitが、何故か突然、<ruby>関連要素をIEの実装に基づいて実装してしまいました。これで、<ruby>関連要素はある意味で本当に市民権を得てしまったと言えます。これが第三の不幸。

そして今、HTML5で<ruby>関連要素は、必要最低限のものに絞り込まれ、勧告へ向けて着々と進んでしまっていて、もはやこの流れを止めることはできないでしょう。ですので、珍しく、W3Cで議論するわけでもなく、ここで愚痴るのみに留めています。

HTML5における<ruby>関連要素

HTML5で定義されている<ruby>関連要素について、簡単にまとめておきましょう。簡単な利用方法には二種類あります。<ruby>要素全体にまとめてルビを振るか、<ruby>内を複数のセグメントに区切って、ルビを振るかの二つです。

<ruby>不撓不屈<rp>(</rp><rt>ふとうふくつ</rt><rp>)</rp></ruby>
<ruby>不<rp>(</rp><rt>ふ</rt><rp>)</rp>撓<rp>(</rp><rt>とう</rt><rp>)</rp>不<rp>(</rp><rt>ふ</rt><rp>)</rp>屈<rp>(</rp><rt>くつ</rt><rp>)</rp></ruby>

これらは、それぞれ、非対応ブラウザだと、不撓不屈(ふとうふくつ)不(ふ)撓(とう)不(ふ)屈(くつ)と表示されます。

では、各要素の意味を簡単にまとめておきましょう。

ruby element

ルビを振りたいテキストと、ルビ全体を含む要素です。DOMツリーで考えた場合に、コンテナとして機能しますが、そういう意味では変な名前になってしまっています。

rt element

<ruby>要素内で、ルビとして振られるテキストを示す要素です。本来なら、これがruby要素という名前の方が正しかったのではないかという意見も見かけたことがあります。

rp element

<ruby>関連要素に対応していないブラウザでも、自然なテキストとしてルビを振られるテキストと、ルビを表示しようとすると、各境界線に括弧のような区切り文字が必要になります。しかし、対応しているブラウザでは逆に不要となります。この区切り文字部分を意味する要素です。

では、私が感じている問題点について解説していきます。

複雑すぎる仕様

まず、上記の例を見てもらえば分かりますが、そもそも複雑すぎます。明らかに手作業でマークアップするためのものとしてデザインされていません。SVGのように複雑すぎてツールが必要なものを制作するにあたって、手作業でのマークアップが不可能に近い、というのは分かりますが、文中に大量に出現する可能性のあるシンプルな機能を付与するマークアップがこれほど複雑であるというのはバランスを欠いていると言えます。

また、ルビそのものもテキストノードですので、選択してコピーすると、再利用しづらい文字列がクリップボードにコピーされてしまいます。

<rp>要素はそのうち無視されるようになる

このように複雑で面倒な代物だと、少しでも簡単に記述してしまいたいと思うのが人情です。現在、メジャーなブラウザで<ruby>をサポートしていないのは、FirefoxとOperaのみですが、Operaは近々、Chromiumベースのブラウザに生まれ変わることが発表されています。ですので、あとはFirefoxが対応し次第、意識の低いWeb開発者は喜んで、<rp>要素を利用しなくなるでしょう。

この流れは確実に発生すると考えていて、そうなった場合に、この仕様のアクセシビリティへの配慮は破綻することになります。

<ruby>要素には意味がない

HTML5の仕様書では、<ruby>関連要素の様々な使い方が例示されています。使い方としてパッと思いつくだけでも、「読み方を明示する」ためと、「当て字を表現する」という二つがあります。後者は、超電磁砲(レールガン)といった形です。

ですが、何故か、どういった目的をもってルビが振られたのかを指定する属性が用意されていません。このため、そもそも<ruby>には意味が定義されておらず、単に、ルビを振るという表現手法のための、プレゼンテーションのための要素となってしまっています。

つまり、CSS登場以前のHTMLの考え方に戻ってしまっていて、(今時の若いデザイナさんは知らないかもしれませんが、) <font color="red">赤いテキスト</font>と同じレベルのことをHTML5という最新仕様で、オトナ達が必死に定義しようとしているという悲しい状況になっています。

では、どのような仕様が望ましかったのか、これには色々な案があると思いますが、私がイチオシなのは、シンプルに属性を活用してしまうことです。

対案1

もっともシンプルなのは、HTML5では何も定義せず、CSSのrubyモジュールに頼るというものです。例えば、略語に対して、ルビを振りたい場合、意味の無い<ruby>要素を使うのは、典型的な残念なマークアップと言わざるを得ません。例えば、TKG(たまごかけごはん)といったケースを考えてみましょう。ルビを振る、という表現手法を頭から取り除いて考えてみてください。何が適切だと思いますか? そう、<abbr>要素ですよね? 略語のマークアップなのですから。ですので、

<abbr title="たまごかけごはん">TKG</abbr>

とマークアップし、CSS rubyモジュールを利用し、

abbr[title] {
  display: ruby;
}

abbr[title]::after {
  content: attr(title);
  display: ruby-text;
  font-size: 0.6em;
}

といった形で表現を定義してしまえば、良いのです。

Sample: TKG

対案2

しかし、対案1では、ルビとしては振りたくない場合にも、ルビが振られてしまう弊害があるため、ドキュメントの構成によっては、クラスを指定したりすることで、切り分けをしなくてはいけません。それは面倒ですよね。また、title属性とは異なるルビを振りたい場合に、data-*属性を利用するというのも、変な感じがします。そして、最大の問題は、CSS rubyモジュールに非対応のブラウザでの対応が、少し面倒になります。

じゃあ、そもそも、特定の要素にruby属性を持たせておくとシンプル、ということになります。つまり、

<abbr ruby="たまごかけごはん" title="たまごかけごはん">TKG</abbr>

というマークアップにし(この例では冗長な感じになってしまっていますが)、

*[ruby] {
  display: ruby;
}

*[ruby]::after {
  content: attr(title);
  display: ruby-text;
  font-size: 0.6em;
}

としてしまうことです。この場合、非対応ブラウザは、ブラウザのデフォルトスタイルシートで、

*[ruby]::after {
  content: " (" attr(title) ") ";
  display: inline;
}

と定義しておくことで、<ruby>要素の想定しているアクセシビリティを現代のブラウザでは簡単に確保できてしまうことになります。

Sample: TKG

要素 vs. 属性

そもそも、何故、ルビは要素で定義するようになったのでしょうか? これについてはMicrosoftの当時のエンジニアに聞いてみないと真実は分かりませんが、当時のWeb標準仕様に対する風潮や、各ブラウザのCSSの実装事情から考えると、やはり、非対応ブラウザのアクセシビリティに配慮したと考えるのが自然でしょう。

当時は、generated contentはもとより、そもそもCSSにまともに対応できているのはIEだけという時代でした。また、時代は、SGMLベースのHTMLから、XMLベースのXHTMLに移行し、より、マシンリーダブルなセマンティックウェブを実現しようと、今よりもアクシビリティ等、地味な部分への意識が高い時代でした。

このため、ルビはIEで独自実装する際には、要素として表現するしか、選択肢がなかったのではないかと思います。

しかし、HTML5の時代が来つつある今、理想よりも現実的なアプローチがより好まれるようになってきました。また、各ブラウザのCSS実装は高度に進化し、上述のスタイルの実現は技術的には可能になっています。

そして、各ブラウザのメジャーリリースの間隔は非常に短いサイクルになりました。企業向けに慎重である必要があるIEですら、年一度程度のペースになりつつあります。

ですので、このような時代に、未対応ブラウザでは標準の動作で非表示となってしまう属性に、新機能であるルビの機能を持たせるのはアクセシビリティ上好ましくないと考えることは、非常に古い考えであると言えます。上述の非対応ブラウザ向けのスタイルを定義することを、非対応ブラウザに義務づけてしまえば、間違いなく、HTML5の正式仕様勧告までに、各ブラウザ、間に合うでしょう。たとえ、間に合わなかったとしても各Webページは自前で記述することにより、対応させることができます。

結局、何が不幸を加速させたのか?

歴史的な事情を踏まえると、ある意味、今の形は自然な結果であると言えます。

しかし、XHTML1.1がまったく実用化されなかったことを踏まえると、初のマトモな仕様化はHTML5が最初と言えますので、ここまでに何度も、このような悲惨な状況になることを回避するチャンスはあったと思います。

まず、HTML5仕様案登場以前に、IEの独自仕様である<ruby>関連仕様を誰も支持しなければ良かったのです。Webサイトは利用せず、WebKitも追っかけ実装をしなければ、既成事実がほとんど存在せず、<blink><marquee>のように、あたかも存在しなかったかのように、無視し、HTML5では、別のより使いやすい仕様を模索できたのではないかと思います。

つまり、HTML5仕様でIE独自仕様の<ruby>関連仕様をそのまま採用しようとしてしまったことが不幸な結果へと突き進むしかなくなった現状の直接的な原因であると言えます。この時点で誰かが、独自拡張を採用しているサイトを無視する、という英断ができていれば、より、今風のシンプルな仕様になっていたでしょう。ここに関われなかったことを非常に個人的にも後悔していますが、時、既に遅しですね。

脱法ルビ

私の、ルビは属性で十分、というアイデアに共感できる方は、お勧めはしませんが、脱法ルビ(HTML5的にInvalidではない)を利用することは将来的には可能です。

HTML5では、<ruby>要素に意味が定義されていないことが逆に幸運だったと言えます。意味が定義されていない以上、これを利用すべき理由が実は無いのです。

そして、HTML5では、data- prefixを付与した属性を独自に、あらゆる要素に勝手に付けることができます。これはつまり、以下の例がまかり通ることを意味します。

<span data-ruby="ふとうふくつ">不撓不屈</span>
<span data-ruby="ふ">不</span><span data-ruby="とう">撓</span><span data-ruby="ふ">不</span><span data-ruby="くつ">屈</span>
/* for ruby unaware browsers */
*[data-ruby]::after {
  content: " (" attr(data-ruby) ") ";
}

@supports (display: ruby-text) {
  *[data-ruby] {
    display: ruby;
  }
  *[data-ruby]::after {
    content: attr(data-ruby);
    display: ruby-text;
    font-size: 0.6em;
  }
}

Sample:

この手法のメリットは、何よりも、最低限の記述なので、手書きに無理が無いレベルのマークアップだという点です。

難点は、DOMでスクリプトから何らかの処理をしづらい点と、現状、まだブラウザの実装が追いついていない点、そして、将来的に、<ruby>要素がHTMLElementではなく、独自APIを持った、派生オブジェクトを生成するようになった場合に、それが利用できない、という点です。

2013年4月29日

Bug-org 842927 Implement DOM3 KeyboardEvent.key only for non-printable key, first 初回投稿日時: 2013年04月29日09時10分03秒
最終更新日時: 2013年04月29日09時31分12秒
カテゴリ: Android Events Gonk GTK IE Mac Mozilla Core Mozilla23 Windows バグ修正
固定リンク: id=2013042900
SNS: (list)

Bug-org 834554で、Firefox OSチームがメチャクチャなパッチを投入して、KeyboardEvent.keyCodeの値をハッキーに利用しようとしていたので、それを阻止するために、仕様がまだもめている文字入力用のキー以外のキーでのみ、KeyboardEvent.keyを先行実装することにしました。

今回の初期実装では、Windowsはできる限り、IEとの互換性を意識していますが、一部、仕様書側の内容を優先して、IEと互換性の無いキーもあります。

また、一部のIME関係のキーに関しては、Windowsではキーボードレイアウトのロケールを見つつ、処理しなくてはいけませんが、それはBug-org 865565に先送りしています。

単純にマッピング可能なキーに関しては、ひとつのファイルで、全プラットフォームのマッピングを定義していますので、非常に参照しやすくなっています。

各プラットフォームのネイティブキーコードからの変換表を参照したいのであれば、MDNにある以下の表を参照する方が見やすいです。

なお、文字入力キーでは、現在、"MozPrintableKeyという値が一時的に返ってきますが、これはあくまで過渡期のものですので、Webアプリは参照しないようにしてください。