1. 推測ルール
HTML § 7.6.1 Speculation rulesを以下のように変更してプリレンダリングをサポートする。
1.1. 構文解析
speculation rule set の構造体を、追加で2つの要素を持つよう拡張する:
-
prerender rules:リスト(speculation rulesのリスト、初期値は空)
-
prerender_until_script rules:リスト( speculation rulesのリスト、初期値は空)
speculation rule の構造体に、次の1つの要素を追加する:
-
target navigable name hint:string またはnull
-
typesToTreatAsPrefetch の構築を削除し、その代わりに parsed["
prerender"]をprerender rulesリストへ、 parsed["prerender_until_script"]をprerender_until_script rulesリストへと、parsed["prefetch"]およびprefetch rulesと同じ方法でパースする。 -
parsed["
prefetch"]からパースしたルールは、target navigable name hintがnullでない場合は破棄する。 -
parsed["
prerender"]と parsed["prerender_until_script"]からパースしたルールは、requirementsが "anonymous-client-ip-when-cross-origin"を含む場合は破棄する。
実装では、§ 1.2 処理モデルの修正により、prerender候補をprefetchとして扱うこともできる。
-
targetHintをnullにする。
-
input["
target_hint"]が存在する場合:-
input["
target_hint"]が有効なナビゲーブル名またはキーワードでない場合:-
ユーザーエージェントは、与えられたtarget hintが無効であることをコンソールに警告できる。
-
nullを返す。
-
-
targetHintをinput["
target_hint"]に設定する。
-
そして最後の段階でspeculation ruleを返す際にtarget navigable name hintにtargetHintをセットするよう更新。
1.2. 処理モデル
prerender candidateは、次の要素を追加で持つspeculative load candidateである:
-
target navigable name hint:有効なナビゲーブル名またはキーワード またはnull
-
should block scripts:boolean(初期値false)
-
prerenderCandidatesを空のリストとする。
-
各 documentのspeculation rule setsのruleSetについて:
-
各 (rules, shouldBlockScripts) in « (ruleSetのprerender rules, false), (ruleSetのprerender_until_script rules, true) »:
-
各 rule in rules:
-
-
referrerPolicy を推測的ロードreferrer policyの計算(rule、null)で得る。
-
追加:新規prerender candidate(以下を付与)をprerenderCandidatesへ
- URL
-
url
- No-Vary-Search hint
-
ruleのNo-Vary-Search hint
- eagerness
-
ruleのeagerness
- referrer policy
-
referrerPolicy
- tags
-
ruleのtags
- target navigable name hint
- should block scripts
-
shouldBlockScripts
-
-
ruleのpredicateがnullでなければ:
-
links = matching linksの検索(document、ruleのpredicate)
-
各 link in linksについて:
-
target = ruleのtarget navigable name hint
-
targetがnullなら、要素のtarget取得(link)でセット。
-
referrerPolicy = 推測的ロードreferrer policyの計算(rule、link)
-
追加: prerender candidate(下記)をprerenderCandidatesに追加:
- URL
-
linkのurl
- No-Vary-Search hint
-
ruleのNo-Vary-Search hint
- eagerness
-
ruleのeagerness
- referrer policy
-
referrerPolicy
- tags
-
ruleのtags
- target navigable name hint
-
target
- should block scripts
-
shouldBlockScripts
-
-
-
-
-
-
speculativeLoadCandidatesをprefetchCandidatesとprerenderCandidatesの和集合とする。
後続の、「もはや推測中でないprefetch record」をキャンセルする処理はspeculativeLoadCandidatesに対して行うこと。
prerenderCandidateGroupsリストをprefetchCandidateGroupsと同様に(ただしprefetchCandidatesの代わりにprerenderCandidatesを使って)作成。
実際のprefetch処理(従来はprefetchCandidateGroupsをループ)の箇所を以下に置換:
-
speculativeLoadCandidateGroupsをprefetchCandidateGroupsとprerenderCandidateGroupsの和集合とする。
-
各 group in speculativeLoadCandidateGroupsについて:
-
ユーザーエージェントは次の手順を行ってもよい:
-
candidate = group[0]
-
tagsToSend = speculative load candidateたちからタグを集めるをgroupで実行
-
prefetchRecord = 新規prefetch record(以下設定)
- source
-
"
speculation rules" - URL
-
candidateのURL
- No-Vary-Search hint
-
candidateのNo-Vary-Search hint
- referrer policy
-
candidateのreferrer policy
- tags
-
tagsToSend
-
candidateがprefetch candidateなら、 prefetchRecordのanonymization policy にcandidateのanonymization policyをセット
-
candidateがprerender candidateなら、次を実行してもよい:
-
prefetchRecordのprerendering traversable に "
to be created" をセット -
prefetchRecordのprerendering target navigable name hintにcandidateのtarget navigable name hintをセット
-
referrer起点のナビゲーションプリレンダ開始(document, prefetchRecord, candidateのshould block scripts)を実行
-
-
前段を実行しなかった場合はreferrer起点のナビゲーションプレフェッチ開始(document、prefetchRecord)を実行。
(以降、その"may"実行タイミングに関する説明文は維持)
-
-
1.3. トリガー
属性変更手順を、
a
および
area
要素について
target
属性も監視し、この属性が変更された場合
推測的ロードの考慮
を実行するようにする。
2. プリレンダリング基盤
2.1. Document
インタフェースへの拡張
[HTML]で定義される
Document
を次のように変更する:
partial interface Document {readonly attribute boolean prerendering ; // "Document" オブジェクトにのみ適用される特殊イベントハンドラーIDL属性の下attribute EventHandler onprerenderingchange ; };
onprerenderingchange
属性は、
イベントハンドラーIDL属性であり、prerenderingchange イベントハンドラーイベントタイプに対応する。(HTMLの該当テーブル—現状
onreadystatechange
のみ—を追記する。)
[HTML]の流儀に従い
prerendering
の定義本体は別セクションに配置。これを以下新設セクションに置く:
2.2. プリレンダリングナビゲーブル
このセクションはHTMLの [HTML] のNavigables 節に新規追加
すべてのnavigableは、 loading mode(以下のいずれか)を持つ:
- "
default" -
この navigable にロードされたコンテンツには特別な扱いなし
- "
prerender" -
この navigable はプリレンダ済みのコンテンツを表示している
デフォルトではnavigableのloading modeは"default"。
loading
modeが"prerender"のnavigableは、prerendering navigableと呼ぶ。
prerendering
navigableかつ
top-level traversableなものをprerendering traversableと呼ぶ。
prerendering navigableのアクティブブラウジングコンテキストは補助ブラウジングコンテキストとなることはない。
loading modeの値は2つのみだが、将来fenced frameやportals、uncredentialed(クロスサイト)prerendering等で拡張しやすい構造で設計済。機能標準化が進み不要ならboolに単純化予定。
すべてのnavigableはscripting mode(以下のいずれか)も持つ:
- "
enabled" -
スクリプトは通常どおり実行される
- "
blocked-until-activation" -
navigableが活性化されるまでスクリプトはブロックされる
デフォルトでnavigableのscripting modeは"enabled"。
scripting modeはnavigableのプロパティでありdocumentには属さない。これにより同じnavigable内でのナビゲーションでも属性が保存される。about:blankの初期documentや活性化前リダイレクトに重要。
すべてのprerendering traversableはprerender初期応答search varianceを持つ。これはURL search varianceかnull(初期値はnull)。
document.prerendering-
そのページが非対話的プリレンダリング文脈で表示されていればtrueを返す。
この値はtrue→falseとなりうる。その際
Documentでprerenderingchangeイベントが発火する(再びtrueになることはない)。
prerenderingのgetter手順は、thisが非nullの
node navigableを持ち、それがprerendering
navigableであればtrue、さもなくばfalseを返す。
すべてのDocument
はpost-prerendering activation steps list
を持ち、その内容はリスト
であり、各要素はアルゴリズム手順列。任意のプラットフォームオブジェクトplatformObjectの
post-prerendering activation steps
listは次とする:
- もしplatformObjectがノード
-
-
platformObjectのノードドキュメントのpost-prerendering activation steps listを返す。
-
- その他
-
-
アサート:platformObjectのrelevant global objectは
Windowオブジェクトである。
-
platformObjectのrelevant global objectの関連付けられたDocumentのpost-prerendering activation steps listを返す。
-
すべてのDocument
はactivation start timeを持つ。初期値は時刻0の
DOMHighResTimeStamp
である。
すべてのDocument
はallow cross origin iframes
navigation while prerenderingを持ち、これはboolean で初期値は false。
2.3. プリレンダリングアルゴリズム
次の手順で ユーザーエージェント主導プリレンダリングの開始 を行う:URL startingURLを与える。
-
アサート: startingURLのスキームはHTTP(S) schemeである。
-
prerenderingTraversableを新規トップレベルtraversableの作成(引数nullと空文字列)で得る。
-
prerenderingTraversableのloading modeを"
prerender"にセットする。 -
prefetchRecordを新規prefetch recordとして、URLをstartingURL、 anonymization policyをnull、 referrer policyを空文字列、 No-Vary-Search hintをdefault URL search variance、 sourceを"browser UI"、 prerendering traversableをprerenderingTraversable とする。
-
referrer起点ナビゲーションプレフェッチ開始を prerenderingTraversableのactive documentとprefetchRecordで呼び出す。
-
navigate prerenderingTraversable to startingURL using prerenderingTraversableのactive document
この最初のナビゲーションはprerenderingTraversable自身によって実行され、関連する全てのセキュリティチェックが実行されることを保証する。
-
ユーザーがactivationURLへのナビゲーションコミットを希望した場合、そのactivationURLについて prefetchRecordが該当URLとして一致する場合:
-
ユーザーが新しいユーザー可視なトップレベルtraversableを作成希望の場合 (例:アドレスバー入力後にShift+Enter)
-
ユーザーが既存のtop-level traversable predecessorTraversableへコミット希望の場合(例:アドレスバー入力後にEnter)
-
活性化 prerenderingTraversableをpredecessorTraversableの場所で "
push", startingURL, activationURL 与えて実行
-
-
ユーザーがこのようなコミット指示を出さない場合や遅れる場合、ユーザーエージェントがプリレンダリソースを即時タスク等で回収できる。 その場合prerenderingTraversableはdestroyされうる。
Document
referrerDoc, prefetchRecord prefetchRecord, boolean
blockScripts):
-
アサート: prefetchRecordのURLの schemeはHTTP(S) schemeである。
-
もしreferrerDocのnode navigableがtop-level traversableでなければreturn。
現在、子ナビゲーブル内でのプリレンダリングは未仕様・未実装。
-
もしreferrerDocのbrowsing contextが補助ブラウジングコンテキストならreturn
これによりプリレンダとreferrerDocのopener関係問題を回避。
-
もしreferrerDocのoriginがprefetchRecordの URLのoriginと same site でなければreturn
現時点でクロスサイトプリレンダは仕様化もされていない。
-
もしreferrerDocがprefetchRecordについて checkPrerender有効で 一致するprefetch recordを持つならreturn
-
アサート: prefetchRecordのprerendering traversableは"
to be created" -
prerenderingTraversableを新規トップレベルtraversable作成の結果とする。
ユーザーエージェントはprefetchRecordのprerendering target navigable name hintをヒントとして利用可。
これはただのヒントであり規範的意味はない。
-
prerenderingTraversableのloading modeを"prerender"にセット
-
blockScriptsがtrueならprerenderingTraversableの scripting modeを "
blocked-until-activation"にセット -
prefetchRecordのprerendering traversableをprerenderingTraversableにセット
-
prerenderingTraversableのremove from referrerを prefetchRecordのprerendering traversableをnullにするアルゴリズムにセット。
top-level traversable同様、prerendering traversableは いつでもdestroyされ得る。destroyされた場合でもprefetch record自体は残り将来ナビゲーション転用可能。
-
referrer起点ナビゲーションプレフェッチ開始(referrerDoc, prefetchRecord)
-
navigate prerenderingTraversable to prefetchRecordのURL using referrerDoc、 referrerPolicyは prefetchRecordのreferrer policy
活性化のため後継更新 を行う(prerendering traversable successorTraversable、 URL startingURL、URL activationURLを与える):
-
successorDocument = successorTraversableのactive document
-
もしstartingURL = successorDocumentのURLかつ startingURL ≠ activationURL なら:
-
アサート:successorDocumentは URLの書き換え可能である
-
navigation = successorDocumentのrelevant global objectのnavigation API
-
continue = push/replace/reload navigateイベント発火 (navigation, "replace", activationURL, true)
-
もしcontinueがtrueならURLと履歴更新 (successorDocument, activationURL)を実行
No-Vary-Search等によるURL不正確一致の場合に、プリレンダURLと実際ナビゲーション先URLを一致させる。
-
活性化 (prerendering traversable successorTraversableをtop-level traversable predecessorTraversableの場所で、history handling behavior historyHandling、URL startingURL、URL activationURL、 オプションでnavigation ID navigationIdも可)
-
アサート:successorTraversableのactive documentのinitial about:blankかはfalse。
-
navigationId未指定ならランダムUUID生成でセット
-
referrerOrigin = predecessorTraversableのactive documentのorigin
-
predecessorTraversableのongoing navigationをnavigationIdにセット
これにより他のナビゲーションをabortする効果がある
-
並列で次を実行:
-
unloadPromptCanceled = アンロードがユーザーにキャンセルされたか確認 (predecessorTraversableのactive documentの包含descendant navigablesについて)
-
もしunloadPromptCanceledがtrue、あるいはpredecessorTraversableのongoing navigationがnavigationIdでなくなったら中断。
-
グローバルタスクをキュー (navigation and traversal task source、 predecessorTraversableのactive window)で abort predecessorTraversableのactive documentを実行
-
活性化のため後継更新を(successorTraversable、startingURL、activationURL)で実行
-
セッション履歴トラバース手順の追加 をpredecessorTraversableに対し、以下実行:
-
アサート:successorTraversableの current session history stepは0
-
アサート:successorTraversableの session history entriesの sizeは1
-
successorEntry = successorTraversableの session history entries[0]
-
削除 successorEntryをsuccessorTraversableの session history entriesから。
この時点でsuccessorTraversableは空になり観測不能なdestroyが可能。 (ただしsuccessorEntryやそのdocument/browsing context等は以降用に生存させてよい)
-
クロスドキュメントナビゲーション完了 (predecessorTraversable, historyHandling, successorEntry)
session history entryまるごと移動するので履歴トラバース時にブラウジングコンテキストグループも切り替わる。 opener関係もCOOPと同様切断される。
-
UIもタブ/ウィンドウ内容やchrome等の変更を反映
-
活性化完了(successorTraversable、referrerOrigin)
-
WebDriver BiDiとの連携は現状未仕様。ブラウザ実装時注意
-
-
-
各 navigable in traversableの active documentの包含descendant navigablesについて グローバルタスクをキュー( navigation and traversal task source) navigableのactive windowを与えて実行:
-
各 origin → hintSet in navigableのprerender-scoped Accept-CH cache:
-
セット Accept-CH cache[origin]=hintSet
-
-
もしnavigableのscripting modeが "
blocked-until-activation" なら:-
navigableのscripting modeを "
enabled"に -
navigableのactive documentのスクリプト実行を解除
スクリプト再開およびキュー済タスク再処理仕様詳細は要記述。
-
-
doc = navigableのactive document
-
ここでloading mode遷移の伝搬が必要。現状traversable上にあるがdocumentにもたせてイベント発火等要検討。
-
もしdocのoriginがoriginと同じなら docのactivation start timeを docのrelevant global objectの current high resolution timeにセット
-
イベント発火
prerenderingchangeをdoc宛に発火 -
各 steps in docの post-prerendering activation steps list:
-
stepsを実行
Promise等何かを返しても無視可能
-
アサート:steps実行で例外投げていない
同一イベントループの
Document間では順序観測可能だが、異なる場合は順序化不能。 -
-
prerendering traversableがdestroyされた際、参照を確実にクリアするため、destroy a top-level traversableの末尾に以下を追加:
-
traversableがprerendering traversableかつ traversableのremove from referrerがnullでないなら、それを呼ぶ。
2.4. ナビゲーブル作成の修正
-
navigableのloading modeをelementのnode navigableのloading modeに設定する。
3. ナビゲーションとセッション履歴
3.1. ナビゲーションのかわりの活性化許可
Document
predecessorDocument と URL urlについて行うアルゴリズム:
-
recordToUseをnullにする。
-
各 record in predecessorDocumentのprefetch recordsに対して:
-
recordのprerendering traversableがprerendering traversableでなければcontinue。
-
recordのprerendering traversableのactive documentのis initial about:blankがtrueならcontinue。
-
recordのURLがurlと等しい場合:
-
recordToUse = record
-
-
recordToUseがnullでrecordがurlで is expected to match a URLなら:
-
recordToUse = record
-
-
-
recordToUseがnullでなければ:
-
Remove recordToUse from predecessorDocumentのprefetch records
-
-
recordToUseを返す。
-
次のいずれかに該当すれば:
-
navigableがtop-level traversableでない
-
navigableがprerendering traversableである
-
navigableがfenced frameである
-
cspNavigationTypeが"
other"でない -
documentResourceがnullでない
ならnullを返す
-
-
predecessorDocumentをnavigableのactive documentとする。
-
cutoffTimeをnullにする。
-
繰り返し:
-
completeRecord = 一致するプリレンダ済みプレフェッチレコードの検索 (predecessorDocument, url)
-
completeRecordがnullでなければ、それを返す。
-
potentialRecordsを空のリストとする。
-
各 record in predecessorDocumentのprefetch recordsについて:
-
全て次を満たせばpotentialRecordsにrecordをappend:
-
recordのprerendering traversableが prerendering traversableである
-
recordのprerendering traversable のactive documentのis initial about:blankがtrue
-
recordがurlで is expected to match a URL
-
cutoffTimeがnull、またはrecordのstart timeがcutoffTime未満
-
-
-
potentialRecordsが空ならnullを返す
-
predecessorDocumentのprefetch recordsの任意の要素の prerendering traversableの ongoing navigationが 変化するまで待機
-
cutoffTimeがnullでpotentialRecordsに prerendering traversableで active documentの is initial about:blankがfalseな要素があれば、 cutoffTimeをpredecessorDocumentのrelevant global objectの current high resolution time で設定
-
navigateアルゴリズムを修正し、通常ナビゲーションの場所でprerendering traversableの活性化 を許可:以下の手順を並列に入った直後に追加:
-
record = 一致するプリレンダ済みプレフェッチレコードの待機 (navigable, url, cspNavigationType, documentResource)
-
recordがnullでなければ:
-
matchingPrerenderedNavigable = recordのprerendering traversable
-
startingURL = recordのURL
-
活性化(matchingPrerenderedNavigable, navigable, historyHandling, startingURL, url, navigationId)
-
この手順を中止。
-
3.2. ナビゲーション取得の変更
-
initiatorOriginをentryのdocument stateのinitiator originとする。
アルゴリズムの"While true:"の最初のサブステップ直後に次も追加:
-
もしnavigableがprerendering navigableかつcurrentURLの originがinitiatorOriginと same siteでなければ:
-
もしnavigableがtop-level traversableならnullを返す。
-
そうでなければ、navigableのtop-level traversableのactive documentのallow cross origin iframes navigation while prerenderingが falseなら、ユーザーエージェントはnavigableのloading mode が"
normal"になるまで待つ。 (この待ち中、または直ちにdestroyしてnullを返してもよい)
-
アルゴリズム終盤、locationURLチェック後に次の手順も追加:
-
もしnavigableがprerendering navigableで、responseOriginが initiatorOriginとsame originでなければ:
-
loadingModes = getting the supported loading modes/response
-
loadingModesに `
credentialed-prerender`が含まれなければnullを返す。将来的には
uncredentialed-prerenderも許容し得るが、現状クロスサイト用途でまだ仕様等もないため除外。
-
Refreshヘッダー」の直後に次追加:
-
もしnavigationParamsのnavigableがprerendering navigableなら:
-
loadingModes = getting the supported loading modes / response
-
loadingModesが `
prerender-cross-origin-frames` を含めばdocumentのallow cross origin iframes navigation while prerenderingをtrueにする
-
-
もしnavigableがprerendering navigableで以下いずれかなら:
-
failureがtrue
-
navigationParamsのrequestがnull
-
navigationParamsのrequestのcurrent URLのschemeがHTTP(S) schemeでない
-
navigationParamsのrequestのcurrent URLがpotentially trustworthyでない
-
navigationParamsのresponseがprefetch非対応
prefetch非許容レスポンス(エラー等)はprerenderにも非許容。将来明確分離される可能性あり -
navigationParamsのresponseが `
Content-Disposition`ヘッダーでattachmentを指定している
なら:
-
Destroy navigableのtop-level traversable
-
return
-
-
navigableがprerendering traversableかつ navigableのprerender initial response search varianceがnullなら:
-
navigableのprerender initial response search varianceをobtaining a URL search variance(navigationParamsのresponse)でセット
-
-
もしnavigableがprerendering navigableなら外部ソフト呼び出しをせずreturn
リダイレクト時もプリレンダ活性化を認めることも可能だが、現状複雑化防止・未実装のため割愛。
3.3. 単純なセッション履歴の維持
-
もしnavigableがprerendering navigableなら、 historyHandlingを"
replace"に設定する。
-
もしnavigableがprerendering navigableなら、 historyHandlingを"
replace"に設定する。
3.4. ワーカーのライフタイムとの相互作用
ワーカーは次のいずれかのownerを持つ場合active needed workerであると言う:
Document
オブジェクトがfully activeかつ、そのnode navigableがprerendering
navigableでない場合、または
active needed workersである。
このため、ワーカーのスクリプトはロードされるが、documentが活性化されるまで実行は保留される。
3.5. Document破棄時のクリーンアップ
destroyアルゴリズム(Document対象)
の末尾に次の処理を追加:
-
空にする documentの post-prerendering activation steps list
4. 他の仕様・概念との相互作用
4.1. Page Visibilityとの相互作用
prerendering
navigables内のDocumentは必ずvisibility stateが"hidden"となる。
おそらく明示的にこの状態の更新が必要。document.prerenderingの扱いと同様。
4.2. システムフォーカスとの相互作用
prerendering traversablesは決してシステムフォーカスを持たない。
4.3. PerformanceNavigationTiming
インタフェースへの拡張
PerformanceNavigationTiming
インタフェースを次のように拡張:
partial interface PerformanceNavigationTiming {readonly attribute DOMHighResTimeStamp activationStart ; };
activationStart
のgetter手順は:
4.4. Client Hint Cacheとの相互作用
Accept-CH cacheはユーザーエージェントがグローバルに持つストレージであるが、prerendering中は変更しないようにし、活性化後に正しく反映させる必要がある。以下の修正でこれを保証する。
各prerendering navigableはprerender-scoped Accept-CH cacheを持ち、これはordered map(originからclient hints setsへのマップ)である。
これはoriginごとにどのclient hintsをopt-inしたかを格納し、活性化時にグローバルAccept-CH cacheにコピーされる。
-
navigableをsettingsObjectのglobal objectのnavigableとする。
-
originMatchingEntriesをAccept-CH cacheのうちsettingsObjectのoriginがsame originとなるもの群とする。
-
もしnavigableがprerendering navigableなら:
-
prerenderAcceptClientHintsCacheをnavigableのprerender-scoped Accept-CH cacheとする。
-
originをsettingsObjectのoriginとする。
-
もしprerenderAcceptClientHintsCache[origin]が存在すれば、originMatchingEntriesをprerenderAcceptClientHintsCache内のoriginがsame originとなるもの群とする。
-
-
navigableをsettingsObjectのglobal objectのnavigableとする。
-
もしnavigableがprerendering navigableならセット navigableのprerender-scoped Accept-CH cache[origin] = hintSetとする。
-
それ以外はセット Accept-CH cache[origin] = hintSet
4.5. Clear Site Dataとの相互作用
Clear Site Data § 3.1 The Clear-Site-Data HTTP Response Header Fieldに次のヘッダー値の説明を追加:
- "
prerenderCache" -
"
prerenderCache"タイプは、特定originから発生した任意のプリレンダを、responseのURLに基づき、サーバが削除希望を指示することを示す。このタイプは"
cache"タイプのサブセットである。実装詳細は下記参照。
parse response’s Clear-Site-Data headerのパース手順を修正し:
-
`"cache"`または`"*"`に遭遇時、typesに "prerenderCache" を追加(かつ既存分も追加) -
`"prerenderCache"`に遭遇時、typesに "prerenderCache" を追加
clear site data for responseのswitch分岐に
"prerenderCache"
を処理し、clear
prerender cacheをoriginに対して呼ぶケースを追加。
-
各 ユーザーエージェントのtop-level traversable set中の top-level traversable traversableについて:
-
navigablesをtraversableのactive documentの包含descendant navigablesとする。
-
各 navigable in navigablesについて:
-
activeDocumentをnavigableのactive documentとする。
-
もしactiveDocumentのoriginがoriginとsame originでなければcontinue。
-
各 prefetchRecord in activeDocumentのprefetch recordsについて:
-
prefetchRecordのprerendering traversable がnullならcontinue。
-
キャンセル・廃棄 prefetchRecord(activeDocumentを与える)
-
-
-
4.6. Fetchとの相互作用
Sec-Purpose`設定処理の後に次のステップを追加:
-
それ以外で、httpRequestのclientが environment settings objectで、かつ そのglobal objectが
Windowで、 さらにそのWindowのnavigableがprerendering navigableなら:-
prefetchトークンに、キー"prerender"、値trueパラメータを追加する。 -
構造化フィールド値のセットを (`
Sec-Purpose`, purpose)でhttpRequestのheader listに実行。
これはprerendering navigable内のサブリソースや、prerendering navigable自身のナビゲーション双方に適用される。
5. `Supports-Loading-Mode`
HTTPレスポンスヘッダー
このセクションは[HTML]のLoading web pages節の下位項目として追加。
場合によっては、クロスオリジンのWebページが新しい文脈でロードされる準備ができていないことがある。それらがそのような方法でのロードを許可するために、`Supports-Loading-Mode`
HTTPレスポンスヘッダーが利用できる。このヘッダーは構造化ヘッダーであり、設定時には下記リストのtokenの1つ以上でなければならない。
実際のパースはlist of tokenとして行われ、不明なtokenは無視される。
`credentialed-prerender`
トークンは、レスポンスがクロスオリジン同一サイトreferrer起点のprerendering navigable作成に利用可能であることを示す。
これがなければ、§ 3.2 ナビゲーション取得の変更にあるように、そのようなプリレンダは失敗する。
`prerender-cross-origin-frames`
トークンは、レスポンスが全クロスオリジンiframeのプリレンダに使用可能であることを示す。これがなければ、該当プリレンダは§ 3.2
ナビゲーション取得の変更通り遅延される。
get the supported loading modes for response responseの手順:
-
もしresponseがnetwork errorなら空リストを返す。
-
slmHeaderを構造化フィールド値の取得で `
Supports-Loading-Mode`, "list"をresponseのheader listから得る。
6. 望ましくない(侵入的な)挙動の防止
プリレンダ中のprerendering navigableでは、ユーザーにとって侵入的となるため種々の挙動が禁止される。
6.1. スクリプト実行の一時停止
navigableのscripting
modeが"blocked-until-activation"の場合、ユーザーエージェントはそのnavigableのactive
documentに対してスクリプトを実行してはならない。これは<script>要素の実行も含むが、それに限らない。
スクリプト実行のブロック方法や関連タスクのキューイング方法など、詳細仕様は今後明確にする必要あり。
この仕様により、ページが活性化されるまでJavaScript実行が完全に停止される。インラインイベントハンドラーの扱いについては議論中。
6.2. リソースのダウンロード
download the hyperlinkアルゴリズムを修正し、prerendering navigable内でのダウンロードは活性化まで遅延されるよう、並列処理直前に次を挿入:
-
もしsubjectのnode navigableがprerendering navigableなら、そのsubjectのpost-prerendering activation steps listに処理を追加してreturn。
6.3. ユーザープロンプト
Window
windowに対し、最初の手順として次を追加:
-
もしwindowのnavigableがprerendering navigableなら、trueを返す。
print()
メソッドの手順冒頭に次を追加:
-
thisのnavigableがprerendering navigableならreturn。
6.4. 非同期API結果の遅延
多くの仕様は、prerendering navigable内でアルゴリズムが呼ばれた場合、navigableのtop-level traversableが活性化されるまで処理の大半を保留するよう修正が必要である。多くの仕様はイベントループの利用設計が未整理であり一律記述は難しいが、以下に指針を示す。
スクリプトモードが"blocked-until-activation"なら、そのアルゴリズムを呼ばせるスクリプト自体が活性化まで実行されないことに注意。
6.4.1.
[DelayWhilePrerendering]
拡張属性
非同期メソッドの挙動を活性化まで遅延する定型ロジックを抽象化するため、[DelayWhilePrerendering] Web
IDL拡張属性を導入する。
これは、prerendering navigable内でメソッドが呼ばれた場合、pending
promiseを即returnし実処理を行わない。活性化時に本来の処理を実行し、戻り値でpromiseをresolve/rejectする。
[DelayWhilePrerendering]
拡張属性は引数なし・
regular operationまたはstatic
operation
で、return typeがpromise
typeまたはundefined、exposure setがWindowのみでなければならない。
[DelayWhilePrerendering]
注釈付きoperationの手順は以下に置換:
-
realmをcurrent realmとする。
-
もしoperationがregular operationなら、realm = relevant realm of this。
-
もしrealmのglobal objectのnavigableがprerendering navigableなら:
-
promiseをrealmで新規Promiseとして作成。
-
thisのpost-prerendering activation steps listに次ステップ追加:
-
result = 本来指定されていたoperation手順を同じ
thisと引数で実行した結果 -
resolve promise with result
-
-
このoperationのreturn typeがpromise typeならpromiseを返す。
-
-
さもなくば本来指定されていた手順をもとの
thisと引数で実行した結果を返す。
6.4.2. Service Workers
[DelayWhilePrerendering]
をupdate()、
unregister()、
register(scriptURL, options)、
postMessage(message, transfer)、
postMessage(message, options)
に追加する。
これにより、プリレンダページが既存Service Workerの利用はできても、Service Worker登録状態自体は変化しない。
6.4.3. BroadcastChannel
[DelayWhilePrerendering]
をpostMessage()
に追加する。
6.4.4. Geolocation API
getCurrentPosition()
メソッドの手順の先頭に次のステップを追加:
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば、thisのpost-prerendering activation steps listに以下の手順を追加し、return する。
watchPosition()
メソッドの手順の先頭に次のステップを追加:
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば:
-
watchIdを実装依存の
unsigned longとし、post-prerendering activation geolocation watch process IDとして記録する。 -
thisのpost-prerendering activation steps listに以下の手順を追加し、その際生成されたwatchIdをIDとして使用し、watchIdを返す。
-
clearWatch(watchId)
メソッドの手順の先頭に次のステップを追加:
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば:
-
もしwatchIdがpost-prerendering activation geolocation watch process IDであれば、対応する手順をthisのpost-prerendering activation steps listから削除する。
-
return。
-
6.4.5. Web Serial API
[DelayWhilePrerendering]
を requestPort()
に追加する。
TODO: 以下は [DelayWhilePrerendering]
を dedicated worker 内で owner document を使うよう一般化すれば実装可能。
getPorts()
メソッドの手順で、promise生成直後に次の手順を挿入:
-
document を thisの relevant global object の associated Document (もしthisのrelevant global objectが
Windowであれば)、または thisのrelevant global objectのowner document(DedicatedWorkerGlobalScopeなら)とする。 -
もし document が null なら、promise rejected with "
SecurityError"DOMExceptionを返す。 -
もし document のnode navigableがprerendering navigableであれば、documentのpost-prerendering activation steps listに手順を追加し、promiseを返す。
6.4.6. Notifications API
[DelayWhilePrerendering]
を requestPermission()
に追加する。
Notification()
コンストラクタの手順で、in parallelとなっていた手順を次のように置換:
-
もしthisのrelevant global objectのnavigableがprerendering navigableならthisのpost-prerendering activation steps listにこれら手順を追加。さもなくば元通りin parallelとして実行。
permission
静的getterの手順を次で置換:
-
もしcurrent global objectのnavigableがprerendering navigableなら、"
default" を返す。これにより実際の許可状態の同期取得を回避できる。活性化後に
Notification.requestPermission()を呼ぶことで、上記修正により初めて実処理がなされる。その時点で"granted"や"denied"となる可能性もあるが、ユーザーへのUIは表示されないかもしれない。しかしこれはWeb開発者のコードからは観測不能で問題ない。 -
さもなくば get the notifications permission state を実行してその値を返す。
6.4.7. Web MIDI API
[DelayWhilePrerendering]
を requestMIDIAccess()
に追加する。
6.4.8. Idle Detection API
[DelayWhilePrerendering]
を start()
に追加する。
もう1つの重要なメソッドIdleDetector.requestPermission()
はtransient
activationでゲートされている。ただしすでにoriginの許可があっても、prerendering中はidle detectorの開始は遅延される。
6.4.9. Generic Sensor API
start()
メソッドの手順で、状態を"activating"にセットした直後に次を挿入:
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば、thisのpost-prerendering activation steps listに手順を追加し、return。
-
もしthis.
[[state]]が"idle"ならreturn。prerendering遅延中に
stop()が実行されていれば、活性化時に何もしないことを保証。
6.4.10. Web NFC
[DelayWhilePrerendering]
をwrite()
およびscan()
に追加する。
6.4.11. Battery Status API
getBattery()メソッドの手順の先頭に次の手順を追加:
6.4.12. Screen Orientation API
-
promiseを新しいpromiseとする。
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば、thisのpost-prerendering activation steps listに手順を追加しpromiseを返す。
-
もしuser agentが画面の向きロックをサポートしないなら、reject promise with "
NotSupportedError"DOMExceptionを投げてpromiseを返す -
もしdocumentのactive sandboxing flag setがsandboxed orientation lock browsing context flagを持つか、user agentが pre-lock conditionsを満たさないなら、 reject promise with "
SecurityError"DOMExceptionを投げてpromiseを返す -
documentの[[orientationPendingPromise]]にpromiseをセット
[DelayWhilePrerendering]
を unlock()
に追加する。
この修正により、screen.orientation.lock()
の直後に screen.orientation.unlock()
が呼ばれた場合にも期待通りの挙動になる。
6.4.13. Gamepad
getGamepads()
メソッドの手順の先頭に次を追加:
-
もしthisのrelevant global objectのnavigableがprerendering navigableであれば空のsequenceを返す。
gamepadconnected
とgamepaddisconnected
イベントに関する説明を修正し、Windowオブジェクトのnavigableがprerendering
navigableの場合はユーザーエージェントがこれらのイベントをdispatchしないことを明記する。
gamepadconnected
セクションを修正し、各Document
documentのpost-prerendering activation steps
listに以下を追加する:
-
もしdocumentが"
gamepad"機能のallowed to useであり、documentのrelevant settings objectがsecure contextで、かつgamepadが一つでも接続されていれば、接続されている各gamepadについてgamepadconnectedイベントをdocumentのrelevant global objectに対しGamepadEventを用いて発火し、gamepad属性は接続中gamepadを示す新規Gamepadオブジェクトで初期化する。
6.4.14. Encrypted Media Extensions
[DelayWhilePrerendering]
をrequestMediaKeySystemAccess()
に追加する。
6.4.15. Media Autoplay
playing the media resource セクションを修正し、
HTMLMediaElement
のcurrent playback positionは
Document
がprerendering
でない場合のみ単調増加することを明記する。
6.4.16. Media Capture and Streams
[DelayWhilePrerendering]
をgetUserMedia()、
getUserMedia()
および
enumerateDevices()
に追加する。
MediaDevices
セクションで、device change notification stepsの先頭に次を追加:
6.4.17. Web Audio API
allowed to startという概念は仕様内で使われているが詳細は実装依存とされている。
プリレンダ中の自動再生を制限するため、AudioContext
インタフェースセクションに以下ルールを追加:
AudioContext
はプリレンダ中はallowed to startにならない。
また、AudioContext()
コンストラクタの返却直前に以下の手順を追加:
-
プリレンダによってcontextがallowed to startになっていない場合、contextのpost-prerendering activation steps listに以下を追加:
-
contextの[[control thread state]] を
runningへセット -
control messageをキューしcontextをresume
-
プリレンダ時にresume()
を呼ぶ開発者もいることがある。その場合contextはallowed to startにならず、promiseは[[pending resume promises]]に格納される。
このpromiseは活性化時に上記手順でresolveされる。
AudioScheduledSourceNode
インタフェースのstart(when)メソッドや
AudioBufferSourceNode
のstart(when, offset, duration)メソッドも
[[control thread state]]に影響する可能性があるが、
contextがallowed to startではないため、該当アルゴリズムが
[[control thread
state]]をセットしない。contextが始動すればnodeも自動始動できるので問題はない。
6.4.18. Audio Output Devices API
[DelayWhilePrerendering]
を
selectAudioOutput()
に追加する。
6.4.19. Push API
[DelayWhilePrerendering]
を
subscribe()
に追加する。
6.4.20. Background Fetch
[DelayWhilePrerendering]
を
fetch()
に追加する。
6.4.21. Background Sync
[DelayWhilePrerendering]
を
register()
に追加する。
6.4.22. Storage API
[DelayWhilePrerendering]
を
persist()
に追加する。
6.4.23. WebUSB API
[DelayWhilePrerendering]
を
getDevices()
および
requestDevice()
に追加する。
6.4.24. Web Bluetooth
[DelayWhilePrerendering]
を
getDevices()
および
requestDevice()
に追加する。
6.4.25. WebHID API
[DelayWhilePrerendering]
を
getDevices()
および
requestDevice()
に追加する。
6.4.26. WebXR Device API
[DelayWhilePrerendering]
を
requestSession()
に追加する。
6.4.27. Credential Management
[DelayWhilePrerendering]
を
get()、
store()、
create()
に追加する。
6.4.28. Web Speech API
[DelayWhilePrerendering]
を
speak(utterance)、
cancel()、
pause()、
resume()
に追加する。
[DelayWhilePrerendering]
を
start()、
stop()、
abort()
に追加する。
6.4.29. Web Locks API
[DelayWhilePrerendering]
を
request(name, callback)、
request(name, options, callback)、
query()
に追加する。
6.4.30. カスタムスキームハンドラー
registerProtocolHandler(scheme, url)
メソッドの最初の並列前までの手順を次のように上書き:
-
(normalizedScheme, normalizedURLString)をnormalize protocol handler parametersの(scheme, url, thisのrelevant settings object)で取得する。
-
もしthisのrelevant global objectのnavigableがprerendering navigableなら、thisのpost-prerendering activation steps listに手順を追加してreturn。
unregisterProtocolHandler(scheme, url)
メソッドの最初の並列前までの手順を次のように上書き:
-
(normalizedScheme, normalizedURLString)をnormalize protocol handler parameters (scheme, url, thisのrelevant settings object)で取得する。
-
もしthisのrelevant global objectのnavigableがprerendering navigableなら、thisのpost-prerendering activation steps listに手順を追加してreturn。
6.5. 暗黙的に制限されるAPI
いくつかのAPIは修正不要です。なぜならprerendering navigableやそのactive window、active documentが絶対に持たない特性が必須条件のため、自動的に失敗またはno-opになります。これらの特性には次が含まれます:
どのAPIを検査済みか明示するため、ここに既知APIを一覧します。
一時的アクティベーション または スティッキーアクティベーション 必須API:
-
beforeunloadイベントで発生するプロンプト [HTML] -
element.requestFullscreen()[FULLSCREEN]-
navigator.keyboard.lock()[KEYBOARD-LOCK](fullscreenが必要)[KEYBOARD-LOCK]はキーボードロック有効化可能だが、fullscreen状態(ユーザー操作要)が条件。要件が変われば再検討要。
-
-
showOpenFilePicker(),showSaveFilePicker(),showDirectoryPicker()[FILE-SYSTEM-ACCESS] -
クリップボードイベントの発火 [CLIPBOARD-APIS]
システムフォーカス必須API:
-
非同期クリップボードAPI:
navigator.clipboard.read(),navigator.clipboard.readText(),navigator.clipboard.write(),navigator.clipboard.writeText()。 [CLIPBOARD-APIS]
"visible"な visibility state が必須なAPI:
より複雑なケース:
-
Request Picture-in-Picture(
video.requestPictureInPicture()呼び出し時)は 一時的アクティベーションまたは visibility stateが"visible"である必要がある。 [PICTURE-IN-PICTURE]
7. セキュリティに関する考慮事項
HTML § 7.6.5 Security considerationsを参照。
No-Vary-Search連携については、No-Vary-Search Security considerationsも参照。
プリレンダ固有のセキュリティ考慮事項追記要。 issue #319参照。
8. プライバシーに関する考慮事項
HTML § 7.6.6 Privacy considerationsを参照。
No-Vary-Search連携については、No-Vary-Search Privacy considerationsも参照。
プリレンダ固有のプライバシー考慮事項追記要。 issue #319参照。特に指摘すべき点として、パーティション間(クロスパーティション)プリレンダは、プライバシー上の複雑さを理由に単純に禁止される点が挙げられる。