1+ /*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */
2+ let coepCredentialless = false ;
3+ if ( typeof window === 'undefined' ) {
4+ self . addEventListener ( "install" , ( ) => self . skipWaiting ( ) ) ;
5+ self . addEventListener ( "activate" , ( event ) => event . waitUntil ( self . clients . claim ( ) ) ) ;
6+
7+ self . addEventListener ( "message" , ( ev ) => {
8+ if ( ! ev . data ) {
9+ return ;
10+ } else if ( ev . data . type === "deregister" ) {
11+ self . registration
12+ . unregister ( )
13+ . then ( ( ) => {
14+ return self . clients . matchAll ( ) ;
15+ } )
16+ . then ( clients => {
17+ clients . forEach ( ( client ) => client . navigate ( client . url ) ) ;
18+ } ) ;
19+ } else if ( ev . data . type === "coepCredentialless" ) {
20+ coepCredentialless = ev . data . value ;
21+ }
22+ } ) ;
23+
24+ self . addEventListener ( "fetch" , function ( event ) {
25+ const r = event . request ;
26+ if ( r . cache === "only-if-cached" && r . mode !== "same-origin" ) {
27+ return ;
28+ }
29+
30+ const request = ( coepCredentialless && r . mode === "no-cors" )
31+ ? new Request ( r , {
32+ credentials : "omit" ,
33+ } )
34+ : r ;
35+ event . respondWith (
36+ fetch ( request )
37+ . then ( ( response ) => {
38+ if ( response . status === 0 ) {
39+ return response ;
40+ }
41+
42+ const newHeaders = new Headers ( response . headers ) ;
43+ newHeaders . set ( "Cross-Origin-Embedder-Policy" ,
44+ coepCredentialless ? "credentialless" : "require-corp"
45+ ) ;
46+ if ( ! coepCredentialless ) {
47+ newHeaders . set ( "Cross-Origin-Resource-Policy" , "cross-origin" ) ;
48+ }
49+ newHeaders . set ( "Cross-Origin-Opener-Policy" , "same-origin" ) ;
50+
51+ return new Response ( response . body , {
52+ status : response . status ,
53+ statusText : response . statusText ,
54+ headers : newHeaders ,
55+ } ) ;
56+ } )
57+ . catch ( ( e ) => console . error ( e ) )
58+ ) ;
59+ } ) ;
60+
61+ } else {
62+ ( ( ) => {
63+ const reloadedBySelf = window . sessionStorage . getItem ( "coiReloadedBySelf" ) ;
64+ window . sessionStorage . removeItem ( "coiReloadedBySelf" ) ;
65+ const coepDegrading = ( reloadedBySelf == "coepdegrade" ) ;
66+
67+ // You can customize the behavior of this script through a global `coi` variable.
68+ const coi = {
69+ shouldRegister : ( ) => ! reloadedBySelf ,
70+ shouldDeregister : ( ) => false ,
71+ coepCredentialless : ( ) => true ,
72+ coepDegrade : ( ) => true ,
73+ doReload : ( ) => window . location . reload ( ) ,
74+ quiet : false ,
75+ ...window . coi
76+ } ;
77+
78+ const n = navigator ;
79+ const controlling = n . serviceWorker && n . serviceWorker . controller ;
80+
81+ // Record the failure if the page is served by serviceWorker.
82+ if ( controlling && ! window . crossOriginIsolated ) {
83+ window . sessionStorage . setItem ( "coiCoepHasFailed" , "true" ) ;
84+ }
85+ const coepHasFailed = window . sessionStorage . getItem ( "coiCoepHasFailed" ) ;
86+
87+ if ( controlling ) {
88+ // Reload only on the first failure.
89+ const reloadToDegrade = coi . coepDegrade ( ) && ! (
90+ coepDegrading || window . crossOriginIsolated
91+ ) ;
92+ n . serviceWorker . controller . postMessage ( {
93+ type : "coepCredentialless" ,
94+ value : ( reloadToDegrade || coepHasFailed && coi . coepDegrade ( ) )
95+ ? false
96+ : coi . coepCredentialless ( ) ,
97+ } ) ;
98+ if ( reloadToDegrade ) {
99+ ! coi . quiet && console . log ( "Reloading page to degrade COEP." ) ;
100+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "coepdegrade" ) ;
101+ coi . doReload ( "coepdegrade" ) ;
102+ }
103+
104+ if ( coi . shouldDeregister ( ) ) {
105+ n . serviceWorker . controller . postMessage ( { type : "deregister" } ) ;
106+ }
107+ }
108+
109+ // If we're already coi: do nothing. Perhaps it's due to this script doing its job, or COOP/COEP are
110+ // already set from the origin server. Also if the browser has no notion of crossOriginIsolated, just give up here.
111+ if ( window . crossOriginIsolated !== false || ! coi . shouldRegister ( ) ) return ;
112+
113+ if ( ! window . isSecureContext ) {
114+ ! coi . quiet && console . log ( "COOP/COEP Service Worker not registered, a secure context is required." ) ;
115+ return ;
116+ }
117+
118+ // In some environments (e.g. Firefox private mode) this won't be available
119+ if ( ! n . serviceWorker ) {
120+ ! coi . quiet && console . error ( "COOP/COEP Service Worker not registered, perhaps due to private mode." ) ;
121+ return ;
122+ }
123+
124+ n . serviceWorker . register ( window . document . currentScript . src ) . then (
125+ ( registration ) => {
126+ ! coi . quiet && console . log ( "COOP/COEP Service Worker registered" , registration . scope ) ;
127+
128+ registration . addEventListener ( "updatefound" , ( ) => {
129+ ! coi . quiet && console . log ( "Reloading page to make use of updated COOP/COEP Service Worker." ) ;
130+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "updatefound" ) ;
131+ coi . doReload ( ) ;
132+ } ) ;
133+
134+ // If the registration is active, but it's not controlling the page
135+ if ( registration . active && ! n . serviceWorker . controller ) {
136+ ! coi . quiet && console . log ( "Reloading page to make use of COOP/COEP Service Worker." ) ;
137+ window . sessionStorage . setItem ( "coiReloadedBySelf" , "notcontrolling" ) ;
138+ coi . doReload ( ) ;
139+ }
140+ } ,
141+ ( err ) => {
142+ ! coi . quiet && console . error ( "COOP/COEP Service Worker failed to register:" , err ) ;
143+ }
144+ ) ;
145+ } ) ( ) ;
146+ }
0 commit comments