WOFF 2.0 Evaluation ReportとBrotli
いつだったかにWOFF2のことを書いた。
タイトルかたいな!
その後どうなったのかなと思いつつもめんどくて調べてなかったんだけど、1月末にWOFF 2.0 Evaluation Reportというのが出た。WOFF2で検討されている圧縮の仕組みなどについて調べたレポートとのこと。
- Transition request: First public working draft of WOFF 2.0 Evaluation Report
- WOFF 2.0 Evaluation Report
以下、2013年夏くらいからの話題なので新しくないよ。
LZMAはやめたらしい
GoogleによってWOFF 2.0の元になる仕組みが提案された当初、圧縮アルゴリズムはLZMAを使うことになっていた。ただ、高圧縮率の犠牲としてえらい圧縮時間とメモリ使用量が必要ということがわかったので、その採用はなくなったとのこと。ある計測結果によると圧縮にかかる時間がgzipの5倍以上、展開時のメモリ使用量が2倍くらいだったそう。
Webフォントはサブセットを配布しないのなら一度圧縮するだけで済むけれど、展開時のメモリ消費量は気になる。とくに世の中がモバイルモバイルしている中でこれはだめだったんだろう。
ほかにも、LZMAの仕様がない(リファレンスコードをリバースエンジニアリングするしかない)、IP関連でロイヤリティフリーにできる保証がないということも問題になったよう。仕様があるって大事なんだね……
Brotli登場
代わりとなったのが、Google内部でDEFLATEをベースにしたBrotliというもの。昨年Googleから出たZopfliやWebP Loslessを作った人たちによるものらしい。
- WOFF2: Compression update
- (PDF) Brotli Compression Algorithm motivation
- font-compression-reference - Reference code for new font compression(Brotliのレポジトリ)
- brotlispec.txt(仕様)
Evaluation ReportによるとLZMAにはやや劣るけれど、フットプリントは半分近くになるらしい。それでもWOFF1と比べて大きいけれどトレードオフなのかと。
実装もChromeにすでにフラグ付きで入ってるらしい。知らなんだ。
今後はBrotliの標準化(IETF?)と平行してWOFF2を標準化するらしい。いつくらいになるのでしょうねえ。
余談:Webでの利用は?
Mozillaのニュースグループでも取り上げられていて、そこではフォントだけではなくて、HTTPとかWeb全般に使えるのではというコメントつきで紹介されている。
Introducing Brotli - an alternative to LZMA - Google Groups
とくに議論が発展してないけれど。新しいものを導入するとなるとだいたい切ない話になるので誰も入ってこないのだろうか。
システムの文字サイズを取得できないものか
80歳の方にiPad Airを使わせてみた方のエントリを読んだ。
母とNexus 7
ちょうど年末年始の帰省時に母(60くらいだったかな?)にNexus 7(2012年モデル)を渡したのだけど、このエントリにある「ボタンはしっかりと押さないとね!」というのがあって困った。画面上じゃなくて電源ボタンも無意識に長押しになるので電源オフにするダイアログが出る。実家から戻るときにはだいぶ良くなってたけど、タップはぎこちなかった。慣れてくれるといいな。
あと面白かったのが、アプリアイコンとブックマークを混同していたというか同一視してたこと。「ニュースを見たい」とアプリ一覧を指して言って「ほえ?」となった。アプリ一覧はできないけど、ちょうどChromeがメニューからホームスクリーンに登録できるようになったので、それを教えてあげた。ホームスクリーンがアイコンだらけにならないといいけれど。
しかし、Windowsのデスクトップを見たところWebサイトへのショートカットがばかすかあるわけでもなく、なんでNexus 7でそんな認識になったのかわからない。Androidはまたアプリ一覧とホームスクリーンがあるのでややこしいよね。iPadだったらまた違う反応をしてたのかな。
他にも面白かった…というかめんどかったのが、半透明のグレーのやつをオーバーレイさせる系のチュートリアルを読みもせずすっとばすこと。「えっえっ」って言って一番目立つ色のボタンを押しちゃってチュートリアル終了という。わかんないと言われてもこっちだって見てないし…アプリ詳細からデータ削除してもう一回やりなおしたりとか。あれ系を採用する場合にはぜひともチュートリアルをやり直すオプションがほしい。
システムの文字サイズが反映されないアプリがかなりある
母の観察記はほどほどにして本題を。件のエントリでも触れられていた点が特に気になった。
文字の表示サイズを大きくできる
「太字」「文字を2まわりくらい大きく」な設定にしてきました。だってiPadの文字を虫眼鏡を通して読んでいたんですもん…。
私が普段コーディングをしながら「ギャアア」と思っている文字サイズ変更機能も、こういう人向けに必要なのですね。知識として知ってはいましたが、「ああ、こういうことなんだー」と思いました(直接的には少々違いますが、概念として)。
こちらもAndroidの設定から文字サイズを指定できたので、てきとーに大きくしておいた。Chromeにも設定あるんだけどそっちはどうだったかな…でも-webkit-text-size-adjust
設定されてたら意味ない気がするけど。
システムの設定はできても、拡大できるのはシステムのサイズを継承してくれるUI周りで、コンテンツ周り?は拡大してくれないアプリが多かった。ピンチズームも効かなくてうーんと思った。
ちょっと見てみて、WebView使ってそうなアプリにそういうのが多い感じがした。システムのサイズを取ってくるAPIとかないのだろうか。
IndieUI User Context
Web標準側にもそういうのは今のところないはずで、構想がIndieUI WGでつくってるIndieUI 1.0: User Contextにあるくらいか。“feature key”というメディアクエリーの媒体特性みたいなの(たまに媒体特性としても使えるらしくよくわからない)にuser-font-size
というのがあるのでそれを使えばよいらしい。
// example of settings keys defined within the IndieUI User Context specification. window.userSetting('user-font-size'); // returns computed value in CSS pixels, e.g. '16px'
とはいってもまだ構想段階な感じ。TPACのときにあったCSS WGとのジョイントミーティング、WebApps WGとのジョイントミーティングでは、ハイコントラストモードの検出とか一部の機能については支持があったけど、セキュリティ・プラバシー的な懸念とかもやっぱりあって、まだまだという印象を受けた。
使えたら使えたで「システムの文字サイズ継承とか…」みたく思ってしまうのだろうけど、読めないよりは崩れてても読めたほうがいいよねえ。
Web技術について書くときの媒体の違いを考える
このエントリはEditors' & Writers' Advent Calendar 2013の12日目のやつです。
これまでいろんな媒体で、HTMLやらCSSやらに関することを書いて、そして書かせていただいてるので、媒体ごとの違いなどを考えてみました。
ブログ
このweblogや過去に書いていたブログ、勤めていたときにお仕事で書いていたWeb標準Blogなど、ぼくが書く技術系のコンテンツのプライマリな媒体はブログです。
ブログのよいところは、好きなときに好きなことを好きなだけ書けるという、書き手中心のところでしょうか。お仕事で書いていたブログについては、会社のコンテンツということもあり多少なりとも内容についての確認などはありましたが、それでも他の媒体と比べて自由度は高いのかなと。
いっぽうで悪いところは自由すぎるところでしょうか。タイミングも分量も表現も自由ですので、自重しないと話しの軸もターゲットも容易に見失います。このブログがよい例です。
オンラインメディア
いまはHTML5 Experts.jpでちょくちょく書いて(と言いたいのだけどまだ1本…すみませんすみません)、お仕事では以前Gihyo.jpさんで原稿を書かせていただいたことがあります。これら2つからオンラインメディア全体について語るのはアレなのですが、とりあえず。
よい点としては、「メディア」として幅広い読者層がいるだろうということが強みでしょうか。自分のブログよりも広い相手にリーチできるのかなと。
わるい点としては、ターゲットを想定しづらいことでしょうか。メディアによって読者層は違うのでしょうが、多くの人が集まるぶん、狭すぎるものは心理的に書きづらく思います。また、広い読者層がいるわけで、自分のキャラが通じないことは意識しないといけないかなと。書き手が基本一人の個人ブログだといいのでしょうけど、多くの執筆者が居て、多くの読者がいるメディアでは、それが伝わらず、たとえば毒舌キャラのまま書いたら無駄な炎上を引き起こしたりとか、そういうのが考えられます。何かを伝えたいのに伝わらない、というか変なコミュニケーションミスまで起こってしまうというのは悲劇です。
また、メディアによっては掲載日というものの関係から、すぐに発信したいニュース的なものを投稿することが難しくなるでしょう。また、こちらもですが、編集権限がないため、文章は提出する前にかっちりさせなければなりません。こちらは編集者のお仕事でもあるのですが、みなさんが技術にえらく詳しいわけでもないので。ぼくはずぼらなので、このブログなんかは「あとで編集しよっと」と思いながらだらだら書いて公開後にだだっと編集してますが、そういうやり方ができません。
雑誌
雑誌の特集記事や連載をお仕事でさせていただいたことがあります。なかでもWeb Designingさんにはとてもお世話になりました。
雑誌で書くことのよい点は、まず肩書的になんとなく箔がついてくれること。いやらしいですけど、自己紹介とかで書きやすいのです。
って、これは書いたことか。
書くにあたってよいなと思うのは、物理的な媒体、つまり面積に縛られるので、文字数や図版などを収める工夫をしないといけないことです。文章は推敲が必要だし、図版などは見せ方を気にしないといけない。Webでできないわけではないのですが、強制されるので、ずぼらなぼくみたいな人にはとても効果があります。面倒ではありますが。
わるい点は、これは扱うテーマがWebという進みの激しいものというせいもあるのでしょうが、お店に出るまでのディレイがかなりあることです。ニュース的なものは他の媒体に食われてしまうので、書く意味はそこまでなくなります(ニュースに疎い層がターゲットであればいいのかもですが)。また、あまりにパッと湧いて出た話をすぐに拾ってしまうと、その後の話を記事では説明できないので、あまり健康的ではありません。Web Designingでは、Web標準がらみのトピックをとりあげる連載をさせていただいたのですが、何度かこれで失敗したなと思うことがありました。
ちょっと時間がないので草稿でだしとく。あとでもうちょいいじる。
all, initial, unsetでCSSのリセットと継承回避をする
追記(2018年4月13日):紹介した機能の実装が進みました(Can I use:all
プロパティ、initial
、unset
)。
一方で文中で取り上げたScoped Stylesheetsは仕様から削除されてしまいました。
このエントリはCSS Property Advent Calendar 2013の10日目のものです。
すみませんすみません日付勘違いしてました。ほんと申し訳ありません……
今回はradial-gradient()
のMixin…は作りません。プロパティじゃないしね。ふつうのプロパティと値についてご紹介しようかと。
CSS Cascading & Inheritanceのall
, initial
, unset
Firefox 27あたりからall
プロパティとunset
値なんてものが実装されました。CSSのCascading and Inheritanceモジュールで定義されてるんですが、これを使うとスタイルを局所的にリセットできます。実装したMozillaのCameronのエントリが詳しいです。
all
は「すべてのプロパティ(※ただしdirection
とunicode-bidi
を除く)」を指します。すべて(※)です。これから定義・実装されるプロパティもすべてall
になります(※)。ターンAみたいですね。
initial
, unset
はCSSワイドな値です。initial
は初期値(を指定値にする)値で、結構前からいろんなブラウザで実装されています。inherit
というのもあります。これは継承値を指定値かつ算出値にするものです。unset
というのはその間の子で、継承するプロパティ(font-size
やらcolor
やら)についてはinherit
, そうでないものにはinitial
という扱いになります。unset
のユースケースがいまいちわからず、昔何かで読んだ気がするのですが忘れました。とりあえず次に進みます。
スタイルをリセットしたい?
スタイルをリセットしたい場合って、今のところそんなあるようなないようなですが、かなり個人的な背景からそう思うときは多々あります。
たとえば、HTMLとCSSの講演スライド。スライド作成ソフトと比べるとまだあんま良くないと思っているのですが、スライド中にWebコンテントを直接埋め込める利点があります。とくにHTMLやCSSについてお話させてもらうので、実際のコンテンツを埋め込めると楽です。
埋め込みというと、外部コンテンツを<iframe>
で読み込むという手もありますが、複数ファイル作るのが面倒な例などは、インラインで直接書きたいものです。
<div class="example"> <!-- サンプルコードがここに入る --> </div>
とはいえ、ここで面倒なのが、div.example
内のコンテンツが親のスタイルを継承してしまうこと。スライドのスタイルは10-feet UIといいますか、背景と前景のコントラストをなるべくとる、文字は大きくするなど、デスクトップスクリーンとはまた違う流儀があります。サンプルがどんなものかにもよりますが、そういったスタイルが継承されると上書きすることが面倒です。サンプルはシンプルにゼロから始めたい。ここでall
とinitial
が役立ちます。
<div class="example"> <style scoped> * { all: initial } </style> <!-- サンプルコードがここに入る --> </div>
<style scoped>
を入れてdiv.example
だけに対応するスタイルを書けるようにします。そして最初でall: initial
でスタイルをキャンセルすることにより、div.example
が親からのスタイルを継承しないようにします。
親のスタイルを一部継承したい場合はall: unset
でもいいかもしれません。
display
がinline
になるのがだるいですね…プロパティごとにinitial
のがいいかもなあ。
Scoped Stylesheetsの危機
HTML+CSSなスライドで例をインラインで書きたい、というあまりにもニッチなユースケースですが、all
, initial
unset
の便利さをお分かりいただけたでしょうか。無理かなあ。
さて、実装が進めば素敵なHTML+CSSなスライドライフをおくれそうですが、現在Scoped Stylesheetsを消さないかという話が出ていたりします。もともとHTML5でat riskな機能で、現在もFirefoxでしかリリースされてません。そんな中blink-devで削除しないという話がでてしまい、あまりいい具合ではありません。Hixieは制作者の要望が大きいことを述べていますが、大きく反対しているわけでもなく、しばらく放置されそう。HTML5からは削除されるかな。
<style scoped>
を使わずとも、スコープさせたい要素の親にid
でもふってやればいいのですが、サンプルコードまわりをひとまとめにしときたいんだよなあ。
WebプラットフォームのこれからとExtensible Web
この記事はFrontrend Advent Calendar 2013の8日目の記事です。
昨日岐阜県にてHTML5 Conference 2013 in Gifuというイベントがありまして、そちらでWebプラットフォーム動向についてお話させていただきました。スライドはこちら。
相変わらずふんにゃりした話しかできず心苦しい。
Extensible Webが実行に移った2013年
今年はOperaのWebKitChromium移行、Blink登場、IE11で互換機能を非推奨に、など、ブラウザの動きが大きくて、あまりWeb標準周りで大きなニュースがなかったように思います。あったらあったで面倒なんですが(たぶん良いニュースはない)。ただ、思ったよりずっと動きが速いなと思ったのが、Extensible Web関連です。
「低レベルなのモデル・APIをつくり、高レベルな機能はその上で表現可能とする」というのがExtensible Webの基本的な考えと認識してますが、その構想が動きを伴って大きく進められたような気がするなと思いました。Service Workersのハイプ化や策定中のPromisesを導入したAPI仕様の登場とかとかを見ると、とくにそう感じます。また、Polymerに見られるWeb Componentsまわりのスタックを一部Prolyfillとして実装する取り組みなど、実践しはじめているのも見られます。とくにProlyfillによる試験実装は、これからのWeb開発・標準化において一つの側面となるのではないかと思っていて、注目しています。
マクロな標準化とミクロな標準化
スライドの中で、こうしたExtensible Webなアプローチが進むことにより「ミクロな標準化」が出てくるのかなと予想を書きました。マクロ・ミクロという言葉の使い方がしっくり来ないまま使っているのでまだもやもやしてるのですが、標準化団体による標準化を「マクロな標準化」、Web開発者コミュニティによる高レベルAPIの開発・普及活動を「ミクロな標準化」と呼んでいます。
低レベルなAPIに集中しようという流れの背景は、高レベルなAPIを定義しても実装においてそのモデルや低レベルなところをさらう必要が出てくる、それをしないとしょうもない機能になってしまう(例:AppCache)ことへの反省がひとつ、そして「すべての望みは標準化によって解決するものではない」という認識の改めがもうひとつあるのかと思っています。ある意味標準化団体が「投げた」のかもしれません。
とはいえ、低レベルなところを作ってくれるおかげで、高レベルなものは表現しやすくなるでしょう。相互運用性も高まるのではないかと期待しています。さらには開発者が作った高レベルな機能が広まった際には、それを「マクロ」側で標準化することもそれなりに容易いのかと。コードが仕様になりますから。
ミクロな標準化とやらがjQueryなどとどう違うのかですが、標準化団体との関係が違うかなと考えてます。高レベルなAPIが作られることをふまえた低レベルなモデル・APIという方針があることで、標準化団体へのアップストリームというパスができたことが大きなことだと思っています。これまで開発者と標準化団体・ベンダーはどうにも接点があるようで弱くて、あまり協力して標準化という流れにはなってない印象があります。これが短期的に変わるとは思いませんが、開発者が自分たちの欲しい機能を作れるというオプションが用意されたので、変な摩擦が少なくなれば健康的かなと。
低レベル指向の落とし穴?
懸念があるとするならば、まず表現においてはExtensibleな部分が少ないというところ。ええと、CSSでの低レベルなモデルが存在していないこととCSSOMが貧弱ということでしょうか。CSS Grid Layoutあたりが来ればもうちょっと良くなるのかとは思っていますが(Blinkでちまちま実装が進んでいるのも、Extensible Webのひとつとして考えてるのかなと)。
あとは、高レベルな機能の設計ができる人がどれくらいいるのかというところ。Web Componentsなどでオレオレな要素やコンポーネントが定義できるようにはなるのでしょうが、jQueryのように広く普及するようなくらいのものが出てくるのか、作れる人がいるのか。高レベルな機能の開発者が不在なのに低レベルなものに終始すると、それはそれでWebの発展を妨げるかなと。
とはいっても、Appleのように高レベルでdeclarativeなのが好きなところもあるので、これから出るものがすべて低レベルでimperativeというわけではないと思いますが。
おわりに
なんだかスライドの反芻しかできてない気がするので、とりあえずここで一旦切ります。Extensible Webについては、TAGと新しいGoFの登場、Layeringという考えの提唱、Extensible Web Manifestoなどの登場などいろんな契機があったのですが考えがまとまらず書けなかったので、ようやく書けたのでうれしいです。といっても、まだまとまってないところもあるし、うまく説明もできてないですが……
PromisesやService Workers, Web Componentsなど個々の技術についても、ぼちぼち何か書いていきたいですね。とくに今はWeb Componentsと静的なWebサイトの部品、文書構造との関連についていろいろ気になっているところです。ではでは。
SVGヤバイ 2013冬
Chrome 31がStableになって久しい。何が変わったのか思い出せないんだけど、ひとつだけ覚えてるのがこちら。
WebKitのパッチをマージしたものらしい。ちょっとずつ離れているらしいけど、まだお互い共有できるパッチもあるんだね。
さて、このパッチによって、CanvasでSVG画像をdrawImage()
などで描画したとき、条件によってはそのCanvasがtaintされなくなった。
Tainted Canvasとは
CanvasにはdrawImage()
など、画像をCanvasに描画するメソッドがある。ここで、スクリプトとsame-originではないとこにある画像を描画してしまうと、セキュリティ上の都合からCanvasが“tainted”(「汚染」)という扱いになり、getImageData()
, toDataURL()
, toBlob()
などができない。
ハックではない正攻法な対策としては、画像の配置場所をスクリプトとsame-originなところにするのが楽か。もしくはCORSのヘッダを設定してその許可したorigin以下に画像を配置し、それから画像にcrossorigin
属性(DOMの場合はcrossOrigin
)を指定するなんてやり方もある。詳しくはMDNのドキュメント参照のこと。日本語訳がある。
こんなニッチなの誰が訳したんだと思ったら自分だった…記憶がまったくない。
きたないSVG
さて、originまわりが良くなってもtainted扱いになるなんて場合がある。SVG画像だ。SVGは中にスクリプトや画像を書けちゃうので、危ないと判断されてWebKit/Blinkではこれまでどうあがいてもtainted扱いとなっていた。
あー説明めんどくさい…と思ってたらgyuqueさんが2年半前に同じことを書かれていた。しかもデモつき。なんと。
今回のパッチで、SVG画像が内部で画像を呼んでない場合、そのSVG画像をdrawImage()
で読み込んでもtainted扱いにならなくなった。Chrome 31で見てみたところ、一番右の列がすべて「OK」となったのを確認。
マミさんは死んだ。
例で使われている画像的には良い気がしないけど、Webプラットフォーム的には良い変更だ。
試してないけど、SVG画像の中に<svg:image>
があるとアウトになるんだろう。
Geckoではだいぶ前からOKだったらしい
Firefoxで見たところこちらもOK(マミさんは死ぬけど)。2011年5月時点ではGeckoでもダメだったようだけど、Geckoでは2011年末に修正され、Firefox 11から使えていたらしい。今回Blinkもサポートされるのでカバー範囲が広がったけど、SafariはSafari 8になるだろう。来年かー
Chromium DashboardのCSS usage metricsとぼくらのusage metrics
火曜にGoogle JapanであったChrome Tech Talk Night #6でライトニングトークをしてきた。
イベント中ずっと資料とコードを書いてて内容をほとんど聞いてないという残念っぷり…こういうのやめたいね。
Chromium Dashboardの概要と、9月に追加されたCSS metricsの紹介と、自分がアクセスしたページならchrome://histograms
からデータとってこれるよという話をした。
資料はこちら。
以下ちょっといろいろ。
CSS usage metricsで気になるところ
すこしある。
- Chromeが解釈できる機能に限定されること
- 現在のところプロパティのみということ
- (たぶん)プロパティの「書かれた回数」をもとにしてないこと
ひとつ目は他のベンダー接頭辞つきプロパティの利用状況がわからないこと。たとえば-moz-border-radius
や-moz-opacity
。Geckoはもう解釈しないけど、使われてるページはまだ多いだろうから、そういうのもわかるとうれしいなと。DevToolsでは他のベンダー接頭辞つきプロパティも表示してるので情報は取れると思うんだけど、むつかしいのかなあ。
ふたつ目は、linear-gradient()
やinput
関連の独自セレクタ、@rule
についてはわからない。ただ値についてはissueが上がっているので、やるひとがいたらなんとかなるかも。
みっつ目はややこしい。ちゃんとソース読んでないので保証できないんだけど、たぶんUseCounterの仕様からプロパティの「書かれた回数」ではなく「出現したか否か」を元にデータを出している。なのでこのmetricsで上位にあるプロパティはWebで多く「書かれている」プロパティではない。「使われている」とは言えると思うけど。そこらへんトリッキー。
ぼくらのCSS metrics
UseCounterを使う関係上、そのデータはGoogleしかわかんないことになる。オープンデータ!とか強く言うつもりはないけど、ちょっとくやしい。
グローバルなデータはないけれど、「ローカル」なデータは手に入る。UseCounterをはじめChromeが集めてるデータはchrome://histograms
で見られる。アクセスするとファンシーなアスキーアートが並んでると思う。DNS関連のあれこれとか、パフォーマンス関連のものが多い。
UseCounterはこの仕組みを使ってるので、このページから探し出せばいい。「ヒストグラム」としては失格だけど、データが手に入るからいいんだ。
で、データの取得がちょっと面倒。なんせ<pre>
なアスキーアートなので。
はじめはXHRで自身をDocumentとして取得して、目的の<pre>
を見つけて、そのtextContent
に正規表現をかけて…ということをやっていた。そしたら先週末くらいにchrome://histograms/FeatureObserver.CSSProperties
とかで絞り込めることがわかって、XHRのところは省けた。すっきり。
Chrome拡張にしようかと思ったのだけど、今のところchrome://
なURLにXHRができない。フラグがあるけど有効にしたら使えるのかな。
そんな中途半端なところでおわった。4分オーバー。すいません。英語むつかしいです。
Autoprefixer ― CSSのベンダー接頭辞をいろいろする
以前CSS-Tricksの記事で知ったAutoprefixerというの、ようやく試してみた。
- ai/autoprefixer
- Autoprefixer: A Postprocessor for Dealing with Vendor Prefixes in the Best Possible Way | CSS-Tricks
CSS-Tricksの記事読んだほうがいいと思うけど、月一のブログ更新ノルマのためここでも書いとく。
かしこい「ポスト」プロセッサ
Autoprefixerはその名前からある程度想像できる通り、ベンダー接頭辞を自動的につけたりしてくれるユーティリティ。CSSファイルを作るのではなく、CSSファイルを処理するので、ポストプロセッサと言っている。
接頭辞まわりは、すでにCompassとかのライブラリでmixinなどが用意されてるので、べつに必要ないじゃんと思うかもしれない。ただ、プリプロセッサのmixinや野良mixinってちょっと雑で、吐き出されるCSSにあまり2013年感がない(個人の感想です)。
あと、とくに野良mixinに多いけど、ただ単に接頭辞つけただけで、仕様の構文が変わった場合に対処できてないものが多いかなと。無駄もしくは無意味なプロパティがCSSに書き出されてるのをちまちま見る。処理前のファイルはクールに書けても、出力されたCSSはクールじゃない。
Autoprefixerはcaniuse.comのデータをもとに、必要だろうとされるバージョンを判定して、そういう無駄な接頭辞を書き出さないようにしている。Compassも接頭辞の出力をカスタマイズできるけど、設定しないといけないのでちょっと煩わしい。自動でやってくれると楽だよね。
試してみた
ではどんなものかということで、試そう。コマンドラインはもとよりGruntやSublime Textなど、いろいろな環境で使える。今回はnpmからインストールして、コマンドラインで試してみた。
まずはborder-radius
とbox-shadow
の組み合わせ。こんなファイルを用意した。
.button { border-radius: 3px; box-shadow: 0 0 5px 1px #999; }
雑な定義なのは気にしない。コマンドラインからAutoprefixerをかけた新しいファイルを出力。
% autoprefixer button.css -o button_a.css
autoprefixerって打つのだるい。あと-oってOperaの接頭辞つけるのかって気分になる。
どうでもいいね。結果はこうなった。
.button { border-radius: 3px; -webkit-box-shadow: 0 0 5px 1px #999; box-shadow: 0 0 5px 1px #999; }
border-radius
は接頭辞なし、box-shadow
はGingerbread用に-webkit-box-shadow
が付け足されて出力されている。おお。
構文の変更もがんばってくれてる
接頭辞ついた版をつけてくれるのは分かった。では、構文の変更にはどれくらい対処してくれるのか。Autoprefixerのソースを見るとhacksというディレクトリがあって、構文の変更があるプロパティとか表記系を処理するファイルは、ここに個別に用意してあるようだ。
では、ぼくが愛を超えた憎しみみたいなガンダムにありそげな感情を持ってる(持ってない)linear-gradient()
はどうなるか。こんなファイルを用意した。
.gradients { background-image: linear-gradient(#eee, #ccc 50%, #aaa); } .gradients-keyword { background-image: linear-gradient(to top left, #eee, #ccc 50%, #aaa); } .gradients-angle { background-image: linear-gradient(30deg, #eee, #ccc 50%, #aaa); }
結果はこちら。
.gradients { background-image: -webkit-gradient(linear, top left, bottom left, from(#eee), color-stop(50%, #ccc), to(#aaa)); background-image: -webkit-linear-gradient(#eee, #ccc 50%, #aaa); background-image: linear-gradient(#eee, #ccc 50%, #aaa); } .gradients-keyword { background-image: -webkit-gradient(linear, bottom right, top left, from(#eee), color-stop(50%, #ccc), to(#aaa)); background-image: -webkit-linear-gradient(bottom right, #eee, #ccc 50%, #aaa); background-image: linear-gradient(to top left, #eee, #ccc 50%, #aaa); } .gradients-angle { background-image: -webkit-linear-gradient(60deg, #eee, #ccc 50%, #aaa); background-image: linear-gradient(30deg, #eee, #ccc 50%, #aaa); }
おお、ちゃんと-webkit-linear-gradient()
(iOS 6まで)と-webkit-gradient()
(Gingerbread用)に対応して、あとは接頭辞なしの物を使うようになっている。キーワードの変換も、角度の変換も、どちらもちゃんとできてるし、角度が使えない -webkit-gradient()
については、ちゃんと無視されている。すばらしい。
ただ、IE9用にSVGのフォールバック画像をつくったり、IE8以下用にフィルタをつけてくれたりはしないようだ。hacks/gradient.coffeeなるファイルがあったので見てみたけど、そういう処理はなさげ。ふーむ。とはいえどちらも完全なハックだし、IE9は順調にIE10に置き換わってるようだし、IE8以下は「もうプレーンでよくない?」って言え…ないかな……
要らないものを消してもくれる
さて、ある程度試したところで、つけたすだけじゃなくて、要らないものを省いてくれることに気づいた。なんと。ではさっそく。
.so-200x { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
結果。
.so-200x { border-radius: 5px; }
おおお。すっきりした。じゃあCompassから出力されたものも、それなりに綺麗にしてくれるのかも。
「ポスト」のよしあし
結構よさげ。仕様のとおりに書いとけばあとは勝手にやってくれるので、簡単なmixinさえ書く必要がない。仕様に変更があっても、あたまの良い人達がきっとすぐ対応してくれるだろうし、すこし複雑なmixinとかも書かなくてもいい。いったいぼくのあの日々はなんだったんだ。
あとは、ポストプロセッサなので、特定のプリプロセッサに依存しないのもよい。プリプロセッサを乗り換えるってことはそんなないだろうけれど、それでもポータビリティは上がるかなと。
とはいえ、ポストプロセッサなところが弱点でもあるかと。主に開発時に面倒に感じることが多そう。
たとえば、プリプロセッサとの併用。Chrome+Sassな環境なら、Source Mapsやデバッグ用の出力モードで、CSSパネルからSassを参照できる。ただ、ポストプロセッサが入ってしまうとマッピングがずれてしまう。Autoprefixer側でプリプロセッサが生成したSource Mapsを解釈して、新しいマッピングファイルを作ってくれればよいのだけど、まだ対応されてない。
あとは、どうやら接頭辞つきのみのコードに、接頭辞なしのものを含めてくれるわけではないみたい。となると、たとえばChromeでアニメーションのコードを書いているときは、@-webkit-keyframes
しか書かないことがほとんどだと思うけど、そこから@keyframes
は生成されない。でもCSS Animationsの接頭辞が省かれるのはだいぶ先だろうし、でも開発中は接頭辞必要だろうし…というジレンマに陥る。
となると、開発中は接頭辞つき、展開時は接頭辞なしのものを吐き出すようにプリプロセッサやツール周りで対応…とかややこしいことになる。接頭辞はだいぶ減ってきたとはいえ、まだまだお世話?になると思うので、ここはなんとかして欲しいなあ。
もいっこ。CSSをパースして処理する関係上、インデントやらが独自のものにされてしまう。これは展開時にCSSOなりして再処理が走るなら、そんな気にならないだろうけど。
Shareいろいろ
思いつくままに書いてたらほぼWeb関係なくなった……まいっか。
Firefox for AndroidのShareメニュー
Firefox 24 for Android (現在Beta) で、メニューの“Share”アイテムの横に、頻繁にシェアする先が並んで出るようになった。
これ便利。これまでだと、メニュー押して、Share押して、シェア先を選んで、と3ステップだったけど、よく使うのを選ぶなら2ステップになる。ぼくの環境だと、Share押してシェア先一覧のダイアログが出てくるまでにけっこう時間がかかるので、ダイアログが開かなくなるのもプラス。
このポストを書いたSriramさんは、どうやらFirefox for AndroidのUI周りをやっているようで、overdrawについて、Viewの削減と、Androidのパフォーマンスまわりの記事なども書いている。Androidわかんないけど読んでて面白かった。
Chrome for Androidの引っ張るメニュー
そういえば、Chrome for Androidも、いちおう2タップライクにShareできる。chrome://flagsから、“Enable draggable menu button”を選ぶと、左上のメニューを下に引っ張りだすようにできる。なのでShareメニューまではいちおう1タップになる。Chrome 30 Betaでデフォルトで有効になったので、Beta使ってるなら設定不要。
横から引っ張りだすUIは増えてきたけど、三点メニューを引っ張りだすのには出くわしたことがなかった。でも使うと便利だし、標準になったりしないだろうか。
Shareアイコンとトレードマーク
Shareアイコン、プラットフォームごとに特徴がある。iOS, OS Xはボックスから矢印が右向きににょっと飛び出しているやつ(新規ウインドウで開くやつっぽいよね)、Androidは3つの点がくの字に配置されてて線でつながってるやつだ。Windows 8は雷神様のうしろにある太鼓みたいな感じ(Developer Preview時はOpen Share Iconとほぼ同じものだったけど変わった)。
“Share”や「シェア」「共有」をアイコンにするのって難しいね。Appleはシェアをするために起こすアクションを、Androidは情報の拡散っていう意味を抽象的に、Windowsはシェア後の状態(共有している)を表してるように見える。何をどうみてるのかが違って面白い。
それで、先日Font Awesomeを眺めてて、Androidのアプリで使われるShareアイコンがないのが気になった。
なんでだろうと思ってIssuesをたどってみたら、どうやらこのアイコンの権利を有してるShareThisというところがアイコンのライセンスを変えたらしく、それで追加をあきらめたと。あらなんと。
Wikipediaのページで過去のアーカイブが紹介されてたので見てみると、昔はGPL, LGPL, BSD, CC-BYでライセンスされてたらしい。この時代のを持ってきていじることはダメなんだろうか。
Google+は右向きのにゅっとした矢印(Appleのからボックスがなくなった版)を使ってたりする。Androidのも今後変わったりするんだろうか。
Webはlossy+alphaを手に入れられるのか
Chrome Canary(今のところM30)でアルファチャネル付きWebMが実験的にサポートされたとのこと。
ビデオ見ると妙な気味悪さがあって面白い。ドラッグ&ドロップしたり背景変えたりね。静止画だとふつうにできてたことが動画でもできると、世界広がるんだって思った。映像つくるの大変そうだけど。
って、これ静止画でもまだできてないのか。少なくともWebには、非可逆圧縮+アルファチャネルがないんだった。というわけで、ちょっと思い出したことを書こうかと。
非可逆圧縮+アルファチャネル
Webで透過する画像フォーマットといえば、GIFかPNGになる。どちらも可逆圧縮なので、写真みたく色数が多くなりがちなものには適さないとされている(GIFは色数にけっこうな制限もあるし)。Web開発でも多分長らく、「写真はJPEG」とされているはず。
ただ一部を透過させた写真を作りたいとき、JPEGだと透過させられない。でも、使いたいことって、けっこうあるんじゃないかなあ。
ワークアラウンドとしては、重ねたい背景を含めた写真として切り出す、切なくなりながら透過PNGで書きだす、とかだろうか。前者は背景と固定しないといけないし使い勝手が悪い。後者はファイルサイズが大きくなる。
ただ、他に方法がないので、透過PNGを使っているケースがある。たとえばApple。製品ページで、製品画像(写真)を透過PNGにしている。ただ、やはりいい方法ではないと思っていたのか、製品画像とマスク用の透過PNG画像を用意しCanvasで合成する、なんてこともやっていた。すごい。でもこういう、スマートさが求められる状況はどうにかならないものか。
非可逆圧縮でアルファチャネルを持つ画像フォーマット、その中でWebに近めなのが、JPEG XRとWebPだろう。
JPEG XR
JPEG XRは、MicrosoftがWindows Media Photoとして開発して、HD Photoと名前変えて、それをJPEG(グループの方)と組んでJPEG XRにして、ITUに提出して、ISOにも提出して標準にしたっていう、がんばった規格。
機能としては、アルファチャネルのほか、圧縮率とか色とかハイダイナミックレンジとかそこらがよくなっているらしい。あと可逆圧縮もできるようになったと。すごい。
Microsoftがつくった規格なので、新しめのWindowsでは当然サポートしている。Internet ExplorerもIE9からサポートしている。IE9+べったりな環境であれば、もう使える。そんなのがあるのかは知らない。
他のエンジンはどうだろう。まずBlink (Chrome) では2010年にissueが上がったけれど、とくにChromiumな人からの反応はない。マイルストーンもX(未定)にされている。JPEG XR is a <strong>standard<strong>
なんてコメントがあるけれど、MNGとかJPEG 2000とかについても言ってあげなよ(´ー`)…
続いてWebKit。2010年末のメールによると、画像のデコーダがプラットフォームごとによって違うことや、Mozillaの動向が読めないなどを挙げて、すぐにサポートすることはないと見解を出している。書いてるのがChrome teamのEric Seidelなので、Blinkでも同じような話になるのだろうか。
ではMozillaはどうか。過去の議論を見ると、もうちょっと突っ込んだ話になっている。
Bugzillaでは、公開されているライブラリのソースコードについてライセンス・特許に関する懸念が示されている(過去にJPEGについてあったらしい特許係争を回避する目的で含まれてると推測されている)。あとは、リファレンス実装のパフォーマンス(試したらlibjpegの10倍遅かったらしい)やセキュリティに対する懸念もあると。
mozilla.dev.platformでは、2011年のTPACにてMicrosoftからMozillaにコンタクトがあったことから議論が始まっている。ライセンスに関する懸念は引き続き課題として出ているものの、MicrosoftがJPEG XRをWebの新しいフォーマットにしたいという思いがあることもあって、なんとかなるんじゃないかという意見が見られる。とはいえクリアにはなってない模様。
機能的なところでは、Mozillaのgraphics teamが興味を示していた。また、ゲームや3Dにおいて非可逆圧縮+アルファチャネルへの需要があるという話も見られる。
機能として需要はあるけれど、今ある実装がまだ使えないという状況なのかな。ただライセンスについては、今年の4月にBSD Licenseのもと公開されたようなので、上で話されていた頃とまたちょっと状況が違うのだろうか。
WebP
で、WebP。Googleが開発しているフォーマット。RIFFの中にVP8を入れたものらしい。知らなかった。
初期は非可逆圧縮だけだったんだけど、2012年に可逆圧縮とアルファチャネルも追加された(可逆圧縮はVP8の派生版を使うらしい)。今年春にはアニメーションやカラープロファイル、メタデータの機能も付加されて、とりあえずどんな画像についてもWebPを使えるようになったとアピールしている。
サポートはもちろんChromeと、Ice Cream Sandwich以降のAndroidブラウザ(可逆圧縮はJelly Beanかららしい)。あと、OperaもPresto時代からサポートしている。Opera Miniで使っているのだろうか。
追記 (2013-08-01): Opera Turboで使ってるというコメントをいただく。ありがとうございます。
他のブラウザではどうか。IE, WebKitは察してもらうとして、Mozillaはどうか。関連するバグは2つ立てられている。
最初に立てられたバグでは、アルファチャネル、メタデータ、カラープロファイルがサポートされていなかったこと、仕様自体が進展中なことを挙げ、前向きではなかったよう。その後、妥当なユースケースと利点があったというわけで2つ目のバグが立てられた。2つ目のバグは…ええと…外野がうるさくてなにが問題になっているのか、なにが進行を妨げているのかわかんない……外野も含めて「コミュニティ」なのだとしたらなかなか美しいね……
JPEG XRに見られた、ライセンスやライブラリの品質については特に触れられていないように見える。Googleが自身の製品にすでに使っているし、VP8もロイヤリティフリーだから、実際に組み込むにあたって、とくに懸念はないということなのかな。
書いたらなんかMozillaがキャスティングボートを握ってる感じになっちゃったけど、Webでのサポートを考えると、非可逆圧縮+アルファチャネルが使えるまでにはまだまだ遠そう。
フォーマットの圧縮率とか品質の優劣、カメラやソフトウェアのサポートなんかを取り上げるとキリがないので置いてく。いま実現できていないものがあって、それがなんとかできないのが問題なんだ。そしてとてもやるせない。
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に入るわけではないのかな。
とっちらかってきた……もう一本書こうか……