aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/platforms/emscripten.cmake3
-rw-r--r--emcc.c12
-rw-r--r--emccpre.js20
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
diff --git a/emcc.c b/emcc.c
index 7d7a09b..2f82878 100644
--- a/emcc.c
+++ b/emcc.c
@@ -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.
diff --git a/emccpre.js b/emccpre.js
index 842a392..de94509 100644
--- a/emccpre.js
+++ b/emccpre.js
@@ -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