SafariのUA文字列が固定されて固定されなくなったおはなし
Jxckが以前、SafariのUA文字列が固定されたというのを書いていた。
Safari Technology Preview 46で入った変更だ。
Froze the user-agent string to reduce web compatibility risk and to prevent its use for fingerprinting
TwitterでもAppleのRicky Mondelloがそれを伝えていて、ちょっと騒ぎになっていた。「それは困る」的な反応が結構多かったのと、中には「やっぱりSafariは新たなIE6だ」みたいな、リスペクトのない反応もちらほら。なんだかね……
さて、これだけだったらここで書くことはなにもないんだけど、続きがある。その後この固定化はとりやめられたのだった。
現在はUA文字列に含まれていたOSのバージョンが固定されず、ちゃんと実際のバージョンを反映するようになっている。先日リリースされたSafari 11.1でもUA文字列の変更については述べているものの、固定という表現ではなくなった。
Updated the User-Agent String Policy
- Changed the updating policy to to only continue updating the OS version number and Safari version number.
参考までに、手元のmacOS 10.13.4で確認した、Safari 11.1のUA文字列を。
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1 Safari/605.1.15
以下はUA文字列固定の経緯と、再度変更されるまでの流れ。
UA文字列の固定とはなんだったのか
RickyのツイートやSTP 46のリリースノートだけだと詳細がわからないが、ちゃんとコミットがある。
Freeze the version reported as User Agent to OS 10.13.4 (OS 11.3 on iOS) and WebKit 605.1.15 for User Agent purposes.
macOSのバージョンが10.13(High Sierra)以降の場合は10_13_4、iOSの場合は11_3になると。ついでにWebKitのバージョンも605.1.15に固定される。
なので、パッチが入ったSTP 46からしばらくは、以下のようになっていた。
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1 Safari/605.1.15
STP 46の時点ではmacOSは10.13.3なので、たしかにOSのバージョンが固定されている感じなのがわかる。
変更の理由
STPのリリースノートにもフィンガープリンティングを避けるという目的が書いてあったけど、該当バグにもう少し細かく書かれていた。
Stop reporting more recent user agent version strings, freezing the version at a specific moment in time. We should do this for a number of reasons:
(1) User Agent sniffing is a terrible way to determine whether a browser supports certain features.
(2) Bad User Agent sniffing code on the web create compatibility problems every time we update the versions.
(3) Overly-specific version information provides useful fingerprinting data while providing almost no user benefit.
- ある機能のサポート状況をチェックする方法としてひどい
- UA文字列検出のコードがひどいと互換性の問題にバージョンを上げるたびに毎回出くわす
- 細かすぎるバージョンの情報はフィンガープリンティングにつながる危険性がある
フィンガープリンティングだけではなくて、UA文字列について一般的に問題とされていることも理由となっていた。
OSのバージョン固定がなくなった
Rickyのツイートにもたくさんの「困る」という声があったし、Appleにそのような声が寄せられたか、はたまた互換性のバグに引っかかったのかわからないけど、件のコミットから2ヶ月ほど経った今年2月、方針が転換されるコミットが入った。
Revert back to dynamically reading the operating system marketing version rather than using a hard-coded version.
OSのバージョンをシステムから読むように(再度)変更したと。つまりは固定されなくなった。
いったん固定するとした方針を軟化させるにあたっては、バグに議論があった。
まずは固定をやめる理由について。
The primary reasons were:
WebKit sometimes ships with bugs that can be worked around at the website level. Having a release version allows websites to activate workarounds where needed.
Decisions about what site content to send to a user agent are often made before the page is loaded. Having UA information when connecting to the server allows websites to send only the relevant payload (e.g., more recent javascript, more efficient image formats, etc.)
Safari (for example) ships with the same version on several operating system revisions. Sometimes bugs exist in specific OS revisions that websites can work around.
For these reasons, we decided to relax some of the restrictions we had originally planned on making.
- バグがある状態でリリースされてしまうと、ウェブサイトで対応するしかない。リリースバージョンを含めるを含めることでワークアラウンドが可能になる
- ブラウザごとにコンテンツを出し分けるサーバーサイドのコードがあって、UA文字列を含めることで必要なものだけを送れる
- SafariはOSといっしょにアップデートされるけど、OSにバグがあるときのワークアラウンドに使える
といった感じ。1、2についてはどのブラウザにも言えるだろうけど、3については半年に一度のリリースで、かつOSとくっついているSafariならではの事情が大きそうだ。
一旦は決めた固定をやめること、そしてその理由については、それはどうなんだという反発もあった。mitz氏はこう問うている。
Shouldn’t WebKit provide a direct and explicit way for websites to determine that a bug is fixed?
バグが直ったら伝える仕組みを設けるべきではという。ドキュメンテーションよりも直接的なものを想定しているのかな。とはいえ、だいぶ理想を見ているようにも見える。そういうのがあってうまく機能したなら、世の中はXMLベースになっていたんじゃないかな。
UA文字列という手段を使い続けることについても、別の方法がないのかという疑問も提示している。
Aren’t there other request headers dedicated to explicitly, directly conveying what the user agent supports?
Client Hintsみたいなものの機能版という感じかな。ヘッダではないけどhasFeature()というものがあって、これはなかなか残念な結果だったはずなので、ヘッダにあってもあまりうまく機能しない気がする。「サポートしている」の粒度が人によってそれぞれ違うだろうから、うまく満たせる仕組みはつくれないだろう。
とまあ、疑問が投げられたけど結局コミットされたので、使えるUA文字列が復活した。めでたいのか、めでたくないのか。
なお、OSのバージョンは固定されなくなったが、WebKitのバージョンは605.1.15に固定されたままだ。WebKitのバージョンでなにかしたいケースってあるかな……ほしいのはOSバージョンだろうから、こいつはそこまで気にされないかなーと思う。
おまけ:なんでアンダースコアで区切ってるのか
OSのバージョンはなぜだか10_13_4と、アンダースコア区切りになっている。
なんかあったのかなーと思ったら、UserAgentCocoa.mmというファイルにこんなコメントが書いてあった。
// Use underscores instead of dots because when we first added the Mac OS X version to the user agent string // we were concerned about old DHTML libraries interpreting "4." as Netscape 4. That's no longer a concern for us // but we're sticking with the underscores for compatibility with the format used by older versions of Safari.
OSのバージョンをUA文字列にぶっこんだときに、4.という文字列が現れたら問答無用でNetscape 4と認識するDHTMLライブラリに出会ったらしくそれを迂回する目的だったらしい。たしかにNetscape Communicator時代は4.0とか4.5とか4.7とかマイナーバージョンが更新されたから、4.でマッチさせるようにしたのかな。たしかにNetscapeはいまと比べてUA文字列だいぶ短かったし。
うーんでも、4.でマッチするならIEもマッチする気がするんだけどな……
コミットを探したらあった。
Added Mac OS X version string, right after the string "Mac OS X", but with underscores instead of dots to avoid the dreaded "4." problem (old libraries that think a "4." anywhere in the user agent means Netscape 4).
No way to detect Tiger vs Leopard from Safari's user agent string
と、TigerとLeopardを判別したいなにかがあったらしい。なのでOSのバージョンを入れたのだけど、4.が問題になった過去の問題をふまえてアンダースコアにしたと。
ではその4.についての言及はどれかなーとさらに探したら、これまたあった。ちゃんとchangelog書いてるのすごいなー
Adds a build phase script that ensures WebKit's version dosen't end in a 4. If our version ends in 4, some sites might think we are Netscape 4 in their user agent checks.
これを読むと4.ではなく4な気がするんだけど、いつのまにか4.になってるのはどうしてなんだろう。もうわかることはないんだろうけど。
元のコメントを読むと、現在はドットにしたところで互換性の問題はないらしいが、逆に過去のSafariとの互換性がとれなくなるという話でアンダースコアが残されているらしい。ふしぎなコードとバグと互換性でウェブは続いていく。
するするさせたい:サイボウズ採用情報のアニメーション(その3)
サイボウズ採用情報のアニメーションがするするしてないので調べた件、今回は雑記。
描画領域とPaint Flashing
その1でPaint flashingを見たときにはアイコンの周りに枠がついていたのに、その2で描画領域を見たら文書全体で起こっていたたのをふしぎに思ったひとがいるかもしれない。
これはPaint flashingの説明 Hightlights areas of the page that need to be repainted
というのをよく読むといいかも。緑色になったところは「再描画が必要になったところ」、paint invalidationを指している。なので変化していない箇所は緑色にならなかったわけだ。
Chromeにおける“Paint”が何を指すかは、Stack Overflowにある回答が詳しい。
モバイルはどうなのか
今回使ったのはふだん使ってるMacBook Air。2011年モデルだしAirだしMacとしてはだいぶしょぼい。それでもなんとかするするさせられた。
ではもっとしょぼい環境はどうなるか。というわけでNexus 5を繋いでリモートデバッグしてみた。 以下通常状態。MacBook Airと比べてCPUの使用率が高い。描画も引き続き高いけど、Scriptingも高いのが気になる。

transform: translateX() をつかったアニメーションに差し替えると、するするした。

いちおう大丈夫っぽい。ただ格安スマホなどもっとしょぼい端末だと、CPUやGPUがこれ以上に専有されるかもしれない。
iPhoneはどうだろう。iOSデバイス持ってないので試せないのだけどiPhoneさまなら大丈夫だろうと勝手に思って眠ることにする(みんなは試そう)。
他のブラウザの開発者ツール
今回はChrome DevToolsを使った。アクティビティの詳細を見られるので説明に便利なのと、まあみんな使ってるんでしょということで。
ただChromeだけの最適化になってしまったらアレだ。他のブラウザはどうなのか。
FirefoxやSafariのDeveloper Tools/Web InspectorにもふつうにElementsパネルはある。h で要素も隠せる。
Paint flashingもどちらにもある。Firefoxではハケのアイコン、SafariはElementsパネルのパンくず右にあるブラシアイコンで同様のものが見られる。なおFirefoxは色相が常に変わり、Safariでは赤色のハイライトになる。

件のアニメーションはSafariでは真っ赤になった。赤いほうが問題っぽさが増していいかもしれない(Chromeも昔は赤色だったけれども)。
レイヤー表示。Safariの場合はPaint flashingアイコンの横にある四角が4つのアイコンを押すと表示される。

FirefoxではDeveloper Toolsからできない。about:config から layers.draw-borders を true にすればいける。ちょっと面倒。Bug 877567なのかな。
で、肝心なタイムライン。Firefox, SafariどちらにもあるんだけれどChromeほど高機能ではない。Chromeが強すぎるというのはある。
ただ今回くらいのレベルであれば、そんな問題はないかも。数秒ほど録る、繰り返しを見つける、時間を見てみる。これでそれなりにわかるかなあと。描画領域についてはとりあえず will-change: transform をコンソールからぶっこんでレイヤー作って確かめるとかね。いろんなサイトのタイムラインを録ってみて調べるうちに感覚が養えてくると思うので、いろいろ見てみてほしい。
EdgeはWindows環境が手元にないのでわからないのだけど、ドキュメンテーションを見る限りは結構強力そう。
Safariでするする
さて、Safariでもとのページのタイムラインを録ってみた。

スタイル計算と描画、タイマー発火が頻繁そうなことがわかる。

Layout & Renderingという行を押したら詳細が見られる。Paintではその領域を見られるけど、これはinvalidationなのかな。ちょっとわからない。
Web Inspectorに新しく入ったRendering Framesモードでも見てみた。

1フレーム目にタイマー、2フレーム目に計算・描画が行われてて面白い。
さてするするさせてみる。transform を使ったコードをぶっこんでまたタイムラインを録ってみる。

するするした。同じ方法が使えるようだ。
なお、CSSアニメーション版のレイヤーを見てみると謎の水色の枠がでてきた。

こいつはなんなんだろう…Web Inspectorはドキュメンテーションがあまりなく、さらには更新されてないのでけっこうつらい。ソース読むしかないのか……
Firefoxでするする?
Firefoxでもみてみる。Firefoxのタイムライン(Performance)ツールは複数のタイムラインを保持できるのがうれしい。
現行のサイトを録ってみた。

あら、そのままでも60FPSに近い。Composite Layersにけっこう時間をとられているね。

Paintもすこしかかっている。描画範囲わからないのかな。もうちょっと調べないといけない。

CSSアニメーションに置き換えたものがこちら。タイマーはなくなったけど、ちょっとところどころフレームが落ちてしまっている。Composite Layersの負荷が変わってないので、もともと負荷が高いのかな。

あとスタイル再計算も走っている。Restyle HintがCSSアニメーションとなっているので、Geckoだとスタイルの再計算が走ってしまうのかな。ふむー
ただ見た目をいうと、CSSアニメーションのほうがするするはしているんだよね。データには現れづらいところなのかな…ちょっと心残り。
もうちょっとなんか考えてた気がするんだけど、メモしてなかったのともう書き疲れたのでこのへんで。
みんなもするするさせるんだよ。
-webkit-alt プロパティ
これを読んでいて、内容とはまったく関係ないのだけれど -webkit-alt プロパティのことを思い出した。昨年11月に実装されたgenerated contentの読みを提供するためのプロパティだ。
- Changeset 159591 – WebKit — AX: Implement CSS -webkit-alt property
- [webkit-dev] AX: Implement CSS -webkit-alt property (text alternative for generated content pseudo-elements ::before and ::after)
実装された時期的にSafari 8/iOS8 Safariに入っててもおかしくないのだけれど、どうなのかな。誰か確かめておくれ。
装飾的なテキストをつける場合に、擬似要素にぶっこむという方法がある。
[data-new]::after {
content: "\2730”; /* a.k.a. ✰ , literally “shadowed white star” */
}
これでOKとおもいきや、どうやらVoiceOverはgenerated contentも読み上げてしまって、この星印を“shadowed white star”と読んでしまうらしい。DOMに存在してたらARIAの属性つけられるけれど、擬似要素なのでそうもいかない。そこで読みを提供するプロパティを導入したいと。
[data-new]::after {
content: "\2730”;
-webkit-alt: "New";
}
attr() も使えるので、ローカライズもしやすいとのこと。
[data-new]::after {
content: "\2730”;
-webkit-alt: attr(data-new);
}
ふうむ。擬似要素にテキストぶっこむというケースがどれくらいあるのかわかんないのだけど、広くサポートされる時代はすごく先になりそうだなあ。
これもまた全然関係ないのだけれど、絵文字を見る機会が増えてきた。ただ、グリフのデザインがよくないのか「これなんだろう?」と思ってしまう文字が多いのだよね。とくにぼくはケータイ持つのが遅くて絵文字の読解に慣れてないというのもあり、ハンディキャップというかなんかそういうのを感じている。絵文字イリテラシーというのかね。
Safari 8?の機能予想
といってもネタは3週間以上も前のもの。5月8日に「safari-538.34-branch」というWebKitのブランチが切られた。
昨年も書いたのだけど、これまでの動きから考えてこれが次のSafariのもとになるブランチのはず。というわけでコミットログとかから次のSafariを予想しようかと。
WebKitのMac portで有効にされる機能は、FeatureDefines.xcconfig というファイルで管理されている。これらはビルドフラグなので、有効にされてないとナイトリーでも使えない。あと、ランタイムフラグもあるらしいんだけどこれは詳しく知らない。
Safari 8に入りそうなもの
538ブランチのFeatureDefines.xcconfigで有効にされてるものはこんな感じ。
- CSS Shapes
- Media Source Extensions
- Promises
- Subpixel Layout
<template>Element- FTL JIT
Indexed Database API
FTL JITは昨年ブランチ後にパッチがガンガン入っていたし、先日Surfin' Safariでも大々的に取り上げられた。
このうち、IndexedDBについてはバグのコメントを読むとwindow.IndexedDBにアクセスしてもnullを返すように仕組んであるとか書いてある。ソースのコメントによるとまだ作ってる最中という話だけど、状況はどうなのかしら。
その他入ったもの
とかとか。昨年から真面目に追いかけてないのもあって思い出せない……
JavaScriptCoreに追加されたもの
JSCにはENABLEマクロ的なものが見当たらない。ここらへんSpiderMonkeyみたくそんな後方互換性重視してないのかなという感じがする。
というわけでJavaScriptCoreのログをふにふにと追ってみた。
Array.prototype.find()Array.prototype.fill()Math.hypot()Number.prototype.clz()Array.prototype.keys()/values()/entries()MathfunctionsMapiteratorsSetiterators- for-of
- Destructuring assignment
SetMap- Spread operators
ES6がいろいろ入った。Spread oprsやDestructuring assgnmnt、for-ofはうれしい。
あとArrayの関数がJavaScriptで書き直されたりもしていた。その前にビルトイン関数をJavaScriptで書けるようになったので、今後他のものもJavaScriptで書かれるようになるんだろうか。
Safari 8に入りそうにないもの
538.34ブランチで無効にされてるものはこちら。
- CSS Exclusions
- Shared Workers
- Grid Layout
- Canvas Path
- Web Timing
<input type="color">
しゅーん。
Web TimingはNavigation Timing, Resource Timing, User Timingを指す(もともとGoogleから提案された時にWeb Timingという1つの仕様だったことに由来する)。Trunkで有効にされてうおーって思ったのだけど、ブランチが切られてからしばらくして消されてしまった。ただ作業はしているので、実装が追いついてないのかもしれない。
機能的にこれからというものもある。CSS Exclusionsはparsingしか入ってなかったらしい。
他にもChromiumが離脱した絡みか、Shadow DOMやらiframe@seamlessとかいろいろなくなっていたりする。
よくわからないもの
条件付きで有効にされているものがある。そのひとつがtelephone number detectionで、iOSの電話番号に自動リンクつけるやつ。たぶんiOSのコードをupstreamした関係でWebKitの方にも入ったのだけど、今年のはじめの方にちょこちょこ作業されてて、Mac port用のマクロが用意されている。有効にされてるのは ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_101000 となってるので、10.10なんだろう。あれが便利だと思ったことはないのだけれど、デスクトップにもあの機能がつくのかな。
ENABLE_FOO_macosx_10nnnn っていう特定のOS Xで有効にされてるのは他にもある。
こんな感じかなあ。さてどうなりますかね。
Safariでせつなくならないために何かしたい
Safariについて言いたかったことを言えてなかったので、もう一本だけ。
ひとことで言うと、「バグ見つけたら報告して、5月までに直してもらおう」と。
5月を逃すとせつない
なんでSafariに気をかけてるかというと、モバイル端末での影響力(シェア)が大きいから。WWDCではモバイルWebでのマーケットシェアのうちiPhoneが60%、タブレットWebではiPadが82%と言っていた。ソースわかんないけど、デスクトップみたく低くないことは確実かと思われる。
影響力があるけど、リリースサイクルが長い。ここがとても気にかかる。
Safari 7予想エントリで、Safariの元になるWebKitが5月にブランチされていることを書いた。これはMac portの話なのでOS XのSafariの予想だったんだけど、iOSのSafariもこれまでのバージョンのUA文字列から判断するに、WebKitのバージョンはOS Xのものとそんな変わらない。なので、同じ時期にiOS portもブランチされてると予想している。
iOSのリリースは秋(9月とか10月とか)なので、ブランチから半年ほどかかる。リリースされたiOSが十分に普及して、古いSafariを無視できるようになるまで1年半くらいかかるとすると、ブランチから2年経っていることになる(WWDCでiOS6のシェアがiPhoneでは93%と言ってたので、そこまで長く考えなくてよいかもしれないけど)。その間にもWebKitはたぶん進むけど、それが製品に反映されて使えるのは、次のサイクルになる。
5月というfeature freezeのタイミングを逃すと、そこから結構な時間、レガシーなものと付き合わないといけない。
せつなくなる前になんとかしたい
機能がまだ実装途中とかならべつにいいんだけど、接頭辞外せる状態なのに外れないとか、パッチあるけどレビューされてないとかがあるので、だいぶせつない。
たとえば、Safari 6ではBlob.slice()がBlob.webkitSlice()として実装されている。他のブラウザはもう接頭辞なんてないのに。
2012年2月に報告されたんだけど目に止まらなかったようで、結果Safari 6のブランチをミスしてしまった。治ったのは、直後の6月。こういうの、なんとかしたい。
接頭辞はまあ、たぶん今よりは良い方向に向かうけど、バグがこんな感じでミスされてしまうと、とてもつらい。とくにiOS Safariナイトリービルドなんて仕組みがないので、ふだんから検証できない。そのくせモバイルでシェアが大きいので、リリースされた後にバグが見つかると、みんな不幸になってしまう。
リリースから次のバージョンのブランチが切られるまでは、半年くらいしかない。この間に報告して直してもらうのって、バグの大きさやAppleの興味・持ってるリソースによりそうだけど、けっこう大変なんじゃないかと思う。
iOS 6の最初で、XHRまわりのでかめなバグが2, 3あった。べつにSafariの品質保証体制みたいなのにけちつけてもいいけど、あれとか、iOSのベータ期間中に開発者が見つけられてたら、リリース後みんな不幸せにならなかったんじゃないかななと思う。もちろんAppleが知ってろよって話だけど、Web開発者だから見つけられるバグだってあると思う。
なので、とくにiOS Developer Programに入ってて、端末余ってたりシミュレータアップデートできて、ちょっと時間があるひとは、新しいiOS入れて、作ってるものチェックしたり、いろんなサイト見たりして、そこでバグを見つけたら報告してほしい。新しい機能を入れろ、っていうのはたぶん通らないだろうけど、バグならWebKitで修正されて、マージされる可能性がまだありそうだから。
バグを認知させるには
バグ報告なんだけど、iOS Developer Programでたぶんフィードバック先についてなんかあると思うので、そこからAppleのバグレポート経由で報告すればいい。
WebKit nightlyでも再現するならWebKit Bugzillaから投げたほうが透明性があってよいかなと思う(iOS7で動かないとか、NDAに触れそうなことは省かないといけないけど)。けど、AppleがWebkit Bugzillaのバグから動くかは疑問。というのは、ブランチへのマージにはだいたいradr://problem/***というアドレスがついてるから。なのでちょっと悔しいけど、Radar経由のほうがいいと思う。
余談:SafariSafari言ってきたけど…
これ、べつにiOS Safariに限ったことじゃない。Chrome/OperaであれFirefoxであれIEであれ、デスクトップであれモバイルであれ、デッドラインに間に合わなければ、期間や大小はばらばらだけど、せつないことに変わりはない。
Chrome, Firefoxは6週間でバージョンが上がる。間にBeta, Stable/Releaseという段階(channel)があるので、ブランチからリリースまでは3ヶ月。強制アップデートもあるし、Safariよりもずっと深刻さはない。あと、モバイルにおいてまだシェアが少ないからそんな問題でもないというのもある(いいのか悪いのか…)。
IEは違って、Safariとおんなじ感じで、リリースサイクルが長い。また、最初のプレビューが出たあたりで大まかにfeature freezeされてる感があるので、機能についてのフィードバックは厳しそう。ただWebKitと違って自分たちのみでfeature setを決められるからBlob.webkitSlice()みたいにちぐはぐなことは、そうないと思う。
Androidブラウザは、ベータプログラム的なものはあるのかな。あれば報告できるけど、なかったら絶望的だ(今に始まったことではないけど)。Chromeとの関係もよくわかんないし、メーカーがなんか手を入れてるし、Chromiumを一部つかってそうな独自ブラウザにしてるケースもあるようだし、もうこれはよくわかんない。
ただ、Androidについてはブラウザ選択の自由があるから、Mozillaコミュニティが過去にやった“Take back the Web”キャンペーンみたいなのとか、そういうのとかできないのかなあ。GingerbreadにはOperaがあるし、Firefoxもだんだん良くなってる気がするし、Chromeだけに任せる必要もないし。
WebViewについては…どうなるんだろうね……GeckoViewに期待すればいいの……?
発散してきた…ここまでにしよう。
なんでこんなこと書いたかって言うと、ソーシャルソーシャルなところでブラウザの愚痴とか見るの本当につらいんでなんとかしたいわけですよ。効率悪い、というかなんにもならないこと多いし。
Safari 7予想:答え合わせなど
WWDCのキーノートから1週間弱。発表・リークしたSafariの情報と、予想したものはどれくらい違うか、あらためてまとめたり、また予想したり。
バージョンはSafari 7.0、7月には出ない
OS X Mavericksのページ下部の脚注に“Safari 7.0”とあるので、バージョンは7.0らしい。
リリースについて、プレビュー版がWWDCで発表というのは当たったけれど、Mavericksの正式リリースはComing this fall
らしいので、7月リリースという予想はどうやらハズレ。くっ。でも、ここ2回、OS XとSafariのリリースが同時だったなあ……
Safari 7のWebKit
UA文字列のちゃんとした(?)リークが見つからないのだけど、"applewebkit/537.43"で検索するとちょっと出てきた。お、バージョン含めて今のところあたってるっぽい。MacのDeveloper Program入ってればちゃんと確かめられるのだろうけど、そうなるとここに書けなくなるだろうし。(「らしい」と書きつつ引用してるのも、いいのかどうかわかんないけど。)
ただ、前回の予想はあくまで7月リリースを前提に書いたものなので、秋リリースなら、別のブランチになったりする可能性も否定できない。少なくとも、リリースまでにマイナーバージョンはけっこう上がると思う。
Safari 6.1もある(らしい)よ
Safari 7.0はどうやらMavericksだけに提供されるようで、Mountain LionとLionにはSafari 6.1が提供されるらしい。こっちはSafari Developer Programに入ってたらダウンロードできるのかな。
6.1が持つWebKitのバージョンも"applewebkit/537.43"で検索すると出てきたので、Safari 7と同じっぽい。Safari 5.0が出た時に、同じWebKitのバージョンを持つSafari 4.1が古いOS X向けにリリースされていたので、同じ流れか。同じWebKitのバージョンなら、機能もだいたい一緒になるはず。
(だいたいと書いたのは、Mountain LionでのNotification Centerみたく、APIの実装がOS Xの新機能に依存するものがあると、機能に差異がでてくるため。)
リリース時期はどうなるんだろう。Mavericksに依存してないなら、6.1が先にリリースされてもいい気がするけど、そんな面倒なことはしないと思う。
機能予想
機能についてはバイナリがないので答え合わせもできないのだけど、入るだろうと予想した機能は、けっこう入ってると思う。
ブランチが先月下旬で、リリースまであと数ヶ月あるけど、なにをするのか。
WebKitのブランチ運用は、Safari 6.0.xのブランチだろうsafari-536.xx-branchの流れを追えばなんとなくわかる。
ブランチの履歴を覗くと、536ブランチから536.26ブランチに→いろいろマージ→536.27ブランチに→いろいろマージ→...→536.30ブランチに…、という感じになっている。マージのchangesetの多くには<rdar://problem/...>とApple内部のIssue trackingシステムのアドレスっぽいものがあるので、Radarに報告された、もしくはAppleが発見したSafariのバグをWebKit trunkで直して、Safariブランチにマージしているのだろう。
なので、必要とあれば新しい機能でもマージされたりするかもしれない。あと、ブランチ時点では不安定だった機能が、その後のメンテで入ってくるとかもあるかもしれない。可能性は低いだろうけど。
基本的には現時点ですでにfeature frozenで、マージされるものはバグやらメモリ使用量の削減とかをしてるものばかりになってるんじゃなかろうか。
“Nitro Tiered JIT”
キーノートでちょっと気になったのが、“Nitro Tiered JIT”というの。これなんなんだろう。“fourthTier”と呼ばれてるもののことなのかなあ。メタバグっぽいのはBug 112836にある。あとConstellationさんのGoogle+ポストや、WebKit Contributor meetingのStatus of JSC / Optimizations, How to debug the JIT in JSCを読むと、LLVMバックエンドでのJITを実験してるものらしい。でもexperimentだしなあ。“fourth”とあるし、すでにtieredされてることだから、べつにSafari 7に入るわけではないのかな。
とっちらかってきた……もう一本書こうか……
新しいSafariについて予想する
追記 (2013-08-13): WWDCでの発表にて、いくつか予想が外れたのが分かったので、短い答え合わせのエントリを書いた。あわせてSafariに懸念していることも書いたので、それもどうぞ。
以下は元記事。
WWDCが近いので新しいSafariの予想をしようかと。
来週まで待って確定的な情報を書いてもよかったけど、まあいいや。
たぶん7月に出る
新しいバージョンが「Safari 7」になるのかわかんないから、Apple風に「新しいSafari」と書くね。
ここ2回のメジャーバージョン(5.1, 6.0)は、7月下旬にリリースされている。なので今回も、WWDCでお披露目+Developer Previewのリリース、7月の同時期に正式版リリースされると予想。
ここ1, 2ヶ月のWebKitでのAppleの動きを見ても、コードのリファクタリングや細かなバグ修正、あとChromeのBlink移行に乗じたコード削除がほとんどな印象がある。なので、リリース準備に入っているんじゃないかと。
あと、ブランチが5月22日に切られた。
safari-537.43-branchという、メジャーバージョンが537になってから、初のブランチ(なはず)。trunkからのマージも行われている。
過去のSafariのブランチも調べてみると、Safari 6.0の元になった536ブランチが切られたのは2012年5月7日、Safari 5.1の元になった534ブランチから派生している。これが2011年5月20日。2週間ばらついてるけど、5月中に行われている。
今回はマイナーバージョンも含めたブランチなので、過去2回とちょっと違うけど、でもこれが新しいSafariのベースになるんじゃないかなと。
なにが入る?
Changesetのメモやコンパイルタイムフラグから拾ってみる。Nightlyで試すのがよいのだろうけど、ちょっと時間かかりそうなので省略。間違ってたらごめんなさいよ。
新しい機能
<main>- Page Visibility API
mouseenter,mouseleaveイベントborder-imageのround- CSS Level 3な
background-position(オフセット指定) backgroundプロパティでのbackground-sizeサポートContent-Security-Policyヘッダ追加- Speech Synthesis API
- DOM4のイベントコンストラクタいろいろ
Page VisibilityはChromeにはあったけど、これまでSafariでは有効にされていなかった。Changesetには[iOS]とあるけれど、デスクトップで使えないなんてことはないと思う。
ちょっと面倒なのが、Blinkではまだ接頭辞がとれてないけど、WebKitでは接頭辞が削除されてしまったこと。webkitHiddenで壊れるWebというのは想像できないけど、どうなんだろう。なんにせよBlinkがんばって。
backgroundでのbackground-sizeサポートでは、backgroundにあったバグが修正されたので、background-sizeの後にbackground書いてたら問題が出るかと思う。あったら修正しよう(background-sizeを後に書こう)。
あと、WebGLも有効になるんじゃないかと思っている。IE11で対応しそうなこのご時世にSafariは対応しないとかね、ないと思うんですよ。Google MapsだってWebGLベースになるのに…あっMapsだからもしかして…いやいや。iOSやWebViewはわかんないけど、デスクトップでは使えるようになるのではないか。
Speech Synthesis APIは何するつもりなんだろう。接頭辞もない。APIは固まってるのかな。
接頭辞つきの新機能(独自拡張、試験実装)
- Flexbox (CR版)
- CSS Masking
-webkit-cursor-visibility: auto-hide追加- CSS
-webkit-fit-contentvalue
Flexboxはつつくとバグがぼろぼろ出てきそうな気がする(特に他の機能と組み合わせると)。Flexbox, 今年中には本格的に使えるかなと思ったけど、そこまでな感じがしなくなったのが残念。OperaのChromium移行で実装がたぶん後退したこと、Firefoxではmultiline Flexboxほかいくつかの機能が未実装ので、接頭辞無しでフルに使えるブラウザは後発のIE11だけになるんじゃないかというこの面白さ。
-webkit-cursor-visibility: auto-hideはビデオとか、フルスクリーン時にマウスカーソル消したい場合に使うらしい。簡単に試したけど、フルスクリーン時しか動作しない感じ。そりゃそうか。
-webkit-fit-contentは「要素内容に依存する幅の指定について」で説明されてるのでそちらをどうぞ。仕様はcss-boxよりもcss-sizingを見たほうがいいかも。
接頭辞がとれた機能(接頭辞つきのも引き続きサポート)
Gradients, Transitions, calc()が接頭辞なしで使えるのは大きい。グラデーションは、これまでさんざん言ってきたけど、構文が変わったので気をつけたい。
あとはTransforms, Animationsか…大掛かりそうだけれど、来年までにはなんとかしてほしいなあ。
接頭辞つき実装が削除された機能
- Page Visibility API
webkitPostMessageBlob.webkitSlice()-apple-,-khtml-なプロパティ(長い説明はこちら)
先々月のWebKit Contributors Meetingで、機能の削除とか接頭辞まわりのスロットがあって、そこで接頭辞は可能な限り削除していく大方針が決まったみたい。大きく進展する気はしないけど、去年くらいからぽつぽつと成果が出ているのはよいこと。
バグ修正で気になったものなど
- デスクトップでの
-webkit-text-size-adjustを削除 - メディアクエリーがズームした値で変わるように
- CSS Transitions, CSS Animationsが
::before,::afterに効かない問題の修正 - ズーム時に画像の
offsetWidth,offsetHeightが間違ってたのを修正 - 画像とかに
border-radiusかけたら四方がはみ出るのを修正 background-clip: margin-box以外でのボックスとborder-radiusの問題を修正- セレクタのspecificityの壁が超えられないように
- class属性をいじっても
classListに反映されなかったバグの修正 - 画像の代替テキストがコピーされなかった問題が修正
-webkit-text-size-adjustがデスクトップで無効になったので、ズームしてもフォントサイズが変わらないとかがなくなったはず。メディアクエリーのやつは、em-based queryでRWDなサイト作ってるとき問題になってたやつ。
border-radius絡みはようやくか、という感じ。classListと画像のオフセットのやつはバグの存在を初めて知った。
入らない(だろう)機能
コンパイルタイムフラグのファイルより、入らなそうな機能の一部を。
- Web Components
- Performance系API(*** Timings, High Resolution Time)
- Scoped Stylesheets
- CSS Exclusions, Shaders, Compositing
<iframe seamless>- Shared Workers
- CSS Device Adaptations
- CSS
resolutionmedia feature - IndexedDB
いろいろない。無理ないなって機能もあるけど、Scoped Stylesheetsは入れて欲しかった……
High Resolution Timeは一度入ったんだけど、performance.now()だけの判定で他のPerf系APIが使えると想定してるコードがあったようでrevertされてしまった。Timing系を入れるって選択肢はないらしい。ちぇっ。
High Resolution Time入らなかったらrequestAnimationFrame()のコールバックが取る引数ってどうなるんだろう。
残念な部分や細かな疑問は尽きないけれど、どのブラウザにもこれ入ってほしいなあというのはあるし、そんなものだよね。あとAppleが保証できない・するつもりもない機能をSafariに入れてしまうのは、それはそれで問題だろう。いまだって、中途半端な実装に泣かされていたりもするんだから。とくにWebKitみたくいろんなベンダーが関わるプロジェクトだと、そういう状況になりやすいだろうから、機能は減っても、安定するまでは使えないようにしとくのはよいかなと思う。
政治的に入ってない機能については、Webサイト・Webアプリ側で無理やり使っていって依存させ、実装せざるを得ない状況にもっていくしかないんだろうか。
Chromeの新エンジンBlink ― どうなるんだろう篇
なぜなに篇とWebプラットフォーム篇ではBlinkに至った背景や、Blinkの互換性への取り組みについてだーっと書いた。
今回はBlinkの登場が何にどんな影響を与えるか、だらだら考えてみる。
Chrome
すでに色々書いてはいるけれど。
WebKitから離れ、Chrome専用エンジンとなるので、これまでWebKitでは合意を得られなかった機能について抵抗なく入れられるのはGoogleにとってはよいことだろう。Pointer EventsとかIME APIとか。Launch Processのもとでだけど、試験実装は進めやすくなる。
WebKitから離れることでの最大の損失は、WebKitに参加している人のタレントだろう。BlinkチームのQ&Aセッションによると、BlinkとWebKitとの間に「フォーマルな関係」はないとのこと。パッチを自動的にやりとりするような仕組みは用意されないから、コントリビュータがボランティアで、パッチをどちらにも投げる、あるいはマージするしかない。BlinkとWebKitが離れていくにつれて難しくなっていく。
あとは、これまでWebKitにあったバグはBlinkにも引き継がれるわけだけど、WebKit BugzillaからChromium issuesに自動インポートするとかそういうのもない。誰かがそれをしないといけない。やんないとなあ。面倒だよねえ……
(追記: Syoichiさんに一部バグ移行をしてる方がいると教えてもらった。)
Opera
OperaがWebKitに移行した時に、WebKitプロジェクト内でどうOperaのユニークネスを活かせるのか、不安を交え書いた。ただ、Blinkに移行したことで政治に関わるプレーヤーが減った、というか決定者に近い立場になった。
Launch Processにある、標準へのコミットやテストへの言及はOperaがこれまでWebに大きく貢献してきたことだ(標準化については、関わってたひとが結構辞めちゃってる印象があるけど……)。BlinkになってOperaはとてもよかったのではないか。
AndroidとWebView
AndroidのWebViewもChromiumベースになっていくので、Blinkがそのうち入ることになる。よりよい設計のものがもたらされるはずなので、よいことなんだろう。
アップデートやフラグメンテーションについては、わからない。たまに家電量販店に行って新しい端末を見るんだけど、Androidのバージョンは4.1だし、Chromeの他にもAndroidブラウザが入っちゃってたりするし、Web開発者にとっては好ましい状況ではまだない。
WebViewに手が入ってしまう問題は解決するのか。なってほしいけど、エンジンが変わったくらいで変わる問題じゃなさそうな気がする。Android 5.0の発表が噂されているけど、WebViewまわりはどうなるのだろう。
あと、WebViewのバージョンはChromeのように6週間でバージョンアップ、なんてしないだろうし、できないだろう。Webなら「これからChromeになるんで〜」とそのうち言えるようになるんだろうけれど、WebViewを使ったハイブリッドアプリとかだと、苦しい状況が続くのかもしれない。
強制的なアップグレード機能をもつChromeの下にAndroidが入ることで、アップデートについて改善したりするといいんだけど。
WebKit
やっぱり気になるのが、WebKitプロジェクトへの影響だ。
BlinkがChromiumに必要ないコードを削除している一方で、WebKitもChromium関連のコードやV8バインディングを削除している。メンテナがいない機能もまとめている。こういうのが削除されて行くと「違うエンジン」になるのは案外早いのかもしれない。
WebKitに集っている他のパーティはどうなるんだろう。GoogleがいたからWebKitを選択したっていうのがひとつの理由だったパーティも少なくないのかなと思う。でも、BlinkはChromiumのContent API上での利用しか検討していない。使うのであればと、Chromium Embedded Frameworkが提示されているけれど、すぽっとWebKit→Blinkに移行ってのはできるんだろうか。
加藤さんが言っている、WebKit発のイノベーションが消えないか、主要スポンサーが一つ失われたOSSプロジェクトはどうなるのかというところも気になる。
WebKitが終わりだ、とは思わないんだけれど、WebKitであることの大変さは、Blinkの登場によって今まで以上に表面化してしまった。ほんと、今後どうなるんだろう。
テキスト選択のハイライト範囲が気持ち悪いのと、いろいろあるバグを除いて、WebKitは好きなので、今後も発展し続けてほしい。
Adobe
注目したいのが、Adobe。
AdobeのWebプラットフォームへの貢献は、ブラウザベンダーではないという彼らの業態もあってユニークだ。WebKitにはRegions, Exclusionsなどレイアウト機能についてパッチを提供してきた。ほかにも、MaskingやCompositing、Custom Filtersなど、画像合成・変形にも多くのリソースを提供している。
彼らが貢献していく領域は、Adobe & the Webというページに書かれている。“Robust graphical foundation”, “Magazine-like layout”, “Cinematic visual effects”, “Typography”, “Consistency”, “App platform”とあるけれど、とくに最初の4つはAdobeの強みがはっきりわかるのではないだろうか。
WebKitに貢献している理由は書かれてないけど、おそらくiBooks登場→EPUB使う→CSSへぼい→InDesign使うパブリッシャーから要望→WebKitに手を入れるしか、的な流れなんだと思う。
なので、今後も基本はMac port, つまりWebKitがプライマリなターゲットなのかなとは思う。ただ、人材募集を見るとWebKitだけでなくGeckoにも詳しい人を探しているし、実際Geckoにもパッチ提供したりしてるし。Blinkについても、Blendingについてのパッチ投げるよ的なことも言ってるので、特定の領域にはAdobeが絡んできそう。彼らの提案する機能はWebから見ると「新しい」ので、成熟させてWebで使えるようになってほしい。
あと、BracketsなどはCEFを使っているので、そっちからBlink/Chromiumへのコミットもあるかもしれない。もうあったりするんだろうか。
Apple
気になるというか懸念してるのが、roc先生も書いてるけど、SafariというかAppleが今後閉じてしまわないかということ。
AppleがWebKitに果たした影響はもちろん大きい。立ち上げたというのももちろん、CSSへのグラデーションやマスク、変形、アニメーションなど、Appleがむりくり導入したから可能性が広がったってのもあると思う(そうじゃなかったら未だにSMILやSVGとか言って、あまり進んでなかったかもしれない)。
ただ、Appleが導入した機能って、設計がまずいといわれることが多々ある。古くはCanvas API、もうちょっと新しいのが<meta name="viewport">とか。あと -webkit-gradient() も評判が良くなかった記憶がある(これは構文変えまくったりとか、標準トラックでの設計もまずかったけど……)。標準化への進みが遅れると、いけてない機能から何年も移行できなくなる。viewportとか、いつCSS側にもってこれるんだろう……
新しい機能の追加は、webkit-devにメールを投げてラフな合意のもと実装というプロセスが2年前くらいから運用が始まっていた。標準に入っていない機能が提案されると「WGに投げとき」てきな返答が返ってくるとか、よい流れになってきたんだけど、そこからGoogleがいなくなる。このプロセスは、今後も維持されるのか。
独自拡張が悪だとはそんな言いたくないけれど、Appleの独自拡張はモバイルでの影響が無視できない。その後標準化が始まったとしても、他での実装やSafariの挙動の修正には時間がかかる。
Appleは今後どれくらい、標準化にリソースを割いてくれるのか。今と同じ、もしくはそれ以上でいてくれるのか。
標準化・Webプラットフォーム
新しいエンジンとはいえ、現段階では「ほとんどWebKit」なので、標準化にあたっての「2つの独立した実装」という要件にBlinkがカウントできるかというと、現時点では無理だろう。Prestoの抜けた穴はすぐには埋まらない。
ただ、今後Blink, WebKit双方に追加されていく機能については、コードが独立する可能性があるので、そうなれば独立した実装と認められるだろう。既存機能については、そこにタッチする何かで大規模なリファクタリングや書き直しが行われたりしないと、WebKitとしてカウントされるんじゃないかなあ。
Webプラットフォームとしてみると、GoogleのリソースとAppleのリソースが離れるので、機能の進みが「鈍化」したと感じるのかもしれない。
Launch Processで明文化された、標準へのコミット。Chromium Feature Dashboardを見ると、けっこう色んな所でベンダー間の思惑に違いがあることがわかる。Webは進んでくれるのか。Blinkプロジェクトは、彼らのプライオリティとしてあまり高くないものについての標準化に、どれくらい貢献してくれるのか。
しかし、他のベンダーの反応が視覚化されると、スタンスがいろいろあるのだなあ、みんなせーので同じものとはいかないのだなあ、と、すこし憂う。良く言えば多様で、よいことなのだけれど、「これが今使えたらなあ」と思うものがちらほらとあるので。
Web開発
Web開発に変化が起こるか。短期的にはもちろんだけど、中期的にも変化が起こるかというと、そんなないと思ってしまう。憂う。
下を見てしまいがちなんだ。デスクトップならIE8(以下)、モバイルならAndroidブラウザ、そこを最低ラインとして作り方を考えてしまう。
モバイルについては、Androidブラウザ+Safari+(UI)WebViewというWebKit寡占状態がしばらく変わりそうにない。Chromeががんばっても、Blinkがしばらくは「ほとんどWebKit」だし、WebKit依存なコードが減るのかというと、そんな気はあまりしない。減ってほしいけど、ずっとゆっくりなのかなとも思う。
モバイルに非WebKitなブラウザが増えるか。どうなんだろう。Firefoxが起こせたようなことが、モバイルでも起こるといいなあとは思うけど、ただでさえダイバーシティが少ないので……
標準においても、UI関連イベントやスクロールとか、追いついてない部分が多い。WebKit依存や開発者への訴えかけで問題が解決するわけでもない。これを「発展の余地がある」と捉え続けられるのか。
ぼく
Blink関連の情報を読んで、Blinkにはとてもポジティブな見方をしている。ひねくれているので、まあ今とそんなに変わんないなとも思うし、プロセスの「例外」が増えることへの危惧は否定できない。けれど、WebKitでなくなったことの利点って、
Blinkで驚きだったのが「こういうことになりまして、これです」という事後発表ではなく、「こうします」という発表だったこと。準備はしていたんだろうけど、MLやレポジトリ、他のいろいろも発表後から始めている。スタートのアピールとして、とても上手いなと思った。
このアピールは何なのだろうかと考えて、Blinkはコミュニティを欲しているのかもしれない、と思った。やはりWebKitのエンジニアを失うのは痛いし、これからは自立してかないといけない。Chromium/Blinkに貢献してくれる人、ほしいのかなあと。「コミュニティ」感が出ると、言ってることの「いい子ちゃん」感も薄れるだろうし。そういう点でMozillaってやっぱ「コミュニティ」としてとても強い気がする。
1週間立ち、要らないコードががーっと削られている。DevToolsは変更が入り始めた。ディスカッションでは、今後どうして行こうかという話が進んでいる。「いま起こっていることとして感じられて」わくわくがある。今まで「『スピード感』て何よ、とくに『感』って」と思ってたのだけど、これがそういうことなのかなあと思った。
標準/ブラウザウォッチャーとしては、WebKit依存でWebが終わる感じが少し薄れたのでよいと思うし、対象が増えて素敵。一方で、対象が増えて、しかも開発スピード上がるとか言うんで、しんどそうとも思う。Peter BeverlooもBlinkウォッチャーになるので、WebKitは有用なソースも減ってしまうし。ウォッチャーとしてはチャンス(なんの)でもあるけれど。
いま気になってるのは、ChromiumとBlinkのレポジトリ統合が提案されて、それが支持されてる感じなこと。開発としてはよいのだろうけど、これされると、Chromiumレポジトリを追いかけないといけなくて、Blinkだけの変更が追いかけづらくなってしまう気がするんだよなあ……。何かいい方法とツールを探したり、場合によっては作ったりしないと……
ただ、いまのやり方はだいぶ非生産的なかたちをとってるので、もうちょい良くしてかないといけない。あと、いつまでもウォッチャーのままでなく、もう少しブラウザやら標準にコミットしないとね。自分にできること見つけないと。そういう点でChromium Feature Dashboardができたのはとても嬉しい。ちょっと突っ込んで参加してみようと思う。
感想なのでだいぶ雑になってしまった。MicrosoftやMozillaについては思いつくことがなかった。Dartについては詳しく知らないので何も書けず。
これにてBlinkについてのエントリはひとまず終了。引き続きウォッチ的なエントリとかを書くよ。
モバイル系ブラウザのUA文字列
何の役に立つか自分でもさっぱりわからないと思いながら、ここ1年半ほどGoogle Spreadsheetsにブラウザのアップデート情報を記録している。
できるだけ情報を入れてるけど、抜けも結構ある。ChromeはStable Channelが入ったマシンがないので細かい情報はないし、Firefox ESRとかは要らんだろうと思って入れてない。
さて、もともとデスクトップだけだったんだけど、最近Chrome for AndroidとOpera Beta(Chromiumベース)が出たので追加し始めた。Opera Betaには chrome://versionみたいなのがなくてしんどい……
それで、UA文字列にバリエーションがけっこうあって複雑だなあと思ったので、ちょっと書いてく。
スマートフォンとタブレット
Chrome for Android, Firefox for Android
Android版Chromeだと、スマートフォンにはMobileというトークンが入る。タブレットでは取れる。
Android版Firefoxだと、スマートフォンにMobile, タブレットにはTabletというトークンが入る。ネットブック的なAndroid端末(あるんだ)だとトークンがなくなるらしい。
iPhone, iPad
iOSのSafariだとプラットフォームトークンがそれぞれiPhone,iPad,iPodになる。
Mobileというのもあるけれど、こちらはどのSafariにもあって、文字列の後にMobile/XXXXXと、ビルド番号がついている。タブレットとモバイルを区別するものとして設けられているわけではない。
Windows Phone 8, Windows 8/RT
IE10は、Windows Phone 8とWindows 8/RTとOSが違うけど、UA文字列の構成はそんなに変わらない。Windows Phone 8のIE10ではIEMobileがつく。あと、Windows Phoneってプラットフォームトークンもある。
一方タブレットなんだけれど、Windows 8/RTのIE10ではタブレットとデスクトップを区別するトークンがUA文字列にない。Windows 8世代の製品はデスクトップでもタブレットでもタッチインターフェースを備えるから、区別っていう概念がないんだろう。
ただ、タッチインターフェースを備えている場合、Touchというトークンがつく。これはWindows Phone 8でもつく。ただ、タッチを備えていてもWindows 7のIE10にはつかない。
「デスクトップ版」のUA
これで終わりかとおもいきや、もう一つ種類がある。「デスクトップ版」のUA文字列というもの。モバイルなのになんだそれ。まあデスクトップセントリックなサイトが多すすぎる一方でしょうもないスマートフォン版のサイトも多いんだろうけれども……
Chrome, Firefox
Android版Chrome, Firefoxには “Request Desktop Site” なんてメニュー項目がある。これを選択すると、UA文字列がデスクトップのものになる。
Nexus 7でChrome BetaとAuroraのUA文字列をそれぞれチェックしてみた。まずはChrome Beta。
// Default Mozilla/5.0 (Linux; Android 4.2.2; Nexus 7 Build/JDQ39) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.40 Safari/537.31 // "Desktop" Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.40 Safari/537.31
続いてAurora。
// Default Mozilla/5.0 (Android; Tablet; rv:21.0) Gecko/21.0 Firefox/21.0 // "Desktop" Mozilla/5.0 (X11; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0
Opera Beta
Opera Betaでは設定からMobile/Desktopを選べるようになっている。これグローバルに変わるんだよね、ちょっと面倒だと思うけど……
UAはこちら。
// Default Mozilla/5.0 (Linux; Android 4.2.2; Nexus 7 Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.123 Safari/537.22 OPR/14.0.1025.53463 // "Desktop" Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.123 Safari/537.22 OPR/14.0.1025.53463
結構すっきりしていたOperaのUAがChromiumベースになったせいでだいぶカオスに……
あとOperaの識別子がOPRになっている。これまでのOperaと区別するせいかな。
どうでもいいけど、「Chrome/Chromium/WebKitベースのOpera」とか「新しいOpera」とか長いので、CrOperaもしくはCrOpと読んでいる。くろぺら、くろっぷ。
ええっと、共通して言えるのは、どれもLinux版のUAになる。まあAndroidだから、そうか。
Opera Beta (Off-Road mode)
さて、Opera BetaはさらにもうひとつUAが文字列がある。Opera Betaにある “Off-Road mode” を選択すると、Opera Miniのレンダリングに切り替わるので、それでUAが変わる。
Opera/9.80 (Android; Opera Mini/14.0.1025/29.3054; U; en) Presto/2.8.119 Version/11.1010
バージョンは14になったけど、UA文字列はほとんどOpera Miniと同じ。
Opera/9.80 (Android; Opera Mini/7.5.32193/29.3054; U; en) Presto/2.8.119 Version/11.10
これを見るにPrestoベースのままだけど、WebKitベースのものに置き換わるという話があるので、このモードのUA文字列もじきに変わるのかな。
番外編:Firefox OS
ちなみに、Firefox OSは今のところえらくすっきりしている。
Mozilla/5.0 (Mobile; rv:18.0) Gecko/18.0 Firefox/18.0
タブレットの展開は発表されてないけれど、もし出たらMobileがTabletになるのかな。
ただ、ちょっとそれも怪しい。というのもUA文字列でスマートフォンの検出をするときにはiPhoneとかAndroid+Mobileで引っ掛けているので、これだとFirefox OSではスマートフォン版Webサイトに飛ばない。
実はもともとAndroidを含んでいたんだけど、Android端末固有のメッセージを出すためにこのトークンが使われていたりしていて、それではFirefox OSで困るので Androidを外す決定がされていた。ただサイト互換性的なところが多いので、いま頑張ってエヴァンジェライズしてるところらしい。入れないと困るけど、入れても困ると。
いやはやカオスだ。とはいえFeature Detectionだけではというケースも往々にしてあるし、サイトのエミュレーションをする時はUA文字列判定のほうが楽なこともあったりするので、UA文字列に頼るなともいいづらい。面倒だなあ。
あんまそういうのに拘らないサイト、拘らない空気作りをしていきたいよ。
接頭辞が必要な場合とはなにか、また削除はできるのか
WebKit Contributor Meetingの機能廃止&接頭辞セッションから、接頭辞の削除について。
非ブラウザでの接頭辞つき機能
まずAppleのSam Weinigから、WebKitはブラウザ以外にも使われるけれど、ブラウザ以外のWebKit利用例で、接頭辞を省くことが話の通ることなのかと話がでている。
weinig: Mozilla has said that they would like to remove vendor prefixes; they're a browser, though. WebKit is used for browsers and other applications. It's not clear that some rule for when to remove prefixes makes sense for the non-browser case [i.e., you can't just break Mac apps].
WebView使うアプリだったりiBooksのコンテンツはロックイン前提だろうから、ってことだろうか。
MozillaもB2Gのためかデバイス関連のAPIの実装を進めているけれど、どう考えているのかな。今みたくアグレッシブにいくんだろうか。
接頭辞をつけるとき
GoogleのJames Robinsonからどういう時に接頭辞をつけるのか、そして、WebKitの接頭辞とは何を意味するかという話がでている。
jamesr: there's also a question about adding properties. when you're adding something, when do you add a -webkit- prefix? there's also a discussion about what the "webkit" prefix means. sometimes a feature is shipped without community discussion, and that seems possibly damaging.
WebKitコミュニティのなかでとくに議論もなく機能が追加されていることがあるらしい。WebKitは昨年5月から、新しい機能を追加するルールを定めて運用している。Bugzillaにバグを立てて、webkit-devでアナウンスする。そこから議論が始まることもあって、ENABLEフラグつけとこうとか、仕様もあんまりよくないしちょっと連絡取ってよみたいなやりとりが交わされていたりする。
Jamesが言っている、コミュニティでの議論なしに機能が追加されてしまうというのは、このルールに漏れたものなのか、それともこのルールができる前にWebKitに入った機能なのか、それともアナウンスしたけど特に反応ないからlandしちゃった系なのか。
いずれにせよ、どんな機能があって、どんな状態にあるのかが分からないということなのかも。
Jamesの話から、接頭辞の目的を再確認する流れになった。
fishd: is it a cover for an experimental feature, or is it just a way of shipping non-standard behavior.
weinig: traditionally, we've hoped that people would not depend on prefixed properties (not standardized, doesn't work in other browsers). as a second measure, we figured that we'd be able to ship the standardized thing with the proper behavior. a second chance to get the API right, basically. seems weirder in DOM than CSS (no fallback). sometimes we also do this for non-standardized properties that are needed for some particular application, when standards bodies don't seem to be interested or fast enough.
arv: vendor prefixes actually started out this way, when Mozilla wanted to expose things to XUL.
ひとつは、実験的なものにつかう。標準に従っているかをテストする目的で使う。
もうひとつは、標準にないけど、目的があって必要だから追加するものに使う。そもそもベンダー接頭辞が生まれた背景がこれで、もともとXULで使う目的でMozillaに追加されたのがはじまりという話がでている。
CSS2仕様書にもvendor-specific extensions
と、ベンダー固有拡張としての用途してしか書かれていなかったりする。これがどこからか、試験的な実装にもと応用されて、今に至っている。
APIは接頭辞なしで実装されることが多かった
さて、この試験実装に対して接頭辞をつけるというのは、どこで始まったんだろう。CSSは置いとくとして、実はいくつかのAPIは、最初から接頭辞なしで実装されていたりする。
fishd: sometimes we implement new stuff without vendor prefixing, maybe because they're small or uncontroversial.
weinig: querySelectorAll, for example. if all the parties are at the table, it's sometimes ideal.
querySelectorAllが例として挙げられている。なんで接頭辞がなかったのか。仕様が小さく、またベンダー間で議論になるようなものでもなかったからじゃないかという推測がある。
どうなんだろう。使用の大きさや合意形成に関係があるんだろうか。
HTML5系のAPIなんかは、仕様は大きいけれど接頭辞つきのもののほうが少ない(機能ごとで考えるとそうでもないかもしれないけど)。ベンダーの合意がとれてるかについては、WebSQLという例がある。接頭辞に関係あるんだろうか。小さくて合意は取れてても、接頭辞つきで実装されているものだってあるかもしれない。
むしろ、APIに接頭辞がつくっていうプラクティスは、最近になって始まったんじゃないだろうか。
Selectors APIを最初に実装したっぽいのはWebKitで、2007年末になる。こないだBlob.slice()について書いたけど、Blobもslice()も、2010年1月に接頭辞なしで実装されている(slice()の問題がでたのでメソッドには接頭辞がつけられたけれど、インターフェースには接頭辞がついていない)。BlobBuilderも同じで2010年6月に接頭辞なしで実装された後、2011年4月に接頭辞がつけられている。
探していたらこんなのもあった。MozillaのJonas SickingがXHRのsendAsBinary(バイナリ送信のためのMozilla拡張メソッド)について、接頭辞つけるべきというバグが立てられたときに、次のように発言している。
Prefixing functions with 'moz' is something we've never done. I'd rather that this was raised with the work group and tried to standardize instead.
このバグは2007年夏に立てられたんだけど、その時点では接頭辞を関数につけるなんてしていなかったらしい。さらにはこれを標準化すればいいのではという立場をとっている。
ただ、すでにsend(ByteArray data)という方法がXHRのほうで提案されていたからか、EditorのAnneも接頭辞をつけるように要請している。ただ、Jonasはこうこう答えている。
I still contend that this is something that no vendor has ever done. The suggested name isn't going to collide with this one, but depends on ES4 features. If other browsers want to support this functionality, but does not yet have an ES4 implementation, they'll likely want to add a function like ours. If we prefix it with 'moz' no other vendor will want to choose the same name and so it'll just make it harder for web authors.
So I'm still going to argue that this is not something we want to do.
どのベンダーもバイナリ送信の仕組みを当時持っていなかったこと、sendAsBinaryとsendは名前が衝突しているわけではないこと。sendAsBinaryがES4の機能に依存していること。他のベンダーがES4の実装をせずバイナリ送信の機能をつけたい場合、もしMozillaが接頭辞をつけたら他のベンダーが"mozSendAsBinary"という名前で実装するとは考えにくく、Web開発者にも面倒がかかるとさえ述べている。
ES4の機能うんぬんというのはよく分からないけれど、接頭辞をつけると他のベンダーや開発者に面倒がかかるというのは、いま直面している問題だ。そして、名前が衝突しいるわけでもなく、それは既存機能に影響がないならそれでもいいというスタンスは、かなり理にかなっているように思える。
なんで、ここ最近増えてきただけなのかなと。仕様の安定度合い、標準化トラックの状況が不明で、とりあえずつけるようになったってだけではないかな。
試験実装と接頭辞
jamesr: what if no one's saying no, but people are saying "I'm not sure"? should we ship unprefixed and force others to match?
weinig: it's a balancing act
jamesr: there's a case where you have especially a big feature, and you're really not sure the API is right without getting developers to right real code against it. we need some way to ship things like this to developers.
weinig: isn't a custom build the right thing?
jamesr: [example from WebAudio, where we needed to get real feedback with all the features at trunk, not just a custom build with WebAudio enabled]
weinig: was that a success? Mozilla won't implement it as is.
jamesr: but we got feedback, that's the success.
Jamesが、提案している機能について反対はないけれど、よいか悪いかもよく分からないといった反応がある場合はどうするのかという質問をしている。結構おおきなfeature setで、ただAPIのデザインが開発者に受け入れられるかわからないとき、試験的に実装して開発者に試させたいということらしい。WebAudio APIがその例だったらしい。
それはカスタムビルドでやればという質問に、trunkで実装されているすべての機能でテストした結果が欲しかったと。ふうむ。なんでなのかよくわからないけど、まあいいか。
で、Chromeではカスタムビルドではなくて、chrome://flagsにAPIとかを有効にするフラグが追加されて、使う場合はそこをさわってというのが増えている気がする。これだと、明示的に有効にしない限りは使えないし、またBetaとかで無効にされたりすることもあるはずなので、依存したコンテンツが〜ということはあまり言えないだろう。
ただ、これってChromiumプロジェクトのさじ加減でいつ有効にされるかが決まるので、標準化の様子を見て有効にするとか、標準化トラックから外れたから省くとか、そういうことではない。
Web Audio APIはChrome 14からStableにも入ったけれど、今のままではMozillaは実装しないと言っているようだ。それで成功なのかという問いに、フィードバックがあったことが成功と答えている。ここでの「フィードバック」は、APIの設計や、実装のバグについて開発者が寄せるもののことだろう。なので、標準化やら接頭辞やらはとくに関係ない気がするんだけどなあ。
WebKitが他ベンダーの接頭辞つき機能を実装する可能性はあるか
[discussion of whether webkit would start supporting, e.g., -ms- prefix; pointed out that it would depend on what happens in the marketplace]
fishd: well, webkit implemented window.external. if it had been called window.msExternal, we probably would have shipped it too.
たとえば -ms- な接頭辞を実装する可能性はという疑問がでて、それはマーケットがどうなるかで決まるのではないかというところで落ち着いたらしい。 window.externalがもしwindow.msExternalだったら、そういう名前でも実装していただろうと。
互換性対応の目的でこれまでも他ベンダーの拡張は実装されている。というかWebブラウザはずっとそうしてきている。
hober: XMLHttpRequest is another example.
XHRとかね。HTML5なんてそんなものが集まっているところだ。
weinig: the example that comes to mind is -moz-outline, which we decided not to implement.
ただすべての機能になるかというと、そうではないようだ。Samは-moz-outline(あったんだ)がWebKitで実装されなかったことを挙げている。接頭辞がついてたのがその理由なのかは、ここでは明らかになっていないけれど、検討されはしたらしい。
そういえば、OperaはSpeed Dialでmetaのapple-touch-iconを解釈するようになっている。Web-facingというわけではないけれど、接頭辞ライクなものは既に取り込まれている。
jamesr: well, iOS has shipped webkit-prefixed things that aren't in upstream webkit, and other mobile webkits have had to implement them too.
さて、互換性への取り組みは、他ベンダーというだけではなく、同じエンジンについてもあるとJamesが述べている。AppleがSafariに突っ込んだけどWebKitにupstreamしてない機能は、あとあとリバースエンジニアリングして実装するしかなかったと。metaのviewportが最たる例かな。-webkit-maskとかも、まだ今はSafariだけだっけか。
これね。どうしたらいいんだろうね。viewportとかはなんでmetaにしたとか評判悪いし、orientationが変わった時にテキストが拡大したりするバグがあるけれど、広まってるからどうしようもない。それをなんとかするのがWebの性なんだろうけれど、「同じ」エンジンでもそうだなんて、やるせないよねえ。
接頭辞の削除に向けて
fishd: we [google] plan to collect data on the usage of CSS on the web, to see which prefixes we could get rid of, how prevalent they are.
fishd: it would be nice if different browsers could move all together, shipping the same set of prefixes, e.g., could we get rid of -webkit-opacity? what would Apple want to know?
weinig: it's hard to say what we would need to know.
hober: if it's used on the web, it's hard to argue that we should remove it and make those pages render worse.
GoogleのDarin Fisherが、Webで使われているCSSにどんなものかあるのかデータを集めるというプランがあると発表。おおお。ただいつやるんだろうね。あとは、Webだけの調査なので、WebViewつかったアプリとかのコードは調べないだろう(できないだろう)。
残さなければいけない機能は、全ベンダーがいっせいに動ければいいねと言っているけれど、無理だろうなあ。6週間のChrome/Firefoxに対して、1年に2回くらいのOpera、毎年6月のSafari、読めないけど1年以上はかかりそうなIEと、リリース間隔を合わせることはきついでしょう。それができるなら標準の実装のタイミングを同じにしてもらったほうが…という話だし。
で、接頭辞つき機能がもう使われているなら、それを削除できるのかという話に戻る。make those pages render worse
とあるから、動かないとかそういうのよりも、角丸とかドロップシャドウ系のことを考えているのかな。
グラデーションは-webkit-だけに依存してもらうと困る(白 ― 白で見えなくなることがある)けど、角丸、ドロップシャドウくらいいは、「依存」といえるのかっていうレベルというのもある。
aklein/jamesr: is there any difference between the first and second parts of the discussion? is the vendor prefixed case different than other deprecation? Mozilla is willing to remove prefixed versions.
weinig: we don't want to break content.
jamesr: presumably Mozilla doesn't want to break content either.
fishd: although are clearly cases where they're more willing to break stuff.
Mozillaのポリシーとの違いについて。
dglazkov: over time, you end up with so many prefixes it becomes hard to build webapps.
weinig: but they could just use the non-prefixed version. it's just a burden on WebKit to support both versions.
jamesr: except that the behavior could be different, and developers have to think about it.
接頭辞だらけでWebアプリを作れなくなるんではというDimitri Glazkovの発言。すてき。Good Morning!
ただ、そういう場合は接頭辞なしの機能だけで組めばいいのではという発言も。えええ、ブーブー。でもたしかにそうでもある。けれどそれは、CR待って、テスト待って、実装待って…と、W3Cのプロセスにだいぶ弄ばれることになる。
結局、実装者 ― 開発者 ― 標準化団体間でのボールのぶつけあいになってしまう。それは避けたいよ。あとこうなると、接頭辞の有無やらベンダー拡張やら標準やら、試験実装やらちゃんとした実装やら、そういうものが吹っ飛んでしまうんだ。
接頭辞のついた機能が問題になっている認識はあるものの、じゃあ接頭辞をなくそうとか、接頭辞を省いていこうというアクションは、このミーティングでは見られなかった。
ただこれ書いて寝かせてる間(先週)にちょっと動きがあったので、それはまた別途書く。
Responsive imagesのための-webkit-image-set()
AppleがWebKitに-webkit-image-set()なるものを実装した。
なにかというと、Retina displayやらPCとデバイスピクセル比が違うディスプレイに対して、違う画像を出し分ける、いわゆるResponsive imagesと呼ばれてるやつのための仕組み。
こんな感じで書くらしい。
selector {
background: -webkit-image-set( url(foo-lowres.png) 1x,
url(foo-highres.png) 2x ) center;
image-set()内には複数の"imagespec"というものが入る。imagespecは<image>(画像、グラデーションでもいい)に続けて、nxという表記で倍率を書いたもの。対応しているブラウザは、高密度なディスプレイには“2x”な画像(foo-highres.png)を、これまでのディスプレイには1xな画像をという風に出し分けることができる。
メディアクエリーとどう違うのか
出し分けるとなるとメディアクエリーとどう違うんだという話になる。この機能を提案したAppleのEdward O'Connorにはこういう考えがあるらしい。
Here are just a few of the problems with the current situation:
- Bugs due to non-locality: One developer fixes a bug in the selector, but only in the low-resolution case. Another developer changes an image reference to refer to a different icon, but only in the high-resolution case.
- Both assets may be loaded by the browser, which may degrade performance in a constrained bandwidth environment.
- Authors can't specify both assets inside a style="" attribute.
メディアクエリーだとセレクタが多重になるので管理性が懸念されること、使わないもう片方の画像が読み込まれてしまう可能性があること、style属性でつかえないこと、この3つがいくつかある問題として取り上げられている。
あと、image-set()で出てきそうな質問にもすでに答えている。
Why a scale factor and not a full-blown media query?
Media queries are a claim about the state of the UA, whereas here we're making a claim about (the relationship between) the image assets themselves. It would be confusing to use similar syntax for such different things. Also, UAs should have the ability to choose between the given variants based on a variety of factors. For instance, a UA could use the lower res asset when a user has zoomed out. No existing media query distinguishes between the page being zoomed-out and being zoomed in. And even if such a media query existed, UAs should be free to choose between variant assets regardless of which media queries happen to match.
MQを使わず2xなんて倍率を使う理由は、MQがUAの性質について何かするという考えのもと作られてるのに対し、こっちは画像自体について言いたいと。なので違う構文のが間違わなくてよいだろうと。あと、UAの性質(デバイスピクセル比とか)だと「どちらか」になってしまうけど、image-set()はたとえば、ズームインしたときは解像度の高いものを選ぶとか、そういう利用も考えられているらしい。
ズームインとかを考えると、たしかにmedia featureとは言いづらいかもね。
The problem of stylesheet verbosity when using media queries isn't limited to image assets. Shouldn't we have a general mechanism for keeping media-specific property values together in rule sets?
In talking with content producers here, we've found that the non-locality of asset references is a real source of Web author pain. I think a focused feature to help with that pain is sensible. That said, we should also explore how to help authors avoid selector repetition and the other pains of @media in general.
image-set()っていう画像だけのやり方じゃなくて、もうちょっと一般的なことにできないのという点については、まずアセットの参照が一箇所にないことがかなり手間ということが分かったので、その解決にフォーカスした機能にしたと。一般化については、セレクタの重複や他にもあるだろうMQの問題について、いま一度どんなことができるか調査すべきだと。
Why not enhance the image() function instead of inventing a new function?
Unlike image(), these image specifiers are unordered. This isn't about fallback. There is no preferred variant. UAs are free to use whichever image it believes would be best. For instance, consider the page zoom example I mentioned earlier. Authors could even use image() and image-set() together to handle more exotic cases, e.g.:
image(image-set(url(foo.png) 1x, url(foo@2x.png) 2x) rtl, image-set(url(bar.png) 1x, url(bar@2x.png) 2x) ltr);
css3-imagesで提案されてるimage()を使わないのはどうしてかと。これは、image()がフォールバック目的で、また値の順序が影響するのに対して、image-set()はズームなんかの状態に応じて画像を選べると。
ふむ。
image()でなんとかできないのか
ズームとかそういうのはわかったんだけど、image()とは別というのは、なんだかね。まだ実装もないし、定義を変えてしまえばいいだけのような気もするんだけれど。
というわけでcss3-imagesのEditorのTab先生とちょっと議論している。ただ読む限り、Ted (Edward)はあくまでimage()はフォールバックのためとしておきたいという気持ちが強いようで。Tabがそのあと、image()のリスト中にスラッシュを入れて、それをimage-set()の代わりにしてはどうだという提案をしているけれど、とくに返信もなくという状態。こっちのが好きかなあ。
Retina時代の準備かねえ
実装されたのはさっきだけれど、やっぱり裏にはRetina display対応が絡んでるんだろう。今WebCoreに入れば、Safari 5.2の正式版に反映されてもおかしくないタイミングだし、iOSの次のバージョンにも取り込まれることは間違いない。
LionでHiDPIモードが進んでたのもあるし、OSXでもそのうちRetina display搭載のデバイスが出るんだろう。そこで多分使ってくるんだろうねえ。
そうなると、気になるのがHTML側ではどうするかということ。CSSではimage-set()ができたけど、HTMLにはそれが無いので、The new iPad™なページはXHRで2xな画像に差し替えてるなんてことをしている。
で、さっきのTedのメールに、こんなのが。
What about content images?
First off, this is www-style, so the design of an HTML feature for responsive <img>es is out of scope. :) That said, I can imagine the image-set() microsyntax being used in an attribute like so:
<img alt="A description of foo" src=foo-lowres.png set="foo-lowres.png 1x, foo-highres.png 2x">I'll post something to the whatwg thread referencing this proposal.
とまあ、www-styleだからって提案ではないとしときながら、<img src=... set=...>と、属性を追加するかたちで提案している。後方互換性を考えると、srcの拡張は現実的ではないし、ズームイン/アウトのユースケースを考えると別の属性にしかならないだろう。<object>は禁句。
WHATWGになんかポストするとあるけれど、現時点ではとくにそんなメッセージはない。ただ今週あたまにCanvas APIにデバイスピクセル比やら高解像度用のImageDataやらが欲しいという提案をしている。
というわけで、来るんじゃないですかねえ。
JavaScriptCoreでparseInt('010')が十進数として処理されるように(→V8, SpiderMonkeyも追従)
ちょっと前に、JavaScriptCoreでparseInt()の挙動が変更されて、0から始まる文字列を8進数として認識しなくなった。
parseIntは入る文字列によって、数値の底が変わっちゃう。基本的には十進数として処理するけれど、"0x10"みたく0x(もしくは0X)から始まる文字列が渡された場合、文字列は16進数として解釈され、処理される。だから、parseInt('0x10')は16を返す。
ここまではまだいいとして、"010"とか0から始まる数値(の文字列)が入ると、それを8進数として処理してしまう「ことがある」。ES3のparseIntの項にはこんな注釈がある。
When radix is 0 or undefined and the string's number begins with a 0 digit not followed by an x or X, then the implementation may, at its discretion, interpret the number either as being octal or as being decimal. Implementations are encouraged to interpret numbers in this case as being decimal
最初に0であっても十進数と解釈するのが望ましいとは書かれてるんだけど、8進数として処理されるブラウザが多かった。
これ、十進数を必ず返すものと思っていて、単にparseInt('str')と使ってる人、結構いるんじゃないかなあと思う。前に何かでバグの原因を探ってて、これだったことがあった。
対処するのは簡単。parseIntは第二引数をとれて、それで底を指定できる。十進数を意図してるなら常にparseInt('010', 10)としとけばいい。
さて、ES5ではこの妙な注釈が削除されて、8進数としての処理はしちゃいけないことになった。
15.1.2.2: The specification of the function parseInt no longer allows implementations to treat Strings beginning with a 0 character as octal values.
ただ、既存コンテンツとの互換性かなんなのか、ES5の仕様が固まったあとも対応が遅い。最初に対応したのがIE9で、次はJavaScriptCoreになる。
OperaはES5.1フルサポートとうたってるけど、テストした限り動いてくれない。あと、詳細なサポート表を見たらOpera Presto partially supports ECMAScript 5
ってなってる。えええ……
Geckoに関しては、一度対応したのだけれど、やめた経緯がある。
Jeff Waldenのコメントで、Strict modeのみで対応したけれど、strictnessで判別して挙動を変えることの問題などからバックアウトされた経緯が語られている。
- Bug 577536 - parseInt() uses radix 8 if the string starts with '0' but not 0x or 0X
- Bug 583925 - parseInt should not use caller's strictness in choosing radix
他のブラウザも同じ挙動だから、それを直さず意図的に対応しないと。
Chromeで使われてるV8も同様に対応しない方針らしい。
ただ、IE9が変わったのはシェア的にも大きいし、JSCもそれに続くとすると、SafariとChromeで挙動が違うことになる。どうなんだろう。
報告してみた
MozillaのBugzillaとV8のIssueに、「JSCがなんかやってるらしいよ」と書いてみた。
まずMozillaの反応。
Interesting. I knew about the former, but the latter is much newer. In light of that, perhaps we should be changing, possibly...
the former
はIE9のこと(バグで言及されてなかったのでついでにしてみた)。変えることになるかもしれないねえ…と。
続いてV8のほう。
Thanks for pointing this out! Currently, no stable version of any of the major browsers support the standard compliant behavior by default, which is why we are very hesitant to be the first to "fix" this and risk problems due to incompatibility with ES3. We will however be closely observing how this turns out once this change to JSC is shipped with the next version of Safari.
「どのメジャーブラウザの安定版もデフォルトでサポートしてないし」ってところにIE9モード…と思ったりもするけれど、でも「直す」というのにはやっぱり抵抗はありますよね。Safariがどうなるかを見て判断すると。
追記 (2012-08-15): Safari 6のリリースによりV8も追従
先月リリースされたSafari 6には変更が取り込まれ、0から始まっても8進数として扱われなくなった。
というわけでV8に報告してみた。そしたら4日後に反映された。このままいくとChrome 23から挙動が変わる模様。
追記 (2013-01-30): Firefox 21でSpiderMonkeyも追従
mozilla-centralにもチェックインされて、FirefoxもES5での仕様に準拠するようになった。
Firefox 21からこの挙動になりそう。
追記 (2013-08-16): OperaもChromiumベースになったので追従→すべてのエンジンが対応
残ったOperaも、Chromiumベースになったことで、ES5の仕様に準拠するようになっている。
IE8がまだ結構多いだろうし、Androidブラウザもあるので、まだ安心して第二引数を省けるわけではなさそう。そこまでコードがごちゃごちゃするわけでもないので、基本はparseInt(str, 10) って書くのが、まだしばらくベストプラクティスのままなんだろう。