attach the laser event handlers to body
authorRaphaël Jakse <raphael.trivabble@jakse.fr>
Tue, 1 Sep 2020 20:45:55 +0000 (22:45 +0200)
committerRaphaël Jakse <raphael.trivabble@jakse.fr>
Tue, 1 Sep 2020 20:45:55 +0000 (22:45 +0200)
public/trivabble.js

index eee36ad958eff3cc114a7f12fcd05d1bbbd5f7a4..79d320cce07eaccd4ac93a3a41ccd5f886dedd71 100644 (file)
         return false;
     }
 
+    function getParentWithClass(element, className) {
+        while (element && element !== document.documentElement) {
+            if (element.classList.contains(className)) {
+                return element;
+            }
+
+            element = element.parentNode;
+        }
+
+        return null;
+    }
+
     function dragTileEnd() {
         movingTile.style.left   = "";
         movingTile.style.top    = "";
                             ? format(_("You changed the language of the board to {0}"), newLang)
                             : format(_("{0} changed the language of the board to {1}"), msg.sender, newLang)
                     );
+                    break;
                 }
 
-                case "highlightTile": {
-                    localHighlightTile(msg.specialMsg.tile);
+                case "highlightCell": {
+                    localHighlightCell(msg.specialMsg.cell);
                     infoMessage(msg.msg);
+                    break;
                 }
             }
         }
         }
     }
 
-    function highlightTile(e) {
-        let id = this.id;
-        if (id === "") {
+    function triggerLaser(cell) {
+        if (!cell) {
             return;
-        } else if (id === "center-cell") {
-            id = 112;
-        }
-        if (e.type === "touchstart") {
-            if ((highlightTile.id !== id) || (Date.now() - highlightTile.date > localStorage.doubleTapDuration)) {
-                highlightTile.id = id;
-                highlightTile.date = Date.now();
-                return;
-            }
-        }
-
-        if (e.type === "dblclick") {
-            const tilePlaceholder = boardCells[id].getElementsByClassName("tile-placeholder")[0];
-            if (tilePlaceholder.getElementsByClassName("tile")[0]) {
-                return;
-            }
         }
 
         const letters = "ABCDEFGHIJKLMNO";
-        const col = (id % 15) + 1;
-        const row = letters[Math.floor(id / 15)];
+        const col = cell.cellIndex - 1;
+        const row = cell.parentNode.rowIndex - 1;
+
         sendCmds([{
             cmd: "msg",
-            msg: _("Look at:") + " " + row + col,
+            msg: _("Look at:") + " " + letters[row] + (cell.cellIndex + 1),
             specialMsg: {
-                type: "highlightTile",
-                tile: id
+                type: "highlightCell",
+                cell: (row * 15) + col
             }
         }]);
     }
 
-    function localHighlightTile(id) {
+    function getCellFromEvent(e) {
+        const tilePlaceholder = getParentWithClass(e.target, "tile-placeholder");
+        if (tilePlaceholder) {
+            const cell = tilePlaceholder.parentNode;
+            if (cell.cellIndex && cell.parentNode.rowIndex) {
+                return cell;
+            }
+        }
+
+        return null;
+    }
+
+    function laserDblClick(e) {
+        triggerLaser(getCellFromEvent(e));
+    }
+
+    function laserTouch(e) {
+        const cell = getCellFromEvent(e);
+
+        if (!cell) {
+            return;
+        }
+
+        if ((laserTouch.last !== cell) || (Date.now() - laserTouch.date > localStorage.doubleTapDuration)) {
+            laserTouch.last = cell;
+            laserTouch.date = Date.now();
+            return;
+        }
+
+        triggerLaser(cell);
+    }
+
+    function localHighlightCell(id) {
         const placeholder = boardCells[id].getElementsByClassName("tile-placeholder")[0];
         placeholder.classList.add("highlight");
         setTimeout(
     function translateDuration(x, values) {
         if (x < 0) {
             return null;
-        } else if (x < values.length) {
+        }
+        
+        if (x < values.length) {
             return values[Math.floor(x)];
-        } else {
-            for (let i = 0; i < values.length; i++) {
-                if (x <= values[i]) {
-                    return i;
-                }
+        }
+        
+        for (let i = 0; i < values.length; i++) {
+            if (x <= values[i]) {
+                return i;
             }
-            return values.length - 1;
         }
+        return values.length - 1;
     }
 
     function initLaserPointer() {
+        document.body.addEventListener("dblclick", laserDblClick);
+        document.body.addEventListener("touchstart", laserTouch);
+
         if (!Object.prototype.hasOwnProperty.call(localStorage, "doubleTapDuration")) {
             localStorage.doubleTapDuration = Conf.DOUBLE_TAP_DURATIONS[Math.floor(Conf.DOUBLE_TAP_DURATIONS.length / 2)];
         }
             doubleTapDuration.max = Conf.DOUBLE_TAP_DURATIONS.length - 1;
             doubleTapDuration.value = translateDuration(localStorage.doubleTapDuration, Conf.DOUBLE_TAP_DURATIONS);
             doubleTapDuration.onchange = function () {
-                localStorage.doubleTapDuration =
-                    translateDuration(document.getElementById("double-tap-duration").value, Conf.DOUBLE_TAP_DURATIONS);
+                localStorage.doubleTapDuration = translateDuration(
+                    document.getElementById("double-tap-duration").value,
+                    Conf.DOUBLE_TAP_DURATIONS
+                );
             };
         }
 
             flashLightDuration.max = Conf.FLASH_LIGHT_DURATIONS.length - 1;
             flashLightDuration.value = translateDuration(localStorage.flashLightDuration, Conf.FLASH_LIGHT_DURATIONS);
             flashLightDuration.onchange = function () {
-                localStorage.flashLightDuration =
-                    translateDuration(document.getElementById("flash-light-duration").value, Conf.FLASH_LIGHT_DURATIONS);
+                localStorage.flashLightDuration = translateDuration(
+                    document.getElementById("flash-light-duration").value,
+                    Conf.FLASH_LIGHT_DURATIONS
+                );
             };
         }
 
         if (flashLightColor) {
             flashLightColor.value = localStorage.flashLightColor;
             flashLightColor.onchange = function () {
-                localStorage.flashLightColor =
-                    document.getElementById("flash-light-color").value;
+                localStorage.flashLightColor = document.getElementById("flash-light-color").value;
                 const style = document.createElement("style");
-                style.innerHTML = ".highlight {background-color: " + localStorage.flashLightColor + ";}";
+                style.textContent = ".highlight {background-color: " + localStorage.flashLightColor + ";}";
                 document.body.appendChild(style);
             };
             flashLightColor.onchange();
     }
 
     function showSettings() {
-           const modal = document.querySelector(".modal");
-           modal.classList.toggle("show-modal");
+        const modal = document.querySelector(".modal");
+        modal.classList.toggle("show-modal");
     }
 
     function initGlobals() {
             board.appendChild(document.createElement("tr"));
             board.lastChild.appendChild(document.createElement("th"));
             board.lastChild.lastChild.textContent = letters[i];
+
             for (let j = 0; j < 15; j++) {
                 cell = document.createElement("td");
                 boardCells.push(cell);
                 board.lastChild.appendChild(cell);
-                cell.id = (i * 15) + j;
-                cell.ondblclick = highlightTile;
-                cell.ontouchstart = highlightTile;
+
                 cell.appendChild(document.createElement("div"));
                 cell.lastChild.className = "tile-placeholder";