Hi all,
there is a planned breaking change that will occur in the future
related to how the HTML5 API (in #include <emscripten/html5.h>) looks
up DOM elements when registering event callbacks and creating WebGL
contexts.
The old lookup rules were a somewhat ad hoc grouping of "default"
behavior plus a lookup to document.getElementById().
The new lookup rule is to use CSS selector strings, that are familiar
to web developers already. Additionally, to allow registering event
handlers to global JS scope objects "window", "document" and "screen",
which are not addressable via CSS selectors, special target tokens,
#define EMSCRIPTEN_EVENT_TARGET_DOCUMENT ((const char*)1)
#define EMSCRIPTEN_EVENT_TARGET_WINDOW ((const char*)2)
#define EMSCRIPTEN_EVENT_TARGET_SCREEN ((const char*)3)
are available.
There is a new option -s
DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 that allows opting in
to the new lookup rules early. In the future, this mode will become
the default (still allowing one to revert back to old behavior if
needed), and later, the old mode will be removed.
Under old lookup rules, one could use "null pointer" to refer to a
preselected default target for each event (this was usually either
"window" or "document", or "Module.canvas"). Under new lookup rules,
attempting to register an event or create a WebGL context using a null
pointer as target will be an error.
For example, under old rules,
emscripten_set_keydown_callback(/*target=*/0, 0, 1, key_callback);
would register 'keydown' event on JS global object "window". Under new
rules, this will be an error, and instead, one should call
emscripten_set_keydown_callback(/*target=*/EMSCRIPTEN_EVENT_TARGET_WINDOW,
0, 1, key_callback);
Here is a more complete set of mappings from old to new rules:
"#window" -> EMSCRIPTEN_EVENT_TARGET_WINDOW
"#document" -> EMSCRIPTEN_EVENT_TARGET_DOCUMENT
"#screen" -> EMSCRIPTEN_EVENT_TARGET_SCREEN
"foo" -> "#foo"
Under old rules, "foo" meant "DOM element with ID 'foo'". With new CSS
selectors, one uses the "#" prefix to denote a DOM element ID, so
under new rules, "#foo" will match a DOM Element with ID 'foo'.
"#canvas" -> no direct counterpart
Under old rules, "#canvas" referred to "Module.canvas". With the new
set of rules, the object "Module.canvas" is no longer utilized.
Instead, use an appropriate CSS selector to target a canvas element in
the DOM. If you have <canvas id='canvas'> element in the DOM, you can
keep using "#canvas", and it will still find the ID 'canvas'. You can
also use just 'canvas' to find the first element of type <canvas> in
the DOM, in case you just have one.
To get more detailed information and help debug the transition, do a
build with -s ASSERTIONS=1 to get debug prints in the web console
regarding event lookup errors.
This change makes event lookup more familiar to web developers, more
flexible in multi-canvas scenarios, and it saves on generated code
size too.
Affected C APIs:
- emscripten_set_*_callback(const char *target, ...);
- emscripten_set_*_callback_on_thread(const char *target, ...);
- emscripten_webgl_create_context(const char *target, ...);
- emscripten_request_fullscreen(const char *target, ...);
- emscripten_request_fullscreen_strategy(const char *target, ...);
- emscripten_enter_soft_fullscreen(const char *target, ...);
- emscripten_request_pointerlock(const char *target, ...);
- emscripten_set_canvas_element_size(const char *target, ...);
- emscripten_get_canvas_element_size(const char *target, ...);
- emscripten_set_element_css_size(const char *target, ...);
- emscripten_get_element_css_size(const char *target, ...);
A related change is that the following event callback fields are deprecated:
long EmscriptenMouseEvent::canvasX;
long EmscriptenMouseEvent::canvasY;
long EmscriptenTouchPoint::canvasX;
long EmscriptenTouchPoint::canvasY;
these fields referenced mouse and touch coordinates relative to the
"Module.canvas" object, which is going away. Instead, refer to the
targetX and targetY fields that report coordinates relative to the
target DOM element in question.
For more information, see
- CSS selectors:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors
- PR where the option is provided:
https://github.com/emscripten-core/emscripten/pull/7977
- Issue to track the deprecation and removal of the old lookup rules:
https://github.com/emscripten-core/emscripten/issues/8047
Hope this helps provide an easy migration path,
Jukka