shithub: puzzles

Download patch

ref: 9d7c2b8c83506c1f239c840e372058fac603b255
parent: 5c858253f9456b970be5d5ef3e7df727d39e3da7
author: Simon Tatham <anakin@pobox.com>
date: Wed Feb 22 07:36:59 EST 2023

JS puzzles: use the PointerEvent API if available.

If the browser knows what 'PointerEvent' means, then we switch our
'onmousefoo' event handlers to the 'onpointerfoo' events, for both the
puzzle canvas and the resize handle.

The immediate effect of this is that we get to use the
setPointerCapture method on the puzzle canvas, in preference to the
deprecated Firefox-only setCapture.

A pointer event also contains extra fields compared to a mouse event:
as well as telling you which pointing device the event comes from, it
can also provide extra information, such as pressure, or the angle of
a stylus if the hardware can detect it. I don't have any immediate
ideas about what those could be used for, but it can't hurt to have
them available just in case we think of something in future.

--- a/emccpre.js
+++ b/emccpre.js
@@ -285,6 +285,11 @@
 }
 
 function set_capture(element, event) {
+    if (element.setPointerCapture !== undefined &&
+        event.pointerId !== undefined) {
+        element.setPointerCapture(event.pointerId);
+        return;
+    }
     if (element.setCapture !== undefined) {
         element.setCapture(true);
         return;
@@ -317,7 +322,7 @@
         return toret;
     };
 
-    onscreen_canvas.onmousedown = function(event) {
+    var canvas_mousedown_handler = function(event) {
         if (event.button >= 3)
             return;
 
@@ -334,9 +339,10 @@
 
         set_capture(onscreen_canvas, event);
     };
+
     var mousemove = Module.cwrap('mousemove', 'boolean',
                                  ['number', 'number', 'number']);
-    onscreen_canvas.onmousemove = function(event) {
+    var canvas_mousemove_handler = function(event) {
         var down = buttons_down();
         if (down) {
             var xy = canvas_mouse_coords(event, onscreen_canvas);
@@ -346,7 +352,7 @@
     };
     var mouseup = Module.cwrap('mouseup', 'boolean',
                                ['number', 'number', 'number']);
-    onscreen_canvas.onmouseup = function(event) {
+    var canvas_mouseup_handler = function(event) {
         if (event.button >= 3)
             return;
 
@@ -358,6 +364,16 @@
         }
     };
 
+    if (PointerEvent !== undefined) {
+        onscreen_canvas.onpointerdown = canvas_mousedown_handler;
+        onscreen_canvas.onpointermove = canvas_mousemove_handler;
+        onscreen_canvas.onpointerup = canvas_mouseup_handler;
+    } else {
+        onscreen_canvas.onmousedown = canvas_mousedown_handler;
+        onscreen_canvas.onmousemove = canvas_mousemove_handler;
+        onscreen_canvas.onmouseup = canvas_mouseup_handler;
+    }
+
     // Set up keyboard handlers. We call event.preventDefault()
     // in the keydown handler if it looks like we might have
     // done something with the key.  This means that users
@@ -665,7 +681,7 @@
         var restore_puzzle_size = Module.cwrap('restore_puzzle_size',
                                                'void', []);
         resize_handle.oncontextmenu = function(event) { return false; }
-        resize_handle.onmousedown = function(event) {
+        var resize_mousedown_handler = function(event) {
             if (event.button == 0) {
                 var xy = element_coords(onscreen_canvas);
                 resize_xbase = xy.x + onscreen_canvas.offsetWidth / 2;
@@ -680,7 +696,7 @@
             set_capture(resize_handle, event);
             event.preventDefault();
         };
-        window.addEventListener("mousemove", function(event) {
+        var resize_mousemove_handler = function(event) {
             if (resize_xbase !== null && resize_ybase !== null) {
                 var dpr = window.devicePixelRatio || 1;
                 resize_puzzle(
@@ -693,8 +709,8 @@
                     window.getSelection().removeAllRanges();
                 else
                     document.selection.empty();        }
-        });
-        window.addEventListener("mouseup", function(event) {
+        };
+        var resize_mouseup_handler = function(event) {
             if (resize_xbase !== null && resize_ybase !== null) {
                 resize_xbase = null;
                 resize_ybase = null;
@@ -714,7 +730,17 @@
                 }, 20);
                 event.preventDefault();
             }
-        });
+        };
+
+        if (PointerEvent !== undefined) {
+            resize_handle.onpointerdown = resize_mousedown_handler;
+            window.addEventListener("pointermove", resize_mousemove_handler);
+            window.addEventListener("pointerup", resize_mouseup_handler);
+        } else {
+            resize_handle.onmousedown = resize_mousedown_handler;
+            window.addEventListener("mousemove", resize_mousemove_handler);
+            window.addEventListener("mouseup", resize_mouseup_handler);
+        }
     }
 
     var rescale_puzzle = Module.cwrap('rescale_puzzle', 'void', []);