16:18去年の9月ごろに書いていたのだけど、ほかに書くことを書いて順を追って公開しようと思っていたら寝かせすぎた...。msWWAがMSAppにかわってたりしたのでその辺を修正して公開。10が持つ機能でローカルアプリケーションを実装できます。ローカルアプリケーションとして動くということで通常のブラウザの機能だけでなくネイティブの機能を利用できるようになっています。それと同時に仕様やセキュリティ上の理由で一部の機能に制限がもうけられています。appでは新規ウィンドウ作成、ウィンドウ位置変更など各種ウィンドウ操作は行えません。ウィンドウ操作にはダイアログも含まれます。具体的には以下のメソッドが影響を受けます。alertpromptopenmovebymovetoresizebyresizetoだだし例外的にアプリケーションからはwindow.closeは実行できます。window.closeはアプリケーションの終了と同じですが基本的には使うべきではないとされています。利用すべき場面は復帰できないエラーが発生した場合に強制終了するといった使い方です。javascriptスキームa要素のjavascriptスキームは動作しないようになっています。これはあまり困りませんね。解決策DOMのclickイベントや直接書きたい場合にはonclick属性を利用するように書き換えます。HTMLを渡して出力したり要素を生成したりできます。appの場合にはinnerHTMLなどに渡すことのできるHTMLに制限がかかります。以下のようなコードを実行しようとします。false);</script>すると実行時に以下の例外エラーが発生します。useこれはinnerHTMLなどのプロパティやメソッドに渡すことのできるHTMLはセキュリティ上静的なもの(安全なもの)となっていることが求められているためです。静的でないHTMLというのはscript要素やonなんとか属性、form要素などのスクリプト等の動的な要素をふくむもののことです。いうscript要素をはじめとして動的・未知の要素・属性をサニタイズをするメソッドを通るものです。titleにそのリストがあります。svg要素なども通らないので注意が必要です。この制限は外部からデータを読み込んでそのままアプリケーションに流し込んだ際、悪意あるスクリプトを実行してしまうのを防ぐためにあるものと思われます。appはローカルアプリケーションなのでコンピュータへのアクセスが行えるようになっていて、たとえばファイルを操作するようなスクリプトを含んだHTMLをinnerHTMLで差し込んでしまうとそのローカルアプリケーションの一部として実行されて困ったことが起こる、といった感じですね。innerHTML以外にも以下のメソッドやプロパティにこの制限のかかっています。document.createElementを利用するinnerHTMLなどを使わずcreateElementで要素を作ってごく普通に内容をセットしていく方法です。この場合自前でHTMLをパースしない限りは悪意あるスクリプトを取り込んでしまうことはなくなります。逆に自前でHTMLをパースしてしまうと潜在的に危険なものも組み立ててしまう可能性があるので注意が必要です。window.toStaticHTMLを利用してサニタイズするinnerHTMLなどが受け取って安全とされるものはwindow.toStaticHTMLを通ることを許可されている要素や属性、ということなのでtoStaticHTMLメソッドを利用してサニタイズしてしまいます。href="#">Link</a>');document.body.appendChild(divE);toStaticHTMLで静的となったHTMLであればinnerHTMLにセットしてもエラーとならなくなります。安全ではない操作として実行する「安全ではない操作を実行する」方法も用意されています。これはinnerHTMLなどに安全ではないHTMLをセットしても動く、普通のIEと同様の挙動を実現する方法です。同様の挙動といっても「安全ではない操作」単位での実行となるのでコードを若干修正する必要があります。安全ではない操作の実行にはwindow.MSAppに存在するexecUnsafeLocalFunctionメソッドを利用します。execUnsafeLocalFunctionメソッドは引数に関数をとり、その関数を実行している間は各種のチェックが無効となります。以下のようなコードで動くようになります。false);</script>この方法は信頼されている、たとえばアプリケーションのローカルリソースを読み込んでのようなデータを差し込む場合にのみ利用すべきです。Studioなどテンプレートからアプリケーションを作った場合についてくるWinJSライブラリに以下のヘルパーメソッドとして用意されています。Previewで変更されて即座にエラーとなるようになりました。この制限のわかりにくいポイントの一つとして、要素がドキュメントに追加された際にエラーが発生するというところがあります。以下のコードで実際エラーが発生するのはdocument.body.appendChildのタイミングとなります。false);</script>innerHTMLをセットした瞬間ではないのでjQueryを使っている場合などjQueryの内部で突然エラーが発生して悩むことになることがあります。appsはHTMLで書けるの?という話。appsがHTMLとJavaScript「で」書けるようになるということについて、先日Twitterでも少し誤解されていたのでちょっとまとめ直してみます。実際書けるの?ざっくり整理するとこうなります。JavaScriptやHTML/CSSを使うなら全体をHTMLで書くしかないそこにXAMLを選ぶということはできないHTMLやCSSがWeb標準であるかというと大半のアプリケーションはそれでは済まないけれど、Web標準だけで書くこともできるちなみにここにはパッケージングが必要だとかそういう話は含めていません。いうわけで関連する技術を適当に図にしたのがこれです。Explorerのエンジンを置いて、上が普通のWebで使うことのできる技術、下がWindowsネイティブの技術です。いうわけですこし分解して見てみます。appsの前にブラウザで見る普通のWebページの場合を。ネイティブの機能は全くありません。appsに必要最低限な構成です。この場合最低HTMLが1ファイルあれば出来上がりです(ほかにも必要であればCSSとかJSとかとか)。この時利用する技術は普通のWebと同じレベル、いわゆるWeb標準としてあるものだけです。先行実装、ベンダー拡張とはいえちょっと高機能にしたい、表現力を上げたいなどという時にはブラウザに先行実装されていたり、ベンダーが独自に拡張したCSSやAPIを利用します。-ms-*プロパティとかですね。これも最近のWebの世界では-webkit-*とかよく使われているのでそれですね。この時点ではやっぱりまだ普通のWebとあまり変わりません。styleにしたくなります。色合いやコントロールなどです。JavaScript、WinJSとよばれるライブラリが提供されています。ライブラリと言いながらスタイルシートも含まれています。WinJSを使うようになるとこんな感じです。WinJSは色々な機能があり、必要なものだけを選択して(要するに.jsファイルの参照)使えるので取り敢えず見た目やベースライブラリだけを使う前提です。図をみるとわかりますがまだこの時点では拡張されたものも含めてWeb寄りの技術で構成されています。appsではUIコントロールにWinJS.UIというものを使いますが、その記述も実態もHTML5と(拡張された)CSSとJavaScriptで構成されています。書き方次第ではまだWebと共存できる可能性があります。WinJS.UIが他のベンダープレフィックスなどを考慮してくれることはないのでこの辺りから普通のブラウザと同じかどうかはだいぶ怪しくなります(IEでは動いてしまうけれどIEでしか動かない)。Runtime(WinRT)に頼ることになります。コンテキストメニュー、ページナビゲーション、アプリケーションのサスペンド、ソケット通信、ファイル操作といったローカルと密接なものたちなどです。WinJSも一部WinRTを知っているので、協調して動いたりラッパーになっていたりするものがあります。ここまで来て最初の図になります。ネイティブ機能を使うことになるのでもはやWeb技術だけではなくなります。appsとしては一般的な構成になるとおもわれます。Studioのテンプレートはこの形で吐き出します。8に依存したHTMLで書くことになるけれどブラウザと同じ形にしようと思えばできる、です。アプリケーションは最後のパターンになると思いますが、重要なのは1や2のパターンもアリだと言うことです。styleを必要としないアプリケーション、例えば全て独自のUIをもつゲームなどを作る場合には有利になるのではないかと思います。ちなみにWeb標準的なもので書こうと思えば書けるといってはみたものの、一部操作に制限があったりするのでWebのコードをそのまま持っていくと何らかの書き換えが必要になる場合がまれにあります。appsに依存して回避する書き方か制限を回避する推奨される別な手段での書き方に修正が必要です。Previewの仕様を元にしています。今後Betaやリリース時には変更される可能性があることに注意してください。スケーリングについて書きましたが、その拡大率が決定される条件がちょっと謎な感じに見えます。同じ画面解像度1920x1080でも10.6インチと23インチとで拡大率が違うわけです。Previewをインストールするとなぜかシステム解像度(以前からあるあのDPI設定)がデフォルトで120dpiになっています。appsはスケーリングしません。画面サイズ(物理的な画面サイズ)をWindows側で把握してコントロールしているような感じです。APIにVERTSIZE,HORZSIZEを渡すと取れそうなのですがいろいろなところでまともな値は返さない(物理サイズの参考にはならない)という声も見かけます。はいっても他に見当たらないのでコードを書いてとりあえず試してみました。1920x1080)で実行したところ530x300mmという値が返ってきました。29.89cmぐらいらしいのでだいたいあってそうです。1920x1080)で試してみると今度は290x160mmという値が返ってきました。動いているっぽいです。8からまともに機能するようになったようです。いうわけでこれをシミュレータで動かしたりして、さらにそのサイズからDPIを求めたりしてまとめたのが以下の表です。スレートと定義しているらしく(ガイドラインの一番上の図がそんな感じ)そこを基準にいろいろ決まっているようです。Zでは約170dpi前後ぐらいしかないので100%の域になるとなっていると推測できます。画面サイズで決定されるので拡大率にシステムのDPI設定は考慮されないことになります。これで画面解像度だけで拡大率が決まるわけではない理由がなんとなくわかりました。CSSのメディアクエリーで使われていた謎のdpi値MSDNのガイドラインでは以下のようなメディアクエリーの例が書かれていました(微妙に間違ってるので直してますけど...)。}}134dpi、135dpi、173dpiとありますがこれは100%を96dpiとしたときの値です。(173dpi)となります。Windowsは96dpiが標準解像度となっているのでそれが基準になっているのですね。三つ目はmin-resolution:173dpiなので180%の時の173dpi以上に適用されることになるわけです。appsではwindow.screen.deviceXDPIとして取得できます。WinRTを経由してもWindows.Graphics.Display.DisplayProperties.LogicalDpiプロパティを使うことで取得できます。180%の時の値が違います。deviceXDPIは173を返しますがLogicalDpiは174を返します。MSDNのメディアクエリーの例に174dpiと書いてあったのはWinRTの値が元なのではないかと思います。実際ダウンロードできるサンプルコードの方では173dpiになっています。計算しても違うわけですしWinRTのバグのような気がします。いうわけでスケーリング周りを調べたらなかなかややこしかったですという話でした。Previewの仕様を元にしています。今後Betaやリリース時には変更される可能性があることに注意してください。Display対応といった風にアプリケーションが対応しているのを見かけるようになりました。8(コードネーム)はこれからリリースされるOSですのでそのあたりも考慮されています。title)があるのでちょっと解説してみます。appsでは解像度と画面の物理サイズによって100%,140%,180%と3段階の拡大率を持ち自動的に適用されます。拡大というのはブラウザの拡大みたいなものです。10.6インチの1366x768では拡大なしですが、同じ物理画面サイズで1920x1080の場合には140%に拡大されるといった感じです。同じ1920x1080でも10.6インチ(スレートサイズ)と23インチ(デスクトップ)では解像度(DPI)が違うので拡大率も違ったりします。10.6インチ/2560x1440アプリケーションですべきこと自動的に拡大されると書きましたが、ただ拡大するだけではキレイになるとは限らないのでアプリケーション側での対応も必要となります。title)によれば以下のことをするようにと書かれています。スケーラブルなベクターグラフィックスを使う解像度非依存なベクター画像を使いましょうという話です。ベクター画像であれば伸び縮みさせてもジャギジャギしたりもやもやしたりしません(Windowsがうまくレンダリングします)。HTMLでアプリケーションを作る場合にはSVGを、C#などで作る場合にはXAMLを使うことで実現します。アプリケーションパッケージからビットマップ画像を読み込むビットマップ画像(JPEG,PNGなど)に特定のルールに従って名前をつけておくと自動的に拡大率の状態に応じて読み込むファイルを変える機能があります。この機能によって拡大率の違いによってサイズの違う画像を読み込むことができます。なく以下の拡大率によってバリエーションも参照されます。して分けるか好きな置き方を選ぶことができます。これはHTMLからの参照だけでなくCSSからの参照(たとえばbackground-imageプロパティ)も対象となります。外部の画像を参照する場合はメディアクエリーを使う外部つまりリモートにある画像を参照する場合には拡大率によって自動でバリエーションを検索する機能は動作しません。appsでCSSから参照する場合にはメディアクエリーで解像度に応じて読み込む画像を切り替えます。MSDNにある例だと以下のようなCSSになっています。}}min-resolution/max-resolutionの値が謎のdpiになっている理由は別に書くことにしますが、メディアクエリーのパターンとしては謎のdpiの指定も含めてこのようになります。ユーザーの画像をファイルシステムから取り出すときにはサムネイルAPIを使うユーザーが持っている画像を動的に読み出して使う場合にはWinRTにあるサムネイルAPIを使います。サムネイルAPIはWindowsが現在の拡大率に最適な画像を返します。サムネイルAPIというのはWindows.Storage名前空間にあるStorageFileクラスが持つ、GetThumbnailAsyncメソッドのことです。StorageFileクラスはフォルダなどから参照したときにとれるものです(よくあるFileクラス的なもの)。title画像を実行時に読み込む場合には拡大率をみて読み込むJavaScriptなどから動的に画像を読み込む場合にはコードで現在の拡大率によって画像の参照をコントロールする必要があります。現在の拡大率はWindows.Graphics.Display.DisplayPropertiesクラスのResolutionScaleプロパティを参照することで得ることができます。break;}画像には幅と高さを指定する拡大率で読み込む画像が変わったりした場合にレイアウトが崩れるのを防ぐため、画像には幅と高さを指定するようにします。グリッドをつかう要するにメジャーなグリッドを20px、マイナーなグリッドを5pxずつとして画面を設計することで拡大した場合にも中途半端な値(たとえば23px*1.4倍=32.2pxに対して25px*1.4倍=35px)にならずピクセルの丸めとズレのようなものが発生しなくなってきれいです。アプリケーションでしてはいけないことスケーリングを考慮する上で逆に避けるべきこともガイドラインには書かれています。スケーリングが必要な場合自動的に拡大されてぼやけた見た目になることになります。いうことで画像は各拡大率にあわせたものを用意しておきましょう。4で実行したようなことになるのでという話です。大きい画像を小さくして使うこと小さい画像を高解像度で使うのと逆に、高解像度用の画像を低い拡大率で使うと縮小するとジャギジャギしてしまうので避けましょう。180%のパターンだけ用意してそれを140%と100%でも使い回す、といったことです。例外的に写真の画像は縮小しても見た目上問題ないのであればよいでしょう。5pxの倍数以外でサイズを指定すること上にも書きましたが5pxの倍数以外でサイズを指定すると拡大したときにズレが生じてしまいますので避けましょう。スケーリングの状態を試すスケーリングの仕組みが用意されていてもどうやってテストすれば?となるわけですが、シミュレータには解像度と画面サイズを想定した設定が用意されていてこれでテストすることができます。参考までに設定時の状態を以下にまとめておきます。16:09今度はズーム系で拡張されているプロパティについてです。ズーム周りはまだ挙動が怪しかったり、まともに動かなかったりしますが一応。タッチ前提のものなのでいくつか動画をつけておきます。実際に試したサンプルもおいておきます。Previewという名の通りベータでもないので今後変更される可能性は大きくあるのはご注意ください。-ms-content-zoomingそのスクロール可能な要素でズームを許可するかどうかのプロパティです。meta要素で指定するviewportのuser-scalable=noと同じような効力がありますが、CSSのプロパティなのでbody要素以外にも適用できるのがちょっと違います。要素に対する指定はデフォルトでnone(ズーム非許可)ですが、body要素のみズームが許可されています。これをnoneにすることでページのズームを抑止できます。noneズームを許可しませんzoomズームを許可します-ms-content-zoom-boundary拡大率の最小値、最大値を指定するプロパティです。-ms-content-zoom-boundary-min/-ms-content-boundary-maxの短縮です。値は拡大率なのでパーセント(%)をとります。-ms-content-zoom-chainingズームが境界(つまり拡大率の最大・最小)に達したとき、親要素に処理が続くかどうかを指定するプロパティです。-ms-scroll-chainingのズーム版です。none境界に達していてもはねるエフェクトがみえるだけで親要素に続きませんchained境界に達して、さらに拡大縮小を行うと一番近い親の要素がズームします-ms-content-zoom-snap-typeズームしたとき拡大率がスナップするかどうかを指定するプロパティです。スナップする値は-ms-content-zoom-snap-pointsプロパティで指定できます。これらのプロパティを指定すると拡大率の刻みを指定できると思うのですがうまく動いていないのでよくわかりません。noneスナップの指定は利用しませんmandatory強制的に一番近いスナップポイントに合わせますproximityズームした後とても近いスナップポイントがあればそこに合わせます-ms-content-zoom-snap-pointsズームの拡大率のスナップする値を指定するプロパティです。今のところ動かし方が間違っているのか変な動きになってしまいます。step<length>)パーセントで刻みを指定しますsnapList(list<lengths>)パーセントでスナップ位置を指定します-ms-content-zoom-snapms-content-zoom-snap-typeと-ms-content-zoom-snap-pointsの短縮系です。-ms-zoom-animation拡大率が変わるときにアニメーションをするかどうかを指定します。今のところ指定しても特に何か変わって見えません。プロパティ(JavaScript)現在の拡大率を取得できるプロパティです。値は0.0から1.0(等倍)、2.0(2倍)のようになります。8ではHTML+JavaScriptでネイティブ機能を使ったアプリケーションを開発できるようになるわけですが、どんな仕組みになっているのか調べたので簡単に書いてみようと思います。はじめはWinRTとは...WinMDが云々...といった感じで細かく書こうかと思ったのですがややこしいので(まとめてると調べるのが終わらない)おおざっぱに、です。Previewという名の通り今後変更される可能性は多いにあるのでそこはご理解とご協力とお察しください。UIに対応したアプリケーションのみで、従来型のデスクトップアプリケーションを作ることはできません。appのことはまれにImmersiveアプリケーションと呼ばれたりします。"Immersive"は「没入型の」ということですね。8のブログにしばしば出てきますし、APIの名前などは大体MetroではなくImmersiveと書かれています。appはHTML+JavaScriptであろうと、C++であろうと、C#であろうと...WinRTと呼ばれるWindowsの新しいAPIセットの上で動きます。APIも(一部を除いて)利用できません。appを作れるということですがどんな形で動くのかというとこんな感じになっています。HTML+JavaScriptでアプリケーションが作れて動く、といったところでいきなりWindowsが直接解釈できる実行形式になるわけではありません。ExplorerのTrident(レンダリングエンジン)とChakra(JavaScriptエンジン)が組み込まれています。WWAHost.exeがHTML+CSS+JavaScriptを読み込んでレンダリングエンジンとJavaScriptエンジンを使ってアプリケーションとして動かすという形になっています。mshta.exeとかちょっと懐かしいですね(ほろり。Explorerのエンジンを組み込むだけでなく、JavaScriptエンジンと協調してWinRTのクラスライブラリをJavaScript側へ公開してくれます。その結果JavaScriptからWinRTつまりWindowsのネイティブな機能などを扱うことができるようになっているという感じです。windowオブジェクト(グローバル)にWindowsなどが生えていて、Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(...)といった感じで呼び出すことができるようになっています。アプリケーションの構成的はだいぶおおざっぱですがこんな感じですね。これに加えて周辺技術にWinRTをはじめとしてパッケージングのAppXやWinJSなどがあるのですがまあそれはまた後で書くかもしれません。Runtime(WinRT)というAPIというかライブラリが提供されています。WinRTはファイルやデバイス、ネットワークなどへのアクセスといった様々なOSネイティブな機能をオブジェクト指向的に整理して構築し直したものです。ネイティブライブラリでありメタデータを持つ規約のようなものでもあるので、C++やC#、JavaScriptなどさまざまな言語に公開できるようになっているのが特徴です。Runtime)のような仮想マシン実行環境を持っていません。その意味では実装形態は問わずさまざまな言語から使うことを考慮した点など従来のCOMにだいぶ近いものといえそうです。ExplorerzshWebKitMetroWinRTWinJSリンクMisuzilla.orgぷろじぇくと、みすじら。