Add DOM globals polyfill + native AbortController for Playground#1708
Add DOM globals polyfill + native AbortController for Playground#1708bkaradzic-microsoft wants to merge 3 commits into
Conversation
…nt.createEvent) Playground tests that use modern browser APIs hit ReferenceErrors on the Chakra-based BN runtime because TextEncoder and PointerEvent are not part of older Chakra's built-ins. Several serializer tests also exercise document.createEvent + element.dispatchEvent shapes that the existing minimal document polyfill in validation_native.js did not cover. - Apps/Playground/Scripts/dom_polyfill.js: new self-detecting JS polyfills for TextEncoder (UTF-8 encode + encodeInto) and PointerEvent (constructor with the MouseEvent + PointerEvent surface). - Apps/Playground/Shared/AppContext.cpp + CMakeLists.txt: wire in the native AbortController polyfill from JsRuntimeHost and load dom_polyfill.js before ammo.js. - Apps/Playground/Scripts/validation_native.js: extend the existing document shim with createEvent, dispatchEvent, addEventListener and a generic-element fallback for createElement so click-event-based serializer tests can run. - Apps/Playground/Scripts/config.json: re-enable "Serialize scene without materials" (idx 342), which now validates with 248 px diff. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AppContext.cpp includes <Babylon/Polyfills/AbortController.h> and calls Babylon::Polyfills::AbortController::Initialize(env), but the Android- specific CMakeLists at Apps/Playground/Android/BabylonNative did not add AbortController to BabylonNativeJNI's PRIVATE link libraries. The header is published only by the AbortController target, so Android CI failed with 'fatal error: Babylon/Polyfills/AbortController.h file not found'. Linux/macOS/Windows builds were fine because they use the main Apps/Playground/CMakeLists.txt which already links AbortController. Mirror the change there so Android picks up the include directory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds missing DOM-like globals to the Playground JS host and wires up native AbortController so DOM-dependent playgrounds/tests stop throwing ReferenceError.
Changes:
- Adds a self-detecting
TextEncoder+PointerEventpolyfill script and loads it in the Playground startup sequence. - Initializes and links the native
AbortControllerpolyfill in Playground (including Android JNI link fix). - Extends the validation runner’s
documentshim withcreateEvent/dispatchEventand re-enables one previously excluded test.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Apps/Playground/Shared/AppContext.cpp | Initializes native AbortController and loads dom_polyfill.js during startup. |
| Apps/Playground/Scripts/validation_native.js | Expands the document/element shims to support event creation/dispatch used by tests. |
| Apps/Playground/Scripts/dom_polyfill.js | New polyfills for TextEncoder and PointerEvent when absent. |
| Apps/Playground/Scripts/config.json | Re-enables one previously excluded serialization test. |
| Apps/Playground/CMakeLists.txt | Packages dom_polyfill.js and links AbortController into Playground. |
| Apps/Playground/Android/BabylonNative/CMakeLists.txt | Links AbortController into BabylonNativeJNI to fix Android builds. |
| var arr = this.encode(input); | ||
| var n = Math.min(arr.length, dest.length); | ||
| for (var i = 0; i < n; i++) dest[i] = arr[i]; | ||
| return { read: String(input).length, written: n }; |
There was a problem hiding this comment.
Addressed in b79d9db. encodeInto now normalizes input (treats undefined as the empty string) before computing both the encoded bytes and read, so the returned read count is consistent with what encode() writes.
| init = init || {}; | ||
| this.type = String(type || ''); | ||
| this.bubbles = !!init.bubbles; | ||
| this.cancelable = init.cancelable !== false; |
There was a problem hiding this comment.
Addressed in b79d9db. cancelable now defaults to false to match the DOM EventInit spec default; callers that need a cancelable event must pass cancelable: true explicitly.
| // Chakra has no `globalThis`; use the Function-constructor trick. | ||
| var g = (new Function('return this'))(); |
There was a problem hiding this comment.
Addressed in b79d9db. Replaced new Function('return this') with a non-eval resolution chain (globalThis -> self -> window -> global) and kept the Function constructor only as a last-resort fallback for runtimes that ship none of those globals.
- Replace `new Function('return this')` with a non-eval globalThis/self/
window/global resolution chain; keep the Function-constructor trick
only as a last-resort fallback for runtimes that ship none of the
standard globals.
- TextEncoder.prototype.encodeInto: normalize `input` (undefined ->
empty string) before computing `read`, so the returned read count
stays consistent with the bytes written by `encode()` (previously
`String(undefined).length` returned 9 for a zero-byte write).
- PointerEvent.cancelable: default to `false` (DOM spec EventInit
default) instead of `true`; callers that need a cancelable event
must pass `cancelable: true` explicitly.
Refs PR BabylonJS#1708.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ryantrem
left a comment
There was a problem hiding this comment.
I guess this makes the tests work, but if a consumer tried to use the same things in their own app, they wouldn't work. Is that really the state we want to be in, or we want to know what things don't work because they aren't polyfilled? I would have thought we would either document these features don't work because we don't polyfill, or we add native polyfills for them.
Wires up native
AbortControllerand adds JS polyfills forTextEncoder+PointerEventso playgrounds depending on DOM globals stop ReferenceError'ing.Changes:
Apps/Playground/Scripts/dom_polyfill.js- self-detectingTextEncoder+PointerEventpolyfills.Apps/Playground/Shared/AppContext.cpp- callsBabylon::Polyfills::AbortController::Initialize(env); loadsdom_polyfill.jsafterfile_polyfill.js.Apps/Playground/CMakeLists.txt- addsdom_polyfill.jsto SCRIPTS list; linksAbortControllerplugin.Apps/Playground/Android/BabylonNative/CMakeLists.txt- addsPRIVATE AbortControllertoBabylonNativeJNIlink list (without this, Android builds fail with missing header - verified via CI).Apps/Playground/Scripts/validation_native.js- extends document shim withcreateEvent+dispatchEvent.Apps/Playground/Scripts/config.json- re-enables 1 test (idx 342).Note: Polyfill foundation. Remaining affected playground tests need native
dispatchEventon canvas /Imagepolyfill / async-module support - out of scope here.Landing context
This PR is one of 7 splits from the proven CI-green combined preview in draft PR #1702 (see #1702 for the full intended end-state and verified CI run 26044922430).
Recommended landing order
Tier 1 - parallel-reviewable, no source conflicts:
reasonrewrites (5 entries)reasonrewrites (17 entries)Tier 2 - sequential, each touches
Apps/Playground/CMakeLists.txtSCRIPTS list +Apps/Playground/Shared/AppContext.cppLoadScript order; rebase the next branch after the previous merges:Reference policy reminder
Reference PNGs across all 7 PRs come from Babylon.js; never re-baked by BN. Combined diff: 0 PNGs.