extendable-event-waituntil.js (2600B)
1 var pendingPorts = []; 2 var portResolves = []; 3 4 onmessage = function(e) { 5 var message = e.data; 6 if ('port' in message) { 7 var resolve = self.portResolves.shift(); 8 if (resolve) 9 resolve(message.port); 10 else 11 self.pendingPorts.push(message.port); 12 } 13 }; 14 15 function fulfillPromise() { 16 return new Promise(function(resolve) { 17 // Make sure the oninstall/onactivate callback returns first. 18 Promise.resolve().then(function() { 19 var port = self.pendingPorts.shift(); 20 if (port) 21 resolve(port); 22 else 23 self.portResolves.push(resolve); 24 }); 25 }).then(function(port) { 26 port.postMessage('SYNC'); 27 return new Promise(function(resolve) { 28 port.onmessage = function(e) { 29 if (e.data == 'ACK') 30 resolve(); 31 }; 32 }); 33 }); 34 } 35 36 function rejectPromise() { 37 return new Promise(function(resolve, reject) { 38 // Make sure the oninstall/onactivate callback returns first. 39 Promise.resolve().then(reject); 40 }); 41 } 42 43 function stripScopeName(url) { 44 return url.split('/').slice(-1)[0]; 45 } 46 47 oninstall = function(e) { 48 switch (stripScopeName(self.location.href)) { 49 case 'install-fulfilled': 50 e.waitUntil(fulfillPromise()); 51 break; 52 case 'install-rejected': 53 e.waitUntil(rejectPromise()); 54 break; 55 case 'install-multiple-fulfilled': 56 e.waitUntil(fulfillPromise()); 57 e.waitUntil(fulfillPromise()); 58 break; 59 case 'install-reject-precedence': 60 // Three "extend lifetime promises" are needed to verify that the user 61 // agent waits for all promises to settle even in the event of rejection. 62 // The first promise is fulfilled on demand by the client, the second is 63 // immediately scheduled for rejection, and the third is fulfilled on 64 // demand by the client (but only after the first promise has been 65 // fulfilled). 66 // 67 // User agents which simply expose `Promise.all` semantics in this case 68 // (by entering the "redundant state" following the rejection of the 69 // second promise but prior to the fulfillment of the third) can be 70 // identified from the client context. 71 e.waitUntil(fulfillPromise()); 72 e.waitUntil(rejectPromise()); 73 e.waitUntil(fulfillPromise()); 74 break; 75 } 76 }; 77 78 onactivate = function(e) { 79 switch (stripScopeName(self.location.href)) { 80 case 'activate-fulfilled': 81 e.waitUntil(fulfillPromise()); 82 break; 83 case 'activate-rejected': 84 e.waitUntil(rejectPromise()); 85 break; 86 } 87 };