1. 動機
このセクションは規範的ではありません。
Webアプリケーションは従来、ネットワークが到達可能であることを前提としています。この前提はプラットフォーム全体に浸透しています。HTML文書はHTTP経由で読み込まれ、従来はすべてのサブリソースも後続のHTTPリクエストで取得されます。このため、Webコンテンツは他の技術スタックと比べて不利な立場に置かれます。
サービスワーカーは、Web Workerコンテキストを提供することで、このバランスを是正するために設計されました。これは、ナビゲーションが発生する際にランタイムによって起動できるイベント駆動型ワーカーです。ワーカーは、オリジンとパス(またはパターン)に対して登録されるため、その場所へのナビゲーションが発生したときに参照されます。ネットワークリクエストに対応するイベントがワーカーに配送され、ワーカーが生成するレスポンスはデフォルトのネットワークスタックの動作を上書きする場合があります。これにより、サービスワーカーは概念的にネットワークとドキュメントレンダラーの間に位置し、オフライン時でもドキュメントにコンテンツを提供することができます。
以前のオフライン問題の解決策に慣れたWeb開発者からは、それらの解決策には柔軟性が欠如していると指摘されています。その結果、サービスワーカーは非常に手続き型となり、柔軟性を最大限に高める代わりに開発者により多くの複雑さをもたらします。この複雑さの一部は、サービスワーカーを単一スレッド実行モデルでも応答性を保つ必要から生じています。そのため、サービスワーカーが公開するAPIはほぼすべて非同期であり、他のJavaScriptコンテキストにも見られるパターンですが、ここではドキュメントやリソースの読み込みをブロックしない必要性から強調されています。
HTML5 Application Cacheを利用している開発者も、設計上のいくつかの属性が報告されているように回復不可能なエラーを引き起こす要因となっています。サービスワーカーの主要な設計原則は、エラーが常に回復可能であるべきだということです。サービスワーカーのアップデートプロセスの多くの詳細は、これらの危険を避けるように設計されています。
サービスワーカーは、ドキュメントではなくイベントとの関係によって開始・存続します。この設計は、共有ワーカーやChromeのバックグラウンドページに関する開発者やベンダーの経験を多く取り入れています。これらのシステムから得られた重要な教訓は、リソースの節約と背景コンテキストの喪失・再起動を開発者の意識の中心に置くために、バックグラウンド処理コンテキストの実行時間を制限する必要性です。その結果、サービスワーカーは、バックグラウンドページの後継であるChromeイベントページに非常に似ています。サービスワーカーは、ドキュメントが紐付いていなくてもユーザーエージェントによって起動され、ほぼいつでもユーザーエージェントによって終了させることができます。概念的には、サービスワーカーは、ドキュメントからのメッセージを処理することなく起動・イベント処理・終了ができる共有ワーカーと考えることができます。サービスワーカーは、1秒間に何度も起動・終了される可能性があることを開発者は意識しておくべきです。
サービスワーカーは、汎用的・イベント駆動・時間制限付きのスクリプトコンテキストであり、オリジンで実行されます。これらの特性により、特定のドキュメントのコンテキストを超えて存続するランタイムサービス(例:プッシュ通知の処理、バックグラウンドデータ同期、他のオリジンからのリソース要求への対応、計算コストの高いデータ(例:位置情報やジャイロスコープ)への一元的更新の受信)に自然なエンドポイントとなります。
2. モデル
2.1. サービスワーカー
サービスワーカーは、Web Workerの一種です。サービスワーカーは、登録元のサービスワークラクライアントのオリジンで実行されます。
サービスワーカーは、"parsed
"、"installing
"、"installed
"、"activating
"、"activated
"、"redundant
"のいずれかの状態を持ちます。初期状態は"parsed
"です。
サービスワーカーは、"classic
"または"module
"のいずれかの型を持ちます。特に明記されていない限り、"classic
"です。
サービスワーカーは、含有サービスワーカー登録(サービスワーカー登録)を持ち、自身を含みます。
サービスワーカーは、グローバルオブジェクト(ServiceWorkerGlobalScope
オブジェクトまたはnull)を持ちます。
サービスワーカーは、スクリプトリソース(スクリプト)を持ち、自身のスクリプトリソースを表します。初期値はnullです。
スクリプトリソースは、評価済みフラグを持ちます。初期状態は未設定です。
スクリプトリソースは、ポリシーコンテナ(ポリシーコンテナ)を持ちます。初期値は新規ポリシーコンテナです。
サービスワーカーは、スクリプトリソースマップ(順序付きマップ)を持ち、キーはURL、値はレスポンスです。
サービスワーカーは、使用済みスクリプト集合(集合)を持ち、要素はURLです。初期値は新規集合です。
注: 使用済みスクリプト集合は、新しいワーカーのインストール後に未使用リソースをマップから削除するためだけに利用され、アップデートチェック時に古いワーカーのマップを元に構築されます。
サービスワーカーは、skip waitingフラグを持ち、特に明記されていない限り未設定です。
サービスワーカーは、クラシックスクリプトインポート済みフラグを持ち、初期状態は未設定です。
サービスワーカーは、処理対象イベントタイプ集合(集合)を持ち、要素はイベントリスナーのイベントタイプです。初期値は新規集合です。
サービスワーカーは、拡張イベント集合(集合)を持ち、要素はExtendableEvent
です。初期値は新規集合です。
サービスワーカーは、nullまたはCompletionとなる開始状態を持ちます。初期値はnullです。
サービスワーカーは、全fetchリスナー空フラグを持ちます。初期状態は未設定です。
サービスワーカーは、ルーター規則リスト(リスト、RouterRule
のリスト)を持ち、初期値は空リストです。
サービスワーカーは、実行中であると言い、これはイベントループが稼働している状態です。
サービスワーカーは、[[service worker queue]](並列キュー)を持ちます。
2.1.1. ライフタイム
サービスワーカーのライフタイムはイベントの実行時間に紐付いており、サービスワークラクライアントがServiceWorker
オブジェクトを保持しているかどうかには依存しません。
ユーザーエージェントは、以下の場合いつでもサービスワーカーを終了することがあります:
-
処理するイベントが存在しない場合。
-
異常な動作(例:イベント処理中の無限ループや課せられた時間制限(存在する場合)を超えるタスク)を検出した場合。
2.1.2. イベント
Service Workers仕様は、サービスワーカーイベント(すべてイベント)を定義しており、以下を含みます(一覧参照):
2.2. サービスワーカーのタイミング
サービスワーカーは、後に navigation timing API で公開される特定の時点を記録します。
サービスワーカータイミング情報は、構造体です。次の項目を持ちます:
- 開始時刻
-
DOMHighResTimeStamp
、初期値は0。 - fetchイベント配送時刻
-
DOMHighResTimeStamp
、初期値は0。
2.3. サービスワーカーの登録
サービスワーカー登録は、スコープURL、ストレージキー、およびサービスワーカーのセット、インストール中ワーカー、待機ワーカー、アクティブワーカーからなるタプルです。ユーザーエージェントは、スコープURLが異なる限り、1つのオリジンで複数のサービスワーカー登録を有効にすることができます。ユーザーエージェント内ですでに存在するスコープURLと同一のサービスワーカー登録が新たに作成された場合、既存のサービスワーカー登録は置き換えられます。
サービスワーカー登録には、関連付けられたストレージキー(ストレージキー)があります。
サービスワーカー登録には、関連付けられたスコープURL(URL)があります。
サービスワーカー登録には、関連付けられたインストール中ワーカー(サービスワーカーまたはnull)があり、その状態は"installing
"です。初期値はnullです。
サービスワーカー登録には、関連付けられた待機ワーカー(サービスワーカーまたはnull)があり、その状態は"installed
"です。初期値はnullです。
サービスワーカー登録には、関連付けられたアクティブワーカー(サービスワーカーまたはnull)があり、その状態は"activating
"または"activated
"です。初期値はnullです。
サービスワーカー登録には、関連付けられた最終更新確認時刻があります。初期値はnullです。
サービスワーカー登録は、登録の最終更新確認時刻がnullでなく、現在時刻から登録の最終更新確認時刻を引いた秒数が86400より大きい場合、古くなっているとされます。
サービスワーカー登録には、関連付けられたキャッシュ経由での更新モードがあり、"imports
"、"all
"、または"none
"のいずれかです。初期値は"imports
"です。
サービスワーカー登録には、1つ以上のタスクキューがあり、タスクをアクティブワーカーのイベントループに対応するタスクキューからバックアップします。(このバックアップ操作のターゲットタスクソースは、fetch処理タスクソースおよび機能イベント処理タスクソースです。)ユーザーエージェントは、アクティブワーカーが終了されたとき、アクティブワーカーのタスクをサービスワーカー登録のタスクキューにダンプし、アクティブワーカーが再起動されたときにそれらのタスクを再度キューイングします。イベントループが所有するタスクキューとは異なり、サービスワーカー登録のタスクキュー自体は、いかなるイベントループによっても処理されません。
サービスワーカー登録には、関連付けられたNavigationPreloadManager
オブジェクトがあります。
サービスワーカー登録には、関連付けられたナビゲーションプリロード有効フラグがあります。初期状態は未設定です。
サービスワーカー登録には、関連付けられたナビゲーションプリロードヘッダー値(バイト列)があります。初期値はtrue
です。
サービスワーカー登録は、登録マップ[このストレージキー、シリアライズされたスコープURL]がこのサービスワーカー登録でない場合、登録解除済みとされます。
2.3.1. ライフタイム
ユーザーエージェントは、明示的に未登録されない限り、登録済みサービスワーカー登録のリストを永続的に保持しなければなりません。ユーザーエージェントは、サービスワーカー登録の(ストレージキー, 直列化された スコープURL)のタプルと、それに対応するサービスワーカー登録を格納するregistration mapを持ちます。サービスワーカー登録のライフタイムは、対応するサービスワークラクライアントのライフタイム内でそれを表すServiceWorkerRegistration
オブジェクトのライフタイムよりも長いです。
2.4. サービスワークラクライアント
サービスワークラクライアントは、環境です。
サービスワークラクライアントは、破棄フラグを持ちます。初期状態は未設定です。
各サービスワークラクライアントは、以下の環境破棄手順を持ちます:
-
clientの破棄フラグを設定する。
注: 実装は、破棄フラグが設定されたクライアントを破棄することができます。
サービスワークラクライアントは、originとして定義されるアルゴリズムを持ち、サービスワークラクライアントが環境設定オブジェクトの場合は、そのoriginを返し、それ以外の場合はサービスワークラクライアントの作成URLのoriginを返します。
ウィンドウクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトがWindow
オブジェクトです。
専用ワークラクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトがDedicatedWorkerGlobalScope
オブジェクトです。
共有ワークラクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトがSharedWorkerGlobalScope
オブジェクトです。
ワークラクライアントは、専用ワークラクライアントまたは共有ワークラクライアントのいずれかです。
2.5. 制御と利用
サービスワークラクライアントは、自身の読み込みやサブリソースのためのアクティブサービスワーカーを持ちます。サービスワークラクライアントが非nullのアクティブサービスワーカーを持つ場合、そのクライアントはそのアクティブサービスワーカーによって制御されていると言います。また、サービスワークラクライアントがサービスワーカーに利用されている場合、そのクライアントは含有サービスワーカー登録を利用していると言います。 サービスワークラクライアントのアクティブサービスワーカーは以下のサブセクションで説明する通りに決定されます。
このセクションの残り部分は規範的ではありません。
このセクションの挙動はまだ完全には規定されておらず、HTML標準で規定される予定です。作業はissueおよびpull requestで追跡されています。
2.5.1. ウィンドウクライアントの場合
ウィンドウクライアントは、作成されるとき、ブラウジングコンテキストが作成されたときや、ナビゲーション時に作成されます。
ウィンドウクライアントが作成され、ブラウジングコンテキストの作成過程にある場合:
そのブラウジングコンテキストの初期アクティブドキュメントのoriginが不透明なoriginの場合、ウィンドウクライアントのアクティブサービスワーカーはnullになります。 それ以外の場合は、作成元ドキュメントのサービスワークラクライアントのアクティブサービスワーカーに設定されます。
ウィンドウクライアントが作成され、ブラウジングコンテキストのナビゲーション過程にある場合:
fetchがHTTP fetchを経由する場合、ウィンドウクライアントのアクティブサービスワーカーはサービスワーカー登録一致の結果になります。 それ以外の場合、新たに作成されたドキュメントのoriginが不透明なoriginであるか、作成元ドキュメントのoriginと同一でない場合、ウィンドウクライアントのアクティブサービスワーカーはnullになります。 それ以外の場合は、作成元ドキュメントのサービスワークラクライアントのアクティブサービスワーカーに設定されます。
注: 初回置換ナビゲーションの場合、ウィンドウクライアントは作成時にブラウジングコンテキストが作成されたものが再利用されますが、アクティブサービスワーカーの決定は上記と同じ動作に従います。
注: sandboxediframe
でsandbox属性にallow-same-origin
およびallow-scripts
が指定されていない場合は、アクティブサービスワーカー値がnullになります。これはoriginが不透明なoriginとなるためです。
2.5.2. ワークラクライアントの場合
ワークラクライアントは、ユーザーエージェントが作成し、ワーカーを実行したときに作成されます。
ワークラクライアントが作成されたとき:
fetchがHTTP fetchを経由する場合、ワークラクライアントのアクティブサービスワーカーはサービスワーカー登録一致の結果になります。 それ以外の場合、ワークラクライアントのoriginが不透明なoriginである場合や、リクエストのURLがblob URLで、そのワークラクライアントのoriginが同一でない場合、最後の項目のワークラクライアントのグローバルオブジェクトのowner setのoriginと一致しない場合、ワークラクライアントのアクティブサービスワーカーはnullになります。 それ以外の場合は、最後の項目のワークラクライアントのグローバルオブジェクトのowner setの環境設定オブジェクトのアクティブサービスワーカーに設定されます。
注: ウィンドウクライアントやワークラクライアントがdata: URLを持つ場合、アクティブサービスワーカー値はnullとなります。これはoriginが不透明なoriginとなるためです。ウィンドウクライアントやワークラクライアントがblob URLを持つ場合は、作成元ドキュメントや所有者のアクティブサービスワーカーを継承できますが、リクエストのoriginが、作成元ドキュメントや所有者のoriginと同一でない場合、アクティブサービスワーカーはnullになります。
2.6. タスクソース
2.7. ユーザーエージェントのシャットダウン
ユーザーエージェントは、保存されたサービスワーカー登録の状態を再起動時にも維持しなければなりません。ただし、以下のルールに従います:
-
installing workerは永続化されず、破棄されます。もしinstalling workerがそのサービスワーカー登録にとって唯一のサービスワーカーだった場合、そのサービスワーカー登録も破棄されます。
-
waiting workerはactive workerに昇格します。
これを実現するため、ユーザーエージェントは終了時にユーザーエージェントのシャットダウン処理を呼び出す必要があります。
3. クライアントコンテキスト
// スコープはデフォルトでスクリプトが存在するパスになります // この例では "/" です navigator. serviceWorker. register( "/serviceworker.js" ). then( registration=> { console. log( "success!" ); if ( registration. installing) { registration. installing. postMessage( "インストール中のページからこんにちは" ); } }, err=> { console. error( "ワーカーのインストールに失敗しました!" , err); });
3.1.
ServiceWorker
[SecureContext ,Exposed =(Window ,Worker )]interface :
ServiceWorker EventTarget {readonly attribute USVString scriptURL ;readonly attribute ServiceWorkerState state ;undefined postMessage (any ,
message sequence <object >);
transfer undefined postMessage (any ,
message optional StructuredSerializeOptions = {}); // event
options attribute EventHandler onstatechange ; };ServiceWorker includes AbstractWorker ;enum {
ServiceWorkerState ,
"parsed" ,
"installing" ,
"installed" ,
"activating" ,
"activated" };
"redundant"
ServiceWorker
オブジェクトは サービスワーカーを表します。各 ServiceWorker
オブジェクトは サービスワーカー に関連付けられます。複数のドキュメントやワーカーで ServiceWorker
インターフェースを実装する個別のオブジェクトが、同じ サービスワーカー に同時に関連付けられることができます。
ServiceWorker
オブジェクトは ServiceWorkerState
オブジェクトを持ち、これは サービスワーカー の state に関連付けられています。
3.1.1. ServiceWorker
インスタンスの取得
環境設定オブジェクトは サービスワーカーオブジェクトマップ(マップ)を持ち、キーは サービスワーカー、値は ServiceWorker
オブジェクトです。
-
objectMap を environment の サービスワーカーオブジェクトマップとする。
-
objectMap[serviceWorker] が 存在しない場合:
-
serviceWorkerObj を environment の Realm で新規作成した
ServiceWorker
とし、serviceWorker に関連付ける。 -
objectMap[serviceWorker] に serviceWorkerObj を設定する。
-
-
objectMap[serviceWorker] を返す。
3.1.2.
scriptURL
scriptURL
ゲッター手順は、サービスワーカーの 直列化された script url を返す。
3.1.3.
state
state
属性は、(ServiceWorkerState
列挙)で最後に設定された値を返さなければなりません。
3.1.4. postMessage(message, transfer)
postMessage(message, transfer)
メソッド手順:
-
options を «[ "transfer" → transfer ]» とする。
-
message と options を引数に
postMessage(message, options)
を呼び出す。
3.1.5. postMessage(message, options)
postMessage(message, options)
メソッド手順:
-
incumbentSettings を 現職設定オブジェクトとする。
-
incumbentGlobal を incumbentSettings の グローバルオブジェクトとする。
-
serializeWithTransferResult を StructuredSerializeWithTransfer(message, options["
transfer
"]) の結果とする。例外は再スローする。 -
"message" と serviceWorkerで イベントスキップ判定アルゴリズムの結果が true なら return。
-
以下のサブステップを 並列で実行:
-
serviceWorker で サービスワーカーの実行アルゴリズムの結果が failure なら return。
-
DOM操作タスクソースで以下を実行:
-
incumbentGlobal の型に応じて source を決定:
ServiceWorkerGlobalScope
- incumbentGlobal の service worker を serviceWorker の 関連設定オブジェクトで表すサービスワーカーオブジェクト取得の結果
Window
- incumbentGlobal の 関連設定オブジェクトを表す新しい
WindowClient
オブジェクト - その他
- incumbentGlobal の関連ワーカーを表す新しい
Client
オブジェクト
-
destination を serviceWorker に関連付けられた
ServiceWorkerGlobalScope
オブジェクトとする。 -
deserializeRecord を StructuredDeserializeWithTransfer(serializeWithTransferResult, destination の Realm) とする。
例外が発生した場合は、originを初期化した
messageerror
イベントをExtendableMessageEvent
を使い作成し、source
を初期化する。 -
それ以外:
-
messageClone を deserializeRecord.[[Deserialized]] とする。
-
newPorts を deserializeRecord.[[TransferredValues]] 内のすべての
MessagePort
オブジェクトから作成した新しい frozen array(順序維持)とする。 -
e を origin、source、messageClone、newPortsを初期化した
message
イベントとしてExtendableMessageEvent
を使い作成する。
-
-
Dispatch e を destination で実行。
-
サービスワーカー拡張イベントセットの更新 を serviceWorker と e で呼び出す。
-
-
3.1.6. イベントハンドラー
以下は イベントハンドラー(および対応する イベントハンドラーイベントタイプ)であり、すべての ServiceWorker
インターフェース実装オブジェクトで イベントハンドラーIDL属性としてサポートしなければなりません:
event handler | event handler event type |
---|---|
onstatechange
| statechange
|
3.2. ServiceWorkerRegistration
[SecureContext ,Exposed =(Window ,Worker )]interface :
ServiceWorkerRegistration EventTarget {readonly attribute ServiceWorker ?installing ;readonly attribute ServiceWorker ?waiting ;readonly attribute ServiceWorker ?active ; [SameObject ]readonly attribute NavigationPreloadManager navigationPreload ;readonly attribute USVString scope ;readonly attribute ServiceWorkerUpdateViaCache updateViaCache ; [NewObject ]Promise <undefined >update (); [NewObject ]Promise <boolean >unregister (); // eventattribute EventHandler onupdatefound ; };enum {
ServiceWorkerUpdateViaCache ,
"imports" ,
"all" };
"none"
ServiceWorkerRegistration
は、サービスワーカー登録(サービスワーカー登録)を持ちます。
3.2.1. ServiceWorkerRegistration
インスタンスの取得
環境設定オブジェクトは、サービスワーカー登録オブジェクトマップを持ちます。これは、マップであり、キーがサービスワーカー登録、値がServiceWorkerRegistration
オブジェクトです。
-
objectMapをenvironmentのサービスワーカー登録オブジェクトマップとする。
-
objectMap[registration]が存在しない場合:
-
registrationObjectをenvironmentのRealmで新規作成した
ServiceWorkerRegistration
とする。 -
registrationObjectのサービスワーカー登録をregistrationに設定する。
-
registrationObjectの
installing
属性をnullに設定する。 -
registrationObjectの
waiting
属性をnullに設定する。 -
registrationObjectの
active
属性をnullに設定する。 -
registrationのinstalling workerがnullでない場合、registrationObjectの
installing
属性をregistrationのinstalling workerをenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。 -
registrationのwaiting workerがnullでない場合、registrationObjectの
waiting
属性をregistrationのwaiting workerをenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。 -
registrationのactive workerがnullでない場合、registrationObjectの
active
属性をregistrationのactive workerをenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。 -
objectMap[registration]にregistrationObjectを設定する。
-
-
objectMap[registration]を返す。
3.2.2. installing
installing
属性は、最後に設定された値を返さなければなりません。
注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorker
オブジェクトのみ存在します。
3.2.3. waiting
waiting
属性は、最後に設定された値を返さなければなりません。
注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorker
オブジェクトのみ存在します。
3.2.4. active
active
属性は、最後に設定された値を返さなければなりません。
注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorker
オブジェクトのみ存在します。
3.2.5. navigationPreload
navigationPreload
ゲッター手順は、サービスワーカー登録のNavigationPreloadManager
オブジェクトを返すこと。
3.2.6. scope
scope
ゲッター手順は、サービスワーカー登録の直列化されたscope urlを返すこと。
registration.scope
(例えばnavigator.serviceWorker.ready.then(registration => console.log(registration.scope))
で取得)は"https://example.com/
"となります。
3.2.7. updateViaCache
updateViaCache
ゲッター手順は、サービスワーカー登録のupdate
via cacheモードを返すこと。
3.2.8. update()
update()
メソッド手順:
-
registrationをサービスワーカー登録とする。
-
newestWorkerを最新ワーカー取得アルゴリズムでregistrationを引数に実行した結果にする。
-
newestWorkerがnullの場合、失敗したpromise("
InvalidStateError
"DOMException
)を返して中断。 -
thisの関連グローバルオブジェクトglobalObjectが
ServiceWorkerGlobalScope
オブジェクトであり、globalObjectの関連サービスワーカーのstateが"installing
"の場合、失敗したpromise("InvalidStateError
"DOMException
)を返して中断。 -
promiseをpromiseとする。
-
jobをジョブ作成アルゴリズムで、update、registrationのstorage key、registrationのscope url、newestWorkerのscript url、promise、thisの関連設定オブジェクトを引数に実行した結果にする。
-
jobのworker typeをnewestWorkerのtypeに設定する。
-
ジョブスケジュールをjobで呼び出す。
-
promiseを返す。
3.2.9. unregister()
注: unregister()
メソッドはサービスワーカー登録を解除します。現在制御されているサービスワークラクライアントのアクティブサービスワーカーの含有サービスワーカー登録は、そのサービスワーカー登録を利用するすべてのサービスワークラクライアント(自身を含む)がアンロードされるまで有効です。つまり、unregister()
メソッドは、以降のナビゲーションにのみ影響します。
unregister()
メソッド手順:
-
registrationをサービスワーカー登録とする。
-
promiseを新規promiseとする。
-
jobをジョブ作成アルゴリズムで、unregister、registrationのstorage key、registrationのscope url、null、promise、thisの関連設定オブジェクトを引数に実行した結果にする。
-
ジョブスケジュールをjobで呼び出す。
-
promiseを返す。
3.2.10. イベントハンドラー
以下はイベントハンドラー(および対応するイベントハンドラーイベントタイプ)であり、すべてのServiceWorkerRegistration
インターフェース実装オブジェクトでイベントハンドラーIDL属性としてサポートしなければなりません:
event handler | event handler event type |
---|---|
onupdatefound
| updatefound
|
3.3.
navigator.serviceWorker
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute ServiceWorkerContainer serviceWorker ; };partial interface WorkerNavigator { [SecureContext ,SameObject ]readonly attribute ServiceWorkerContainer serviceWorker ; };
serviceWorker
ゲッターの手順は、ServiceWorkerContainer
オブジェクトをthisに関連付けて返すことです。
3.4. ServiceWorkerContainer
[SecureContext ,Exposed =(Window ,Worker )]interface :
ServiceWorkerContainer EventTarget {readonly attribute ServiceWorker ?controller ;readonly attribute Promise <ServiceWorkerRegistration >ready ; [NewObject ]Promise <ServiceWorkerRegistration >register ((TrustedScriptURL or USVString ),
scriptURL optional RegistrationOptions = {}); [
options NewObject ]Promise <(ServiceWorkerRegistration or undefined )>getRegistration (optional USVString = ""); [
clientURL NewObject ]Promise <FrozenArray <ServiceWorkerRegistration >>getRegistrations ();undefined startMessages (); // eventsattribute EventHandler oncontrollerchange ;attribute EventHandler onmessage ; // event.source of message events is ServiceWorker objectattribute EventHandler onmessageerror ; };
dictionary {
RegistrationOptions USVString ;
scope WorkerType = "classic";
type ServiceWorkerUpdateViaCache = "imports"; };
updateViaCache
ユーザーエージェントは、ServiceWorkerContainer
オブジェクトをNavigator
オブジェクトまたはWorkerNavigator
オブジェクト作成時に生成し、それらのオブジェクトに関連付けなければなりません。
ServiceWorkerContainer
は、サービスワーカー登録の登録・解除・更新の機能を提供し、サービスワーカー登録およびそれに関連するサービスワーカーの状態へのアクセスを提供します。
ServiceWorkerContainer
は、関連するサービスワークラクライアントを持ちます。これは、サービスワークラクライアントであり、そのグローバルオブジェクトがNavigator
またはWorkerNavigator
オブジェクトに関連付けられています。
ServiceWorkerContainer
オブジェクトは、関連するready promise
(promiseまたはnull)を持ちます。初期値はnullです。
ServiceWorkerContainer
オブジェクトは、タスクソースとしてクライアントメッセージキュー(初期値は空)を持ちます。クライアントメッセージキューは有効・無効にでき、初期状態は無効です。ServiceWorkerContainer
オブジェクトのクライアントメッセージキューが有効な場合、イベントループはそれをタスクソースの一つとして使用しなければなりません。ServiceWorkerContainer
オブジェクトの関連グローバルオブジェクトがWindow
オブジェクトの場合、すべてのタスクはキューされる際、クライアントメッセージキューに関連付けられ、その関連設定オブジェクトの関連ドキュメントに紐付けられます。
3.4.1. controller
controller
属性の手順は以下の通り実行しなければなりません:
-
clientをthisのサービスワークラクライアントとする。
-
clientのアクティブサービスワーカー がnullの場合、nullを返す。
-
clientのアクティブサービスワーカーをサービスワーカーオブジェクト取得で、thisの関連設定オブジェクトで表現した結果を返す。
注: navigator.serviceWorker.controller
はリクエストが強制リフレッシュ(shift+refresh)の場合、null
を返します。
3.4.2. ready
ready
属性は以下の手順で実行しなければなりません:
-
thisのready promiseがnullの場合、thisのready promiseに新規promiseを設定する。
-
readyPromiseをthisのready promiseとする。
-
readyPromiseがpendingの場合、以下のサブステップを並列で実行:
-
clientをthisの サービスワークラクライアントとする。
-
storage keyをストレージキー取得でclientを引数に実行した結果とする。
-
registrationをサービスワーカー登録一致でstorage keyとclientの作成URLを引数に実行した結果とする。
-
registrationがnullでなく、registrationのactive workerがnullでない場合、DOM操作タスクソースでreadyPromiseの関連設定オブジェクトの責任イベントループにタスクをキューし、readyPromiseをregistrationを表すサービスワーカー登録オブジェクト取得の結果で解決する。
-
-
readyPromiseを返す。
注: 返されるready promiseはrejectされません。このアルゴリズムでresolveされない場合でも、該当するサービスワーカー登録が登録され、active workerが設定されると必ずresolveされます。(該当するActivateアルゴリズム参照)
3.4.3. register(scriptURL, options)
注: register(scriptURL, options)
メソッドは、指定されたscope
urlのサービスワーカー登録を新規作成または更新します。成功すると、提供されたscriptURLがscope
urlに関連付けられ、以後ナビゲーションマッチング(navigation matching)で使用されます。
register(scriptURL, options)
メソッド手順:
-
pをpromiseとする。
-
scriptURLを
TrustedScriptURL
、 thisの関連グローバルオブジェクト、 scriptURL、"ServiceWorkerContainer register"、"script"でGet Trusted Type compliant stringを呼び出した結果にする。 -
clientをthisのサービスワークラクライアントとする。
-
scriptURLをURLパーサーでthisの関連設定オブジェクトのAPI base URLで解析した結果にする。
-
scopeURLをnullとする。
-
options["
scope
"] が存在する場合、scopeURLをURLパーサーでoptions["scope
"]をthisの関連設定オブジェクトのAPI base URLで解析した結果に設定する。 -
Start RegisterをscopeURL、scriptURL、p、client、clientの作成URL、options["
type
"]、options["updateViaCache
"]で呼び出す。 -
pを返す。
3.4.4. getRegistration(clientURL)
getRegistration(clientURL)
メソッド手順:
-
clientをthisのサービスワークラクライアントとする。
-
storage keyをストレージキー取得でclientを引数に実行した結果とする。
-
clientURLをURLパーサーでclientURLをthisの関連設定オブジェクトのAPI base URLで解析した結果にする。
-
clientURLが失敗の場合、promiseをTypeErrorでrejectして返す。
-
clientURLのfragmentをnullに設定する。
-
clientURLのoriginがclientのoriginでない場合、promiseをSecurityErrorのDOMExceptionでrejectして返す。
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationをサービスワーカー登録一致でstorage keyとclientURLを引数に実行した結果とする。
-
registrationがnullの場合、promiseをundefinedでresolveして手順終了。
-
promiseをregistrationを表すサービスワーカー登録オブジェクト取得の結果でresolveする。
-
-
promiseを返す。
3.4.5. getRegistrations()
getRegistrations()
メソッド手順:
-
clientをthisのサービスワークラクライアントとする。
-
client storage keyをストレージキー取得でclientを引数に実行した結果とする。
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationsを新規リストとする。
-
各 (storage key, scope) → registration をregistration mapから反復:
-
DOM操作タスクソースでpromiseの関連設定オブジェクトの責任イベントループにタスクをキューして、以下を実行:
-
registrationObjectsを新規リストとする。
-
各 registrationをregistrationsで反復:
-
registrationObjをregistrationを表すサービスワーカー登録オブジェクト取得の結果とする。
-
append registrationObjをregistrationObjectsに追加。
-
-
promiseを新規frozen arrayでregistrationObjectsをpromiseの関連Realmで解決する。
-
-
-
promiseを返す。
3.4.6. startMessages()
startMessages()
メソッドの手順は、thisのクライアントメッセージキューが有効でなければ有効化すること。
3.4.7. イベントハンドラー
以下はイベントハンドラー(および対応するイベントハンドラーイベントタイプ)であり、すべてのServiceWorkerContainer
インターフェース実装オブジェクトでイベントハンドラーIDL属性としてサポートしなければなりません:
event handler | event handler event type |
---|---|
oncontrollerchange
| controllerchange
|
onmessage
| message
|
onmessageerror
| messageerror
|
初めてonmessage
セッター手順が実行された時、thisのクライアントメッセージキューを有効化します。
3.5. イベント
以下のイベントは ServiceWorker
オブジェクト上で配送されます:
イベント名 | インターフェース | 配送タイミング |
---|---|---|
statechange
| Event
| state
属性が ServiceWorker
オブジェクトで変更されたとき。
|
以下のイベントは ServiceWorkerRegistration
オブジェクト上で配送されます:
イベント名 | インターフェース | 配送タイミング |
---|---|---|
updatefound
| Event
| サービスワーカー登録の installing worker が変更されたとき(Installアルゴリズムのステップ8参照)。 |
以下のイベントは ServiceWorkerContainer
オブジェクト上で配送されます:
イベント名 | インターフェース | 配送タイミング |
---|---|---|
controllerchange
| Event
| サービスワークラクライアントのアクティブサービスワーカーが変更されたとき(Activateアルゴリズムのステップ9.2参照。skip
waitingフラグ付きのサービスワーカーはactivationをサービスワーカー登録がサービスワークラクライアントに利用されている間に発生させ、navigator.serviceWorker.controller
は即座に active worker を、そのサービスワーカーが制御するサービスワークラクライアントとして即座に反映します。)
|
message
| Event
| サービスワークラクライアントがサービスワーカーからメッセージを受信したとき。postMessage(message, options) 参照。
|
messageerror
| Event
| サービスワークラクライアントがサービスワーカーからデシリアライズできないメッセージを受信したとき。postMessage(message, options) 参照。
|
3.6.
NavigationPreloadManager
[SecureContext ,Exposed =(Window ,Worker )]interface {
NavigationPreloadManager Promise <undefined >enable ();Promise <undefined >disable ();Promise <undefined >setHeaderValue (ByteString );
value Promise <NavigationPreloadState >getState (); };dictionary {
NavigationPreloadState boolean =
enabled false ;ByteString ; };
headerValue
3.6.1. enable()
enable()
メソッドの手順:
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationをthisの関連付けられたサービスワーカー登録とする。
-
registrationのactive workerがnullの場合、promiseを "
InvalidStateError
"DOMException
でrejectし、この手順を中断。 -
registrationのnavigation preload enabled flagを設定する。
-
promiseをundefinedでresolveする。
-
-
promiseを返す。
3.6.2. disable()
disable()
メソッドの手順:
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationをthisの関連付けられたサービスワーカー登録とする。
-
registrationのactive workerがnullの場合、promiseを "
InvalidStateError
"DOMException
でrejectし、この手順を中断。 -
registrationのnavigation preload enabled flagを解除する。
-
promiseをundefinedでresolveする。
-
-
promiseを返す。
3.6.3. setHeaderValue(value)
setHeaderValue(value)
メソッドの手順:
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationをthisの関連付けられたサービスワーカー登録とする。
-
registrationのactive workerがnullの場合、promiseを "
InvalidStateError
"DOMException
でrejectし、この手順を中断。 -
registrationのnavigation preload header valueをvalueに設定する。
-
promiseをundefinedでresolveする。
-
-
promiseを返す。
3.6.4. getState()
getState()
メソッドの手順:
-
promiseを新規promiseとする。
-
以下の手順を並列で実行:
-
registrationをthisの関連付けられたサービスワーカー登録とする。
-
stateを新規
NavigationPreloadState
辞書とする。 -
registrationのnavigation preload enabled flagが設定されている場合、state["
enabled
"]をtrueに設定する。 -
state["
headerValue
"]をregistrationのnavigation preload header valueに設定する。 -
promiseをstateでresolveする。
-
-
promiseを返す。
4. 実行コンテキスト
// caching.js self. addEventListener( "install" , event=> { event. waitUntil( // リソースのキャッシュを開く。 caches. open( "shell-v1" ). then( cache=> { // それらの取得処理を開始する。全てのリソースが保存された場合のみ成功。 // 一つでも失敗すると、全体の操作は失敗となる。 return cache. addAll([ "/app.html" , "/assets/v1/base.css" , "/assets/v1/app.js" , "/assets/v1/logo.png" , "/assets/v1/intro_video.webm" ]); }) ); }); self. addEventListener( "fetch" , event=> { // Service Workerが正常にインストール・アクティベートされるまで、"fetch"イベントはディスパッチされない。 // キャッシュ操作は全て非同期で行われるため、URL照合を含めPromiseを多用する。e.respondWith()もPromiseを受け付ける: event. respondWith( caches. match( e. request). then( response=> { return response|| fetch( e. request); }). catch (() => { return caches. match( "/fallback.html" ); }) ); });
4.1. ServiceWorkerGlobalScope
[Global =(Worker ,ServiceWorker ),Exposed =ServiceWorker ,SecureContext ]interface :
ServiceWorkerGlobalScope WorkerGlobalScope { [SameObject ]readonly attribute Clients clients ; [SameObject ]readonly attribute ServiceWorkerRegistration registration ; [SameObject ]readonly attribute ServiceWorker serviceWorker ; [NewObject ]Promise <undefined >skipWaiting ();attribute EventHandler oninstall ;attribute EventHandler onactivate ;attribute EventHandler onfetch ;attribute EventHandler onmessage ;attribute EventHandler onmessageerror ; };
ServiceWorkerGlobalScope
オブジェクトは、Service
Worker のグローバルな実行コンテキストを表します。
ServiceWorkerGlobalScope
オブジェクトは、関連付けられた service worker
(Service
Worker)を持ちます。
ServiceWorkerGlobalScope
オブジェクトには、import
scripts用キャッシュ強制バイパスフラグ が関連付けられています。初期状態では未設定です。
ServiceWorkerGlobalScope
オブジェクトには、race response
map が関連付けられています。これは 順序付きマップ であり、キー は リクエスト で、
値 は race response です。
race response
は、構造体
であり、"race-network-and-fetch-handler"
が実行された際のネットワークレスポンスを保持するために使われます。これは value(response、"pending" または null)を持ちます。
注: ServiceWorkerGlobalScope
オブジェクトは、オリジンで実行される汎用的なイベント駆動型・時間制限付きスクリプトの実行コンテキストを提供します。
正常に 登録 されると、
Service
Worker が起動し、
イベントとの関係によって存続・終了されます。 Service Workerクライアント との直接的な関係では存続しません。
Service Worker内で同期リクエストは開始しないでください。
4.1.1. clients
4.1.2. registration
registration
のgetterは、
サービスワーカー登録オブジェクトの取得 の結果を返します。
これは this の
service worker の
含まれるService Worker登録 を
該当設定オブジェクト内で表します。
4.1.3. serviceWorker
serviceWorker
のgetterは、
Service Workerオブジェクトの取得 の結果を返します。
これは this の
service worker を、
該当設定オブジェクト内で表します。
4.1.4. skipWaiting()
注: skipWaiting()
メソッドは、この Service Worker を、
登録 の waiting 状態から
active
状態へと進めることができます。
Service Workerクライアント
がその 登録 を
利用している最中でも実行可能です。
skipWaiting()
メソッドの手順:
-
promise を新しい Promise とする。
-
以下のサブステップを 並行して実行する:
-
service worker の skip waitingフラグ を設定する。
-
Try Activate を service worker の 含まれるService Worker登録 に対して呼び出す。
-
promise を undefined で解決する。
-
-
promise を返す。
4.1.5. イベントハンドラ
以下は、イベントハンドラ
(対応する イベント型)であり、
ServiceWorkerGlobalScope
インターフェースを実装する全てのオブジェクトで 必ず サポートされるべき
イベントハンドラIDL属性 です:
イベントハンドラ | イベント型 |
---|---|
oninstall
| install
|
onactivate
| activate
|
onfetch
| fetch
|
onmessage
| message
|
onmessageerror
| messageerror
|
4.2. Client
[Exposed =ServiceWorker ]interface {
Client readonly attribute USVString url ;readonly attribute FrameType frameType ;readonly attribute DOMString id ;readonly attribute ClientType type ;undefined postMessage (any ,
message sequence <object >);
transfer undefined postMessage (any ,
message optional StructuredSerializeOptions = {}); }; [
options Exposed =ServiceWorker ]interface :
WindowClient Client {readonly attribute VisibilityState visibilityState ;readonly attribute boolean focused ; [SameObject ]readonly attribute FrozenArray <USVString >ancestorOrigins ; [NewObject ]Promise <WindowClient >focus (); [NewObject ]Promise <WindowClient ?>navigate (USVString ); };
url enum {
FrameType ,
"auxiliary" ,
"top-level" ,
"nested" };
"none"
Client
オブジェクトには、関連付けられた service worker client
(service worker client)があります。
Client
オブジェクトには、関連付けられた frame
type(フレームタイプ)があり、"auxiliary
"、"top-level
"、"nested
"、"none
"
のいずれかです。特に記載がなければ "none
" となります。
WindowClient
オブジェクトには、関連付けられた 閲覧コンテキスト(browsing
context)があり、これはその service worker client の グローバルオブジェクト の 閲覧コンテキストです。
WindowClient
オブジェクトには、関連付けられた 可視状態(visibility state)があり、これは visibilityState
属性値のいずれかです。
WindowClient
オブジェクトには、関連付けられた フォーカス状態(focus state)があり、true または false(初期値は
false)です。
WindowClient
オブジェクトには、関連付けられた 先祖オリジン配列(ancestor origins
array)があります。
4.2.1.
url
url
のgetter手順は、this に関連付けられた service worker client の 直列化された 作成URL を返します。
4.2.2.
frameType
frameType
のgetter手順は、this の frame type を返します。
4.2.3.
id
id
のgetter手順は、this に関連付けられた service worker client の id を返します。
4.2.4.
type
type
のgetter手順:
-
client を this の service worker client とする。
-
client が environment settings object なら:
-
client が window client なら
"window"
を返す。 -
そうでなく、client が dedicated worker client なら
"worker"
を返す。 -
さらにそうでなく、client が shared worker client なら
"sharedworker"
を返す。
-
-
それ以外の場合:
-
"window"
を返す。
-
4.2.5.
postMessage(message, transfer)
postMessage(message, transfer)
メソッドの手順:
-
options を «[ "transfer" → transfer ]» とする。
-
postMessage(message, options)
を message と options を引数として呼び出す。
4.2.6. postMessage(message, options)
postMessage(message, options)
メソッドの手順:
-
contextObject を this とする。
-
sourceSettings を contextObject の 該当設定オブジェクト とする。
-
serializeWithTransferResult を StructuredSerializeWithTransfer(message, options["
transfer
"]) とする。例外は再スローする。 -
以下の手順を 並行して実行する:
-
targetClient を null とする。
-
各 service worker client client について:
-
client が contextObject の service worker client であれば、targetClient に client を設定し、break する。
-
-
targetClient が null なら return。
-
destination を、関連する service worker client が targetClient である
ServiceWorkerContainer
オブジェクトとする。 -
destination の client message queue に、次の手順を実行するタスクを追加する:
-
source を、service workerオブジェクトの取得の結果とし、これは contextObject の 該当グローバルオブジェクト の service worker を targetClient で表す。
-
deserializeRecord を StructuredDeserializeWithTransfer(serializeWithTransferResult, destination の 該当Realm) とする。
例外が発生した場合、それをキャッチし、
messageerror
イベントを destination でMessageEvent
を使って発火し、origin
属性を origin で、source
属性を source で初期化し、その後これらの手順を中止する。 -
messageClone を deserializeRecord.[[Deserialized]] とする。
-
newPorts を、deserializeRecord.[[TransferredValues]] 内の全ての
MessagePort
オブジェクトからなる新しい frozen array とする(もしあれば)。 -
message
イベントを destination でMessageEvent
を使って発火し、origin
属性を origin で、source
属性を source で、data
属性を messageClone で、ports
属性を newPorts で初期化する。
-
4.2.7. visibilityState
4.2.8.
focused
4.2.9. ancestorOrigins
4.2.10.
focus()
focus()
メソッド手順:
-
この オリジン に
Window
が一つも 一時的なアクティベーション を持たない場合、"InvalidAccessError
"DOMException
で拒否された promise を返す。 -
promise を新しい promise とする。
-
タスクをキューに入れる。次の手順を this に関連付けられた service worker client の 責任イベントループ上で ユーザー操作タスクソース を使って実行する:
-
frameType を Get Frame Type を this の 閲覧コンテキスト で実行した結果とする。
-
visibilityState を this の 閲覧コンテキスト の アクティブドキュメント の
visibilityState
属性値とする。 -
focusState を has focus手順 を this の 閲覧コンテキスト の アクティブドキュメント に対して実行した結果とする。
-
ancestorOriginsList を this の 閲覧コンテキスト の アクティブドキュメント の 該当グローバルオブジェクト の
Location
オブジェクトの 先祖オリジンリスト の関連リストとする。 -
タスクをキューに入れる。次の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:
-
windowClient を Create Window Client に this に関連付けられた service worker client、frameType、visibilityState、focusState、ancestorOriginsList を渡して実行した結果とする。
-
windowClient の フォーカス状態 が true なら、promise を windowClient で解決する。
-
そうでなければ、promise を
TypeError
で拒否する。
-
-
promise を返す。
4.2.11.
navigate(url)
navigate(url)
メソッド手順:
-
url を パース した結果とし、this の 該当設定オブジェクト の APIベースURL を使う。
-
url が失敗の場合、
TypeError
で拒否された promise を返す。 -
url が
about:blank
の場合、TypeError
で拒否された promise を返す。 -
this に関連付けられた service worker client の active service worker が this の 該当グローバルオブジェクト の service worker でない場合、
TypeError
で拒否された promise を返す。 -
serviceWorkerEventLoop を 現在のグローバルオブジェクト の イベントループ とする。
-
promise を新しい promise とする。
-
タスクをキューに入れる。次の手順を this に関連付けられた service worker client の 責任イベントループ上で ユーザー操作タスクソース を使って実行する:
-
browsingContext の 関連ドキュメント が 完全アクティブ でない場合、タスクをキューに入れる。promise を
TypeError
で serviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。 -
HandleNavigate: ナビゲート browsingContext を url へ、browsingContext の 関連ドキュメント を使い、例外有効 を true とする。
-
HandleNavigate ラベル付きのアルゴリズム手順が 例外 を投げた場合、タスクをキューに入れる。promise を例外で serviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。
-
frameType を Get Frame Type を browsingContext で実行した結果とする。
-
visibilityState を browsingContext の アクティブドキュメント の
visibilityState
属性値とする。 -
focusState を has focus手順 を browsingContext の アクティブドキュメント に対して実行した結果とする。
-
ancestorOriginsList を browsingContext の アクティブドキュメント の 該当グローバルオブジェクト の
Location
オブジェクトの 先祖オリジンリスト の関連リストとする。 -
タスクをキューに入れる。次の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:
-
browsingContext の
Window
オブジェクトの environment settings object の 作成URL の origin が 同一 でない場合、service worker の origin と、promise を null で解決し、これらの手順を中止する。 -
windowClient を Create Window Client に this の service worker client、frameType、visibilityState、focusState、ancestorOriginsList を渡して実行した結果とする。
-
promise を windowClient で解決する。
-
-
promise を返す。
4.3.
Clients
[Exposed =ServiceWorker ]interface { // 返されるオブジェクトは毎回新しいインスタンスとなる [
Clients NewObject ]Promise <(Client or undefined )>get (DOMString ); [
id NewObject ]Promise <FrozenArray <Client >>matchAll (optional ClientQueryOptions = {}); [
options NewObject ]Promise <WindowClient ?>openWindow (USVString ); [
url NewObject ]Promise <undefined >claim (); };
dictionary {
ClientQueryOptions boolean =
includeUncontrolled false ;ClientType = "window"; };
type
enum {
ClientType ,
"window" ,
"worker" ,
"sharedworker" };
"all"
ユーザーエージェントは ServiceWorkerGlobalScope
オブジェクトが作成されるとき、必ず Clients
オブジェクトを作成し、そのオブジェクトに関連付けなければならない。
4.3.1.
get(id)
get(id)
メソッドの手順:
-
promise を新しい promise とする。
-
以下のサブステップを 並行して実行する:
-
各 service worker client client について、ストレージキーの取得 の結果が、関連する service worker の 含まれるService Worker登録 の ストレージキー と等しい場合:
-
promise を undefined で解決する。
-
-
promise を返す。
4.3.2.
matchAll(options)
matchAll(options)
メソッドの手順:
-
promise を 新しいpromise とする。
-
以下の手順を 並行して実行する:
-
targetClients を新しい リスト とする。
-
各 service worker client client について、ストレージキーの取得 の結果が、関連する service worker の 含まれるService Worker登録 の ストレージキー と等しい場合:
-
client の 実行準備フラグ が未設定、または client の 破棄フラグ が設定されている場合、continue。
-
client が セキュアコンテキスト でない場合、continue。
-
options["
includeUncontrolled
"] が false であり、かつ client の active service worker が関連 service worker でない場合、continue。 -
client を targetClients に追加する。
-
-
matchedWindowData を新しい リスト とする。
-
matchedClients を新しい リスト とする。
-
targetClients 内の各 service worker client client について:
-
options["
type
"] が"window"
または"all"
であり、 client が environment settings object でない、または window client である場合:-
windowData を «[ "client" → client, "ancestorOriginsList" → 新しい リスト ]» とする。
-
browsingContext を null とする。
-
isClientEnumerable を true とする。
-
client が environment settings object なら、browsingContext を client の グローバルオブジェクト の 閲覧コンテキスト とする。
-
そうでなければ、browsingContext を client の ターゲット閲覧コンテキスト とする。
-
タスクをキューに入れる。以下のサブステップを browsingContext の イベントループ で ユーザー操作タスクソース を使って実行する:
-
browsingContext が 破棄済み なら、isClientEnumerable を false にしてこれらの手順を中止する。
-
client がwindow clientかつ client の 関連ドキュメント が browsingContext の アクティブドキュメント でない場合、isClientEnumerable を false にしてこれらの手順を中止する。
-
windowData["
frameType
"] に Get Frame Type を browsingContext で実行した結果を設定する。 -
windowData["
visibilityState
"] に browsingContext の アクティブドキュメント のvisibilityState
属性値を設定する。 -
windowData["
focusState
"] に has focus手順 を browsingContext の アクティブドキュメント に対して実行した結果を設定する。 -
client が window client なら、 windowData["
ancestorOriginsList
"] に browsingContext の アクティブドキュメント の 該当グローバルオブジェクト のLocation
オブジェクトの 先祖オリジンリスト の関連リストを設定する。
-
-
task が実行されるまで待つ。
注: 待機はブロッキングだが、実装者は状態が壊れない限り並行して反復処理できる。
-
isClientEnumerable が true なら:
-
windowData を matchedWindowData に追加する。
-
-
-
そうでなく options["
type
"] が"worker"
または"all"
かつ client が dedicated worker client の場合、あるいは options["type
"] が"sharedworker"
または"all"
かつ client が shared worker client の場合:-
client を matchedClients に追加する。
-
-
-
タスクをキューに入れる。以下の手順を promise の 該当設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使って実行する:
-
clientObjects を新しい リスト とする。
-
各 windowData について、matchedWindowData 内で:
-
windowClient を Create Window Client アルゴリズムを windowData["
client
"], windowData["frameType
"], windowData["visibilityState
"], windowData["focusState
"], windowData["ancestorOriginsList
"] で実行した結果とする。 -
windowClient を clientObjects に追加する。
-
-
各 client について、matchedClients 内で:
-
clientObject を Create Client アルゴリズムを client で実行した結果とする。
-
clientObject を clientObjects に追加する。
-
-
clientObjects を以下のようにソートする:
-
WindowClient
オブジェクトでその 閲覧コンテキスト が フォーカスされたものは先頭に、最新の フォーカス順で並ぶ。 -
WindowClient
オブジェクトでその 閲覧コンテキスト が一度も フォーカスされていないものは次に、service worker client の生成順で並ぶ。 -
Client
オブジェクトで関連する service worker client が worker client のものはその後、service worker client の生成順で並ぶ。
注: window client は常に worker client より先に配置される。
-
-
promise を clientObjectsの新しいFrozenArray で promise の 該当Realm で解決する。
-
-
-
promise を返す。
4.3.3.
openWindow(url)
openWindow(url)
メソッドの手順:
-
url を パースした結果とし、this の 該当設定オブジェクト の APIベースURL を使う。
-
url が失敗の場合、
TypeError
で拒否された promise を返す。 -
url が
about:blank
の場合、TypeError
で拒否された promise を返す。 -
この オリジン に
Window
が一つも 一時的なアクティベーション を持たない場合、"InvalidAccessError
"DOMException
で拒否された promise を返す。 -
serviceWorkerEventLoop を 現在のグローバルオブジェクト の イベントループ とする。
-
promise を新しい promise とする。
-
以下のサブステップを 並行して実行する:
-
newContext を新しい トップレベル閲覧コンテキスト とする。
-
タスクをキューに入れる。以下の手順を newContext の
Window
オブジェクトの environment settings object の 責任イベントループ で ユーザー操作タスクソース を使って実行する:-
HandleNavigate: ナビゲート newContext を url へ、例外有効 を true、historyHandling を "
replace
" とする。 -
HandleNavigate ラベル付きのアルゴリズム手順が 例外 を投げた場合、タスクをキューに入れる。promise を例外で serviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。
-
frameType を Get Frame Type を newContext で実行した結果とする。
-
visibilityState を newContext の アクティブドキュメント の
visibilityState
属性値とする。 -
focusState を has focus手順 を newContext の アクティブドキュメント に対して実行した結果とする。
-
ancestorOriginsList を newContext の アクティブドキュメント の 該当グローバルオブジェクト の
Location
オブジェクトの 先祖オリジンリスト の関連リストとする。 -
タスクをキューに入れる。以下の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:
-
newContext の
Window
オブジェクトの environment settings object の ストレージキーの取得 の結果が、equal でない場合、service worker の 含まれるService Worker登録 の ストレージキー と、promise を null で解決し、これらの手順を中止する。 -
client を Create Window Client に newContext の
Window
オブジェクトの environment settings object、frameType、visibilityState、focusState、ancestorOriginsList を渡して実行した結果とする。 -
promise を client で解決する。
-
-
-
-
promise を返す。
4.3.4.
claim()
claim()
メソッドの手順:
-
service worker が アクティブワーカー でない場合、"
InvalidStateError
"DOMException
で拒否された promise を返す。 -
promise を新しい promise とする。
-
以下のサブステップを 並行して実行する:
-
各 service worker client client について、ストレージキーの取得 の結果が、equal である場合、service worker の 含まれるService Worker登録 の ストレージキー と等しい場合:
-
client の 実行準備フラグ が未設定、または client の 破棄フラグ が設定されている場合、continue。
-
client が セキュアコンテキスト でない場合、continue。
-
storage key を ストレージキーの取得 を client で実行した結果とする。
-
registration を Match Service Worker Registration を storage key と client の 作成URL で実行した結果とする。
-
registration が service worker の 含まれるService Worker登録 でない場合、continue。
注: registration は、service worker の 含まれるService Worker登録 が 登録解除済み の場合、null になる。
-
client の active service worker が service worker でない場合、以下を実行する:
-
Handle Service Worker Client Unload を client で呼び出す。
-
client の active service worker を service worker に設定する。
-
Notify Controller Change アルゴリズムを client で呼び出す。
-
-
-
promise を undefined で解決する。
-
-
promise を返す。
4.4.
ExtendableEvent
[Exposed =ServiceWorker ]interface :
ExtendableEvent Event {(
constructor DOMString ,
type optional ExtendableEventInit = {});
eventInitDict undefined waitUntil (Promise <any >); };
f
dictionary :
ExtendableEventInit EventInit { // 派生イベントに対する将来の互換性のために定義 };
ExtendableEvent
オブジェクトは、関連付けられた extend lifetime
promises(存続期間拡張promise群)(promiseの配列)を持ちます。初期値は空配列です。
ExtendableEvent
オブジェクトは、関連付けられた pending promises
count(保留中promise数)(extend lifetime
promisesの中で保留中のpromise数)を持ちます。初期値は0です。
ExtendableEvent
オブジェクトは、関連付けられた timed out flag(タイムアウトフラグ)
を持ちます。これは初期状態では未設定であり、pending promises count
が0より大きい場合、ユーザーエージェントが任意で遅延をかけた後に設定されます。
ExtendableEvent
オブジェクトは、timed out flag が未設定であり、かつpending promises count が0より大きい、またはdispatch flag が設定されている場合、active(有効)であると言います。
Service
Worker には2つのライフサイクルイベント(install
と activate
)があります。
Service
Worker は、ExtendableEvent
インターフェースを install
および activate
イベントで利用します。
Service Worker拡張でイベントハンドラを定義するものも、ExtendableEvent
インターフェースを利用または拡張することができます。
4.4.1.
event.waitUntil(f)
注: waitUntil()
メソッドはイベントの存続期間を延長します。
waitUntil(f)
メソッドの手順は、lifetime promiseの追加 f を this に対して行うことです。
ExtendableEvent
)に対して行う手順:
-
event の
isTrusted
属性がfalseの場合、"InvalidStateError
"DOMException
をthrowする。 -
event が active でない場合、"
InvalidStateError
"DOMException
をthrowする。注: イベントハンドラを呼び出したタスク内でlifetime extension promiseが追加されていない場合、後続の非同期タスクで
waitUntil()
を呼ぶと例外となります。 -
promise を event の extend lifetime promises に追加する。
-
event の pending promises count を1増加させる。
注: 渡されたpromiseが既に解決済みでもpending promises countは加算されます。減算はpromiseのreactionでマイクロタスクがキューされる際に行われます。
-
fulfillment または rejection が発生したら、マイクロタスクをキューして以下のサブステップを実行する:
-
event の pending promises count を1減らす。
-
event の pending promises count が0なら:
-
registration を 現在のグローバルオブジェクト の関連 service worker の 含まれるService Worker登録 とする。
-
registration が 登録解除済み なら、Try Clear Registration を registration で呼ぶ。
-
registration が null でない場合、Try Activate を registration で呼ぶ。
-
-
ユーザーエージェントは、Service Worker Has No Pending Events がその service worker に対してfalseを返す場合、service workerの終了 をすべきではないです。
Service Worker や 拡張でイベントハンドラを定義するものは、独自の挙動を定義できます。これらはextend lifetime promisesによって処理の長さを示唆したり、promiseがrejectされた場合は処理の失敗を示唆できます。
注: Service Worker は installing worker を"installed
"として扱うのを、install
イベントの extend lifetime promises
が全て正常解決するまで遅延します(Installアルゴリズムステップ参照)。promiseがrejectされるとインストールは失敗となります。これは主に service
worker のコアキャッシュが全て準備完了してからインストール済みとみなすために使われます。同様に service worker は active
worker を"activated
"として扱うのを、activate
イベントの extend lifetime promises
が解決するまで遅延します(Activateアルゴリズムステップ参照)。これは、functional events
が、DBスキーマの更新や不要なキャッシュ削除が終わるまでdispatchされないようにするために使われます。
4.5.
InstallEvent
[Exposed =ServiceWorker ]interface :
InstallEvent ExtendableEvent {(
constructor DOMString ,
type optional ExtendableEventInit = {});
eventInitDict Promise <undefined >addRoutes ((RouterRule or sequence <RouterRule >)); };
rules dictionary {
RouterRule required RouterCondition ;
condition required RouterSource ; };
source dictionary {
RouterCondition URLPatternCompatible ;
urlPattern ByteString ;
requestMethod RequestMode ;
requestMode RequestDestination ;
requestDestination RunningStatus ;
runningStatus sequence <RouterCondition >;
_or RouterCondition ; };
not typedef (RouterSourceDict or RouterSourceEnum );
RouterSource dictionary {
RouterSourceDict DOMString ; };
cacheName enum {
RunningStatus ,
"running" };
"not-running" enum {
RouterSourceEnum ,
"cache" ,
"fetch-event" ,
"network" };
"race-network-and-fetch-handler"
count router condition result(ルーター条件結果のカウント)は、次からなる構造体です:
-
condition count(条件数)(数値)。
-
quota exceeded(クォータ超過)(真偽値)。
4.5.1. event.addRoutes(rules)
注: addRoutes(rules)
は、このサービスワーカーでfetchイベントハンドラが通常行う単純なタスクを分担するためのルールを登録します。
addRoutes(rules)
メソッドの手順:
-
rules が
RouterRule
辞書のときは、rules を « rules » に設定する。 -
serviceWorker を 現在のグローバルオブジェクト の関連 service worker とする。
-
rules の各 rule について:
-
Verify Router Condition アルゴリズムを rule["
condition
"] と serviceWorker で実行して false なら、promiseで拒否し、TypeError
を返す。 -
rule["
source
"] が "fetch-event
" または "race-network-and-fetch-handler
" のいずれかで、 serviceWorker の 処理するイベント型の集合 が fetch イベントを含んでいなければ、 promiseで拒否し、TypeError
を返す。
-
-
lifetimePromise を新しい promise とする。
-
lifetime promiseの追加 lifetimePromise を this に対して行う。
注:
event.addRoutes(rules)
はevent.waitUntil(promise)
が呼ばれるのと同様に、デフォルトでイベントの存続期間を延長します。 -
promise を新しい promise とする。
-
fulfillment または rejection が promise で発生したら、 lifetimePromise を undefined で解決する。
注: このステップは install イベント失敗を避けるため、lifetimePromise を必ずfulfilledにします。
-
以下の手順をエンキューして [[service worker queue]] で実行する:
-
allRules を serviceWorker の ルーター規則リスト のコピーとする。
-
rules の各 rule について:
-
rule を allRules に追加する。
-
-
Check Router Registration Limit を allRules に対して実行して false なら、promise を
TypeError
で拒否する。 -
serviceWorker の ルーター規則リスト を allRules に設定する。
-
serviceWorkerEventLoop を 現在のグローバルオブジェクト の イベントループ とする。
-
タスクをキューに入れる。以下の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:
-
promise を undefined で解決する。
-
-
-
promise を返す。
4.6.
FetchEvent
[Exposed =ServiceWorker ]interface :
FetchEvent ExtendableEvent {(
constructor DOMString ,
type FetchEventInit ); [
eventInitDict SameObject ]readonly attribute Request request ;readonly attribute Promise <any >preloadResponse ;readonly attribute DOMString clientId ;readonly attribute DOMString resultingClientId ;readonly attribute DOMString replacesClientId ;readonly attribute Promise <undefined >handled ;undefined respondWith (Promise <Response >); };
r
dictionary :
FetchEventInit ExtendableEventInit {required Request ;
request Promise <any >;
preloadResponse DOMString = "";
clientId DOMString = "";
resultingClientId DOMString = "";
replacesClientId Promise <undefined >; };
handled
ServiceWorker には重要な機能的イベント fetch
があります。
fetch
イベントでは、ServiceWorker は FetchEvent
インターフェースを利用し、これは ExtendableEvent
インターフェースを拡張します。
FetchEvent
インターフェースを使用する各イベントには、関連付けられた potential response(潜在的レスポンス)(response)があり、初期値はnullです。また、初期状態で未設定の以下のフラグを持ちます:
-
wait to respond flag(応答待ちフラグ)
-
respond-with entered flag(respondWith実行済みフラグ)
-
respond-with error flag(respondWithエラーフラグ)
4.6.1.
event.request
request
属性は、初期化時に設定された値を返すべきです。
4.6.2. event.preloadResponse
preloadResponse
属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は undefinedで解決されたpromise に初期化すべきです。
4.6.3.
event.clientId
clientId
属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。
4.6.4. event.resultingClientId
resultingClientId
属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。
4.6.5. event.replacesClientId
replacesClientId
属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。
4.6.6.
event.handled
handled
属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性はpendingな promise で初期化すべきです。
4.6.7. event.respondWith(r)
注: 開発者は引数 r に promise(Response
オブジェクトで解決される)または Response
オブジェクト(自動的にpromiseへ変換)を指定できます。それ以外の場合は ネットワークエラー が Fetch
に返されます。
レンダラー側のクロスオリジンコンテンツの汚染に関するセキュリティチェックは、filtered response の型に依存します。
respondWith(r)
メソッドの手順:
-
event を this とする。
-
event の dispatch flag が未設定なら、"
InvalidStateError
"DOMException
をthrowする。 -
event の respond-with entered flag が 設定済みなら、"
InvalidStateError
"DOMException
をthrowする。 -
lifetime promiseの追加 r を event に対して行う。
注:
event.respondWith(r)
はevent.waitUntil(r)
を呼ぶのと同様に、デフォルトでイベントの存続期間を延長します。 -
event の stop propagation flag および stop immediate propagation flag を設定する。
-
event の respond-with entered flag を設定する。
-
event の wait to respond flag を設定する。
-
targetRealm を event の relevant Realm とする。
-
-
event の respond-with error flag を設定する。
-
event の wait to respond flag を解除する。
-
-
rのfulfillment時、response で:
-
response が
Response
オブジェクトでない場合、respond-with error flag を設定する。注: respond-with error flag が設定された場合、 ネットワークエラー が Fetch の Handle Fetch アルゴリズムを通じて返されます(ステップ21.1参照)。そうでなければ、値 response が Fetch の Handle Fetch アルゴリズムを通じて返されます(ステップ22.1参照)。
-
それ以外の場合:
-
bytes を空のバイト列とする。
-
end-of-body をfalseとする。
-
done をfalseとする。
-
potentialResponse を response の関連付けられた response のコピーとし、body を除く。
-
response の body がnullでない場合、以下のサブステップを実行:
-
pullAlgorithm を以下を行うactionとする:
-
readRequest を新しい read request とし、以下の item を持つ:
- chunk steps(chunkを受け取る)
-
-
アサート:chunk は
Uint8Array
である。 -
chunk で表されるバイトを bytes に追加する。
-
potentialResponse の body info の encoded size を bytes の byte length だけ増加させる。
-
potentialResponse の body info の decoded size を bytes の byte length だけ増加させる。
-
! DetachArrayBuffer(chunk.[[ViewedArrayBuffer]]) を実行する。
-
- close steps
-
-
end-of-body をtrueにする。
-
- error steps
-
read a chunk を reader に readRequest を与えて実行する。
-
-
cancelAlgorithm を readerのキャンセルアクションとする。
-
highWaterMark を非負・非NaNな数値(ユーザーエージェントが決定)とする。
-
sizeAlgorithm を chunk オブジェクトを受け取り、非負・非NaN・無限大でない値を返すアルゴリズム(ユーザーエージェントが決定)とする。
-
newStream を新しい
ReadableStream
とし、set up で pullAlgorithm pullAlgorithm、cancelAlgorithm cancelAlgorithm、highWaterMark highWaterMark、sizeAlgorithm sizeAlgorithm を targetRealm でセットアップする。 -
potentialResponse の body を新しい body とし、その stream を newStream にする。
-
以下を 並行して done がfalseの間繰り返す:
-
newStream が errored なら、done をtrueにする。
-
それ以外で bytes が空かつ end-of-body がtrueなら、close newStream、done をtrueにする。
-
それ以外で bytes が空でない場合、以下のサブサブサブステップを実行:
-
chunk を bytes の先頭からの部分列とする。
-
chunk を bytes から除去する。
-
buffer を targetRealm で作られた
ArrayBuffer
オブジェクトで、chunk を含むものとする。 -
enqueue を targetRealm で作られた
Uint8Array
オブジェクトで buffer をラップし、newStream に追加する。
-
-
注: これらのサブステップは response の body の stream を potentialResponse に「パイプ」する観測可能な同等物を生成するためのものです。
注: ServiceWorkerがチャンクで書き込んだデータは、受け取ったクライアントが必ずしも同じチャンクで読むとは限りません。つまり、クライアントは同じ内容を読むが、ブラウザによってチャンク分割方法が異なる場合があります。
-
event の potential response を potentialResponse に設定する。
-
-
event の wait to respond flag を解除する。
-
4.7. ExtendableMessageEvent
[Exposed =ServiceWorker ]interface :
ExtendableMessageEvent ExtendableEvent {(
constructor DOMString ,
type optional ExtendableMessageEventInit = {});
eventInitDict readonly attribute any data ;readonly attribute USVString origin ;readonly attribute DOMString lastEventId ; [SameObject ]readonly attribute (Client or ServiceWorker or MessagePort )?source ;readonly attribute FrozenArray <MessagePort >ports ; };
dictionary :
ExtendableMessageEventInit ExtendableEventInit {any =
data null ;USVString = "";
origin DOMString = ""; (
lastEventId Client or ServiceWorker or MessagePort )?=
source null ;sequence <MessagePort >= []; };
ports
ServiceWorker は extendable
message
イベントを定義し、イベントの存続期間を延長できるようにします。message
イベントでは、ServiceWorker は ExtendableMessageEvent
インターフェースを利用し、これは ExtendableEvent
インターフェースを拡張します。
4.7.1. event.data
data
属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性はnullで初期化すべきです。送信されるメッセージを表します。
4.7.2. event.origin
origin
属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空文字列で初期化すべきです。これはメッセージを送信したオリジンを表します。
4.7.3. event.lastEventId
lastEventId
属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空文字列で初期化すべきです。
4.7.4. event.source
source
属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性はnullで初期化すべきです。これはメッセージを送信した Client
オブジェクトを表します。
4.7.5. event.ports
ports
属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空配列で初期化すべきです。これは送信される MessagePort
配列を表します。
4.8. イベント
以下のイベントは ServiceWorkerイベント と呼ばれ、ServiceWorkerGlobalScope
オブジェクト上でdispatchされます:
イベント名 | インターフェース | カテゴリ | dispatch時の条件 |
---|---|---|---|
install
| InstallEvent
| ライフサイクル | ServiceWorker の 含まれるServiceWorker登録 の installing worker が変化したとき(Installアルゴリズムステップ11.2参照) |
activate
| ExtendableEvent
| ライフサイクル | ServiceWorker の 含まれるServiceWorker登録 の active worker が変化したとき(Activateアルゴリズムステップ12.2参照) |
fetch
| FetchEvent
| 機能 | http fetch が Handle Fetch を
request で呼び出したとき。その結果、Handle Fetch の実行により、ServiceWorker が response を http fetch に返す。Response
オブジェクトは Cache
オブジェクトから取得するか、self.fetch(input, init)
メソッドでネットワークから直接取得できる。(カスタム Response
オブジェクトも選択肢となる。)
|
push | PushEvent
| 機能 | (pushイベントの発火参照) |
notificationclick | NotificationEvent
| 機能 | (通知のアクティベート参照) |
notificationclose | NotificationEvent
| 機能 | (通知のクローズ参照) |
sync | SyncEvent
| 機能 | (syncイベントの発火参照) |
canmakepayment | CanMakePaymentEvent | 機能 | (CanMakePaymentEventの処理参照) |
paymentrequest | PaymentRequestEvent | 機能 | (PaymentRequestEventの処理参照) |
message
| ExtendableMessageEvent
| レガシー | メッセージ受信時 |
messageerror
| MessageEvent
| レガシー | デシリアライズできないメッセージ受信時 |
5. キャッシュ
著者がオフライン利用のためにコンテンツキャッシュを完全に管理できるよう、Window
および WorkerGlobalScope
は、Cache
オブジェクトを開いて操作できる非同期キャッシュメソッドを提供します。オリジンごとに複数の名前付き Cache
オブジェクトを持つことができ、その内容は完全にスクリプトで制御できます。キャッシュは オリジン間で共有されず、ブラウザのHTTPキャッシュとも完全に分離されています。
5.1. 構成要素
リクエスト・レスポンスリストは、リストであり、タプル(リクエストとレスポンス)で構成されます。
関連リクエスト・レスポンスリストは、thisが表すインスタンスです。
名前 → キャッシュマップは、順序付きマップであり、エントリーは キー (リクエスト・レスポンスリストの名前を表す文字列)と 値 (リクエスト・レスポンスリスト)で構成されます。
各ストレージキーは、関連付けられた名前 → キャッシュマップを持ちます。
関連名前 → キャッシュマップは、名前 → キャッシュマップであり、ストレージキーを取得したものに、thisの関連するグローバルオブジェクトの環境設定オブジェクトが使われます。
5.2. キャッシュの寿命の理解
Cache
インスタンスはブラウザのHTTPキャッシュとは無関係です。Cache
オブジェクトは著者が自ら管理するものです。Cache
オブジェクトは、著者が明示的に更新を要求しない限り更新されません。Cache
オブジェクトは、著者がエントリーを削除しない限り期限切れになりません。Cache
オブジェクトは、ServiceWorkerスクリプトが更新されても消えません。つまり、キャッシュは自動で更新されません。更新は手動で管理する必要があります。したがって、著者はキャッシュ名でバージョン管理し、ServiceWorkerの安全に操作できるバージョンのキャッシュのみ利用するようにしてください。
5.3. self.caches
partial interface mixin WindowOrWorkerGlobalScope { [SecureContext ,SameObject ]readonly attribute CacheStorage caches ; };
5.3.1.
caches
caches
のgetter手順は、thisの関連付けられたCacheStorage
オブジェクトを返します。
5.4. Cache
[SecureContext ,Exposed =(Window ,Worker )]interface { [
Cache NewObject ]Promise <(Response or undefined )>match (RequestInfo ,
request optional CacheQueryOptions = {}); [
options NewObject ]Promise <FrozenArray <Response >>matchAll (optional RequestInfo ,
request optional CacheQueryOptions = {}); [
options NewObject ]Promise <undefined >add (RequestInfo ); [
request NewObject ]Promise <undefined >addAll (sequence <RequestInfo >); [
requests NewObject ]Promise <undefined >put (RequestInfo ,
request Response ); [
response NewObject ]Promise <boolean >delete (RequestInfo ,
request optional CacheQueryOptions = {}); [
options NewObject ]Promise <FrozenArray <Request >>keys (optional RequestInfo ,
request optional CacheQueryOptions = {}); };
options
dictionary {
CacheQueryOptions boolean =
ignoreSearch false ;boolean =
ignoreMethod false ;boolean =
ignoreVary false ; };
Cache
オブジェクトは、リクエスト・レスポンスリストを表します。複数のドキュメントやワーカー間で Cache
インターフェースを実装する別々のオブジェクトが、同じ リクエスト・レスポンスリスト に関連付けられる場合もあります。
キャッシュバッチ操作は、構造体であり、次の要素からなります:
-
type(種類)("
delete
" または "put
")。 -
request(リクエスト)(リクエスト)。
-
response(レスポンス)(レスポンス)。
-
options(オプション)(
CacheQueryOptions
)。
5.4.1.
match(request, options)
match(request, options)
メソッドの手順:
-
promise を 新しいpromise とする。
-
以下のサブステップを 並行して実行する:
-
p を
matchAll(request, options)
メソッド(requestとoptionsを渡す)で実行したアルゴリズムの結果とする。 -
p がsettleするまで待つ。
-
p が例外でrejectされたら:
-
promise をその例外でrejectする。
-
-
p が配列responsesでresolveされた場合:
-
responses が空配列の場合:
-
promise をundefinedでresolveする。
-
-
それ以外の場合:
-
promise をresponsesの最初の要素でresolveする。
-
-
-
-
promise を返す。
5.4.2.
matchAll(request, options)
matchAll(request, options)
メソッドの手順:
-
r をnullとする。
-
オプション引数requestが省略されていない場合:
-
request が
Request
オブジェクトなら:-
r を request の request とする。
-
r の method が `
GET
` でなく、かつ options.ignoreMethod がfalseなら、空配列でresolveされたpromise を返す。
-
-
そうでなくrequestが文字列なら:
-
r を request を引数として
Request
のコンストラクタを呼び出した結果の関連 request とする。例外が発生したら その例外でrejectされたpromise を返す。
-
-
-
promise を 新しいpromise とする。
-
以下のサブステップを 並行して実行する:
-
responses を空の リスト とする。
-
オプション引数requestが省略されている場合:
-
各 requestResponse について、関連リクエスト・レスポンスリスト内で:
-
requestResponse のレスポンスのコピーを responses に追加する。
-
-
-
そうでない場合:
-
requestResponses を Query Cache を r と options で実行した結果とする。
-
各 requestResponse について、requestResponses内で:
-
requestResponse のレスポンスのコピーを responses に追加する。
-
-
-
各 response について、responses内で:
-
response の type が "
opaque
" かつ cross-origin resource policy check(promise の 関連設定オブジェクト の origin、promise の 関連設定オブジェクト、空文字列、response の internal response で実行)がblockedを返した場合、promise をTypeError
でrejectし、これらの手順を中止する。
-
-
タスクをキューに入れる。promise の 関連設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使い、以下の手順を実行する:
-
responseList を リストとする。
-
各 response について、responses内で:
-
promise を frozen array(responseListから生成、realmで)でresolveする。
-
-
-
promise を返す。
5.4.3.
add(request)
add(request)
メソッドの手順:
-
requests を request だけを含む配列とする。
-
responseArrayPromise を
addAll(requests)
のアルゴリズム(requestsを引数に)で実行した結果とする。 -
responseArrayPromise のsettle後にundefinedを返すfulfillmentハンドラで reactする結果を返す。
5.4.4.
addAll(requests)
addAll(requests)
メソッドの手順:
-
responsePromises を空の リストとする。
-
requestList を空の リストとする。
-
requests 内の
Request
型の各 request について:-
r を request の request とする。
-
r の url の scheme が "
http
" または "https
" 以外の場合、もしくは r の method が `GET
` でない場合、TypeErrorでrejectされたpromise を返す。
-
-
fetchControllers を リスト(fetch controller)とする。
-
requests の各 request について:
-
r を request を引数に
Request
のコンストラクタを呼び出した結果の関連 request とする。例外が発生したら 例外でrejectされたpromise を返す。 -
r の url の scheme が "
http
" または "https
" 以外の場合: -
r の client の global object が
ServiceWorkerGlobalScope
オブジェクトなら、request の service-workers mode を "none
" に設定する。 -
r の initiator を "
fetch
"、destination を "subresource
" に設定する。 -
requestList に r を追加する。
-
responsePromise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行する:
-
fetching r の結果を追加する。
-
processResponse を response に対して実行:
-
processResponseEndOfBody を response に対して実行:
-
response の aborted flag が設定されている場合、"
AbortError
"DOMException
で responsePromise をrejectし、これらの手順を中止する。 -
responsePromise を response でresolveする。
注: レスポンスのbodyが完全に受信されたときにキャッシュコミットが許可されます。
-
-
-
responsePromise を responsePromises に追加する。
-
-
p を responsePromises全部がsettleするpromiseの結果とする。
-
p のsettle後、引数 responses を受け取るfulfillmentハンドラで reactし、以下のサブステップを実行:
-
operations を空の リストとする。
-
index をゼロとする。
-
responses の各 response について:
-
operation を キャッシュバッチ操作とする。
-
operation の type を "
put
" に設定する。 -
operation の request を requestList[index] に設定する。
-
operation の response を response に設定する。
-
operation を operations に追加する。
-
index を1増やす。
-
-
cacheJobPromise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行する:
-
errorData をnullとする。
-
Batch Cache Operations を operations で呼び出す。例外が発生したら errorData にその例外を設定する。
-
タスクをキューに入れる。cacheJobPromise の 関連設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使い、以下のサブステップを実行:
-
-
cacheJobPromise を返す。
-
5.4.5.
put(request, response)
put(request, response)
メソッドの手順:
-
innerRequest を null とする。
-
request が
Request
オブジェクトの場合、innerRequest を request の request に設定する。 -
それ以外の場合:
-
requestObj を
Request
のコンストラクタに request を渡して呼び出した結果とする。例外が発生した場合は その例外でrejectされたpromise を返す。 -
innerRequest を requestObj の request に設定する。
-
-
innerRequest の url の scheme が "
http
" または "https
" 以外の場合、または innerRequest の method が `GET
` でない場合、TypeErrorでrejectされたpromise を返す。 -
innerResponse を response の response に設定する。
-
innerResponse の status が
206
の場合、TypeErrorでrejectされたpromise を返す。 -
innerResponse の header list に header Vary が含まれる場合:
-
fieldValues を list(Vary header の field-values)とする。
-
各 fieldValue について、fieldValues内で:
-
fieldValue が "
*
" と一致する場合、TypeErrorでrejectされたpromise を返す。
-
-
-
innerResponse の body が disturbed または locked の場合、TypeErrorでrejectされたpromise を返す。
-
clonedResponse を innerResponseのclone とする。
-
bodyReadPromise を undefinedでresolveされたpromise とする。
-
innerResponse の body が null でない場合、以下のサブステップを実行:
-
reader を streamのreader取得の結果とする。
-
bodyReadPromise を 全バイト読み取りを reader で実行した結果とする。
注: これは innerResponse の body が locked になり、clonedResponse に完全なバッファ済みコピーを保持することを保証します。実装ではメモリではなく直接ディスクにストリームする最適化も可能です。
-
operations を空の リストとする。
-
operation を キャッシュバッチ操作とする。
-
operation の type を "
put
" に設定する。 -
operation の request を innerRequest に設定する。
-
operation の response を clonedResponse に設定する。
-
operation を operations に追加する。
-
bodyReadPromise の fulfillment時に以下を実行:
-
cacheJobPromise を 新しいpromiseとする。
-
cacheJobPromise を返し、以下のサブステップを 並行して実行:
-
errorData を null とする。
-
Batch Cache Operations を operations で呼び出す。例外が発生したら errorData にその例外を設定する。
-
タスクをキューに入れる。cacheJobPromise の 関連設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使い、以下のサブステップを実行:
-
-
5.4.6.
delete(request, options)
delete(request, options)
メソッドの手順:
-
r を null とする。
-
request が
Request
オブジェクトの場合:-
r を request の request に設定する。
-
r の method が `
GET
` でなく、かつ options.ignoreMethod が false なら falseでresolveされたpromise を返す。
-
-
そうでなくrequestが文字列の場合:
-
r を request を引数として
Request
のコンストラクタを呼び出した結果の関連 request とする。例外が発生した場合は その例外でrejectされたpromise を返す。
-
-
operations を空の リストとする。
-
operation を キャッシュバッチ操作とする。
-
operation の type を "
delete
" に設定する。 -
operation の request を r に設定する。
-
operation の options を options に設定する。
-
operation を operations に追加する。
-
cacheJobPromise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行:
-
errorData を null とする。
-
requestResponses を Batch Cache Operations を operations で呼び出した結果とする。例外が発生したら errorData にその例外を設定する。
-
タスクをキューに入れる。cacheJobPromise の 関連設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使い、以下のサブステップを実行:
-
-
cacheJobPromise を返す。
5.4.7.
keys(request, options)
keys(request, options)
メソッドの手順:
-
r を null とする。
-
オプション引数requestが省略されていない場合:
-
request が
Request
オブジェクトの場合:-
r を request の request に設定する。
-
r の method が `
GET
` でなく、かつ options.ignoreMethod がfalseなら、空配列でresolveされたpromise を返す。
-
-
そうでなくrequestが文字列の場合:
-
r を request を引数に
Request
のコンストラクタを呼び出した結果の関連 request とする。例外が発生した場合は その例外でrejectされたpromise を返す。
-
-
-
promise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行:
-
requests を空の リストとする。
-
オプション引数requestが省略されている場合:
-
各 requestResponse について、関連リクエスト・レスポンスリスト内で:
-
requestResponse のリクエストを requests に追加する。
-
-
-
そうでない場合:
-
requestResponses を Query Cache を r と options で実行した結果とする。
-
各 requestResponse について、requestResponses内で:
-
requestResponse のリクエストを requests に追加する。
-
-
-
タスクをキューに入れる。promise の 関連設定オブジェクト の 責任イベントループ で DOM操作タスクソース を使い、以下の手順を実行:
-
requestList を リストとする。
-
各 request について、requests内で:
-
promise を frozen array(requestListから生成、realmで)でresolveする。
-
-
-
promise を返す。
5.5.
CacheStorage
[SecureContext ,Exposed =(Window ,Worker )]interface { [
CacheStorage NewObject ]Promise <(Response or undefined )>match (RequestInfo ,
request optional MultiCacheQueryOptions = {}); [
options NewObject ]Promise <boolean >has (DOMString ); [
cacheName NewObject ]Promise <Cache >open (DOMString ); [
cacheName NewObject ]Promise <boolean >delete (DOMString ); [
cacheName NewObject ]Promise <sequence <DOMString >>keys (); };dictionary :
MultiCacheQueryOptions CacheQueryOptions {DOMString ; };
cacheName
注: CacheStorage
インターフェースは基本的に ECMAScript 6
のMapオブジェクトに準拠して設計されていますが、完全に非同期で、追加の便利なメソッドも備えています。clear
、forEach
、entries
、values
メソッドは、TC39によるasyncイテレーションの議論に依存するため初版では意図的に除外されています。
ユーザーエージェントは CacheStorage
オブジェクトを、Window
オブジェクトまたは WorkerGlobalScope
オブジェクト生成時に作成し、その グローバルオブジェクト に関連付ける必要があります。
CacheStorage
オブジェクトは、関連付けられた グローバルオブジェクト の 環境設定オブジェクト の オリジン に紐付く 名前 → キャッシュマップ
を表します。複数のドキュメントやワーカーで CacheStorage
インターフェースを実装する別々のオブジェクトが、同じ 名前 → キャッシュマップ に同時に関連付けられる場合もあります。
5.5.1.
match(request, options)
match(request, options)
メソッドの手順:
-
-
新しいpromise promise を返し、以下のサブステップを 並行して実行:
-
各 cacheName → cache について、関連名前 → キャッシュマップ内で:
-
options["
cacheName
"] が cacheName と一致する場合:-
match(request, options)
メソッド(requestとoptionsを渡す)をCache
インターフェースで実行し、その結果で promise をresolveする(thisArgumentとしてcacheを渡す)。 -
これらの手順を中止する。
-
-
-
promise をundefinedでresolveする。
-
-
-
それ以外の場合:
-
promise を undefinedでresolveされたpromise とする。
-
各 cacheName → cache について、関連名前 → キャッシュマップ内で:
-
promise を自身の settle後にreactするように設定し、引数 response を受け取るfulfillmentハンドラで以下を実行:
-
response がundefinedでなければ response を返す。
-
match(request, options)
メソッド(requestとoptionsを渡す)をCache
インターフェースで実行し、その結果を返す(thisArgumentとしてcacheを渡す)。
-
-
-
promise を返す。
-
5.5.2.
has(cacheName)
has(cacheName)
メソッドの手順:
-
promise を 新しいpromise とする。
-
以下のサブステップを 並行して実行:
-
各 key → value について、関連名前 → キャッシュマップ内で:
-
cacheName が key と一致すれば promise を true でresolveし、これらの手順を中止する。
-
-
promise を false でresolveする。
-
-
promise を返す。
5.5.3.
open(cacheName)
open(cacheName)
メソッドの手順:
-
promise を 新しいpromise とする。
-
以下のサブステップを 並行して実行:
-
各 key → value について、関連名前 → キャッシュマップ内で:
-
cacheName が key と一致する場合:
-
value を表す新しい
Cache
オブジェクトで promise をresolveする。 -
これらの手順を中止する。
-
-
-
cache を新しい リクエスト・レスポンスリスト とする。
-
関連名前 → キャッシュマップ[cacheName] に cache を設定する。このキャッシュ書き込み操作がクォータ制限超過で失敗した場合、promise を "
QuotaExceededError
"DOMException
でrejectし、これらの手順を中止する。 -
cache を表す新しい
Cache
オブジェクトで promise をresolveする。
-
-
promise を返す。
5.5.4.
delete(cacheName)
delete(cacheName)
メソッドの手順:
-
promise を
has(cacheName)
メソッドで cacheName を渡して実行したアルゴリズムの結果とする。 -
promise のsettle後、引数 cacheExists を受け取るfulfillmentハンドラで reactし、以下のサブステップを実行:
-
cacheExists がfalseの場合:
-
false を返す。
-
-
cacheJobPromise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行:
-
関連名前 → キャッシュマップ[cacheName] を削除する。
-
cacheJobPromise を true でresolveする。
注: このステップ後、既存のDOMオブジェクト(参照中のCache、Request、Responseオブジェクト)は機能を維持します。
-
-
cacheJobPromise を返す。
-
5.5.5.
keys()
keys()
メソッドの手順:
-
promise を 新しいpromiseとする。
-
以下のサブステップを 並行して実行:
-
cacheKeys を 関連名前 → キャッシュマップ のキー取得結果とする。
注: 結果の item(順序付き集合)は 名前 → キャッシュマップ に追加された順序です。
-
promise を cacheKeys でresolveする。
-
-
promise を返す。
6. セキュリティに関する考慮事項
6.1. セキュアコンテキスト
ServiceWorker は 必ず セキュアコンテキスト で実行されなければなりません。ServiceWorkerクライアント も 必ず セキュアコンテキスト で、ServiceWorker登録の登録や、ServiceWorker登録・ServiceWorkerへのアクセス、ServiceWorkerとのメッセージ送受信、ServiceWorkerによる操作ができる必要があります。
注: これは ServiceWorker および ServiceWorkerクライアント
がHTTPSでホストされる必要があることを意味します。ユーザーエージェントは開発目的で localhost
(要件参照)、127.0.0.0/8
、::1/128
を許可できます。この制限の主な理由は、非セキュアコンテキストに関連するリスクからユーザーを保護するためです。
6.2. Content Security Policy(CSP)
ユーザーエージェントが Run Service Worker アルゴリズムを ServiceWorker serviceWorker で呼び出す際:
-
serviceWorker の スクリプトリソース が
Content-Security-Policy
HTTPヘッダー値 policy で配信された場合、ユーザーエージェントは 必ず policyを強制 しなければなりません。 -
serviceWorker の スクリプトリソース が
Content-Security-Policy-Report-Only
HTTPヘッダー値 policy で配信された場合、ユーザーエージェントは 必ず policyを監視 しなければなりません。
この制限の主な理由は、クロスサイトスクリプティング(XSS)などの幅広いコンテンツ注入脆弱性を緩和するためです。
6.3. オリジン依存性
6.3.1. オリジン制限
この節は規範的ではありません。
ServiceWorker は登録した ServiceWorkerクライアント の オリジン で実行されます。大規模なアプリケーションで課題となるのはCDNからのホスト可否ですが、CDNは定義上他の場所や他の オリジン です。したがって、ServiceWorkerはCDNでホストできません。ただし importScripts() 経由でリソースを含めることは可能です。この制限理由は、ServiceWorkerが悪意ある者によって永続的な被害をもたらす可能性があるためです。
6.3.2.
importScripts(urls)
importScripts(urls)
メソッドが ServiceWorkerGlobalScope
オブジェクトで呼ばれると、ユーザーエージェントは 必ず workerグローバルスコープへスクリプトをimportします(この
ServiceWorkerGlobalScope
オブジェクトと urls を渡す)。さらに fetchフック手順(リクエスト request
に対し)を以下の通り実行します:
-
serviceWorker を request の client の グローバルオブジェクト の ServiceWorker とする。
-
map を serviceWorker の スクリプトリソースマップ とする。
-
url を request の url とする。
-
serviceWorker の state が "
parsed
" または "installing
" でない場合: -
map[url] が存在する場合:
-
urlを serviceWorker の 使用済みスクリプト集合 に追加する。
-
map[url] を返す。
-
-
registration を serviceWorker の ServiceWorker登録 とする。
-
request の service-workers mode を "
none
" に設定する。 -
次のいずれかに該当する場合 request の cache mode を "
no-cache
" に設定する:-
registration の update via cache mode が "
none
" の場合。 -
現在のグローバルオブジェクト の importScripts用キャッシュバイパスフラグ が設定されている場合。
-
registration が stale の場合。
-
-
response を requestのfetch結果とする。
-
response の cache state が "
local
" でない場合、registration の last update check time を現在時刻に設定する。 -
response の unsafe response が bad import script response なら ネットワークエラー を返す。
-
map[url] に response を設定する。
-
urlを serviceWorker の 使用済みスクリプト集合 に追加する。
-
serviceWorker の クラシックスクリプトimport済みフラグ を設定する。
-
response を返す。
6.4. クロスオリジンリソースとCORS
この節は規範的ではありません。
アプリケーションはCDN等、他の オリジン
から取得したアイテムをキャッシュすることが多いです。<script>
、<img>
、<video>
、<link>
等で直接取得できます。これらがオフラインで動作しなくなると制約が大きくなります。同様に、適切なCORSヘッダーがセットされた場合 fetch
で様々なオフオリジンリソース取得も可能です。ServiceWorker は Cache
でオフオリジンアイテムのfetch・キャッシュを可能にします。ただし制限があります。同一オリジンリソースは Cache
で Response
オブジェクト(対応する response は basic filtered response)として管理されますが、クロスオリジンリソースは
Response
オブジェクト(対応する response は CORS filtered response または opaque filtered response)として保存されます。これらは event.respondWith(r)
で同様に渡せますが、プログラム的に意味ある形で生成はできません。こうした制約はプラットフォームのセキュリティ保証の維持に必要です。Cache
で格納できることで、アプリの大半は再設計せずに済みます。
6.5. パス制限
この節は規範的ではありません。
オリジン制限に加え、ServiceWorkerはスクリプトの パス
でも制限されます。例えば https://www.example.com/~bob/sw.js
の ServiceWorkerは scope url
https://www.example.com/~bob/
では登録できますが、https://www.example.com/
や
https://www.example.com/~alice/
ではできません。これは同一オリジンでユーザーごとに分離されるディレクトリ構成のサイトの保護に役立ちます。ただしパス制限は厳密なセキュリティ境界ではなく、オリジンのみが厳密な境界です。サイトは必要に応じて異なるオリジンを用いて安全な分離を推奨します。
サーバーは ServiceWorker スクリプトに Service-Worker-Allowed ヘッダーを設定することでパス制限を解除できます。
6.6. ServiceWorkerスクリプトリクエスト
この節は規範的ではありません。
悪意あるServiceWorker登録への対策として、本仕様は以下を要求します:
-
ServiceWorkerスクリプトリクエストには Service-Worker ヘッダーが存在すること
-
ServiceWorkerスクリプトは JavaScript MIMEタイプ で配信されること
6.7. 実装者向け注意事項
この節は規範的ではありません。
実装者は以下に留意してください:
-
プラグインは ServiceWorker 経由ではロードすべきではありません。プラグインは自身のURLからセキュリティオリジンを取得する場合があり、埋め込んだ ServiceWorker では扱えません。このため Handle Fetch アルゴリズムは
<embed>
および<object>
リクエストをfetch
イベントdispatchせず即座にネットワークへフォールバックします。 -
レガシーネットワークスタックの一部コードは ServiceWorker との相互作用の影響を理解するため、慎重な監査が必要な場合があります。
6.8. プライバシー
ServiceWorker は新しい永続ストレージ機能(登録マップ(ServiceWorker登録とその ServiceWorker用)、リクエスト・レスポンスリストと名前→キャッシュマップ(キャッシュ用)、スクリプトリソースマップ(スクリプト用))を導入します。不正なWebトラッキングの脅威からユーザーを守るため、これらの永続ストレージはユーザーが消去を望む場合は消去できるべきであり、既存のユーザーコントロール(全永続ストレージの一括削除等)と連携・互換すべきです。
7. 拡張性
Service Workers仕様は他の仕様から拡張可能です。
7.1. ServiceWorkerRegistrationに結びつけたAPI定義
仕様は、ServiceWorker登録に結びつけたAPIを、ServiceWorkerRegistration
インターフェースへの partial interface
定義を使って、仕様固有の属性やメソッドを定義することで定義してもよいです:
partial interface ServiceWorkerRegistration { // 例: API名前空間の定義readonly attribute APISpaceType APISpace ; // 例: メソッドの定義Promise <T >methodName (/* 引数リスト */); };
7.2. 機能的イベントの定義
仕様は、ExtendableEvent
インターフェースを拡張して機能的イベントを定義してもよいです:
// 例: FunctionalEventインターフェース定義interface FunctionalEvent :ExtendableEvent { // 機能的イベント固有の属性・メソッドを追加 };
7.3. イベントハンドラの定義
仕様は、対応する機能的イベントのイベントハンドラ属性を、ServiceWorkerGlobalScope
インターフェースへの partial interface 定義で定義してもよいです:
partial interface ServiceWorkerGlobalScope {attribute EventHandler onfunctionalevent ; };
7.4. 機能的イベントの発火
機能的イベントをServiceWorker登録のactive workerにdispatch要求するには、 仕様はFire Functional Eventを呼び出すべきです。
付録A:アルゴリズム
以下の定義は、現行標準仕様全体で使われるユーザーエージェントの内部データ構造です。
登録マップは、(順序付きマップ)であり、キーは(ストレージキー、シリアライズされたscope url)、値はServiceWorker登録です。
ジョブは、ServiceWorker登録に対するregister、update、unregisterリクエストの抽象化です。
ジョブはワーカータイプ("classic
" または "module
")を持ちます。
ジョブはupdate
via cache mode("imports
"、"all
"、"none
")を持ちます。
ジョブはclient(ServiceWorkerクライアント)を持ちます。初期値はnullです。
ジョブはreferrer(URLまたはnull)を持ちます。
ジョブはジョブpromise(promise)。初期値はnullです。
ジョブは所属ジョブキュー(ジョブキューまたはnull)。初期値はnullです。
ジョブは等価ジョブリスト(ジョブのリスト)。初期値は空リストです。
ジョブはforce bypass cache flagを持ちます。初期値は未設定です。
2つのジョブが等価とは、ジョブタイプが同じで、以下がすべて同じ場合です:
-
registerおよびupdateのジョブの場合、scope url、script url、worker type、update via cache modeが同じ。
ジョブキューは、同時実行されるジョブ群を同期させるためのスレッドセーフなキューです。ジョブキューはジョブをitemとして含みます。ジョブキューの初期値は空です。
scope→ジョブキュー マップは、順序付きマップで、キーはシリアライズされたscope url、値はジョブキューです。
bad import script responseは、responseで、以下のいずれかの条件を満たすものです:
-
response の type が "
error
" -
response の header list からMIME type抽出した結果がJavaScript MIME typeでない
注: この定義はクラシックworker-importedスクリプトのfetchと同期させてください。
ジョブの作成
- 入力
-
jobType:ジョブタイプ
storage key:ストレージキー
scopeURL:URL
scriptURL:URL
promise:promise
client:ServiceWorkerクライアント
- 出力
-
job:ジョブ
-
job を新規 ジョブとする。
-
job の ジョブタイプ を jobType に設定する。
-
job の ストレージキー を storage key に設定する。
-
job の scope url を scopeURL に設定する。
-
job の script url を scriptURL に設定する。
-
job の ジョブpromise を promise に設定する。
-
job の client を client に設定する。
-
job を返す。
ジョブのスケジュール
- 入力
-
job:ジョブ
- 出力
-
なし
-
jobQueue を null とする。
-
scope→ジョブキューマップ[jobScope] が 存在しない場合、scope→ジョブキューマップ[jobScope] を新しい ジョブキュー に設定する。
-
jobQueue を scope→ジョブキューマップ[jobScope] に設定する。
-
jobQueue が空なら:
-
そうでない場合:
-
lastJob を jobQueue の末尾要素とする。
-
job が lastJobと等価 かつ lastJob の ジョブpromise がsettleしていなければ、job を lastJob の 等価ジョブリストに追加する。
-
それ以外なら、job の 所属ジョブキュー を jobQueue に設定し、jobQueue に job をenqueueする。
-
ジョブの実行
- 入力
-
jobQueue:ジョブキュー
- 出力
-
なし
-
アサート:jobQueue が 空ではない。
-
タスクをキューに入れる。以下の手順を実行:
ジョブの完了
- 入力
-
job:ジョブ
- 出力
-
なし
ジョブpromiseの解決
- 入力
-
job:ジョブ
value:任意
- 出力
-
なし
-
job の client が null でなければ、タスクをキューに入れる。job の client の 責任イベントループ で DOM操作タスクソース を使い、以下の手順を実行:
-
convertedValue を null とする。
-
job の ジョブタイプ が register または update なら、convertedValue に valueを表すServiceWorkerRegistrationオブジェクト(job の client)を設定する。
-
job の ジョブpromise を convertedValue でresolveする。
-
-
job の 等価ジョブリスト の各 equivalentJob について:
-
equivalentJob の client が null なら、次のループへ。
-
タスクをキューに入れる。equivalentJob の client の 責任イベントループ で DOM操作タスクソース を使い、以下の手順を実行:
-
convertedValue を null とする。
-
equivalentJob の ジョブタイプ が register または update なら、convertedValue に valueを表すServiceWorkerRegistrationオブジェクト(equivalentJob の client)を設定する。
-
それ以外なら、convertedValue を equivalentJob の client の Realm で value に設定する。
-
equivalentJob の ジョブpromise を convertedValue でresolveする。
-
-
ジョブpromiseの拒否
- 入力
-
job:ジョブ
errorData:例外生成に必要な情報
- 出力
-
なし
-
job の client が null でなければ、タスクをキューに入れる。job の client の 責任イベントループ で DOM操作タスクソース を使い、job の ジョブpromise を 新規例外(exception、errorData、job の client の Realm)でrejectする。
-
job の 等価ジョブリスト の各 equivalentJob について:
-
タスクをキューに入れる。equivalentJob の client の 責任イベントループ で DOM操作タスクソース を使い、equivalentJob の ジョブpromise を 新規例外(exception、errorData、equivalentJob の client の Realm)でrejectする。
登録開始
- 入力
-
scopeURL:URL/失敗/null
scriptURL:URL/失敗
promise:promise
client:ServiceWorkerクライアント
referrer:URL
workerType:ワーカータイプ
updateViaCache:update via cache mode
- 出力
-
なし
-
scriptURL が失敗なら、promise を
TypeError
でrejectし、これらの手順を中止する。 -
scriptURL の fragment を null に設定する。
注: ユーザーエージェントはスクリプトurlの fragment を保存しません。つまりfragmentはServiceWorkerの識別には影響しません。
-
scriptURL の scheme が "
http
"/"https
" 以外なら、promise をTypeError
でrejectし、これらの手順を中止する。 -
scriptURL の path 内のいずれかに ASCII大文字小文字無視 "
%2f
" または ASCII大文字小文字無視 "%5c
" が含まれるなら、promise をTypeError
でrejectし、これらの手順を中止する。 -
scopeURL が null なら、scopeURL を "./" を scriptURL でパースした結果に設定する。
注: 登録のscope urlはデフォルトでServiceWorkerスクリプトの場所になります。
-
scopeURL が失敗なら、promise を
TypeError
でrejectし、これらの手順を中止する。 -
scopeURL の fragment を null に設定する。
注: ユーザーエージェントはscope urlの fragment を保存しません。つまりfragmentはServiceWorker登録の識別には影響しません。
-
scopeURL の scheme が "
http
"/"https
" 以外なら、promise をTypeError
でrejectし、これらの手順を中止する。 -
scopeURL の path 内のいずれかに ASCII大文字小文字無視 "
%2f
" または ASCII大文字小文字無視 "%5c
" が含まれるなら、promise をTypeError
でrejectし、これらの手順を中止する。 -
storage key を clientからストレージキー取得 の結果とする。
-
job を Create Job(register、storage key、scopeURL、scriptURL、promise、client)の結果とする。
-
job の worker type を workerType に設定する。
-
job の update via cache mode を updateViaCache に設定する。
-
job の referrer を referrer に設定する。
-
ジョブのスケジュール(job)を呼び出す。
登録
- 入力
-
job:ジョブ
- 出力
-
なし
-
potentially trustworthy origin(job の script urlのorigin)の結果が
Not Trusted
なら:-
ジョブpromiseの拒否(job、"
SecurityError
"DOMException
)を呼び出す。 -
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
job の script url の origin と job の referrer の origin が 同一オリジンでなければ:
-
ジョブpromiseの拒否(job、"
SecurityError
"DOMException
)を呼び出す。 -
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
job の scope url の origin と job の referrer の origin が 同一オリジンでなければ:
-
ジョブpromiseの拒否(job、"
SecurityError
"DOMException
)を呼び出す。 -
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
registration を Get Registration(job の ストレージキー、job の scope url)の結果とする。
-
registration が null でなければ:
-
newestWorker を Get Newest Worker(registration)の結果とする。
-
newestWorker が null でなく、job の script url が newestWorkerのscript urlと一致、job の worker type が newestWorkerのtypeと一致、job の update via cache mode が registrationのupdate via cache modeと一致するなら:
-
ジョブpromiseの解決(job、registration)を呼び出す。
-
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
-
それ以外:
-
Set Registration(job の ストレージキー、job の scope url、job の update via cache mode)アルゴリズムを呼び出す。
-
-
Update(job)アルゴリズムを呼び出す。
更新
- 入力
-
job:ジョブ
- 出力
-
なし
-
registration を Get Registration(job の ストレージキー、job の scope url)の結果とする。
-
registration が null なら:
-
ジョブpromiseの拒否(job、
TypeError
)を呼び出す。 -
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
newestWorker を Get Newest Worker(registration)の結果とする。
-
job の ジョブタイプ が update かつ newestWorker が null でなく、かつ newestWorker の script url が jobのscript urlと一致しないなら:
-
ジョブpromiseの拒否(job、
TypeError
)を呼び出す。 -
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
hasUpdatedResources を false とする。
-
job の worker type に応じて以下のオプションでサブステップを実行:
- "
classic
" -
クラシックワーカースクリプトのfetch(job の シリアライズ済み script url、job の client、"
serviceworker
"、このServiceWorker用の生成予定environment settings object)を呼び出す。 - "
module
" -
モジュールワーカースクリプトグラフのfetch(job の シリアライズ済み script url、job の client、"
serviceworker
"、"omit
"、このServiceWorker用の生成予定environment settings object)を呼び出す。
実体environment settings objectではなく生成予定objectを使う。ServiceWorker独自の処理モデルのため。他のweb workerとの違い。HTML標準のスクリプトfetchアルゴリズムは本来他のweb worker用で実行環境のsettings objectが必要だが、ServiceWorkerは後で何度もスクリプトを実行するため先にfetchする。
HTMLのクラシック/モジュールワーカースクリプトfetchアルゴリズムはjob の clientを引数に取るが、job の clientはSoft Updateアルゴリズムから呼ぶときnull。
fetchフック(request)の実行手順:
-
request の header list に `
Service-Worker
`/`script
` を追加する。注: Service-Workerヘッダー定義は付録B参照。
-
以下のいずれかが真なら request の cache mode を "
no-cache
" に設定:-
registration の update via cache mode が "
all
" でない。 -
job の force bypass cache flag が設定済み。
-
newestWorker が null でなく、かつ registration が stale。
注: cache modeが"
no-cache
"でなくても、ユーザーエージェントはネットワーク層でCache-Controlヘッダーmax-age値に従いキャッシュバイパス判断。 -
-
request の service-workers mode を "
none
" に設定する。 -
isTopLevelフラグが未設定なら、fetch(request)結果を返す。
-
request の redirect mode を "
error
" に設定する。 -
fetch(request)を実行し、processResponseのresponse(response)で残りの手順を非同期で実行。
-
response の header list からMIME type抽出。このMIME type(パラメータ無視)がJavaScript MIME typeでなければ:
-
ジョブpromiseの拒否(job、"
SecurityError
"DOMException
)を呼び出す。 -
非同期でネットワークエラーとして処理終了。
-
-
serviceWorkerAllowed を extracting header list values(`
Service-Worker-Allowed
`、response の header list)の結果とする。注: Service-Worker-Allowedヘッダー定義は付録B参照。
-
policyContainer を fetch responseからポリシーコンテナ生成(response)の結果とする。
-
serviceWorkerAllowed が失敗なら:
-
非同期でネットワークエラーとして処理終了。
-
-
scopeURL を registration の scope url に設定する。
-
maxScopeString を null とする。
-
serviceWorkerAllowed が null なら:
-
resolvedScope を "./" を job の script urlでパースした結果とする。
-
maxScopeString を "
/
"+resolvedScope の path(空文字含む)を"/
"区切りで連結した文字列に設定。注: 最後のpath要素は常に空文字なのでmaxScopeStringは末尾"/"。
-
-
それ以外:
-
scopeString を "
/
"+scopeURL の path(空文字含む)を"/
"区切りで連結した文字列に設定。 -
maxScopeString が null または scopeString が maxScopeString で始まらなければ:
-
ジョブpromiseの拒否(job、"
SecurityError
"DOMException
)を呼び出す。 -
非同期でネットワークエラーとして処理終了。
-
-
url を request の url に設定。
-
updatedResourceMap[url] に response を設定。
-
response の cache state が "
local
" でなければ、registration の last update check time を現在時刻に設定。 -
以下のいずれかが真なら hasUpdatedResources をtrueに:
-
newestWorker が null。
-
newestWorker の script url が url でない、または newestWorker の type が job の worker type でない。
-
newestWorker の script resource map[url] の body が response の bodyとバイト単位で一致しない。
-
-
hasUpdatedResources がfalseで newestWorker の classic scripts imported flag が設定済みなら:
注: メインスクリプトが変わらない場合importされたスクリプトの更新有無を確認。
-
各 importUrl → storedResponse について、newestWorker の script resource map内で:
-
importUrl が url なら次へ。
-
importRequest を新しいrequest(url: importUrl、client: job の client、destination: "
script
"、parser metadata: "not parser-inserted
"、use-URL-credentials flagセット)とする。 -
importRequest の cache mode を "
no-cache
" にする条件:-
registration の update via cache mode が "
none
"。 -
job の force bypass cache flag が設定済み。
-
registration が stale。
-
-
fetchedResponse を fetch(importRequest)の結果とする。
-
updatedResourceMap[importRequest の url] に fetchedResponse を設定。
-
fetchedResponse を fetchedResponse の unsafe response に設定。
-
fetchedResponse の cache state が "
local
" でなければ、registration の last update check time を現在時刻に。 -
fetchedResponse が bad import script response なら次へ。
注: importScripts() のbad responseはバイト比較対象外。詳細はissue #1374参照。
-
fetchedResponse の body が storedResponse の unsafe response の body とバイト一致しなければ hasUpdatedResources をtrueに。
注: この判定でループbreakしない。全import済みスクリプトをキャッシュに入れる。
-
-
-
非同期でresponseとして手順終了。
アルゴリズムが非同期完了したら、残りの手順をscript(非同期完了値)で続行。
- "
-
script がnullまたは Is Async Module(script の record、script の base URL、« »)がtrueなら:
-
ジョブpromiseの拒否(job、
TypeError
)を呼び出す。注: 既にSecurityErrorでreject済みなら何もしない。
-
newestWorker が null なら 登録マップ[(registration の ストレージキー、シリアライズ済み scopeURL)]を削除。
-
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
hasUpdatedResources がfalseなら:
-
registration の update via cache mode を job の update via cache mode に設定。
-
ジョブpromiseの解決(job、registration)を呼び出す。
-
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
worker を新規ServiceWorkerとする。
-
worker の script url を job の script url に、 worker の script resource を script に、 worker の type を job の worker type に、 worker の script resource map を updatedResourceMap に設定。
-
worker の set of used scripts に url を追加。
-
worker の script resource の policy container を policyContainer に設定。
-
forceBypassCache を job の force bypass cache flag が設定済みならtrue、そうでなければfalseに。
-
runResult を Run Service Worker(worker、forceBypassCache)の結果とする。
-
runResult がfailureまたはabrupt completionなら:
-
ジョブpromiseの拒否(job、
TypeError
)を呼び出す。 -
newestWorker が null なら 登録マップ[(registration の ストレージキー、シリアライズ済み scopeURL)]を削除。
-
ジョブの完了(job)を呼び出す。
-
-
それ以外の場合、Install(job、worker、registration)アルゴリズムを呼び出す。
ソフトアップデート
ユーザーエージェントは好きな頻度で呼び出してアップデートを確認してもよい。
- 入力
-
registration:ServiceWorker登録
forceBypassCache:オプションのboolean。デフォルトはfalse。
注: 実装者はforceBypassCacheをデバッグ用途(開発者ツールなど)や、ServiceWorker拡張仕様で任意に利用してもよい。
- 出力
-
なし
-
newestWorker を Get Newest Worker(registration)の結果とする。
-
newestWorker が null なら、これらの手順を中止する。
-
job を Create Job(update、registration の ストレージキー、registration の scope url、newestWorker の script url、null、null)で生成。
-
job の worker type を newestWorker の type に設定する。
-
forceBypassCache が true なら job の force bypass cache flag を設定する。
-
ジョブのスケジュール(job)を呼び出す。
インストール
- 入力
-
job:ジョブ
worker:ServiceWorker
registration:ServiceWorker登録
- 出力
-
なし
-
installFailed を false とする。
-
newestWorker を Get Newest Worker(registration)の結果とする。
-
registration の update via cache mode を job の update via cache mode に設定する。
-
Update Registration State(registration、"
installing
"、worker)を呼び出す。 -
Update Worker State(registration の installing worker、"
installing
")を呼び出す。 -
アサート:job の ジョブpromise はnullではない。
-
ジョブpromiseの解決(job、registration)を呼び出す。
-
settingsObjects を environment settings object のうち origin が registration の scope url の origin であるもの全てとする。
-
settingsObjects の各 settingsObject について、タスクをキューに入れる(settingsObject の 責任イベントループ、DOM操作タスクソース)で以下を実行:
-
registrationObjects を settingsObject の realmにある
ServiceWorkerRegistration
オブジェクトのうち service worker registration が registration であるもの全てとする。 -
registrationObjects の各 registrationObject について updatefoundイベント発火(registrationObject)。
-
-
installingWorker を registration の installing worker に設定。
-
Should Skip Event(installingWorker、"install")の結果がfalseなら:
-
job の force bypass cache flag が設定済みなら forceBypassCache を true、そうでなければ false。
-
Run Service Worker(installingWorker、forceBypassCache)が失敗なら:
-
installFailed を true に。
-
-
そうでなければ:
-
タスクtaskをキューに入れる(installingWorker の event loop、DOM操作タスクソース)で以下を実行:
-
e を InstallEventイベント生成結果とする。
-
Dispatch(e、installingWorker の グローバルオブジェクト)。
-
WaitForAsynchronousExtensions: 以下のサブステップを 並行して実行:
-
e が active でなくなるまで待つ。
-
e の timed out flag がセットされたら installFailed を true に。
-
p を extend lifetime promises全て待つpromise(e の extend lifetime promises)の結果とする。
-
pがrejectされたら installFailed を true に。
-
task が破棄されたら installFailed を true に。
-
-
task が実行または破棄されるまで待つ。
-
WaitForAsynchronousExtensionsラベルのステップが完了するまで待つ。
-
-
-
installFailed が true なら:
-
Update Worker State(registration の installing worker、"
redundant
")を実行。 -
Update Registration State(registration、"
installing
"、null)を実行。 -
newestWorker が null なら 登録マップ[(registration の ストレージキー、シリアライズ済み registration の scope url)]を削除。
-
ジョブの完了(job)を呼び出し、これらの手順を中止する。
-
-
map を registration の installing worker の script resource map に設定。
-
usedSet を registration の installing worker の set of used scripts に設定。
-
各 url について map 内で:
-
registration の waiting worker が null でなければ:
-
Terminate(registration の waiting worker)。
-
Update Worker State(registration の waiting worker、"
redundant
")を実行。
-
-
Update Registration State(registration、"
waiting
"、registration の installing worker)を実行。 -
Update Registration State(registration、"
installing
"、null)を実行。 -
Update Worker State(registration の waiting worker、"
installed
")を実行。 -
ジョブの完了(job)を呼び出す。
-
このアルゴリズムで タスクキューされた Update Worker State の task がすべて実行完了するまで待つ。
-
Try Activate(registration)を呼び出す。
注: Try Activate で Activate が発火しなかった場合は、既存のactive workerを制御する最後のクライアントがアンロードされたり、
skipWaiting()
が非同期で呼び出された場合、または既存active workerのextend lifetime promisesがsettleした場合に再度Activateが試行される。
アクティベート
- 入力
-
registration:ServiceWorker登録
- 出力
-
なし
-
registration の waiting worker が null なら、これらの手順を中止する。
-
registration の active worker が null でなければ:
-
Terminate(registration の active worker)。
-
Update Worker State(registration の active worker、"
redundant
")を実行。
-
-
Update Registration State(registration、"
active
"、registration の waiting worker)を実行。 -
Update Registration State(registration、"
waiting
"、null)を実行。 -
Update Worker State(registration の active worker、"
activating
")を実行。注: active workerがactivating中は、ランタイムスクリプトエラーや強制終了があってもactive workerのアクティベートは妨げられない。
注: アクティベートハンドラは非本質的な作業(クリーンアップなど)を行うよう設計すること。ブラウザ終了等で完了しないこともあり得るので、ServiceWorkerはアクティベートハンドラが完了しなくても正常動作するよう設計すべき。
-
matchedClients を リスト(ServiceWorkerクライアントで、creation URLがregistration の ストレージキーおよびregistration の scope urlと一致するもの)とする。
-
各 client について matchedClients内で、タスクをキューに入れる(client の 責任イベントループ、DOM操作タスクソース)で以下を実行:
-
readyPromise を client の global object の
ServiceWorkerContainer
の ready promise とする。 -
readyPromise が null なら次へ。
-
readyPromiseがpendingなら、registrationを表すServiceWorkerRegistrationオブジェクト(readyPromise の relevant settings objectで)でresolve。
-
-
ServiceWorkerクライアント client(registrationをuseしているもの)について:
-
client の active worker を registration の active worker に設定。
-
Notify Controller Change(client)アルゴリズムを呼び出す。
-
-
activeWorker を registration の active worker に設定。
-
Should Skip Event(activeWorker、"activate")の結果がfalseなら:
-
Run Service Worker(activeWorker)の結果が失敗でなければ:
-
タスクtaskをキューに入れる(activeWorker の event loop、DOM操作タスクソース)で以下を実行:
-
e を ExtendableEventイベント生成結果とする。
-
Dispatch(e、activeWorker の グローバルオブジェクト)。
-
-
task が実行または破棄されるまで待つ。
-
WaitForAsynchronousExtensionsラベルのステップが完了するまで待つ。
-
-
-
Update Worker State(registration の active worker、"
activated
")を実行。
アクティベート試行
- 入力
-
registration:ServiceWorker登録
- 出力
-
なし
-
registration の waiting worker が null なら return。
-
registration の active worker が null でなく、かつ registration の active worker の state が "
activating
" なら return。注: 既存active workerがまだactivating状態なら、waiting workerのアクティベートは遅延される。
-
以下のいずれかが真なら Activate(registration)を呼び出す:
-
registration の active worker が null。
-
Service Worker Has No Pending Events(registration の active worker)がtrue、かつ ServiceWorkerクライアントがregistrationをuseしていない、またはregistration の waiting worker の skip waiting flag が設定済み。
-
ServiceWorkerGlobalScopeのセットアップ
- 入力
-
serviceWorker:ServiceWorker
- 出力
-
ServiceWorkerGlobalScope
オブジェクトまたはnull
注: このアルゴリズムはCSPチェック等で使えるServiceWorkerGlobalScope
またはnullを返す。serviceWorkerがactiveなServiceWorkerGlobalScope
を持つ場合はそれを返し、そうでなければ新規生成。
仕様上、こうしたセキュリティチェックにはServiceWorkerGlobalScope
、relevant settings object、realm、agent生成が必要。実装ではこのアルゴリズムで必要最低限の作業だけ行い、Run Service
Workerで残りを実行しても良い(結果が観測可能に等価ならOK。特に全セキュリティチェック結果が同じならOK)。
-
unsafeCreationTime を unsafe shared current time に設定。
-
serviceWorker が running なら serviceWorker の global object を返す。
-
serviceWorker の state が "
redundant
" なら null を返す。 -
serviceWorker の global object が nullでなければ serviceWorker の global object を返す。
-
アサート:serviceWorker の start status は null。
-
setupFailed を false とする。
-
globalObject を null とする。
-
agent を service worker agent取得の結果とし、そのコンテキストで以下を実行:
-
realmExecutionContext を 新規realm生成(agent+以下カスタマイズ)結果とする:
-
グローバルオブジェクトとして新しい
ServiceWorkerGlobalScope
オブジェクトを生成。workerGlobalScopeはこのオブジェクト。
-
-
settingsObject を新規environment settings object(以下のアルゴリズム定義):
- realm execution context
-
realmExecutionContext を返す。
- module map
-
workerGlobalScope の module map を返す。
- API base URL
-
serviceWorker の script url を返す。
- origin
-
登録元 ServiceWorkerクライアント の origin を返す。
- policy container
-
workerGlobalScope の policy container を返す。
- time origin
-
coarsening(unsafeCreationTime、workerGlobalScope の cross-origin isolated capability)の結果を返す。
-
settingsObject の idを新規一意な不透明文字列、creation URLをserviceWorker の script url、top-level creation URLをnull、top-level originを実装依存値、target browsing contextをnull、active service workerをnullに設定。
-
workerGlobalScope の url を serviceWorker の script url に設定。
-
workerGlobalScope の policy container を serviceWorker の script resource の policy container に設定。
-
新規
WorkerLocation
オブジェクトを生成し、workerGlobalScopeに関連付ける。 -
CSP初期化(workerGlobalScope)の結果が"
Blocked
"なら setupFailed を true にして手順中止。 -
globalObject を workerGlobalScope に設定。
-
-
globalObject が null でなくなるか setupFailed が true になるまで待つ。
-
setupFailed が true なら null を返す。
-
globalObject を返す。
ServiceWorkerの実行
- 入力
-
serviceWorker:ServiceWorker
forceBypassCache:オプションのboolean。デフォルトはfalse
- 出力
-
Completionまたは失敗
注: このアルゴリズムはServiceWorkerがrunning状態になるか起動失敗するまでブロックする。
-
serviceWorker が running なら、serviceWorker の start status を返す。
-
serviceWorker の state が "
redundant
" なら 失敗 を返す。 -
アサート:serviceWorker の start status は null。
-
script を serviceWorker の script resource に設定。
-
アサート:script は null でない。
-
startFailed を false とする。
-
workerGlobalScope を serviceWorker の global object に設定。
-
workerGlobalScope が null なら:
-
workerGlobalScope を ServiceWorkerGlobalScopeのセットアップ(serviceWorker)の結果に設定。
-
workerGlobalScope が null なら 失敗 を返す。
-
serviceWorker の global object を workerGlobalScope に設定。
-
-
workerGlobalScope の realm execution context用エージェント取得し、そのコンテキストで以下を実行:
-
forceBypassCache が true なら workerGlobalScope の importScripts用キャッシュバイパスフラグ を設定。
-
serviceWorker が active worker かつ serviceWorker の 登録の task queues にタスクがあれば、それらをserviceWorker の event loopの task queuesに元のtask source順でキューに入れる。
-
evaluationStatus を null とする。
-
script が クラシックスクリプトなら:
-
evaluationStatus を クラシックスクリプトの実行(script)の結果に設定。
-
evaluationStatus.[[Value]]が空なら(スクリプト未評価)、startFailed を true にし手順中止。
-
-
それ以外で script が モジュールスクリプトなら:
-
evaluationPromise を モジュールスクリプトの実行(script、report errors: false)の結果に設定。
-
アサート:evaluationPromise.[[PromiseState]] は "pending" でない。
-
evaluationPromise.[[PromiseState]] が "rejected" なら:
-
evaluationStatus を ThrowCompletion(evaluationPromise.[[PromiseResult]])に設定。
-
-
それ以外なら:
-
evaluationStatus を NormalCompletion(undefined)に設定。
-
-
-
スクリプトがTerminate Service Workerアルゴリズムで中断されたら、startFailed を true にし手順中止。
-
serviceWorker の start status を evaluationStatus に設定。
-
script の has ever been evaluated flag が未設定なら:
-
settingsObject の global object の関連付けられたevent listenersのevent typeごとに:
-
eventType を workerGlobalScope の関連service worker の set of event types to handleに追加。
注: この時点でevent listenerがなければ、service workerのset of event types to handleは空集合。
-
-
script の has ever been evaluated flag をセット。
-
serviceWorker の all fetch listeners are empty flag を未設定に。
-
ユーザーエージェントは、All Fetch Listeners Are Empty(workerGlobalScope)がtrueならserviceWorker の all fetch listeners are empty flag を設定してもよい。
-
-
responsible event loop(settingsObject指定)を破棄されるまで実行。
-
Clear(workerGlobalScope の map of active timers)。
-
-
serviceWorker が running になるか startFailed がtrueになるまで待つ。
-
startFailed がtrueなら 失敗 を返す。
-
serviceWorker の start status を返す。
fetchリスナーが全て空である
- 入力
-
workerGlobalScope:global object
- 出力
-
boolean
-
workerGlobalScope の set of event types to handle が fetch を含まなければ true を返す。
-
eventHandler を workerGlobalScope の event handler map["onfetch"]の値に設定。
-
eventListenerCallbacks を legacy-obtain service worker fetch event listener callbacks(workerGlobalScope)の結果に設定。
-
各 eventListenerCallback について eventListenerCallbacks内で:
-
callback を null とする。
-
eventHandler が null でなく eventListenerCallback が eventHandler の listener の callback と等しいなら、callback を IDL値→ECMAScript値変換(eventHandler の value)結果に設定。
-
それ以外なら callback を IDL値→ECMAScript値変換(eventListenerCallback)結果に設定。
-
IsCallable(callback)がfalseなら false を返す。
注: Callback オブジェクトが
handleEvent(event)
を使う場合は空でないと判断。getter呼び出しでevent listener変更されるのを避けるため。 -
callback の function body が空でなければ(statementまたはdeclarationがあれば) false を返す。
注:
() => {}
のようなfetchリスナーを検出。一部サイトはPWA認定目的で空bodyのfetchリスナーを持つ。 -
-
true を返す。
注: ユーザーエージェントは空fetchリスナーが不要で性能低下の可能性ある旨警告表示を推奨。
ServiceWorkerの終了
- 入力
-
serviceWorker:ServiceWorker
- 出力
-
なし
-
serviceWorker のメインループと並行して以下を実行:
-
serviceWorkerGlobalScope を serviceWorker の global object に設定。
-
serviceWorkerGlobalScope の closing フラグをtrueに。
-
serviceWorker の set of extended events から全itemを削除。
-
serviceWorkerGlobalScope の event loop の task queues に「handle fetch task source」か「handle functional event task source」のtask sourceを持つタスクがあれば、それらをserviceWorker の 登録の対応する task queues に元のtask source順でキューに入れ、他のタスク(messageイベント等)は全て破棄する。
注: fetchイベントやpush等他の機能的イベントはregistrationのtask queuesに退避され、他のtask(message等)は破棄される。
-
実行中スクリプトの中断(serviceWorker)。
-
serviceWorker の start status を null に。
-
Fetch処理
Fetch処理アルゴリズムはfetch処理をServiceWorkerコンテキストへ委譲するエントリポイントです。
- 入力
-
request:request
fetchController:fetch controller
useHighResPerformanceTimers:boolean
- 出力
-
registration を null とする。
-
client を request の clientに設定。
-
reservedClient を request の reserved clientに設定。
-
preloadResponse を新規promiseに設定。
-
workerRealm を null とする。
-
timingInfo を新規service worker timing infoに設定。
-
アサート:request の destination は "
serviceworker
" でない。 -
request の destination が "
embed
" または "object
" なら:-
null を返す。
-
-
それ以外で request が 非サブリソースリクエストなら:
-
reservedClient が null でなく environment settings objectなら:
-
reservedClient が secure context でなければ null を返す。
-
-
それ以外:
-
request の url が 潜在的に信頼できるURLでなければ null を返す。
-
-
request が ナビゲーションリクエストで、navigateがshift+reload等で起動された場合は null を返す。
-
Assert:reservedClient は null でない。
-
storage key を ストレージキー取得(reservedClient)の結果に設定。
-
registration を Match Service Worker Registration(storage key、request の url)の結果に設定。
-
registrationが null または registration の active workerが null なら null を返す。
-
request の destination が
"report"
でなければ、reservedClient の active service worker を registration の active workerに設定。
注: この時点からServiceWorkerクライアントは自身のactive service workerのServiceWorker登録をuseし始めます。
-
-
それ以外で request が サブリソースリクエストなら:
-
client の active service worker が非nullなら、registration を client の active service worker の ServiceWorker登録に設定。
-
それ以外は null を返す。
-
-
activeWorker を registration の active workerに設定。
-
以下いずれかが真なら shouldSoftUpdate を true、そうでなければ false に:
-
request が 非サブリソースリクエスト。
-
request が サブリソースリクエストかつ registration が stale。
-
-
activeWorker の routerルールリストが空でなければ:
-
source を Get Router Source(registration の active worker、request)の結果に設定。
-
source が
"network"
なら:-
shouldSoftUpdate が true なら 並行してSoft Update(registration)を実行。
-
null を返す。
-
-
それ以外で source が
"cache"
または source["cacheName
"]が存在するなら:-
shouldSoftUpdate が true なら 並行してSoft Update(registration)を実行。
-
各 cacheName → cache について registration の ストレージキー の name to cache map から:
-
source["
cacheName
"]が存在しかつcacheNameと一致しなければスキップ。 -
requestResponses を Query Cache(request、新規
CacheQueryOptions
、cache)の結果に設定。 -
requestResponses が空リストなら null を返す。
-
それ以外:
-
requestResponse を requestResponses の先頭要素に設定。
-
response を requestResponse の response に設定。
-
globalObject を activeWorker の global objectに設定。
-
globalObject が null なら:
-
globalObject を ServiceWorkerGlobalScopeのセットアップ(activeWorker)の結果に設定。
-
-
globalObject が null なら null を返す。
注: CORSチェックのためServiceWorkerGlobalScopeを生成するだけであり、実装で実際に生成するとは限らない。
-
response の type が "
opaque
"かつcross-origin resource policy check(globalObject の origin、globalObject、""、response の internal response)がblockedなら null を返す。 -
response を返す。
-
-
-
null を返す。
-
-
それ以外で source が
"race-network-and-fetch-handler"
かつ request の method が `GET
` なら:-
shouldSoftUpdate が true なら 並行してSoft Update(registration)を実行。
-
raceFetchController を null に設定。
-
raceResponse を race response(valueが "
pending
")に設定。 -
以下のサブステップを並行して、かつfetchController の stateが"
terminated
"または"aborted
"なら中断: -
中断時、raceFetchControllerがnullでなければ:
-
Abort(raceFetchController)。
-
raceResponse を race response(valueがnull)に設定。
-
-
preloadResponse を undefined でresolve。
-
以下のサブステップを並行して実行:
-
fetchHandlerResponse を Create Fetch Event and Dispatch (request、registration、useHighResPerformanceTimers、timingInfo、workerRealm、reservedClient、preloadResponse、raceResponse)の結果に設定。
-
fetchHandlerResponse が null でもなく network error でもなく、かつ raceFetchControllerがnullでなければ Abort(raceFetchController)。
-
queueにfetchHandlerResponseをenqueue。
-
-
queueが空でなくなるまで待つ。
-
dequeue(queue)の結果を返す。
-
-
アサート:sourceは"
fetch-event
"である。
-
-
request がnavigation requestで、 registration の navigation preload enabled flagがセットされ、 request の methodが`
GET
`で、 registration の active worker の set of event types to handleがfetch
を含み、 registration の active worker の all fetch listeners are empty flagが未設定なら:注: 上記でregistration の active worker の set of event types to handle が
fetch
を含まない場合は、コンソール警告表示推奨(開発者意図不明のため)。-
preloadRequest を request複製(request)の結果に設定。
-
preloadRequestHeaders を preloadRequest の header listに設定。
-
preloadResponseObject を新規
Response
(新規Headers
、guard: "immutable
")に設定。 -
header追加(preloadRequestHeaders、name: `
Service-Worker-Navigation-Preload
`、value: registration の navigation preload header value)。 -
preloadRequest の service-workers mode を "
none
" に設定。 -
preloadFetchController を null に設定。
-
以下のサブステップを並行して、fetchController の state が"
terminated
"または"aborted
"なら中断: -
中断時:
-
deserializedError を deserialize a serialized abort reason(null、workerRealm)の結果に設定。
-
Abort(preloadFetchController、deserializedError)。
-
-
-
それ以外は preloadResponse を undefined でresolve。
-
Create Fetch Event and Dispatch(request、registration、useHighResPerformanceTimers、timingInfo、workerRealm、reservedClient、preloadResponse、null)の結果を返す。
Fetchイベント生成・dispatch
- 入力
-
request:request
registration:ServiceWorker登録
useHighResPerformanceTimers:boolean
timingInfo:ServiceWorker timing info
workerRealm:グローバルオブジェクトのrelevant realm
reservedClient:reserved client
preloadResponse:promise
raceResponse:race responseまたはnull
- 出力
-
response を null とする。
-
eventCanceled を false とする。
-
client を request の clientに設定。
-
activeWorker を registration の active workerに設定。
-
eventHandled を null とする。
-
handleFetchFailed を false とする。
-
respondWithEntered を false とする。
-
以下いずれかが真なら shouldSoftUpdate を true、そうでなければ false に:
-
request が 非サブリソースリクエスト。
-
request が サブリソースリクエストかつ registration が stale。
-
-
Should Skip Event("fetch"、activeWorker)がtrueなら:
-
shouldSoftUpdate が true なら 並行して Soft Update(registration)を実行。
-
null を返す。
-
-
activeWorker の all fetch listeners are empty flag がセットされていれば:
-
並行して:
-
activeWorker の state が "activating" なら、activeWorker の state が "activated" になるまで待つ。
-
ServiceWorkerの実行(activeWorker)を実行。
-
shouldSoftUpdate が true なら Soft Update(registration)を実行。
-
-
null を返す。
-
-
useHighResPerformanceTimers が true なら useHighResPerformanceTimers を activeWorker の global object の cross-origin isolated capabilityに設定。
-
timingInfo の start time を coarsened shared current time(useHighResPerformanceTimers)に設定。
-
activeWorker の state が "
activating
"なら activeWorker の state が "activated
"になるまで待つ。 -
ServiceWorkerの実行(activeWorker)の結果が失敗なら handleFetchFailed を true に。
-
それ以外:
-
workerRealm を activeWorker の global object の relevant realmに設定。
-
eventHandled を 新規promise(workerRealm)に設定。
-
raceResponse が null でなければ、set(activeWorker の global object の race response map[request] = raceResponse)。
-
タスクtaskをキューに入れる(以下のサブステップを実行):
-
e を FetchEventイベント生成結果に設定。
-
abortController を新規
AbortController
(workerRealm)に設定。 -
requestObject を Requestオブジェクト生成(request、新規
Headers
(guard: "immutable
")、abortController の signal、workerRealm)結果に設定。 -
e の
cancelable
を true に初期化。 -
e の
request
を requestObject に初期化。 -
e の
preloadResponse
を preloadResponse に初期化。 -
request が 非サブリソースリクエストかつ request の destination が
"report"
でなければ、e のresultingClientId
を reservedClient の id、それ以外は空文字列に初期化。 -
request が ナビゲーションリクエストなら e の
replacesClientId
を request の replaces client id、それ以外は空文字列に初期化。 -
e の
handled
を eventHandled に初期化。 -
timingInfo の fetch event dispatch time を coarsened shared current time(useHighResPerformanceTimers)に設定。
-
Dispatch(e、activeWorker の global object)。
-
Update Service Worker Extended Events Set(activeWorker、e)を呼び出す。
-
e の respond-with entered flag がセットされていれば respondWithEntered を true に。
-
e の wait to respond flag がセットされていれば:
-
e の wait to respond flag が解除されるまで待つ。
-
e の respond-with error flag がセットされていれば handleFetchFailed を true に。
-
それ以外は response を e の potential responseに設定。
-
-
response が null かつ request の body が nullでなく、かつ request の body の source が nullなら:
-
response が nullでなければ response の service worker timing info を timingInfoに設定。
-
e の canceled flag がセットされていれば eventCanceled を true に。
-
fetchController の state が"
terminated
"または"aborted
"なら:-
deserializedError を deserialize a serialized abort reason(fetchController の serialized abort reason、workerRealm)に設定。
-
タスクをキューに入れる(signal abort(abortController、deserializedError))。
-
task が破棄されたら handleFetchFailed を true に。
task は activeWorker の event loopおよび handle fetch task source を必ず使うこと。
-
-
-
task が実行されるか handleFetchFailed が true になるまで待つ。
-
shouldSoftUpdate が true なら 並行してSoft Update(registration)を実行。
-
activeWorker の global object の race response map[request]が存在するなら、race response map[request]を削除。
-
respondWithEntered が false なら:
-
eventCanceled が true なら:
-
eventHandled が nullでなければ reject(eventHandled、"
NetworkError
"DOMException
、workerRealm)。 -
network errorを返す。
-
-
eventHandled が nullでなければ resolve(eventHandled)。
-
raceResponse の value が nullでなければ:
-
null を返す。
-
-
handleFetchFailed が true なら:
-
eventHandled が nullでなければ reject(eventHandled、"
NetworkError
"DOMException
、workerRealm)。 -
network errorを返す。
-
-
eventHandled が nullでなければ resolve(eventHandled)。
-
response を返す。
URLパターンの解析
- 入力
-
rawPattern、
URLPatternCompatible
serviceWorker、サービスワーカー
- 出力
-
baseURLをserviceWorkerのスクリプトURLとする。
-
rawPatternおよびbaseURLを与えて、Web IDL値からURLパターンを構築する結果を返す。
ルーター条件の検証
- 入力
-
condition、
RouterCondition
serviceWorker、サービスワーカー
- 出力
-
真偽値
-
hasConditionをfalseにする。
-
condition["
urlPattern
"] が存在する場合:-
rawPatternをcondition["
urlPattern
"]とする。 -
rawPatternとserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。これが例外を投げた場合はcatchし、falseを返す。
-
patternが正規表現グループを持つ場合、falseを返す。
注:ユーザー定義正規表現の実行はセキュリティ上の懸念があるため、禁止されている。
-
hasConditionをtrueにする。
-
-
condition["
requestMethod
"] が存在する場合:-
methodをcondition["
requestMethod
"]とする。 -
methodがメソッドでなければ、falseを返す。
-
methodが禁止メソッドならば、falseを返す。
-
hasConditionをtrueにする。
-
-
condition["
requestMode
"] が存在する場合、hasConditionをtrueにする。 -
condition["
requestDestination
"] が存在する場合、hasConditionをtrueにする。 -
condition["
runningStatus
"] が存在する場合、hasConditionをtrueにする。 -
hasConditionを返す。
ルーター条件のマッチング
- 入力
-
condition、
RouterCondition
serviceWorker、サービスワーカー
request、リクエスト
- 出力
-
真偽値
注:複数の条件(例:urlPattern
、runningStatus
、requestMethod
が設定されている場合)は、すべての条件が一致した場合にtrueが返される。
-
-
orConditionsをcondition["
or
"]とする。 -
orConditionsの各orConditionについて:
-
orCondition、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はtrueを返す。
-
-
falseを返す。
-
-
-
condition["
not
"]、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はfalseを返す。 -
trueを返す。
-
-
それ以外:
注:ルーター条件の検証アルゴリズムは、
or
、not
と他の条件が排他されていることを保証する。-
condition["
urlPattern
"] が存在する場合:-
rawPatternをcondition["
urlPattern
"]とする。 -
rawPatternとserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。
-
-
condition["
requestMethod
"] が存在する場合:-
methodをcondition["
requestMethod
"]とする。 -
methodを正規化する。
-
requestのメソッドがmethodでなければ、falseを返す。
-
-
condition["
requestMode
"] が存在する場合:-
modeをcondition["
requestMode
"]とする。 -
requestのモードがmodeでなければ、falseを返す。
-
-
condition["
requestDestination
"] が存在する場合:-
destinationをcondition["
requestDestination
"]とする。 -
requestの宛先がdestinationでなければ、falseを返す。
-
-
condition["
runningStatus
"] が存在する場合:-
runningStatusをcondition["
runningStatus
"]とする。 -
runningStatusが
"not-running"
であり、serviceWorkerが稼働中ならば、falseを返す。
-
-
trueを返す。
-
ルーター登録制限の確認
- 入力
-
routerRules、ルーター規則のリスト
- 出力
-
真偽値
注: ルーター条件は_or
やnot
を用いて複雑かつネスト可能です。過度な処理を防ぐため、このアルゴリズムでは2つの制限を設けます。第一に、すべてのネストされた条件を含む合計条件数は1024を超えてはなりません。第二に、ネストの深さは10レベルまでに制限され、指数的計算を回避します。
-
resultをルーター条件カウント結果とする。
-
resultの条件数を1024に設定する。
-
resultのクォータ超過をfalseに設定する。
-
各ruleをrouterRulesから取り出して:
-
resultを、Count Router Inner Conditionsアルゴリズムの rule["
condition
"], result、10を渡した結果で更新する。 -
resultのクォータ超過がtrueなら、falseを返す。
-
-
trueを返す。
ルーター内条件数のカウント
- 入力
-
condition、
RouterCondition
result、ルーター条件カウント結果
depth、数値
- 出力
-
result、ルーター条件カウント結果
-
resultの条件数を1減らす。
-
resultの条件数が0、またはdepthが0なら:
-
resultのクォータ超過をtrueに設定する。
-
resultを返す。
-
-
-
depthを1減らす。
-
condition["
_or
"]の各orConditionについて:-
resultを、ルーター内条件数のカウントをorCondition、result、depthで実行した結果で更新する。
-
resultのクォータ超過がtrueなら、resultを返す。
-
-
-
それ以外でcondition["
not
"] が存在する場合:-
depthを1減らす。
-
resultを、ルーター内条件数のカウントを condition["
not
"]、result、depthで実行した結果で更新する。 -
resultのクォータ超過がtrueなら、resultを返す。
-
-
resultを返す。
ルーターソースの取得
- 入力
-
serviceWorker、サービスワーカー
request、リクエスト
- 出力
-
RouterSource
またはnull
-
各ruleをserviceWorkerのルーター規則のリストから取り出して:
-
rule["
condition
"]、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueなら rule["source
"]を返す。
-
-
nullを返す。
イベントをスキップすべきか
- 入力
-
eventName、文字列
serviceWorker、サービスワーカー
- 出力
-
真偽値
注: 不要な遅延を避けるため、この仕様ではサービスワーカーのグローバルにイベントリスナーが初回スクリプト実行時に決定的に追加されていない場合、イベントのdispatchをスキップすることを許可します。
-
serviceWorkerの処理するイベント型の集合がeventNameを含まない場合、ユーザーエージェントはスキップ可能としてtrueを返すことができる。
-
falseを返す。
機能イベントの発火
- 入力
-
eventName、文字列
eventConstructor、
ExtendableEvent
を拡張したイベントコンストラクターregistration、サービスワーカー登録
initialization、eventのためのeventConstructorで構築したプロパティ初期化(オプション)
postDispatchSteps、アクティブワーカーのイベントループで、dispatchedEventにeventConstructorでdispatchされたインスタンスをセットして実行する追加ステップ(オプション)
- 出力
-
なし
-
アサート: registrationのアクティブワーカーはnullでない。
-
activeWorkerをregistrationのアクティブワーカーとする。
-
eventNameとactiveWorkerを使ってイベントをスキップすべきかを実行し、trueなら:
-
activeWorkerの状態が"
activating
"なら、activeWorkerの状態が"activated
"になるまで待つ。 -
サービスワーカーの実行アルゴリズムをactiveWorkerで実行し、失敗なら:
-
タスクtaskをキューイングして以下のサブステップを実行:
-
initializationがnullでなければ、eventをinitializationで初期化する。
-
dispatchをeventとactiveWorkerのグローバルオブジェクトに対して実行する。
-
サービスワーカー拡張イベント集合の更新をactiveWorkerとeventで実行する。
-
postDispatchStepsがnullでなければ、eventをdispatchedEventとして渡してpostDispatchStepsを実行する。
taskはactiveWorkerのイベントループと機能イベントタスクソースを利用する必要がある。
-
taskが実行または破棄されるのを待つ。
amazingthing
"イベント(型はAmazingThingEvent
)をあるserviceWorkerRegistration上で発火し、イベントオブジェクトのプロパティを初期化する場合、次のように記述する:
-
機能イベントの発火 "
amazingthing
" をAmazingThingEvent
を使い serviceWorkerRegistration 上で以下のプロパティで行う:- propertyName
-
value
- anotherPropertyName
-
anotherValue
次にdispatchedEventで以下のステップを実行:
-
サービスワーカーのイベントループ上でdispatchedEventを必要な処理に利用する。
初期化ステップやdispatch後のステップが不要な場合の記述例:
-
機能イベントの発火 "
whatever
" をExtendableEvent
を使い serviceWorkerRegistration 上で行う。
サービスワーカークライアントのアンロード処理
ユーザーエージェントは、サービスワーカークライアントがドキュメントのアンロードクリーンアップ手順または終了によりアンロードされる際、次の手順を必ず実行しなければならない。
- 入力
-
client、サービスワーカークライアント
- 出力
-
なし
-
以下の手順をアトミックに実施する。
-
registrationをclientが利用しているサービスワーカー登録とする。
-
registrationがnullの場合、これらの手順を中止する。
-
他のサービスワーカークライアントがregistrationを利用している場合、これらの手順を中止する。
-
アクティベート試行をregistrationで呼び出す。
ユーザーエージェントのシャットダウン処理
- 入力
-
なし
- 出力
-
なし
サービスワーカー拡張イベント集合の更新
登録解除
- 入力
-
job、ジョブ
- 出力
-
なし
-
jobのオリジンがjobのスコープURLのオリジンと一致しない場合:
-
ジョブプロミス拒否をjobと"
SecurityError
"DOMException
で呼び出す。 -
ジョブ完了をjobで呼び出し、これらの手順を中止する。
-
-
registrationがnullの場合:
-
ジョブプロミス解決をjobとtrueで呼び出す。
-
登録クリア試行をregistrationで呼び出す。
注: 登録クリア試行がここで登録クリアを発火しない場合、登録クリアは、最後のクライアントが登録利用している状態でアンロードされた時や、その登録のサービスワーカーのライフタイム延長プロミスが解決された際に再度試行される。
-
ジョブ完了をjobで呼び出す。
登録設定
- 入力
-
storage key、ストレージキー
scope、URL
updateViaCache、キャッシュ経由更新モード
- 出力
-
registration、サービスワーカー登録
-
以下の手順をアトミックに実施する。
-
scopeStringをscopeをフラグメント除外フラグ付きで直列化したものとする。
-
registrationを新規サービスワーカー登録として、ストレージキーをstorage keyに、スコープURLをscopeに、キャッシュ経由更新モードをupdateViaCacheに設定する。
-
登録マップ[(storage key, scopeString)]にregistrationを設定する。
-
registrationを返す。
登録クリア
- 入力
-
registration、サービスワーカー登録
- 出力
-
なし
-
以下の手順をアトミックに実施する。
-
registrationのインストール中ワーカーがnullでなければ:
-
終了をregistrationのインストール中ワーカーに対して呼び出す。
-
ワーカー状態更新アルゴリズムをregistrationのインストール中ワーカーと"
redundant
"で実行する。 -
登録状態更新アルゴリズムをregistration、"
installing
"、nullで実行する。
-
-
registrationの待機中ワーカーがnullでなければ:
-
registrationのアクティブワーカーがnullでなければ:
登録クリア試行
- 入力
-
registration、サービスワーカー登録
- 出力
-
なし
-
次のすべてが満たされ、かつどのサービスワーカークライアントもregistrationを利用していない場合、登録クリアをregistrationで呼び出す:
-
registrationのインストール中ワーカーがnull、またはサービスワーカーが保留イベントなしアルゴリズムをregistrationのインストール中ワーカーで実行した結果がtrueである。
-
registrationの待機中ワーカーがnull、またはサービスワーカーが保留イベントなしアルゴリズムをregistrationの待機中ワーカーで実行した結果がtrueである。
-
registrationのアクティブワーカーがnull、またはサービスワーカーが保留イベントなしアルゴリズムをregistrationのアクティブワーカーで実行した結果がtrueである。
-
登録状態更新
- 入力
-
registration、サービスワーカー登録
target、文字列("
installing
"、"waiting
"、"active
"のいずれか)source、サービスワーカーまたはnull
- 出力
-
なし
-
registrationObjectsをregistrationに関連付けられているすべての
ServiceWorkerRegistration
オブジェクトを含む配列とする。 -
targetが"
installing
"の場合:-
registrationのインストール中ワーカーをsourceに設定する。
-
registrationObjectsの各registrationObjectについて:
-
タスクキューを使い、registrationObjectの
installing
属性をregistrationのインストール中ワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistrationのインストール中ワーカーとregistrationObjectの関連設定オブジェクトで実行した結果に設定する。
-
-
-
それ以外でtargetが"
waiting
"の場合:-
registrationの待機中ワーカーをsourceに設定する。
-
registrationObjectsの各registrationObjectについて:
-
タスクキューを使い、registrationObjectの
waiting
属性をregistrationの待機中ワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistrationの待機中ワーカーとregistrationObjectの関連設定オブジェクトで実行した結果に設定する。
-
-
-
それ以外でtargetが"
active
"の場合:-
registrationのアクティブワーカーをsourceに設定する。
-
registrationObjectsの各registrationObjectについて:
-
タスクキューを使い、registrationObjectの
active
属性をregistrationのアクティブワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistrationのアクティブワーカーとregistrationObjectの関連設定オブジェクトで実行した結果に設定する。
-
タスクはregistrationObjectの関連設定オブジェクトの責任イベントループとDOM操作タスクソースを必ず利用する。
-
ワーカー状態の更新
-
アサート: stateは"
parsed
"でない。注: "
parsed
"は初期状態であり、サービスワーカーはこの状態に更新されることはない。 -
workerの状態をstateに設定する。
-
settingsObjectsを、環境設定オブジェクトのうち、オリジンがworkerのスクリプトURLのオリジンと一致するもの全てとする。
-
settingsObjectsの各settingsObjectについて、タスクをキューし、settingsObjectの責任イベントループ上でDOM操作タスクソースを利用して、以下の手順を実行する:
-
objectMapをsettingsObjectのサービスワーカーオブジェクトマップとする。
-
objectMap[worker]が存在しない場合、これらの手順を中止する。
-
workerObjをobjectMap[worker]とする。
-
workerObjの
state
属性をstateに設定する。 -
statechangeという名前のイベントをworkerObjに発火する。
-
コントローラー変更の通知
- 入力
-
client、サービスワーカークライアント
- 出力
-
なし
-
アサート: clientはnullでない。
-
clientが環境設定オブジェクトの場合、タスクキューを使い、controllerchangeという名前のイベントをclientが関連付けられている
ServiceWorkerContainer
オブジェクトに発火する。
タスクはclientの責任イベントループとDOM操作タスクソースを必ず利用する。
サービスワーカー登録のマッチング
-
以下の手順をアトミックに実施する。
-
clientURLStringを直列化したclientURLとする。
-
matchingScopeStringを空文字列とする。
-
scopeStringSetを空リストとする。
-
clientURLStringで始まるscopeStringSet内の最長値があれば、それをmatchingScopeStringに設定する。
注: このステップのURL文字列マッチングはパス構造ではなくプレフィックスに基づく。例えば、"https://example.com/prefix-of/resource.html"というクライアントURL文字列は、"https://example.com/prefix"というスコープの登録に一致する。URL文字列比較は同一オリジンのセキュリティ上安全で、HTTP(S) URLは常にオリジン部分の末尾にスラッシュ付きで直列化される。
-
matchingScopeをnullとする。
-
matchingScopeStringが空文字列でなければ:
-
storage keyとmatchingScopeを使い登録取得アルゴリズムを実行した結果を返す。
登録取得
最新ワーカー取得
- 入力
-
registration、サービスワーカー登録
- 出力
-
newestWorker、サービスワーカー
-
以下の手順をアトミックに実施する。
-
newestWorkerをnullとする。
-
registrationのインストール中ワーカーがnullでなければ、newestWorkerをregistrationのインストール中ワーカーに設定する。
-
それ以外でregistrationの待機中ワーカーがnullでなければ、newestWorkerをregistrationの待機中ワーカーに設定する。
-
それ以外でregistrationのアクティブワーカーがnullでなければ、newestWorkerをregistrationのアクティブワーカーに設定する。
-
newestWorkerを返す。
サービスワーカーに保留イベントがないか
- 入力
-
worker、サービスワーカー
- 出力
-
trueまたはfalse(真偽値)
クライアント作成
- 入力
-
client、サービスワーカークライアント
- 出力
-
clientObject、
Client
オブジェクト
-
clientObjectを新規
Client
オブジェクトとして作成する。 -
clientObjectのサービスワーカークライアントをclientに設定する。
-
clientObjectを返す。
ウィンドウクライアント作成
- 入力
-
client、サービスワーカークライアント
frameType、文字列
visibilityState、文字列
focusState、真偽値
ancestorOriginsList、リスト
- 出力
-
windowClient、
WindowClient
オブジェクト
-
windowClientを新規
WindowClient
オブジェクトとして作成する。 -
windowClientのサービスワーカークライアントをclientに設定する。
-
windowClientのフレームタイプをframeTypeに設定する。
-
windowClientの表示状態をvisibilityStateに設定する。
-
windowClientのフォーカス状態をfocusStateに設定する。
-
windowClientのancestor origins arrayを、ancestorOriginsListから作成したFrozen Arrayに設定する。
-
windowClientを返す。
フレームタイプ取得
- 入力
-
navigable、ナビゲーブル
- 出力
-
frameType、文字列
-
navigableの親がnullでなければ、"
nested
"を返す。 -
navigableのアクティブなブラウジングコンテキストが補助的ブラウジングコンテキストであれば、"
auxiliary
"を返す。 -
"
top-level
"を返す。
Get Client Promise解決
- 入力
-
client、サービスワーカークライアント
promise、プロミス
- 出力
-
なし
-
clientが環境設定オブジェクトの場合:
-
clientがセキュアコンテキストでなければ、タスクキューによりpromiseを"
SecurityError
"DOMException
で拒否する。この際、promiseの関連設定オブジェクトの責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。
-
-
それ以外:
-
clientの作成URLが潜在的に信頼できるURLでなければ、タスクキューによりpromiseを"
SecurityError
"DOMException
で拒否する。この際、promiseの関連設定オブジェクトの責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。
-
-
clientが環境設定オブジェクトであり、ウィンドウクライアントでなければ:
-
clientObjectをクライアント作成アルゴリズムでclientを引数に実行した結果とする。
-
タスクキューによりpromiseをclientObjectで解決する。この際、promiseの関連設定オブジェクトの責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。
-
-
それ以外:
-
browsingContextをnullとする。
-
clientが環境設定オブジェクトであれば、browsingContextをclientのグローバルオブジェクトのブラウジングコンテキストに設定する。
-
それ以外の場合、browsingContextをclientのターゲットブラウジングコンテキストに設定する。
-
navigableをbrowsingContextのナビゲーブルで、アクティブなブラウジングコンテキストがbrowsingContextのものとする。
-
タスクキューで以下の手順をbrowsingContextのイベントループ上、ユーザー操作タスクソースを使って実行:
-
frameTypeをフレームタイプ取得アルゴリズムをnavigableで実行した結果とする。
-
visibilityStateをbrowsingContextのアクティブドキュメントの
visibilityState
属性値とする。 -
focusStateをフォーカス取得手順でbrowsingContextのアクティブドキュメントを引数に実行した結果とする。
-
ancestorOriginsListを空リストとする。
-
clientがウィンドウクライアントの場合、ancestorOriginsListをbrowsingContextのアクティブドキュメントの関連グローバルオブジェクトの
Location
オブジェクトのancestor origins listの関連リストに設定する。 -
タスクキューで以下の手順をpromiseの関連設定オブジェクトの責任イベントループ上、DOM操作タスクソースで実行:
-
clientの廃棄フラグが設定されていれば、promiseをundefinedで解決し、これらの手順を中止する。
-
windowClientをウィンドウクライアント作成アルゴリズムでclient、frameType、visibilityState、focusState、ancestorOriginsListを引数に実行した結果とする。
-
promiseをwindowClientで解決する。
-
-
-
キャッシュクエリ
- 入力
-
requestQuery、リクエスト
options、
CacheQueryOptions
オブジェクト(オプション)targetStorage、リクエストレスポンスリスト(オプション)
- 出力
-
resultList、リクエストレスポンスリスト
-
resultListを空のリストとする。
-
storageをnullとする。
-
オプション引数targetStorageが省略された場合、storageを関連リクエストレスポンスリストに設定する。
-
それ以外の場合、storageをtargetStorageに設定する。
-
各requestResponseをstorageから取り出して:
-
cachedRequestをrequestResponseのリクエストとする。
-
cachedResponseをrequestResponseのレスポンスとする。
-
リクエストキャッシュ一致アルゴリズムをrequestQuery、cachedRequest、cachedResponse、optionsで実行し、trueなら:
-
requestCopyをcachedRequestのコピーとする。
-
responseCopyをcachedResponseのコピーとする。
-
requestCopy/responseCopyをresultListに追加する。
-
-
-
resultListを返す。
リクエストがキャッシュ項目に一致するか
- 入力
-
requestQuery、リクエスト
request、リクエスト
response、レスポンスまたはnull(オプション、省略時はnull)
options、
CacheQueryOptions
オブジェクト(オプション) - 出力
-
真偽値
-
options["
ignoreMethod
"] がfalseで、requestのメソッドがGET
でなければ、falseを返す。 -
queryURLをrequestQueryのurlとする。
-
cachedURLをrequestのurlとする。
-
options["
ignoreSearch
"] がtrueなら: -
queryURLがフラグメント除外フラグ付きでcachedURLと等しくない場合、falseを返す。
-
responseがnull、options["
ignoreVary
"] がtrue、またはresponseのヘッダーリストがVary
を含まない場合、trueを返す。 -
fieldValuesをリストとして、field-valuesでresponseの
Vary
ヘッダー値に対応する要素を格納する。 -
fieldValuesの各fieldValueについて:
-
trueを返す。
バッチキャッシュ操作
- 入力
-
operations、リスト(キャッシュバッチ操作オブジェクトのリスト)
- 出力
-
resultList、リクエストレスポンスリスト
-
cacheを関連リクエストレスポンスリストとする。
-
backupCacheをcacheのコピーで新規リクエストレスポンスリストとする。
-
addedItemsを空のリストとする。
-
以下のサブステップをアトミックに試行する:
-
resultListを空のリストとする。
-
各operationをoperationsから取り出して:
-
operationのtypeが"
delete
"で、operationのresponseがnullでなければ、TypeErrorを投げる。 -
キャッシュクエリをoperationのrequest、operationのoptions、addedItemsで実行した結果が空でなければ、InvalidStateError
DOMException
を投げる。 -
requestResponsesを空のリストとする。
-
operationのtypeが"
delete
"なら: -
それ以外でoperationのtypeが"
put
"なら:-
operationのresponseがnullなら、TypeErrorを投げる。
-
rのメソッドが
GET
でなければ、TypeErrorを投げる。 -
operationのoptionsがnullでなければ、TypeErrorを投げる。
-
各requestResponseをrequestResponsesから取り出して:
-
item値がrequestResponseに一致するものをcacheから削除する。
-
-
前2ステップでキャッシュ書き込みが割り当てクォータ上限超過で失敗した場合、QuotaExceededError
DOMException
を投げる。
-
-
resultListを返す。
-
-
そして、例外が投げられた場合:
-
関連リクエストレスポンスリストから全てのitemを削除する。
-
各requestResponseをbackupCacheから取り出して:
-
requestResponseを関連リクエストレスポンスリストに追加する。
-
-
例外を投げる。
注: 例外が投げられた場合、実装はバッチ操作ジョブ中にキャッシュストレージに加えた変更を元に戻す(ロールバック)する。
-
非同期モジュールか判定
- 入力
-
record、Module Record
moduleMap、モジュールマップ
base、URL
- 出力
-
真偽値
-
recordがCyclic Module Recordでなければ:
-
falseを返す。
-
-
record.[[Async]]がtrueなら:
-
trueを返す。
-
-
各文字列requestedをrecord.[[RequestedModules]]から取り出して:
-
urlをモジュール指定子の解決アルゴリズムをbaseとrequestedで実行した結果とする。
-
アサート: urlは失敗にならない。なぜならモジュール指定子の解決は同じ引数で事前に必ず成功しているため。
-
seenがurlを含まない場合:
-
urlをseenに追加する。
-
moduleMap[url]にrecordがなければ:
-
falseを返す。
-
-
非同期モジュールか判定アルゴリズムを moduleMap[url]のrecord、moduleMap、base、seenで実行してtrueなら:
-
trueを返す。
-
-
-
-
falseを返す。
Race Responseの検索
-
registrationをnullとする。
-
requestが非サブリソースリクエストの場合:
-
requestのreserved clientがnullなら、nullを返す。
-
storage keyをストレージキー取得アルゴリズムをrequestのreserved clientで実行した結果に設定する。
-
registrationをサービスワーカー登録のマッチングアルゴリズムをstorage keyとrequestのurlで実行した結果に設定する。
-
-
それ以外でrequestがサブリソースリクエストの場合:
-
clientをrequestのclientとする。
-
clientのアクティブサービスワーカーがnullなら、nullを返す。
-
registrationをclientのアクティブサービスワーカーの関連サービスワーカー登録に設定する。
-
-
それ以外の場合、nullを返す。
-
activeWorkerをregistrationのアクティブワーカーに設定する。
-
mapをactiveWorkerのグローバルオブジェクトのrace response mapに設定する。
-
map[request]が存在する場合:
-
nullを返す。
付録B: 拡張HTTPヘッダー
サービスワーカーのスクリプトリクエスト
サービスワーカーのスクリプトレスポンス
サービスワーカーのスクリプトリソースリクエストへのHTTPレスポンスには、次のヘッダーを含めることができる:
- `
Service-Worker-Allowed
` -
ユーザーエージェントがパス制限(スクリプトが制御できる最大のスコープURLを制限)の上限を、指定された値に上書きすることを示す。
注: 値はURLである。相対URLが指定された場合は、スクリプトのURLを基準にパースされる。
// 許容される最大スコープのデフォルトはスクリプトのパス(この例では "/js/") // "/js/" の場合 navigator. serviceWorker. register( "/js/sw.js" ). then(() => { console. log( "デフォルトスコープ'/js/'でインストールに成功しました。" ); });
// スクリプトより上位パスへスコープを指定 // レスポンスにService-Worker-Allowedヘッダーなし navigator. serviceWorker. register( "/js/sw.js" , { scope: "/" }). catch (() => { console. error( "パス制限違反でインストールに失敗しました。" ); });
構文
ABNFによる、サービスワーカーのスクリプトリソースリクエストとレスポンスで使われるヘッダー値の構文定義:
Service-Worker = %x73.63.72.69.70.74 ; "script", case-sensitive
注: Service-Worker-Allowedヘッダー値の検証はABNFではなくURLパースアルゴリズム(Updateアルゴリズム)で行われる。
8. 謝辞
Andrew Betts氏には、Jake Archibald氏、Jackson Gabbard氏、Tobie Langel氏、Robin Berjon氏、Patrick Lauke氏、Christian Heilmann氏など志を同じくする方々を集めて小さなワークショップを主催してくれたことに深く感謝します。その日の議論の明快さと、そこで示されたユースケースから多くの可能性が生まれました。さらに、オフライン問題への意識向上にも感謝します。彼のEdgeConfの運営と、オフラインを継続的なテーマにしたことで、この作業が前進する多くの機会とつながりが生まれました。
Anne van Kesteren氏には、Webプラットフォームの専門知識と標準化経験を惜しみなく提供いただき、サービスワーカーの開発を通じて助けていただきました。彼のURL、HTTP Fetch、Promises、DOMの実際の挙動についての先行研究がなければ、この仕様は不完全だったでしょう。同様に、Ian Hickson氏のWeb Worker仕様の厳密さにも多大な感謝を捧げます。
順不同ですが、設計指針や議論に深く感謝する方々:Jungkee Song氏、Alec Flett氏、David Barrett-Kahn氏、Aaron Boodman氏、Michael Nordman氏、Tom Ashworth氏、Kinuko Yasuda氏、Darin Fisher氏、Jonas Sicking氏、Jesús Leganés Combarro氏、Mark Christian氏、Dave Hermann氏、Yehuda Katz氏、François Remy氏、Ilya Grigorik氏、Will Chan氏、Domenic Denicola氏、Nikhil Marathe氏、Yves Lafon氏、Adam Barth氏、Greg Simon氏、Devdatta Akhawe氏、Dominic Cooney氏、Jeffrey Yasskin氏、Joshua Bell氏、Boris Zbarsky氏、Matt Falkenhagen氏、Tobie Langel氏、Gavin Peters氏、Ben Kelly氏、Hiroki Nakagawa氏、Jake Archibald氏、Josh Soref氏、Jinho Bang氏、Yutaka Hirano氏、Michael(tm) Smith氏、isonmad氏、Ali Alabbas氏、Philip Jägenstedt氏、Mike Pennisi氏、Eric Willigers氏。
Jason Weber氏、Chris Wilson氏、Paul Kinlan氏、Ehsan Akhgari氏、Daniel Austin氏にも、要件や標準化プロセスに関して貴重かつ的確なフィードバックをいただきました。
著者らは、Dimitri Glazkov氏にも感謝します。彼のスクリプトやフォーマットツールは、この仕様書の作成に不可欠でした。また、彼の多大なガイダンスにも感謝します。
Vivian Cromwell氏、Greg Simon氏、Alex Komoroske氏、Wonsuk Lee氏、Seojin Kim氏にも、その専門的な支援に感謝します。