From 776c915c8cf08a8b1201d2afa8b9f6e21913b192 Mon Sep 17 00:00:00 2001 From: "c.kai" Date: Mon, 27 Jul 2026 14:47:48 +0800 Subject: [PATCH] fix(js): add global PromiseRejectionEvent and StorageEvent constructors Obscura lacked these two standard event constructors on globalThis. The missing PromiseRejectionEvent caused core-js to misdetect the environment and override native Promise with a broken polyfill, breaking Vue application rendering. StorageEvent completes the localStorage/sessionStorage API surface. Both are also registered in document.createEvent() for legacy callers. Fixes #521, fixes #522. --- crates/obscura-js/js/bootstrap.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/obscura-js/js/bootstrap.js b/crates/obscura-js/js/bootstrap.js index 3ef371a..c11b770 100644 --- a/crates/obscura-js/js/bootstrap.js +++ b/crates/obscura-js/js/bootstrap.js @@ -2627,6 +2627,8 @@ class Document extends Node { 'popstateevent': PopStateEvent, 'animationevent': AnimationEvent, 'transitionevent': TransitionEvent, + 'promiserejectionevent': PromiseRejectionEvent, + 'storageevent': StorageEvent, }; const Cls = map[String(type || '').toLowerCase()] || Event; return new Cls(''); @@ -5007,6 +5009,35 @@ globalThis.ToggleEvent = class ToggleEvent extends Event { }; _markNative(globalThis.ToggleEvent); +globalThis.PromiseRejectionEvent = class PromiseRejectionEvent extends Event { + constructor(type, init = {}) { + super(type, init); + this.promise = init.promise; + this.reason = init.reason; + } +}; +_markNative(globalThis.PromiseRejectionEvent); + +globalThis.StorageEvent = class StorageEvent extends Event { + constructor(type, init = {}) { + super(type, init); + this.key = init.key !== undefined ? init.key : null; + this.oldValue = init.oldValue !== undefined ? init.oldValue : null; + this.newValue = init.newValue !== undefined ? init.newValue : null; + this.url = init.url || ""; + this.storageArea = init.storageArea || null; + } + initStorageEvent(type, bubbles, cancelable, key, oldValue, newValue, url, storageArea) { + this.initEvent(type, bubbles, cancelable); + this.key = key !== undefined ? key : null; + this.oldValue = oldValue !== undefined ? oldValue : null; + this.newValue = newValue !== undefined ? newValue : null; + this.url = url || ""; + this.storageArea = storageArea || null; + } +}; +_markNative(globalThis.StorageEvent); + // AbortController / AbortSignal. AbortSignal is a real constructor with a // prototype, so feature-detection and `AbortSignal.prototype` access work. It // carries aborted/reason, supports throwIfAborted(), and fires "abort" to