1. はじめに
このセクションは規範的ではありません。
現在、HTMLVideoElement
を
ピクチャインピクチャウィンドウ(requestPictureInPicture())に表示するためのWeb
APIが存在します。このため、ウェブサイトはカスタムのピクチャインピクチャ体験(PiP)を提供する能力が制限されています。
この機能を拡張し、ウェブサイトが常に最前面に表示されるウィンドウ上で完全なDocument
を提供できるようにしたいと考えています。
この新しいウィンドウは、既存の open() メソッドを使って開かれる、同一オリジンの白紙ウィンドウに似ていますが、いくつかの違いがあります:
-
PiPウィンドウは他のウィンドウの上に浮かびます。
-
PiPウィンドウはオープニングウィンドウより長く存続することはありません。
-
ウェブサイトはPiPウィンドウの位置を設定できません。
-
PiPウィンドウは遷移できません(`window.history`や`window.location`を使って新しいドキュメントへ変更するとPiPウィンドウが閉じます)。
2. 依存関係
この仕様に記載されたIDL断片は、Web IDL仕様で定められた通り、適合するIDL断片として解釈される必要があります。[WEBIDL]
3. セキュリティに関する考慮事項
3.1. セキュアコンテキスト
このAPIは [SECURE-CONTEXTS] のみで利用可能です。
3.2. なりすまし
ユーザーエージェントは、DocumentPictureInPicture
ウィンドウ上に十分なUIを提供し、悪意のあるウェブサイトが他のウィンドウの上に表示される能力を乱用して他サイトやシステムUIのなりすましを防止することが求められます。
3.2.1. 位置指定
ユーザーエージェントは、ウェブサイトがウィンドウの位置を設定できないようにする必要があります。これにより、ウェブサイトが意図的にウィンドウを他ページのUIの一部と思わせる場所に配置することを防ぎます。特に、moveTo()
や moveBy()
APIは、ドキュメントピクチャインピクチャウィンドウでは無効化されなければなりません。
3.2.2. オリジンの可視性
ユーザーエージェントは、DocumentPictureInPicture
ウィンドウをどのオリジンが制御しているかを常にユーザーに明確に伝える必要があります。これにより、ユーザーはコンテンツの出所を認識できます。例えば、ユーザーエージェントはウィンドウのタイトルバーにウェブサイトのオリジンを表示することが考えられます。
3.2.3. 最大サイズ
ユーザーエージェントは、常に最前面に表示されるウィンドウでウェブサイトが画面全体を覆いユーザーをピクチャインピクチャウィンドウに閉じ込めることを防ぐため、ドキュメントピクチャインピクチャウィンドウの最大サイズを制限すべきです。これによりユーザーのデスクトップのなりすましも防止できます。
3.2.4. 全画面表示
ユーザーエージェントは、文書のピクチャーインピクチャーウィンドウが全画面表示に入ることを、最大サイズの制限と同じ理由により防がなければならない。特に、これは
requestFullscreen()
API を、ドキュメントのピクチャーインピクチャーウィンドウ内のすべての要素で無効化しなければならないことを意味する。
3.3. IFrame
このAPIは 最上位トラバーサブル でのみ利用できます。ただし、DocumentPictureInPicture
Window
には HTMLIFrameElement
を含めることができ、
クロスオリジンの HTMLIFrameElement
も利用可能です。
4. プライバシーに関する考慮事項
4.1. フィンガープリント
PiPウィンドウを閉じてから後で再度開いた場合、前回のPiPウィンドウのサイズや場所を再利用することでユーザー体験を向上できることがあります。しかし、ユーザーエージェントは異なるオリジン間でサイズや位置を再利用しないことが推奨されます。これは悪意のあるウェブサイトによるフィンガープリントの手段となる可能性があるためです。
5. API
[Exposed =Window ]partial interface Window { [SameObject ,SecureContext ]readonly attribute DocumentPictureInPicture documentPictureInPicture ; }; [Exposed =Window ,SecureContext ]interface :DocumentPictureInPicture EventTarget { [NewObject ]Promise <Window >requestWindow (optional DocumentPictureInPictureOptions = {});options readonly attribute Window window ;attribute EventHandler ; };onenter dictionary { [DocumentPictureInPictureOptions EnforceRange ]unsigned long long = 0; [width EnforceRange ]unsigned long long = 0;height boolean =disallowReturnToOpener false ;boolean =preferInitialWindowPlacement false ; }; [Exposed =Window ,SecureContext ]interface :DocumentPictureInPictureEvent Event {(constructor DOMString ,type DocumentPictureInPictureEventInit ); [eventInitDict SameObject ]readonly attribute Window ; };window dictionary :DocumentPictureInPictureEventInit EventInit {required Window ; };window
DocumentPictureInPicture
オブジェクトは、ウェブサイトが新しい常に最前面の
Window
を作成・開くこと、そしてその Window
の開閉に関連するイベントを監視することを可能にします。
各 Window
オブジェクトは、関連付けられた documentPictureInPicture API
を持ちます。これは DocumentPictureInPicture
の新しいインスタンスであり、Window
の作成時に同時に生成されます。
documentPictureInPicture ゲッタの手順は:
-
this の documentPictureInPicture API を返す。
各 DocumentPictureInPicture
オブジェクトは、関連付けられた
last-opened window(最後に開かれたウィンドウ)
を持ちます。これは
Window
オブジェクトであり、初期状態では null です。
これは requestWindow() メソッドの手順の一部として設定されます。
window ゲッタの手順は:
-
win を this の last-opened window とする。
-
win が
nullでなく、かつ win の closed 属性がfalseであれば、win を返す。 -
nullを返す。
requestWindow(options) メソッドの手順は:
-
Document Picture-in-Picture サポート が
falseの場合、 "NotSupportedError"DOMExceptionをスローする。 -
this の relevant global object の navigable が トップレベルの traversable(走査可能)でなければ、 "
NotAllowedError"DOMExceptionをスローする。 -
this の relevant global object の navigable の Is Document Picture-in-Picture ブール値が
trueの場合、 "NotAllowedError"DOMExceptionをスローする。 -
this の relevant global object が transient activation(一時的なアクティベーション) を持っていなければ、 "
NotAllowedError"DOMExceptionをスローする。 -
もし options["
width"] が存在し、値が0より大きいが、 options["height"] が存在しない、または0の場合は、RangeErrorをスローする。 -
もし options["
height"] が存在し、かつ値が0より大きいが、 options["width"] が存在しないか0の場合は、RangeErrorをスローする。 -
win を this の last-opened window とする。win が
nullでなく、かつ win の closed 属性がfalseなら、 close win の navigable を。 -
ユーザーエージェントは 既存のピクチャーインピクチャーウィンドウを閉じる こともできる(任意)。
-
pip traversable に 新しいトップレベル traversable を作成 の結果をセットする。引数として this の relevant global object の navigable の アクティブな browsing context と "
_blank" を使う。
生成される Document
の URL は `about:blank` ですが、
文書のベース URL は requestWindow()
を呼び出した発信者のものをフォールバックとして使用します。
一部ブラウザは通常の `about:blank` ポップアップにはこのフォールバック動作を実装していません。
議論は whatwg/html#421 を参照。
実装者は、ドキュメントピクチャーインピクチャーウィンドウについては指定どおり継承させ、
さらなる互換性問題を避けるよう推奨されます。
-
pip traversable の アクティブなドキュメント の mode を this の relevant global object の 関連付けられた Document の mode にセットする。
-
pip traversable の Is Document Picture-in-Picture ブール値を
trueにセットする。 -
もし options["
width"] が存在し、値が0より大きいなら:-
必要に応じて、options["
width"] が大きすぎる/小さすぎる場合はユーザーフレンドリーなウィンドウサイズに収まるように丸めたり無視してもよい。 -
必要に応じて、pip traversable の アクティブな browsing context のウィンドウのビューポート左右端間距離を options["
width"] ピクセルにしてもよい。
-
-
もし options["
height"] が存在し、値が0より大きい場合:-
必要に応じて、options["
height"] が大きすぎる/小さすぎる場合はユーザーフレンドリーなウィンドウサイズに収まるように丸めたり無視してもよい。 -
必要に応じて、pip traversable の アクティブな browsing context のウィンドウのビューポート上下端間距離を options["
height"] ピクセルにしてもよい。
-
もし options["preferInitialWindowPlacement"]
が存在し true なら、ユーザーエージェントはこのヒントに従い、以前閉じた pip traversable
ウィンドウの位置やサイズより、手順13・14類似の動作を優先してもよい。
-
もし options["
disallowReturnToOpener"] が存在しtrueなら、ユーザーエージェントは ピクチャーインピクチャーウィンドウ上で、 ユーザーがオープナーウィンドウへ戻る操作UIを表示しないようにすべきである。
ビデオ・ドキュメントピクチャーインピクチャーの両方で、ユーザーエージェントはよく
「元ページに戻る」ボタンやピクチャーインピクチャーウィンドウを閉じる
ボタンを表示します。この操作は大抵妥当ですが(特にビデオPiPでは元ドキュメントに
ビデオを戻します)、ドキュメントPiPウィンドウではそうとは限りません。
disallowReturnToOpener
は、ウェブサイト側からユーザーエージェントへの
「このドキュメントPiP体験ではそのアクションは妥当か否か」のヒントです。
-
pip traversable の アクティブな browsing context のウィンドウを 他のウィンドウの上にフロートさせるよう構成する。
-
this の last-opened window を pip traversable の アクティブなウィンドウ に設定する。
-
グローバルタスクをキューイングする。 DOM 操作タスクソース上で、 this の relevant global object で イベントを発火する。 イベント名は
enterであり、DocumentPictureInPictureEventを使い、 this で、 そのwindow属性に pip traversable の アクティブなウィンドウ をセットして。 -
Promise を resolve し、 pip traversable の アクティブなウィンドウ を返す。
ウィンドウのサイズはウェブサイト側で設定できるが、初期位置はユーザーエージェントの裁量に委ねられる。
enter-
PiP ウィンドウが開かれたとき、
DocumentPictureInPicture上で発火される。
6. 概念
6.1. ドキュメントピクチャインピクチャのサポート
各ユーザーエージェントは ドキュメントピクチャインピクチャサポート 真理値を持ち、その値は 実装依存(ユーザーの設定によって変化する場合がある)です。
6.2. DocumentPictureInPicture ウィンドウ
各 トップレベル traversable は、「ドキュメントピクチャーインピクチャーかどうか」
というブール値を持つ。この値はデフォルトでは false であるが、requestWindow() メソッドの手順中で
true に設定されることがある。
ユーザーエージェントは、最小化されたウィンドウや他の理由でユーザーに表示されていないウィンドウでは、レンダリングを停止したりスクリプトの実行頻度を下げたりすることが一般的である。ドキュメントピクチャーインピクチャーウィンドウが開いている場合、オープナーウィンドウが実行するスクリプトが、ドキュメントピクチャーインピクチャーウィンドウ内のコンテンツへ影響を及ぼすことがある。
実装者はこのようなオープナーウィンドウをスロットリングする影響を検討することが推奨される。また、開発者はピクチャーインピクチャーウィンドウ自身の中でアプリケーションロジックを実行することが推奨される。
6.3. ドキュメントピクチャインピクチャウィンドウの閉じ方
これに十分なコンセンサスが得られたら、 definitely close に統合すること。
definitely close の 手順2 "If the result of checking if unloading is user-canceled for toUnload is not "continue", then return." を次のように変更する:
-
もし traversable の Is Document Picture-in-Picture ブール値が true なら、このステップをスキップする。そうでなければ アンロードがユーザーによりキャンセルされたかの確認 を toUnload で実行した結果が "continue" でなければ、return する。
6.4. 既存のPiPウィンドウを閉じる
既存のピクチャインピクチャウィンドウを閉じるには:
-
ユーザーエージェントの 最上位トラバーサブル集合 の各 top-level traversable に対して:
-
もし top-level traversable のドキュメントピクチャインピクチャかどうか真理値が
trueなら、close top-level traversableを実行。 -
もし top-level traversable のactive documentのpictureInPictureElement が
nullでなければ、ピクチャインピクチャ終了アルゴリズムを top-level traversableのactive documentに対して実行。 -
top-level traversable のactive documentの子孫ナビゲーブル各 navigable に対して:
-
もし navigable のactive documentのpictureInPictureElement が
nullでなければ、ピクチャインピクチャ終了アルゴリズムを navigableのactive documentに対して実行。
-
-
6.5. PiPウィンドウは1つだけ
どの最上位トラバーサブルも同時に開いているドキュメントピクチャインピクチャウィンドウは最大1つでなければならない。最上位トラバーサブル でそのactive windowのdocumentPictureInPicture APIのlast-opened windowがnullでなければ、
さらにドキュメントピクチャインピクチャウィンドウを開こうとしたとき、ユーザーエージェントは既存のlast-opened windowをrequestWindow()メソッドの手順に従い閉じなければならない。
ただし、全最上位トラバーサブルでピクチャインピクチャモードのウィンドウがひとつだけ許可されるかどうかは、実装とプラットフォームによる。
そのため、すでに最上位トラバーサブルでドキュメントピクチャインピクチャかどうか真理値がtrueだったり
active documentのpictureInPictureElement
がnullでない場合にピクチャインピクチャ要求が来たらどうなるかは実装依存である。ユーザーエージェントは既存のピクチャインピクチャウィンドウを閉じる動作や
複数のピクチャインピクチャウィンドウを作成する動作もあり得る。
6.6. 元のドキュメントやPiPドキュメントが破棄された時にPiPウィンドウを閉じる
関連付けられたドキュメントピクチャインピクチャウィンドウを閉じる、与えられた
Document
documentに対して:
-
navigableをdocumentのnode navigableとする。
-
もしnavigableが最上位トラバーサブルでなければこれらの手順を中止。
-
もしnavigableのドキュメントピクチャインピクチャかどうか真理値が
trueなら close navigableを実行してこの手順を中止。 -
winをnavigableのactive windowのdocumentPictureInPicture APIのlast-opened windowとする。
destroy に十分な合意が得られたら統合すること。
destroy の最後に「ステップ10」を追加:
-
関連付けられたドキュメントピクチャインピクチャウィンドウを閉じる、与えられたdocumentに対して。
開いているドキュメントピクチャインピクチャウィンドウがあるページを閉じた時、そのPiPウィンドウも閉じることを保証するためです。
6.7. 元のドキュメントやPiPドキュメントが遷移した時にPiPウィンドウを閉じる
これに十分な合意が得られたら navigate に統合すること。
navigate の手順23.3 「navigableのアクティブウィンドウを指定してnavigation and traversal task sourceでグローバルタスクをキューイングし、navigableのアクティブドキュメントを指定してドキュメントおよびその子孫を中断する」 を修正し、その直後にステップ23.4を挿入する:
-
グローバルタスクをキューイング する。 navigation and traversal task source で、navigable の アクティブウィンドウ を指定して、 ドキュメントおよびその子孫の中断 を navigable の アクティブドキュメント で行い、 関連付けられたDocument Picture-in-Pictureウィンドウを閉じる を navigable の アクティブドキュメント で実行する。
-
もし navigable が トップレベルtraversable で その 「ドキュメントピクチャーインピクチャーかどうか」ブール値が
trueなら、これらの手順を中断する。
これにより、Document Picture-in-Picture ウィンドウが開いているページがナビゲートされた場合、そのPiPウィンドウも同時に閉じられることが保証される。また、Document Picture-in-Picture ウィンドウ内のドキュメントがナビゲートされたときにも、Document Picture-in-Picture ウィンドウが閉じられることを保証する。
6.8. PiPウィンドウのサイズ変更
ドキュメントピクチャインピクチャウィンドウをプログラムでサイズ変更することは便利ですが、常時最前面の特性のため、サイズ変更の自由度が高いと迷惑・侵襲的な使われ方をされるおそれがあります。 そのため、ウィンドウサイズ変更APIの利用にはユーザー操作を消費する形にして一部懸念を緩和します。
resizeTo()
に十分な合意が得られたら統合すること。
resizeTo()
のステップ3「targetがスクリプトによって生成された補助ブラウジングコンテキストでないなら return」の後ろに次の新手順を追加:
-
もし target の最上位トラバーサブルのドキュメントピクチャインピクチャかどうかが
trueなら:
resizeBy()
に十分な合意が得られたら統合すること。
resizeBy()
のステップ3「targetがスクリプトによって生成された補助ブラウジングコンテキストでないなら return」の後ろに次の新手順を追加:
-
もし target の最上位トラバーサブルのドキュメントピクチャインピクチャかどうかが
trueなら:
6.9. PiPウィンドウの移動
§ 3.2.1 配置 に記載されているスプーフィングを防ぐため、ドキュメントピクチャーインピクチャーウィンドウでは moveTo()
および moveBy()
を無効化します。
本件について十分な合意が得られたら、moveTo()
および moveBy()
の手順に統合してください。
moveTo()
の手順3の後に、次の新しい手順を1つ追加します。 "If target is not an
スクリプト(ユーザーの操作ではなく)によって作成された
補助閲覧コンテキスト(auxiliary browsing context)でない場合は、returnする。":
-
もし target の トップレベルtraversable の Is Document Picture-in-Picture ブール値が
trueなら、returnする。
moveBy()
の手順3の後に、次の新しい手順を1つ追加します。 "If target is not an
スクリプト(ユーザーの操作ではなく)によって作成された
補助閲覧コンテキスト(auxiliary browsing context)でない場合は、returnする。":
-
もし target の トップレベルtraversable の Is Document Picture-in-Picture ブール値が
trueなら、returnする。
6.10. オープナーウィンドウへのフォーカス
PiPウィンドウがオープナーのタブに再度フォーカスできると便利な場合が多いです。たとえば、ウィンドウが小さいフォームファクターだとユーザーの期待する体験に十分でないときです。
そこで focus()
API は、PiPウィンドウがオープナーにフォーカスする際にシステムレベルのフォーカスを取得できるよう修正します。
本件について十分な合意が得られたら、focus()
に統合してください。
focus()
の手順4「focusing steps を current で実行する。」の後に新しい手順を追加します:
-
もし current が トップレベルtraversable なら:
-
pipWindow を current の アクティブウィンドウ の documentPictureInPicture API の last-opened window とする。
-
もし pipWindow が
nullでなく、かつ pipWindow の relevant global object が 一時的なアクティベーション を持っている場合:-
ユーザーアクティベーションを消費する を pipWindow の relevant global object に対して実行する。
-
current に システムフォーカス を与える。
-
-
オープナーにシステムフォーカスを与えても、必ずしもドキュメントピクチャーインピクチャーウィンドウを閉じる必要はありません。ウェブサイトがフォーカス後にPiPウィンドウを閉じたい場合は、
PiPウィンドウ自身で close()
を使うことができます。
6.11. CSS display-mode
CSS の display mode メディア機能 picture-in-picture により、ウェブアプリがピクチャーインピクチャーモードで表示されているときだけ適用される 特定のCSSルールを開発者が記述できます。
6.12. ユーザーアクティベーションの伝播
ドキュメントピクチャーインピクチャーウィンドウの特性上、 ウィンドウ内のボタンのイベントハンドラが 実際にはオープナーのコンテキストで動作することがよくあります。 そのため、ドキュメントPiPウィンドウに activation consuming APIs を呼び出すのが開発者にとって使いにくくなることがあります。 なぜなら時にはドキュメントPiPウィンドウには 一時的なアクティベーション があり、 オープナーには無い場合があるためです。
この問題を解消するため、 activation notification の手順を、ドキュメントPiPウィンドウでユーザーアクティベーションが発生した時にオープナー側も アクティブにし、逆も同様にオープナーでアクティベーションされた時は PiPウィンドウ内の同一オリジンのフレームもアクティベートされるように拡張します(同一オリジンの子孫フレームの処理と同様)。
本件について十分な合意が得られたら、 activation notification の手順に統合してください。
activation notification の手順4「Extend windows を document の descendant navigables の active window で拡張する。 ただし、navigables のうち その active document の origin が 同一オリジン であるものだけを含める」の後に新しい3手順を追加する:
-
もし document の node navigable の トップレベルtraversable の Is Document Picture-in-Picture ブール値が
trueなら、 windows を document の node navigable の トップレベルtraversable の active browsing context の opener browsing context の active window で拡張する。 -
document picture-in-picture window を document の node navigable の トップレベルtraversable の active window の documentPictureInPicture API の last-opened window とする。
-
もし document picture-in-picture window が
nullでなければ、 windows を document picture-in-picture window の associated document の descendant navigables の active window で拡張する。 ただし、navigables のうち その active document の origin が 同一オリジン であるものだけを含める。
さらに、このアクティベーションが正しく消費されて、(オープナーとPiPウィンドウで)二重消費されないことを保証する必要があります。 そのため consume user activation にも手順を追加し、 PiPウィンドウのアクティベーション消費時にはオープナーからも消費し、逆も同様にオープナー消費時には関連するPiPウィンドウのアクティベーションも消費するようにします。
本件について十分な合意が得られたら consume user activation の手順に統合してください。
consume user activation の手順3 「Let navigables be the inclusive descendant navigables of top’s active document.」の後に3手順を追加:
-
もし top の Is Document Picture-in-Picture ブール値が
trueなら、 navigables を top の active browsing context の opener browsing context の active document の inclusive descendant navigables で拡張する。 -
document picture-in-picture window を top の active window の documentPictureInPicture API の last-opened window とする。
-
もし document picture-in-picture window が
nullでなければ navigables を document picture-in-picture window の associated document の inclusive descendant navigables で拡張する。
6.13. PiPウィンドウの全画面表示
§ 3.2.4 全画面 で述べた通り、 ドキュメントピクチャーインピクチャーウィンドウは全画面表示できません。 この制限を強制するため fullscreen is supported を更新します。
十分な合意が得られたら、 fullscreen is supported に統合してください。
fullscreen is supported の "if there is no previously-established user preference, security risk, or platform limitation." を以下に置き換えます:
Fullscreen is supported は Window
window について、以下全てが true の場合のみ成立する:
-
事前に設定されたユーザープリファレンス、セキュリティリスク、またはプラットフォーム制限が無い。
-
window の navigable の トップレベルtraversable の Is Document Picture-in-Picture ブール値が
falseである。
fullscreen is supported を呼ぶ際は
Window
を必ず渡すように修正が必要です。
7. 例
このセクションは規範的ではありません
7.1. 動画プレイヤーをPiPへ抽出する
7.1.1. HTML
< body > < div id = "player-container" > < div id = "player" > < video id = "video" src = "foo.webm" ></ video > <!-- プレーヤーの追加要素 --> </ div > </ div > < input type = "button" onclick = "enterPiP();" value = "PiPに入る" /> </ body >
7.1.2. JavaScript
// ピクチャインピクチャウィンドウのハンドル。 let pipWindow= null ; function enterPiP() { const player= document. querySelector( '#player' ); // ウィンドウサイズを適切に設定するため、width/heightを指定。 const pipOptions= { width: player. clientWidth, height: player. clientHeight, }; documentPictureInPicture. requestWindow( pipOptions). then(( pipWin) => { pipWindow= pipWin; // プレイヤーがPiPへ移行したことを示すコンテナのスタイル変更。 playerContainer. classList. add( 'pip-mode' ); // プレイヤーをPiPウィンドウへ追加。 pipWindow. document. body. append( player); // PiP終了イベント監視してプレイヤーを戻す。 pipWindow. addEventListener( 'pagehide' , onLeavePiP. bind( pipWindow), { once: true }); }); } // PiPウィンドウが閉じた時呼ばれる。 function onLeavePiP() { if ( this !== pipWindow) { return ; } // コンテナのPiPスタイルを除去。 const playerContainer= document. querySelector( '#player-container' ); playerContainer. classList. remove( 'pip-mode' ); // プレイヤーをメインウィンドウへ戻す。 const player= pipWindow. document. querySelector( '#player' ); playerContainer. append( player); pipWindow= null ; }
7.2. PiPウィンドウで要素にアクセスする
const video= pipWindow. document. querySelector( '#video' ); video. loop= true ;
7.3. PiPウィンドウでイベントをリッスンする
より良いピクチャインピクチャ体験のため、ウェブサイトではユーザー入力イベント(クリックなど)に反応するカスタムボタンやコントロールを実装することがよくあります。
const pipDocument= pipWindow. document; const video= pipDocument. querySelector( '#video' ); const muteButton= pipDocument. document. createElement( 'button' ); muteButton. textContent= 'ミュート切替' ; muteButton. addEventListener( 'click' , () => { video. muted= ! video. muted; }); pipDocument. body. append( muteButton);
7.4. PiPを終了する
ウェブサイトは、ユーザーがウィンドウの閉じるボタンを明示的にクリックしなくても、DocumentPictureInPicture
のWindow
を閉じたい場合があります。これは、そのWindow
オブジェクトでclose()メソッドを使うことで実現できます。
// これでPiPウィンドウを閉じ、onLeavePiP()が実行されます。 // リスナー付き。 pipWindow. close();
7.5. PiPウィンドウが閉じる時に要素を取得する
PiPウィンドウを閉じる理由が何であれ(ウェブサイトが閉じる・ユーザーが閉じる)、要素をPiPウィンドウから元に戻したくなる場合がよくあります。これはpagehide
イベントのハンドラで実装可能です。上記動画プレイヤー例のonLeavePiP()でも示されています:
// PiPウィンドウが閉じた時呼ばれる。 function onLeavePiP() { if ( this !== pipWindow) { return ; } // コンテナのPiPスタイルを除去。 const playerContainer= document. querySelector( '#player-container' ); playerContainer. classList. remove( 'pip-mode' ); // プレイヤーをメインウィンドウへ戻す。 const player= pipWindow. document. querySelector( '#player' ); playerContainer. append( player); pipWindow= null ; }
7.6. PiPウィンドウをプログラムでサイズ変更する
ドキュメントピクチャインピクチャウィンドウはresizeTo()
やresizeBy()
APIをサポートしていますが、PiPウィンドウ上でのユーザー操作が必要です:
const expandButton= pipWindow. document. createElement( 'button' ); expandButton. textContent= 'PiPウィンドウを拡張' ; expandButton. addEventListener( 'click' , () => { // PiPウィンドウの幅を20px、高さを30px拡張。 pipWindow. resizeBy( 20 , 30 ); }); pipWindow. document. body. append( expandButton);
7.7. オープナータブに戻る
focus()
APIを使えば、ピクチャインピクチャウィンドウからオープナータブにフォーカスを移動でき(要ユーザー操作):
const returnToTabButton= pipWindow. document. createElement( 'button' ); returnToTabButton. textContent= 'オープナータブに戻る' ; returnToTabButton. addEventListener( 'click' , () => { window. focus(); }); pipWindow. document. body. append( returnToTabButton);
7.8. CSSピクチャインピクチャディスプレイモードの使用例
次の例は、PiPウィンドウ内の body 要素のマージンを除去し、タイトルのフォントサイズを小さくしてコンテンツをウィンドウにフィットさせる方法を示します:
@media all and( display-mode: picture-in-picture) { body{ margin : 0 ; } h1{ font-size : 0.8 em ; } }
7.9. 戻るボタンの非表示
多くのユーザーエージェントは、動画やドキュメントピクチャインピクチャウィンドウでオープナーに戻ってウィンドウを閉じるボタンを表示しますが、これは一部のウェブサイトのドキュメントピクチャインピクチャ体験では適していない場合もあります。disallowReturnToOpener
オプションでこのボタンを非表示にできます。
await documentPictureInPicture. requestWindow({ disallowReturnToOpener: true });
7.10. 初期ウィンドウ配置の優先
ドキュメントピクチャインピクチャウィンドウは開いている間にユーザーがサイズ変更や再配置する場合があります。閉じてから再度開いた時、ユーザーエージェントは前回の位置・サイズをヒントとして使い、ウィンドウをデフォルト位置以外に配置する場合もあります。
前回のウィンドウ位置・サイズを使って欲しくない場合、preferInitialWindowPlacement
をtrueに指定してヒントを出すことができます。例えば、新規の活動用に新しいPiPウィンドウを開く場合などです。これによりユーザーエージェントはデフォルト位置やサイズ、あるいはサイトが指定したサイズヒント通りに表示する場合があります。
await documentPictureInPicture. requestWindow({ preferInitialWindowPlacement: true });
8. 謝辞
Frank Liberato、Mark Foltz、Klaus Weidner、François Beaufort、Charlie Reis、Joe DeBlasio、Domenic Denicola、Yiren Wang各氏の意見や貢献、また本ドキュメントと議論に寄せられた知見に感謝します。