-
Notifications
You must be signed in to change notification settings - Fork 23
XMLHttpRequest: implement the on<event> handler properties
#221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
8166d52
c870d43
20b0c20
87c5c1b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,6 +39,23 @@ namespace Babylon::Polyfills::Internal | ||||||||||||||||
| Napi::Value GetErrorCode(const Napi::CallbackInfo& info); | |||||||||||||||||
| Napi::Value GetErrorDetail(const Napi::CallbackInfo& info); | |||||||||||||||||
|
|
|||||||||||||||||
| // Indices into XMLHttpRequest::EVENT_TYPE_NAMES; used to instantiate the `on<event>` | |||||||||||||||||
| // property accessors below without needing a distinct method per event type. | |||||||||||||||||
| enum class EventIndex : size_t | |||||||||||||||||
| { | |||||||||||||||||
| ReadyStateChange = 0, | |||||||||||||||||
| Load = 1, | |||||||||||||||||
| Error = 2, | |||||||||||||||||
| LoadEnd = 3, | |||||||||||||||||
| Abort = 4, | |||||||||||||||||
| Count = 5, | |||||||||||||||||
| }; | |||||||||||||||||
|
|
|||||||||||||||||
| static const char* const EVENT_TYPE_NAMES[static_cast<size_t>(EventIndex::Count)]; | |||||||||||||||||
|
|
|||||||||||||||||
| template<EventIndex Index> Napi::Value GetEventHandler(const Napi::CallbackInfo& info); | |||||||||||||||||
| template<EventIndex Index> void SetEventHandler(const Napi::CallbackInfo& info, const Napi::Value& value); | |||||||||||||||||
|
|
|||||||||||||||||
| void AddEventListener(const Napi::CallbackInfo& info); | |||||||||||||||||
| void RemoveEventListener(const Napi::CallbackInfo& info); | |||||||||||||||||
| void Abort(const Napi::CallbackInfo& info); | |||||||||||||||||
|
|
@@ -53,5 +70,9 @@ namespace Babylon::Polyfills::Internal | ||||||||||||||||
| JsRuntimeScheduler m_runtimeScheduler; | |||||||||||||||||
| ReadyState m_readyState{ReadyState::Unsent}; | |||||||||||||||||
| std::unordered_map<std::string, std::vector<Napi::FunctionReference>> m_eventHandlerRefs; | |||||||||||||||||
| // The DOM `on<event>` handler properties (onreadystatechange, onload, ...). These are | |||||||||||||||||
| // kept separate from m_eventHandlerRefs because they have assignment semantics -- setting | |||||||||||||||||
| // one replaces the previous handler -- whereas addEventListener accumulates. | |||||||||||||||||
| std::unordered_map<std::string, Napi::FunctionReference> m_onEventHandlerRefs; | |||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
HTML registers one internal listener on first set whose callback indirects through the stored value, so reassignment keeps its position ("If eventHandler's listener is not null, then return"). One The duplicate throw predates this PR.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed — the parallel map is the wrong model, and I'll switch to the single-list design you described. To confirm I've got the shape right: struct Listener
{
Napi::FunctionReference callback;
bool isEventHandler; // registered via on<event>, not addEventListener
};
std::unordered_map<std::string, std::vector<Listener>> m_listeners;
That fixes the ordering divergence: For the second divergence, I'll scope the duplicate check in That leaves the pre-existing I'll add a test asserting dispatch order across both registration styles.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 20b0c20 — switched to the single-list design.
struct Listener
{
Napi::FunctionReference callback;
bool isEventHandler;
};
Four tests cover the behaviour, and each fails against the previous implementation:
On the pre-existing
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Responded by Copilot on behalf of @bghgary] Remove it here. You're already in that code, and per DOM a duplicate add is a silent no-op — leaving the throw would park a second known-wrong behaviour next to the one you're fixing. Your UrlLib audit holds, checked independently: all sixteen
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed in 87c5c1b — the duplicate The scan still skips Added a test pinning the new behaviour (doesn't throw, handler fires exactly once); the existing "called twice" test guards the other direction. Suite is 227 passing on Windows. And thanks for double-checking the One note: the identical throw also exists in |
|||||||||||||||||
| }; | |||||||||||||||||
| } | |||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.