diff options
| -rw-r--r-- | cmake/platforms/emscripten.cmake | 3 | ||||
| -rw-r--r-- | emcc.c | 12 | ||||
| -rw-r--r-- | emccpre.js | 20 |
3 files changed, 35 insertions, 0 deletions
diff --git a/cmake/platforms/emscripten.cmake b/cmake/platforms/emscripten.cmake index b7e9c7d..e13366f 100644 --- a/cmake/platforms/emscripten.cmake +++ b/cmake/platforms/emscripten.cmake @@ -35,6 +35,9 @@ set(emcc_export_list _timer_callback # Callback from button presses in the UI outside the canvas _command + # Text-formatting for copying to clipboard + _get_text_format + _free_text_format # Game-saving and game-loading functions _get_save_file _free_save_file @@ -115,6 +115,8 @@ bool key(int keycode, const char *key, const char *chr, int location, bool shift, bool ctrl); void timer_callback(double tplus); void command(int n); +char *get_text_format(void); +void free_save_file(char *buffer); char *get_save_file(void); void free_save_file(char *buffer); void load_game(void); @@ -880,6 +882,16 @@ void command(int n) } } +char *get_text_format(void) +{ + return midend_text_format(me); +} + +void free_text_format(char *buffer) +{ + sfree(buffer); +} + /* ---------------------------------------------------------------------- * Called from JS to prepare a save-game file, and free one after it's * been used. @@ -670,6 +670,26 @@ function initPuzzle() { } }); + // Handle "copy" actions. Browsers don't reliably target the + // "copy" event at the canvas when it's focused. Firefox 102 + // targets the containing <div> while Chromium 114 targets the + // <body>. So we catch the event at the document level and work + // out if it's relevant ourselves. + var get_text_format = Module.cwrap('get_text_format', 'number', []); + var free_text_format = Module.cwrap('free_text_format', 'void', ['number']); + document.addEventListener("copy", function(event) { + // Make sure the target is an ancestor of the canvas. And if + // there's a selection assume the user wants to copy that and + // not the puzzle. + if (event.target.contains(onscreen_canvas) && + window.getSelection().isCollapsed) { + var ptr = get_text_format(); + event.clipboardData.setData('text/plain', UTF8ToString(ptr)); + event.preventDefault(); + free_text_format(ptr); + } + }); + // Event handler to fake :focus-within on browsers too old for // it (like KaiOS 2.5). Browsers without :focus-within are also // too old for focusin/out events, so we have to use focus events |