Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ See docs/process.md for more on how version tagging works.

4.0.20 (in development)
-----------------------
- Added `emscripten_html5_remove_event_listener` function in `html5.h` in order to be
able to remove a single callback. (#25535)
- The standalone `file_packager.py` script no longer supports `--embed` with JS
output (use `--obj-output` is now required for embedding data). This usage
has been producing a warning since #16050 which is now an error. (#25049)
Expand Down
48 changes: 48 additions & 0 deletions site/source/docs/api_reference/html5.h.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,54 @@ The ``useCapture`` parameter maps to ``useCapture`` in `EventTarget.addEventLis

Most functions return the result using the type :c:data:`EMSCRIPTEN_RESULT`. Zero and positive values denote success. Negative values signal failure. None of the functions fail or abort by throwing a JavaScript or C++ exception. If a particular browser does not support the given feature, the value :c:data:`EMSCRIPTEN_RESULT_NOT_SUPPORTED` will be returned at the time the callback is registered.

Unregister function
-------------------

In order to unregister a single event handler callback, call the following function:

.. code-block:: cpp

EMSCRIPTEN_RESULT emscripten_html5_remove_event_listener(
const char *target, // ID of the target HTML element.
void *userData, // User-defined data (passed to the callback).
int eventTypeId, // The event type ID (EMSCRIPTEN_EVENT_XXX).
void *callback // Callback function.
);


The ``target``, ``userData`` and ``callback`` parameters are the same parameters provided in ``emscripten_set_some_callback`` with the only difference being that, since this function applies to all types of callbacks, the type of ``callback`` is ``void *``.

Note in particular that the value of ``userData`` will need to match with the call that was used to register the callback. If you are having trouble, double check the value of ``userData``.

The ``eventTypeId`` represents the event type, the same Id received in the callback functions.

The function returns ``EMSCRIPTEN_RESULT_SUCCESS`` when the event handler callback is removed and ``EMSCRIPTEN_RESULT_INVALID_PARAM`` otherwise.

.. code-block:: cpp

// Example

bool my_mouse_callback_1(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
// ...
}

bool my_mouse_callback_2(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
// ...
}

void main() {

// 1. set callbacks for mouse down and mouse move
emscripten_set_mousedown_callback("#mydiv", 0, my_mouse_callback_1);
emscripten_set_mousedown_callback("#mydiv", (void *) 34, my_mouse_callback_2);
emscripten_set_mousemove_callback("#mydiv", 0, my_mouse_callback_1);

// 2. remove these callbacks
emscripten_html5_remove_event_listener("#mydiv", 0, EMSCRIPTEN_EVENT_MOUSEDOWN, my_mouse_callback_1);
emscripten_html5_remove_event_listener("#mydiv", (void *) 34, EMSCRIPTEN_EVENT_MOUSEDOWN, my_mouse_callback_2);
emscripten_html5_remove_event_listener("#mydiv", 0, EMSCRIPTEN_EVENT_MOUSEMOVE, my_mouse_callback_1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't love the asymmetry to the API design, but I get that adding 30+ emscripten_clear_xxx_callback API calls probably isn't great either.

}


Callback functions
------------------
Expand Down
57 changes: 57 additions & 0 deletions src/lib/libhtml5.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ var LibraryHTML5 = {
return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}};
},

removeSingleHandler(eventHandler) {
for (var [i, handler] of JSEvents.eventHandlers.entries()) {
if (handler.target === eventHandler.target
&& handler.eventTypeId === eventHandler.eventTypeId
&& handler.callbackfunc === eventHandler.callbackfunc
&& handler.userData === eventHandler.userData) {
JSEvents._removeHandler(i);
return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}};
}
}
return {{{ cDefs.EMSCRIPTEN_RESULT_INVALID_PARAM }}};
},

#if PTHREADS
getTargetThreadForEventCallback(targetThread) {
switch (targetThread) {
Expand Down Expand Up @@ -291,6 +304,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: keyEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -405,6 +420,18 @@ var LibraryHTML5 = {
},
#endif

emscripten_html5_remove_event_listener__proxy: 'sync',
emscripten_html5_remove_event_listener__deps: ['$JSEvents', '$findEventTarget'],
emscripten_html5_remove_event_listener: (target, userData, eventTypeId, callback) => {
var eventHandler = {
target: findEventTarget(target),
userData,
eventTypeId,
callbackfunc: callback,
};
return JSEvents.removeSingleHandler(eventHandler);
},

emscripten_set_keypress_callback_on_thread__proxy: 'sync',
emscripten_set_keypress_callback_on_thread__deps: ['$registerKeyEventCallback'],
emscripten_set_keypress_callback_on_thread: (target, userData, useCapture, callbackfunc, targetThread) =>
Expand Down Expand Up @@ -495,6 +522,8 @@ var LibraryHTML5 = {
allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
#endif
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: mouseEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -586,6 +615,8 @@ var LibraryHTML5 = {
allowsDeferredCalls: true,
#endif
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: wheelHandlerFunc,
useCapture
Expand Down Expand Up @@ -658,6 +689,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: uiEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -702,6 +735,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: focusEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -759,6 +794,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: deviceOrientationEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -827,6 +864,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: deviceMotionEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -907,6 +946,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: orientationChangeEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1014,6 +1055,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: fullscreenChangeEventhandlerFunc,
useCapture
Expand Down Expand Up @@ -1512,6 +1555,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: pointerlockChangeEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1556,6 +1601,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: pointerlockErrorEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1706,6 +1753,8 @@ var LibraryHTML5 = {
var eventHandler = {
target,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: visibilityChangeEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1821,6 +1870,8 @@ var LibraryHTML5 = {
allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',
#endif
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: touchEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1904,6 +1955,8 @@ var LibraryHTML5 = {
allowsDeferredCalls: true,
#endif
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: gamepadEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -1990,6 +2043,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: beforeUnloadEventHandlerFunc,
useCapture
Expand Down Expand Up @@ -2040,6 +2095,8 @@ var LibraryHTML5 = {
var eventHandler = {
target: battery,
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: batteryEventHandlerFunc,
useCapture
Expand Down
2 changes: 2 additions & 0 deletions src/lib/libhtml5_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ var LibraryHtml5WebGL = {
var eventHandler = {
target: findEventTarget(target),
eventTypeString,
eventTypeId,
userData,
callbackfunc,
handlerFunc: webGlEventHandlerFunc,
useCapture
Expand Down
1 change: 1 addition & 0 deletions src/lib/libsigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ sigs = {
emscripten_has_threading_support__sig: 'i',
emscripten_hide_mouse__sig: 'v',
emscripten_html5_remove_all_event_listeners__sig: 'v',
emscripten_html5_remove_event_listener__sig: 'ippip',
emscripten_idb_async_clear__sig: 'vpppp',
emscripten_idb_async_delete__sig: 'vppppp',
emscripten_idb_async_exists__sig: 'vppppp',
Expand Down
2 changes: 2 additions & 0 deletions system/include/emscripten/html5.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ EMSCRIPTEN_RESULT emscripten_get_element_css_size(const char *target __attribute

void emscripten_html5_remove_all_event_listeners(void);

EMSCRIPTEN_RESULT emscripten_html5_remove_event_listener(const char *target __attribute__((nonnull)), void *userData, int eventTypeId, void *callback __attribute__((nonnull)));

#define EM_CALLBACK_THREAD_CONTEXT_MAIN_RUNTIME_THREAD ((pthread_t)0x1)
#define EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD ((pthread_t)0x2)

Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_ctors1.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19670,
"a.out.js.gz": 8152,
"a.out.nodebug.wasm": 129466,
"a.out.nodebug.wasm.gz": 49162,
"total": 149136,
"total_gz": 57314,
"a.out.nodebug.wasm": 129503,
"a.out.nodebug.wasm.gz": 49248,
"total": 149173,
"total_gz": 57400,
"sent": [
"__cxa_throw",
"_abort_js",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_ctors2.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19647,
"a.out.js.gz": 8139,
"a.out.nodebug.wasm": 128893,
"a.out.nodebug.wasm.gz": 48808,
"total": 148540,
"total_gz": 56947,
"a.out.nodebug.wasm": 128930,
"a.out.nodebug.wasm.gz": 48886,
"total": 148577,
"total_gz": 57025,
"sent": [
"__cxa_throw",
"_abort_js",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_except.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 23325,
"a.out.js.gz": 9128,
"a.out.nodebug.wasm": 171274,
"a.out.nodebug.wasm.gz": 57279,
"total": 194599,
"total_gz": 66407,
"a.out.nodebug.wasm": 171311,
"a.out.nodebug.wasm.gz": 57348,
"total": 194636,
"total_gz": 66476,
"sent": [
"__cxa_begin_catch",
"__cxa_end_catch",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_except_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19486,
"a.out.js.gz": 8077,
"a.out.nodebug.wasm": 144630,
"a.out.nodebug.wasm.gz": 54849,
"total": 164116,
"total_gz": 62926,
"a.out.nodebug.wasm": 144667,
"a.out.nodebug.wasm.gz": 54907,
"total": 164153,
"total_gz": 62984,
"sent": [
"_abort_js",
"_tzset_js",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_except_wasm_legacy.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19555,
"a.out.js.gz": 8099,
"a.out.nodebug.wasm": 142219,
"a.out.nodebug.wasm.gz": 54301,
"total": 161774,
"total_gz": 62400,
"a.out.nodebug.wasm": 142256,
"a.out.nodebug.wasm.gz": 54366,
"total": 161811,
"total_gz": 62465,
"sent": [
"_abort_js",
"_tzset_js",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_lto.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19009,
"a.out.js.gz": 7829,
"a.out.nodebug.wasm": 106468,
"a.out.nodebug.wasm.gz": 42566,
"total": 125477,
"total_gz": 50395,
"a.out.nodebug.wasm": 106439,
"a.out.nodebug.wasm.gz": 42591,
"total": 125448,
"total_gz": 50420,
"sent": [
"a (emscripten_resize_heap)",
"b (_setitimer_js)",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_mangle.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 23375,
"a.out.js.gz": 9148,
"a.out.nodebug.wasm": 235300,
"a.out.nodebug.wasm.gz": 78896,
"total": 258675,
"total_gz": 88044,
"a.out.nodebug.wasm": 235343,
"a.out.nodebug.wasm.gz": 78952,
"total": 258718,
"total_gz": 88100,
"sent": [
"__cxa_begin_catch",
"__cxa_end_catch",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_noexcept.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 19670,
"a.out.js.gz": 8152,
"a.out.nodebug.wasm": 131883,
"a.out.nodebug.wasm.gz": 50164,
"total": 151553,
"total_gz": 58316,
"a.out.nodebug.wasm": 131920,
"a.out.nodebug.wasm.gz": 50242,
"total": 151590,
"total_gz": 58394,
"sent": [
"__cxa_throw",
"_abort_js",
Expand Down
Loading
Loading