Merge pull request #98069 from thedinosoar/fix/service-worker-sandbox-error-98068

[Web] Fix PWA callback assignment causing crash in sandboxed iframes
This commit is contained in:
Thaddeus Crews 2024-11-25 13:22:29 -06:00
commit 57125f48ce
4 changed files with 48 additions and 25 deletions

View File

@ -363,24 +363,28 @@ window.addEventListener('load', () => {
btn.style.display = ''; btn.style.display = '';
} }
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service.worker.js').then(function (reg) { try {
if (reg.waiting) { navigator.serviceWorker.register('service.worker.js').then(function (reg) {
notifyUpdate(reg.waiting); if (reg.waiting) {
} notifyUpdate(reg.waiting);
reg.addEventListener('updatefound', function () { }
const update = reg.installing; reg.addEventListener('updatefound', function () {
update.addEventListener('statechange', function () { const update = reg.installing;
if (update.state === 'installed') { update.addEventListener('statechange', function () {
// It's a new install, claim and perform aggressive caching. if (update.state === 'installed') {
if (!reg.active) { // It's a new install, claim and perform aggressive caching.
update.postMessage('claim'); if (!reg.active) {
} else { update.postMessage('claim');
notifyUpdate(update); } else {
notifyUpdate(update);
}
} }
} });
}); });
}); });
}); } catch (e) {
console.error('Error while registering service worker:', e);
}
} }
const missing = Engine.getMissingFeatures({ const missing = Engine.getMissingFeatures({

View File

@ -152,9 +152,15 @@ const engine = new Engine(GODOT_CONFIG);
if (missing.length !== 0) { if (missing.length !== 0) {
if (GODOT_CONFIG['serviceWorker'] && GODOT_CONFIG['ensureCrossOriginIsolationHeaders'] && 'serviceWorker' in navigator) { if (GODOT_CONFIG['serviceWorker'] && GODOT_CONFIG['ensureCrossOriginIsolationHeaders'] && 'serviceWorker' in navigator) {
let serviceWorkerRegistrationPromise;
try {
serviceWorkerRegistrationPromise = navigator.serviceWorker.getRegistration();
} catch (err) {
serviceWorkerRegistrationPromise = Promise.reject(new Error('Service worker registration failed.'));
}
// There's a chance that installing the service worker would fix the issue // There's a chance that installing the service worker would fix the issue
Promise.race([ Promise.race([
navigator.serviceWorker.getRegistration().then((registration) => { serviceWorkerRegistrationPromise.then((registration) => {
if (registration != null) { if (registration != null) {
return Promise.reject(new Error('Service worker already exists.')); return Promise.reject(new Error('Service worker already exists.'));
} }

View File

@ -241,7 +241,11 @@ const Engine = (function () {
*/ */
installServiceWorker: function () { installServiceWorker: function () {
if (this.config.serviceWorker && 'serviceWorker' in navigator) { if (this.config.serviceWorker && 'serviceWorker' in navigator) {
return navigator.serviceWorker.register(this.config.serviceWorker); try {
return navigator.serviceWorker.register(this.config.serviceWorker);
} catch (e) {
return Promise.reject(e);
}
} }
return Promise.resolve(); return Promise.resolve();
}, },

View File

@ -441,8 +441,12 @@ const GodotPWA = {
godot_js_pwa_cb__sig: 'vi', godot_js_pwa_cb__sig: 'vi',
godot_js_pwa_cb: function (p_update_cb) { godot_js_pwa_cb: function (p_update_cb) {
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
const cb = GodotRuntime.get_func(p_update_cb); try {
navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb)); const cb = GodotRuntime.get_func(p_update_cb);
navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb));
} catch (e) {
GodotRuntime.error('Failed to assign PWA callback', e);
}
} }
}, },
@ -450,12 +454,17 @@ const GodotPWA = {
godot_js_pwa_update__sig: 'i', godot_js_pwa_update__sig: 'i',
godot_js_pwa_update: function () { godot_js_pwa_update: function () {
if ('serviceWorker' in navigator && GodotPWA.hasUpdate) { if ('serviceWorker' in navigator && GodotPWA.hasUpdate) {
navigator.serviceWorker.getRegistration().then(function (reg) { try {
if (!reg || !reg.waiting) { navigator.serviceWorker.getRegistration().then(function (reg) {
return; if (!reg || !reg.waiting) {
} return;
reg.waiting.postMessage('update'); }
}); reg.waiting.postMessage('update');
});
} catch (e) {
GodotRuntime.error(e);
return 1;
}
return 0; return 0;
} }
return 1; return 1;