Browse Source

Platforms: update Emscripten markup for 1.38.27 and up.

This took me a while -- the old behavior for all emscripten_*()
functions was to take a DOM element ID as an argument, with nullptr
acting as a "the element that makes most sense for given operation". The
new behavior when -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 is
enabled is to take a CSS selector instead. Presence of this option is
not detectable at compile time, so there was no easy way of knowing
what's the expected value, whether `"module"` or `"#module"`.

After a few failed attempts, I discoverd that using `"#canvas"` would
work for both the old and the new version -- in the new version it would
be selecting an element with id="canvas", while in the old version it
was a special value denoting Module['canvas']. Problem was, however,
that the markup was historically using id="module" and not id="canvas",
so this had to be changed.

This is a breaking change affecting everyone who targets Emscripten. You
need to update the HTML markup and, in case you maintain copies or forks
of the CSS and JS files, these as well. Details in the changelog.
pull/331/head
Vladimír Vondruš 7 years ago
parent
commit
39678dac09
  1. 18
      doc/changelog.dox
  2. 8
      doc/platforms-html5.dox
  3. 2
      src/Magnum/Platform/EmscriptenApplication.js
  4. 25
      src/Magnum/Platform/Sdl2Application.cpp
  5. 4
      src/Magnum/Platform/Test/Sdl2ApplicationTest.html
  6. 2
      src/Magnum/Platform/Test/WindowlessEglApplicationTest.html
  7. 8
      src/Magnum/Platform/WebApplication.css
  8. 2
      src/Magnum/Platform/WindowlessEmscriptenApplication.js

18
doc/changelog.dox

@ -143,6 +143,10 @@ See also:
@ref Platform-Sdl2Application-usage-gles for more information.
- Replaced uses of `Pointer_stringify()` in @ref Platform::Sdl2Application
which was removed in Emscripten 1.38.27
- @ref Platform::Sdl2Application and all Emscripten markup was updated to
work correctly both with the
[`-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1`](https://github.com/emscripten-core/emscripten/pull/7977)
option available since Emscripten 1.38.27 and with older versions
@subsubsection changelog-latest-changes-text Text library
@ -220,6 +224,20 @@ See also:
@ref Text::AbstractFont::openData(Containers::ArrayView<const char>, Float)
and @ref Text::AbstractFont::setFileCallback()
@subsection changelog-latest-compatibility Potential compatibility breakages, removed APIs
- In order to be compatible with both Emscripten 1.38.27 and the versions
before, all Emscripten markup is now expected to have the HTML @cb{.html} <canvas> @ce element identified by @cb{.css} #canvas @ce. You need to:
- update your HTML markup to use
@cb{.html} <canvas id="canvas"> @ce instead of
@cb{.html} <canvas id="module"> @ce
- in case you have a copy or a fork of the JS driver file, it needs to
define @cb{.js} Module.canvas @ce as
@cb{.js} document.getElementById('canvas') @ce (instead of
@cb{.js} 'module' @ce)
- and for CSS files, all references to @cb{.css} #module @ce need to be
@cb{.css} #canvas @ce now
@section changelog-2019-01 2019.01
Released 2019-02-04, tagged as

8
doc/platforms-html5.dox

@ -129,7 +129,7 @@ variables.
<h1>Magnum Emscripten Application</h1>
<div id="container">
<div id="sizer"><div id="expander"><div id="listener">
<canvas id="module"></canvas>
<canvas id="canvas"></canvas>
<div id="status">Initialization...</div>
<div id="status-description"></div>
<script src="EmscriptenApplication.js"></script>
@ -145,7 +145,7 @@ everything can be set up directly from the HTML markup. Replace
@cb{.jinja} {{ application }} @ce with the name of your application executable
and adapt page title and heading as desired. You can modify all files to your
liking, but the HTML file must contain at least
@cb{.html} <canvas id="module"> @ce enclosed in
@cb{.html} <canvas id="canvas"> @ce enclosed in
@cb{.html} <div id="listener"> @ce. The JavaScript file contains event
listeners that print loading status on the page. The status is displayed in the
remaining two @cb{.html} <div> @ce s, if they are available. The CSS file
@ -229,7 +229,7 @@ and `MAGNUM_WEBAPPLICATION_CSS` CMake variables.
<h1>Magnum Windowless Emscripten Application</h1>
<div id="container">
<div id="sizer"><div id="expander"><div id="listener">
<canvas id="module" class="hidden"></canvas>
<canvas id="canvas" class="hidden"></canvas>
<pre id="log"></pre>
<div id="status">Initialization...</div>
<div id="status-description"></div>
@ -360,7 +360,7 @@ make it receive keyboard input, you have to add a `tabindex` attribute to it
like this:
@code{.html}
<canvas id="module" tabindex="0"></canvas>
<canvas id="canvas" tabindex="0"></canvas>
@endcode
After that, the canvas can be focused with a @m_class{m-label m-default} **Tab**

2
src/Magnum/Platform/EmscriptenApplication.js

@ -46,7 +46,7 @@ var Module = {
Module.setStatusDescription("The app crashed. Refresh the page or check the browser console for details.");
},
canvas: document.getElementById('module'),
canvas: document.getElementById('canvas'),
setStatus: function(message) {
var status = document.getElementById('status');

25
src/Magnum/Platform/Sdl2Application.cpp

@ -477,10 +477,17 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf
/* Get CSS canvas size. This is used later to detect canvas resizes and
fire viewport events, because Emscripten doesn't do that. Related info:
https://github.com/kripken/emscripten/issues/1731 */
/** @todo don't hardcode "module" here, make it configurable from outside */
/** @todo don't hardcode "#canvas" here, make it configurable from outside */
{
Vector2d canvasSize;
emscripten_get_element_css_size("module", &canvasSize.x(), &canvasSize.y());
/* Emscripten 1.38.27 changed to generic CSS selectors from element
IDs depending on -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
being set (which we can't detect at compile time). Fortunately,
using #canvas works the same way both in the previous versions and
the current one. Unfortunately, this is also the only value that
works the same way for both. Further details at
https://github.com/emscripten-core/emscripten/pull/7977 */
emscripten_get_element_css_size("#canvas", &canvasSize.x(), &canvasSize.y());
_lastKnownCanvasSize = Vector2i{canvasSize};
}
@ -542,7 +549,7 @@ Vector2i Sdl2Application::windowSize() const {
SDL_GetWindowSize(_window, &size.x(), &size.y());
#else
CORRADE_ASSERT(_glContext, "Platform::Sdl2Application::windowSize(): no window opened", {});
emscripten_get_canvas_element_size(nullptr, &size.x(), &size.y());
emscripten_get_canvas_element_size("#canvas", &size.x(), &size.y());
#endif
return size;
}
@ -555,7 +562,7 @@ Vector2i Sdl2Application::framebufferSize() const {
SDL_GL_GetDrawableSize(_window, &size.x(), &size.y());
#else
CORRADE_ASSERT(_glContext, "Platform::Sdl2Application::framebufferSize(): no window opened", {});
emscripten_get_canvas_element_size(nullptr, &size.x(), &size.y());
emscripten_get_canvas_element_size("#canvas", &size.x(), &size.y());
#endif
return size;
}
@ -646,14 +653,18 @@ void Sdl2Application::mainLoopIteration() {
avoid resizing the canvas when the user doesn't want that. Related
issue: https://github.com/kripken/emscripten/issues/1731 */
if(_flags & Flag::Resizable) {
/** @todo don't hardcode "module" here, make it configurable from outside */
Vector2d canvasSize;
emscripten_get_element_css_size("module", &canvasSize.x(), &canvasSize.y());
/* Emscripten 1.38.27 changed to generic CSS selectors from element
IDs depending on -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
being set (which we can't detect at compile time). See above for the
reason why we hardcode #canvas here. */
emscripten_get_element_css_size("#canvas", &canvasSize.x(), &canvasSize.y());
const Vector2i canvasSizei{canvasSize};
if(canvasSizei != _lastKnownCanvasSize) {
_lastKnownCanvasSize = canvasSizei;
const Vector2i size = _dpiScaling*canvasSizei;
emscripten_set_canvas_element_size(nullptr, size.x(), size.y());
emscripten_set_canvas_element_size("#canvas", size.x(), size.y());
ViewportEvent e{size, size, _dpiScaling};
viewportEvent(e);
_flags |= Flag::Redraw;

4
src/Magnum/Platform/Test/Sdl2ApplicationTest.html

@ -10,14 +10,14 @@
<h1>Magnum Sdl2Application Test</h1>
<div id="container">
<div id="sizer"><div id="expander"><div id="listener">
<canvas id="module" tabindex="0"></canvas>
<canvas id="canvas" tabindex="0"></canvas>
<div id="status">Initialization...</div>
<div id="status-description"></div>
<script src="EmscriptenApplication.js"></script>
<script async="async" src="PlatformSdl2ApplicationTest.js"></script>
<script>
/* To test keyboard capture directly on the canvas */
Module.keyboardListeningElement = document.getElementById('module');
Module.keyboardListeningElement = Module.canvas;
Module.canvas.addEventListener('mousedown', function(event) {
event.target.focus();
});

2
src/Magnum/Platform/Test/WindowlessEglApplicationTest.html

@ -10,7 +10,7 @@
<h1>Magnum WindowlessEglApplication Test</h1>
<div id="container" class="">
<div id="sizer"><div id="expander"><div id="listener">
<canvas id="module" class="hidden"></canvas>
<canvas id="canvas" class="hidden"></canvas>
<pre id="log"></pre>
<div id="status">Initialization...</div>
<div id="status-description"></div>

8
src/Magnum/Platform/WebApplication.css

@ -109,15 +109,15 @@ body {
#container.aspect-2-1 #expander { padding-bottom: 50%; }
#container.aspect-1-2 #expander { padding-bottom: 200%; }
#module, pre#log {
#canvas, pre#log {
max-width: 100%;
width: 100%;
height: 100%;
z-index: 10;
border-radius: 0.2rem; /*var(--border-radius)*/
}
#module:focus { outline-color: #5b9dd9; } /*var(--header-link-current-color)*/
#module {
#canvas:focus { outline-color: #5b9dd9; } /*var(--header-link-current-color)*/
#canvas {
margin-bottom: -0.25rem; /* otherwise there's scrollbar w/ fullsize (why?) */
}
#status, #status-description {
@ -136,7 +136,7 @@ body {
padding-left: 2rem;
padding-right: 2rem;
}
#module.hidden {
#canvas.hidden {
display: none;
}
pre#log {

2
src/Magnum/Platform/WindowlessEmscriptenApplication.js

@ -49,7 +49,7 @@ var Module = {
/* onAbort not handled here, as the output is printed directly on the page */
canvas: document.getElementById('module'),
canvas: document.getElementById('canvas'),
setStatus: function(message) {
var status = document.getElementById('status');

Loading…
Cancel
Save