worker.js (4382B)
1 // Any copyright is dedicated to the Public Domain. 2 // http://creativecommons.org/licenses/publicdomain/ 3 4 // This worker is used for two types of tests. `handlePush` sends messages to 5 // `frame.html`, which verifies that the worker can receive push messages. 6 7 // `handleMessage` receives messages from `test_push_manager_worker.html` 8 // and `test_data.html`, and verifies that `PushManager` can be used from 9 // the worker. 10 11 /* globals PushEvent */ 12 13 this.onpush = handlePush; 14 this.onmessage = handleMessage; 15 this.onpushsubscriptionchange = handlePushSubscriptionChange; 16 17 function getJSON(data) { 18 var result = { 19 ok: false, 20 }; 21 try { 22 result.value = data.json(); 23 result.ok = true; 24 } catch (e) { 25 // Ignore syntax errors for invalid JSON. 26 } 27 return result; 28 } 29 30 function assert(value, message) { 31 if (!value) { 32 throw new Error(message); 33 } 34 } 35 36 function broadcast(event, promise) { 37 event.waitUntil( 38 Promise.resolve(promise).then(message => { 39 return self.clients.matchAll().then(clients => { 40 clients.forEach(client => client.postMessage(message)); 41 }); 42 }) 43 ); 44 } 45 46 function reply(event, promise) { 47 event.waitUntil( 48 Promise.resolve(promise) 49 .then(result => { 50 event.ports[0].postMessage(result); 51 }) 52 .catch(error => { 53 event.ports[0].postMessage({ 54 error: String(error), 55 }); 56 }) 57 ); 58 } 59 60 function handlePush(event) { 61 if (event instanceof PushEvent) { 62 if (!("data" in event)) { 63 broadcast(event, { type: "finished", okay: "yes" }); 64 return; 65 } 66 var message = { 67 type: "finished", 68 okay: "yes", 69 }; 70 if (event.data) { 71 message.data = { 72 text: event.data.text(), 73 arrayBuffer: event.data.arrayBuffer(), 74 json: getJSON(event.data), 75 blob: event.data.blob(), 76 bytes: event.data.bytes(), 77 }; 78 } 79 broadcast(event, message); 80 return; 81 } 82 broadcast(event, { type: "finished", okay: "no" }); 83 } 84 85 var testHandlers = { 86 publicKey() { 87 return self.registration.pushManager 88 .getSubscription() 89 .then(subscription => ({ 90 p256dh: subscription.getKey("p256dh"), 91 auth: subscription.getKey("auth"), 92 })); 93 }, 94 95 resubscribe(data) { 96 return self.registration.pushManager 97 .getSubscription() 98 .then(subscription => { 99 assert( 100 subscription.endpoint == data.endpoint, 101 "Wrong push endpoint in worker" 102 ); 103 return subscription.unsubscribe(); 104 }) 105 .then(result => { 106 assert(result, "Error unsubscribing in worker"); 107 return self.registration.pushManager.getSubscription(); 108 }) 109 .then(subscription => { 110 assert(!subscription, "Subscription not removed in worker"); 111 return self.registration.pushManager.subscribe(); 112 }) 113 .then(subscription => { 114 return { 115 endpoint: subscription.endpoint, 116 }; 117 }); 118 }, 119 120 denySubscribe() { 121 return self.registration.pushManager 122 .getSubscription() 123 .then(subscription => { 124 assert( 125 !subscription, 126 "Should not return worker subscription with revoked permission" 127 ); 128 return self.registration.pushManager.subscribe().then( 129 _ => { 130 assert(false, "Expected error subscribing with revoked permission"); 131 }, 132 error => { 133 return { 134 isDOMException: error instanceof DOMException, 135 name: error.name, 136 }; 137 } 138 ); 139 }); 140 }, 141 142 subscribeWithKey(data) { 143 return self.registration.pushManager 144 .subscribe({ 145 applicationServerKey: data.key, 146 }) 147 .then( 148 subscription => { 149 return { 150 endpoint: subscription.endpoint, 151 key: subscription.options.applicationServerKey, 152 }; 153 }, 154 error => { 155 return { 156 isDOMException: error instanceof DOMException, 157 name: error.name, 158 }; 159 } 160 ); 161 }, 162 }; 163 164 function handleMessage(event) { 165 var handler = testHandlers[event.data.type]; 166 if (handler) { 167 reply(event, handler(event.data)); 168 } else { 169 reply(event, Promise.reject("Invalid message type: " + event.data.type)); 170 } 171 } 172 173 function handlePushSubscriptionChange(event) { 174 broadcast(event, { type: "changed", okay: "yes" }); 175 }