document.createEvent('CustomEvent') was returning a generic Event,
so the legacy DOM Level 2 pattern
var e = document.createEvent('CustomEvent');
e.initCustomEvent('foo', true, false, payload);
threw "TypeError: e.initCustomEvent is not a function" because the
returned object was an Event, not a CustomEvent — and CustomEvent
didn't define initCustomEvent anyway. The Starbucks China bundle
(and a long tail of other CDN bundles using the same shim) depended
on this and aborted bootstrap.
Two changes in crates/obscura-js/js/bootstrap.js:
1. Add CustomEvent.prototype.initCustomEvent(type, bubbles, cancelable,
detail) matching the spec.
2. Rewrite Document.prototype.createEvent so it dispatches to the
right class based on the type string ('CustomEvent', 'MouseEvent',
'MouseEvents', 'KeyboardEvent', 'FocusEvent', 'InputEvent',
'UIEvent', 'WheelEvent', 'PointerEvent', 'ErrorEvent',
'PopStateEvent', 'AnimationEvent', 'TransitionEvent', and
case-insensitive 'Events' aliases). The HTMLDocument variant on
the second Document class delegates to the canonical impl.
Spec note: createEvent returns the event with an empty type until
init*Event() is called — matched exactly.
Four new unit tests cover initCustomEvent presence and field setters,
class dispatch for CustomEvent / MouseEvent / MouseEvents / KeyboardEvent,
and the unknown-type fallback to Event.
Generated by Ora Studio
Vibe coded by ousamabenyounes
Co-authored-by: Ora Studio <[email protected]>
This commit is contained in:
1 parent
86a868bfd6
commit
d50dd0f553
2 files changed
+95
-3
No files matched your search
Vendored
+35
-3
@@ -825,7 +825,28 @@ class Document extends Node {
|
||||
_cache.set(nid, frag);
|
||||
return frag;
|
||||
}
|
||||
createEvent(type) { return new Event(type); }
|
||||
// Legacy DOM Level 2 event factory. Spec returns an event of the requested
|
||||
// class with an empty type until init*Event() is called. We previously
|
||||
// returned a generic Event for every type, which broke libraries that call
|
||||
// createEvent('CustomEvent').initCustomEvent(...) — see issue #41.
|
||||
createEvent(type) {
|
||||
const map = {
|
||||
'customevent': CustomEvent, 'customevents': CustomEvent,
|
||||
'mouseevent': MouseEvent, 'mouseevents': MouseEvent,
|
||||
'keyboardevent': KeyboardEvent, 'keyboardevents': KeyboardEvent,
|
||||
'focusevent': FocusEvent,
|
||||
'inputevent': InputEvent,
|
||||
'uievent': UIEvent, 'uievents': UIEvent,
|
||||
'wheelevent': WheelEvent,
|
||||
'pointerevent': PointerEvent,
|
||||
'errorevent': ErrorEvent,
|
||||
'popstateevent': PopStateEvent,
|
||||
'animationevent': AnimationEvent,
|
||||
'transitionevent': TransitionEvent,
|
||||
};
|
||||
const Cls = map[String(type || '').toLowerCase()] || Event;
|
||||
return new Cls('');
|
||||
}
|
||||
createRange() { return { setStart(){}, setEnd(){}, collapse(){}, selectNodeContents(){}, cloneContents(){ return document.createDocumentFragment(); } }; }
|
||||
addEventListener(type, fn, opts) {} removeEventListener() {} dispatchEvent() { return true; }
|
||||
createTreeWalker(root, whatToShow, filter) {
|
||||
@@ -1890,7 +1911,18 @@ globalThis.Event = class Event {
|
||||
preventDefault() { this.defaultPrevented=true; } stopPropagation(){} stopImmediatePropagation(){}
|
||||
initEvent(type,bubbles,cancelable) { this.type=type;this.bubbles=!!bubbles;this.cancelable=!!cancelable; }
|
||||
};
|
||||
globalThis.CustomEvent = class extends Event { constructor(t,o={}) { super(t,o);this.detail=o.detail; } };
|
||||
globalThis.CustomEvent = class extends Event {
|
||||
constructor(t,o={}) { super(t,o);this.detail=o.detail; }
|
||||
// Legacy DOM Level 2 init; some libraries (Starbucks China bundle, older
|
||||
// analytics shims) still call createEvent('CustomEvent') + initCustomEvent
|
||||
// instead of new CustomEvent(...). See issue #41.
|
||||
initCustomEvent(type,bubbles,cancelable,detail) {
|
||||
this.type = type;
|
||||
this.bubbles = !!bubbles;
|
||||
this.cancelable = !!cancelable;
|
||||
this.detail = detail;
|
||||
}
|
||||
};
|
||||
globalThis.MouseEvent = class extends Event { constructor(t,o={}) { super(t,o);this.clientX=o.clientX||0;this.clientY=o.clientY||0; } };
|
||||
globalThis.KeyboardEvent = class extends Event { constructor(t,o={}) { super(t,o);this.key=o.key||"";this.code=o.code||""; } };
|
||||
globalThis.FocusEvent = class extends Event {};
|
||||
@@ -2154,7 +2186,7 @@ class _IframeDocument {
|
||||
createTextNode(text) { return document.createTextNode(text); }
|
||||
createComment(text) { return document.createComment(text); }
|
||||
createDocumentFragment() { return document.createDocumentFragment(); }
|
||||
createEvent(type) { return new Event(type); }
|
||||
createEvent(type) { return document.createEvent(type); }
|
||||
hasFocus() { return false; }
|
||||
|
||||
get cookie() { return ''; }
|
||||
|
||||
Reference in new issue
Block a user