Linting: let it be
authorRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 13:49:48 +0000 (15:49 +0200)
committerRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 13:49:48 +0000 (15:49 +0200)
.eslintrc.json
trivabble-server.js
trivabble.js

index ebc72cf0fce9e484eac5baa154937f265f936087..988e72a6a62ad675dae7f6bf58a05ab61d85e447 100644 (file)
         "max-nested-callbacks": "error",
         "max-params": "error",
         "max-statements": "off",
-        "max-statements-per-line": "off",
+        "max-statements-per-line": "error",
         "multiline-comment-style": "off",
         "new-cap": "error",
         "new-parens": "error",
         "no-useless-constructor": "error",
         "no-useless-rename": "error",
         "no-useless-return": "error",
-        "no-var": "off",
+        "no-var": "error",
         "no-void": "error",
         "no-warning-comments": "off",
         "no-whitespace-before-property": "error",
             "never"
         ],
         "object-shorthand": "off",
-        "one-var": "off",
-        "one-var-declaration-per-line": "off",
+        "one-var": [
+            "error",
+            "never"
+        ],
+        "one-var-declaration-per-line": "error",
         "operator-assignment": [
             "error",
             "always"
index b3c88f1eaf55ee4041317f610f482eb0265292db..25bfb3d05a5c41311389eeda97a5b0482c59402e 100644 (file)
@@ -42,12 +42,12 @@ if (DEV_ENABLE_SERVING_FILES) {
     console.log("DEV_ENABLE_SERVING_FILES: Serving files in the current directory. Please never do this on a production server, this is for development purposes only.");
 }
 
-var debuglog = DEBUG_LOG ? console.log.bind(console) : () => null;
+const debuglog = DEBUG_LOG ? console.log.bind(console) : () => null;
 
-var http = require("http");
-var fs   = require("fs");
+const http = require("http");
+const fs   = require("fs");
 
-var frBag = [
+const frBag = [
     " ", " ", // Jokers
     "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E",
     "A", "A", "A", "A", "A", "A", "A", "A", "A",
@@ -77,7 +77,7 @@ var frBag = [
     "Z"
 ];
 
-var frValues = {
+const frValues = {
     " ": 0,
     "E": 1,
     "A": 1,
@@ -108,11 +108,11 @@ var frValues = {
 };
 
 
-var games = {};
-var dateNow = 0;
+const games = {};
+let dateNow = 0;
 
-var saveTimeout = null;
-var running = true;
+let saveTimeout = null;
+let running = true;
 
 function saveGames(exit) {
     fs.writeFile("games.backup.json", JSON.stringify(games), function (err) {
@@ -189,9 +189,9 @@ function keepAlive(responseAndIsES) {
 }
 
 function newBoard() {
-    var res = new Array(15 * 15);
+    const res = new Array(15 * 15);
 
-    for (var i = 0; i < 15 * 15; i++) {
+    for (let i = 0; i < 15 * 15; i++) {
         res[i] = "";
     }
 
@@ -219,7 +219,7 @@ Game.prototype.toJSON = function () {
 };
 
 Game.fromJSON = function (obj) {
-    var game = new Game();
+    const game = new Game();
     game.board            = obj.board  || newBoard();
     game.bag              = obj.bag    || frBag.slice();
     game.remainingLetters = obj.remainingLetters || game.bag.length;
@@ -230,17 +230,17 @@ Game.fromJSON = function (obj) {
 };
 
 Game.prototype.getPlayerRack = function (player) {
-    var playerID = "#" + player;
+    const playerID = "#" + player;
     return (this.racks[playerID] || (this.racks[playerID] = []));
 };
 
 Game.prototype.getPlayerScore = function (player) {
-    var playerID = "#" + player;
+    const playerID = "#" + player;
     return (this.scores[playerID] || (this.scores[playerID] = 0));
 };
 
 Game.prototype.setPlayerScore = function (player, score) {
-    var playerID = "#" + player;
+    const playerID = "#" + player;
 
     if (!Object.prototype.hasOwnProperty.call(this.racks, playerID) || typeof score !== "number") {
         return;
@@ -264,9 +264,9 @@ Game.prototype.playerJoined = function (playerName) {
         this.getPlayerRack(playerName); // Create the player's rack
     }
 
-    var players = [];
+    const players = [];
 
-    for (var player in this.racks) {
+    for (let player in this.racks) {
         if (Object.prototype.hasOwnProperty.call(this.racks, player)) {
             player = player.slice(1); // '#'
             players.push({
@@ -284,12 +284,12 @@ Game.prototype.playerJoined = function (playerName) {
 };
 
 Game.prototype.addListeningPlayer = function (playerName, responseAndIsES) {
-    var that = this;
+    const that = this;
 
     that.listeningPlayers.push(responseAndIsES);
     keepAlive(responseAndIsES);
 
-    var closed = false;
+    let closed = false;
 
     function close () {
         if (closed) {
@@ -299,7 +299,7 @@ Game.prototype.addListeningPlayer = function (playerName, responseAndIsES) {
         closed = true;
         stopKeepAlive(responseAndIsES);
 
-        var index = that.listeningPlayers.indexOf(responseAndIsES);
+        const index = that.listeningPlayers.indexOf(responseAndIsES);
         if (index !== -1) {
             that.listeningPlayers[index] = that.listeningPlayers[that.listeningPlayers.length - 1];
             that.listeningPlayers.pop();
@@ -315,11 +315,11 @@ Game.prototype.addListeningPlayer = function (playerName, responseAndIsES) {
 };
 
 Game.prototype.commit = function () {
-    var pendingEvents = this.pendingEvents;
+    const pendingEvents = this.pendingEvents;
     this.pendingEvents = [];
-    var msg = JSON.stringify(pendingEvents);
+    const msg = JSON.stringify(pendingEvents);
 
-    for (var i = 0; i < this.listeningPlayers.length; i++) {
+    for (let i = 0; i < this.listeningPlayers.length; i++) {
         while (i < this.listeningPlayers.length && !this.listeningPlayers[i]) {
             this.listeningPlayers[i] = this.listeningPlayers[this.listeningPlayers.length - 1];
             this.listeningPlayers.pop();
@@ -337,8 +337,8 @@ Game.prototype.commit = function () {
 
 Game.prototype.bagPopLetter = function (player) {
     if (this.remainingLetters) {
-        var letter = "";
-        var index;
+        let letter = "";
+        let index;
 
         while (letter === "") {
             index = Math.floor(Math.random() * this.bag.length);
@@ -379,7 +379,7 @@ Game.prototype.setCell = function (index, letter, player) {
 
 Game.prototype.bagPushLetter = function (letter, player) {
     if (letter) {
-        var index = 0;
+        let index = 0;
 
         while (this.bag[index] !== "") {
             index++;
@@ -415,10 +415,10 @@ Game.prototype.reset = function (player) {
 };
 
 function newGameId() {
-    var number;
+    let number;
 
-    var k = 10000;
-    var retries = 0;
+    let k = 10000;
+    let retries = 0;
 
     do {
         number = Math.floor(Math.random() * k).toString();
@@ -435,9 +435,9 @@ function newGameId() {
 }
 
 function countTiles(rack) {
-    var count = 0;
+    let count = 0;
 
-    for (var i = 0; i < rack.length; i++) {
+    for (let i = 0; i < rack.length; i++) {
         if (rack[i]) {
             count++;
         }
@@ -459,15 +459,15 @@ function joinGame(gameNumber, playerName) {
 }
 
 function handleCommand(cmd, gameNumber, playerName, response) {
-    var game;
+    let game;
 
     ({gameNumber, game} = joinGame(gameNumber, playerName));
     game.lastUpdated = new Date();
 
-    var rack = null;
+    let rack = null;
 
     switch (cmd.cmd) {
-        case "joinGame":
+        case "joinGame": {
             response.write(
                 JSON.stringify({
                     "error": 0,
@@ -482,12 +482,14 @@ function handleCommand(cmd, gameNumber, playerName, response) {
                 })
             );
             break;
+        }
 
-        case "hello":
+        case "hello": {
             game.playerJoined(playerName);
             break;
+        }
 
-        case "sync":
+        case "sync": {
             response.write(
                 JSON.stringify({
                     "error":0,
@@ -502,14 +504,16 @@ function handleCommand(cmd, gameNumber, playerName, response) {
                 })
             );
             break;
+        }
 
-        case "score":
+        case "score": {
             game.setPlayerScore(cmd.player, cmd.score);
             response.write("{\"error\":0}");
             break;
+        }
 
-        case "moveLetter":
-            var letter = "";
+        case "moveLetter": {
+            let letter = "";
 
             switch (cmd.from) {
                 case "rack":
@@ -602,14 +606,15 @@ function handleCommand(cmd, gameNumber, playerName, response) {
                 });
             }
             break;
+        }
 
-        case "setRack":
+        case "setRack": {
             cmd.rack.length = 8;
 
             rack = game.getPlayerRack(playerName);
 
-            var initialRackCount = countTiles(rack);
-            var rackCount = countTiles(cmd.rack);
+            const initialRackCount = countTiles(rack);
+            const rackCount = countTiles(cmd.rack);
 
             debuglog(rack, cmd.rack);
 
@@ -625,13 +630,12 @@ function handleCommand(cmd, gameNumber, playerName, response) {
                 break;
             }
 
-            var oldRack = rack.slice();
-
+            const oldRack = rack.slice();
 
             for (let i = 0; i < 8; i++) {
                 cmd.rack[i] = (cmd.rack[i] || "")[0] || "";
                 if (cmd.rack[i]) {
-                    var indexLetter = oldRack.indexOf(cmd.rack[i]);
+                    const indexLetter = oldRack.indexOf(cmd.rack[i]);
 
                     if (indexLetter === -1) {
                         response.write(
@@ -661,12 +665,15 @@ function handleCommand(cmd, gameNumber, playerName, response) {
             );
 
             break;
-        case "resetGame":
+        }
+
+        case "resetGame": {
             game.reset();
             response.write("{\"error\":0}");
             break;
+        }
 
-        case "msg":
+        case "msg": {
             game.pendingEvents.push({
                 msg: {
                     sender: playerName,
@@ -676,16 +683,18 @@ function handleCommand(cmd, gameNumber, playerName, response) {
             });
             response.write("{\"error\":0}");
             break;
+        }
 
-        default:
+        default: {
             response.write("{\"error\":1,\"reason\":\"Unknown command\"}");
             break;
+        }
     }
 }
 
 function handleCommands(cmds, responseAndIsES) {
     if (!cmds.cmds || !cmds.cmds.length) {
-        var {gameNumber, game} = joinGame(cmds.gameNumber, cmds.playerName);
+        const {gameNumber, game} = joinGame(cmds.gameNumber, cmds.playerName);
 
         writeResponse(responseAndIsES,
             JSON.stringify({
@@ -703,11 +712,11 @@ function handleCommands(cmds, responseAndIsES) {
         return;
     }
 
-    var response = responseAndIsES[0];
+    const response = responseAndIsES[0];
 
     response.write("[");
 
-    for (var i = 0; i < cmds.cmds.length; i++) {
+    for (let i = 0; i < cmds.cmds.length; i++) {
         if (i) {
             response.write(",");
         }
@@ -723,8 +732,8 @@ function handleCommands(cmds, responseAndIsES) {
 }
 
 function handleRequest(request, response) {
-    var post = "";
-    var responseAndIsES = [response, false];
+    let post = "";
+    const responseAndIsES = [response, false];
 
     response.on("error", function connectionError(e) {
         console.error("An error occurred while trying to write on a socket", e);
@@ -765,8 +774,8 @@ function handleRequest(request, response) {
                             response.end(err);
                         }
 
-                        var mime = "application/xhtml+xml; charset=utf-8";
-                        var mimes = {
+                        let mime = "application/xhtml+xml; charset=utf-8";
+                        const mimes = {
                             ".mp3": "audio/mpeg",
                             ".ogg": "audio/ogg",
                             ".js": "application/javascript; charset=utf-8",
@@ -774,7 +783,7 @@ function handleRequest(request, response) {
                             ".svg": "image/svg+xml"
                         };
 
-                        for (var i in mimes) {
+                        for (const i in mimes) {
                             if (request.url.endsWith(i)) {
                                 mime = mimes[i];
                                 break;
@@ -793,7 +802,7 @@ function handleRequest(request, response) {
             return;
         }
 
-        var eventSourceMatch = request.url.match(/\/:[^/]+\/sse\/(?<data>[\s\S]+)$/u);
+        const eventSourceMatch = request.url.match(/\/:[^/]+\/sse\/(?<data>[\s\S]+)$/u);
 
         if (eventSourceMatch) {
             response.setHeader("Content-Type", "text/event-stream");
@@ -815,9 +824,9 @@ fs.readFile("games.backup.json", function (err, data) {
         if (err) {
             console.error("WARNING: Could not restore previous backup of the games");
         } else {
-            var backup = JSON.parse(data);
+            const backup = JSON.parse(data);
 
-            for (var gameNumber in backup) {
+            for (const gameNumber in backup) {
                 if (Object.prototype.hasOwnProperty.call(backup, gameNumber)) {
                     games[gameNumber] = Game.fromJSON(backup[gameNumber]);
                 }
index 1cfd57c805c29180a37e42c66b06d95bc8ab98c3..7f14c8647d3b0ae3271e9574d9cce41728c9ec53 100644 (file)
 (function () {
     "use strict";
 
-    var VERSION = 202004041733;
-    var POLLING_DELAY = 2000;
+    const VERSION = 202004041733;
+    const POLLING_DELAY = 2000;
 
-    var _ = (window.libD && libD.l10n) ? libD.l10n() : function (s) {return s;};
+    const _ = (window.libD && libD.l10n) ? libD.l10n() : function (s) {return s;};
 
-    var trivabble = window.trivabble = {l10n: _};
+    const trivabble = window.trivabble = {l10n: _};
 
     function format(s, v) {
         return s.replace("{0}", v);
     }
 
-    var board, rack, boardCells = [], scoreOf, bag;
+    let board;
+    let rack;
+    const boardCells = [];
+    let scoreOf;
+    let bag;
 
-    var playerLetters = [];
+    const playerLetters = [];
 
-    var audioNotification, audioChat;
-    var chatMessages, helpBag, helpClear;
+    let audioNotification;
+    let audioChat;
+    let chatMessages;
+    let helpBag;
+    let helpClear;
 
-    var tablePlayers = {};
-    var participantPlaceholder, participants, name;
+    let tablePlayers = {};
+    let participantPlaceholder;
+    let participants;
+    let name;
 
-    var lastDate = 0;
+    let lastDate = 0;
 
-    var blockMove = 0;
-    var needsRestart = false;
-    var gameInProgress = false;
+    let blockMove = 0;
+    let needsRestart = false;
+    const gameInProgress = false;
 
-    var eventSource = null;
-    var blockEventSourceAutoRetry = false;
-    var connectionLostMessage = null;
-    var boundEventShowConnectionLost = false;
+    let eventSource = null;
+    let blockEventSourceAutoRetry = false;
+    let connectionLostMessage = null;
+    let boundEventShowConnectionLost = false;
 
     function mouseDown(ele, fun, stop) {
-        var meth = stop ? "removeEventListener" : "addEventListener";
+        const meth = stop ? "removeEventListener" : "addEventListener";
         ele[meth]("mousedown", fun, false);
     }
 
     function mouseUp(ele, fun, stop) {
-        var meth = stop ? "removeEventListener" : "addEventListener";
+        const meth = stop ? "removeEventListener" : "addEventListener";
         ele[meth]("mouseup", fun, false);
     }
 
     function mouseMove(ele, fun, stop) {
-        var meth = stop ? "removeEventListener" : "addEventListener";
+        const meth = stop ? "removeEventListener" : "addEventListener";
         ele[meth]("mousemove", fun, false);
     }
 
     function setRack(rack) {
-        for (var i = 0; i < 7; i++) {
+        for (let i = 0; i < 7; i++) {
             setTileParent(playerLetters[i], rack[i] || "");
         }
     }
 
     function getFreeRackSpaceIndex() {
-        for (var i = 0; i < 7; i++) {
+        for (let i = 0; i < 7; i++) {
             if (!playerLetters[i].getElementsByClassName("tile")[0]) {
                 return i;
             }
         unbindEventsShowConnectionLost();
 
         if (!connectionLostMessage) {
-            connectionLostMessage = chatMessage("", _("Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."))
+            connectionLostMessage = chatMessage("", _("Whoops, there is a problem. We are trying to fix it as soon as possible. Please wait a few seconds. If it persists, please contact the person who is able to fix the problem."));
             connectionLostMessage.classList.add("error");
         }
     }
         }
     }
 
-    var tileInitCoords      = null;
-    var tileInitMouseCoords = null;
-    var tileDest            = null;
-    var tileInitDest        = null;
-    var movingTile          = null;
-    var rackBCR             = null;
-    var boardBCR            = null;
-    var bagBCR              = null;
-    var moveCMD             = null;
+    let tileInitCoords      = null;
+    let tileInitMouseCoords = null;
+    let tileDest            = null;
+    let tileInitDest        = null;
+    let movingTile          = null;
+    let rackBCR             = null;
+    let boardBCR            = null;
+    let bagBCR              = null;
+    let moveCMD             = null;
 
     function getLetter(l) {
-        var tile = l.getElementsByClassName("tile")[0];
+        const tile = l.getElementsByClassName("tile")[0];
         if (!tile) {
             return "";
         }
             tileDest.appendChild(movingTile);
 
             if (isParentOf(board, tileDest)) {
-                var tiles = [].slice.call(board.getElementsByClassName("tile-highlight"));
-                var len = tiles.length;
-
-                for (var i = 0; i < len; i++) {
-                    tiles[i].classList.remove("tile-highlight");
+                for (const tile of board.getElementsByClassName("tile-highlight")) {
+                    tile.classList.remove("tile-highlight");
                 }
             }
         } else if (tileInitDest.getElementsByClassName("tile")[0]) {
-            for (var i = 0; i < 7; i++) {
+            for (let i = 0; i < 7; i++) {
                 if (!playerLetters[i].getElementsByClassName("tile")[0]) {
                     playerLetters[i].appendChild(movingTile);
                     break;
         if (tileDest) {
             tileDest.classList.remove("tile-target");
 
-            var moveRack = {
+            const moveRack = {
                 cmd: "setRack",
                 rack: [
                     getLetter(playerLetters[0]),
     }
 
     function dragTileMove(e) {
-        var newLeft = (tileInitCoords.left + (e.clientX - tileInitMouseCoords.clientX));
-        var newTop  = (tileInitCoords.top  + (e.clientY - tileInitMouseCoords.clientY));
+        let newLeft = (tileInitCoords.left + (e.clientX - tileInitMouseCoords.clientX));
+        let newTop  = (tileInitCoords.top  + (e.clientY - tileInitMouseCoords.clientY));
 
         movingTile.style.left = (newLeft + window.scrollX) + "px";
         movingTile.style.top  = (newTop  + window.scrollY) + "px";
 
-        var newDest = null;
+        let newDest = null;
 
         newTop  += tileInitCoords.height / 2;
         newLeft += tileInitCoords.width / 2;
             (newTop  > boardBCR.top  && newTop  < (boardBCR.top + boardBCR.height)) &&
             (newLeft > boardBCR.left && newLeft < (boardBCR.left + boardBCR.width))
         ) {
-            var rowIndex = Math.floor(
+            const rowIndex = Math.floor(
                 (
                     (newTop  - boardBCR.top)  / boardBCR.height
                 ) * board.rows.length
             );
 
             if (rowIndex > 0 && rowIndex < board.rows.length - 1) {
-                var row = board.rows[rowIndex];
+                const row = board.rows[rowIndex];
 
-                var colIndex = Math.floor(
+                const colIndex = Math.floor(
                     (
                         (newLeft - boardBCR.left) / boardBCR.width
                     ) * row.cells.length
             (newTop  > rackBCR.top  && newTop  < (rackBCR.top + rackBCR.height)) &&
             (newLeft > rackBCR.left && newLeft < (rackBCR.left + rackBCR.width))
         ) {
-            var index = Math.floor(
+            const index = Math.floor(
                 (
                     (newLeft - rackBCR.left) / rackBCR.width
                 ) * playerLetters.length
             newDest = playerLetters[index];
 
             if (newDest && newDest.getElementsByClassName("tile")[0]) {
-                var i = index + 1, tile;
+                let i = index + 1;
+let tile;
 
                 while (playerLetters[i]) {
                     tile = playerLetters[i].getElementsByClassName("tile")[0];
                     if (!tile) {
-                        var j = i;
+                        let j = i;
                         while (j > index) {
                             playerLetters[j].appendChild(
                                 playerLetters[j - 1].getElementsByClassName("tile")[0]
                     while (playerLetters[i]) {
                         tile = playerLetters[i].getElementsByClassName("tile")[0];
                         if (!tile) {
-                            var j = i;
+                            let j = i;
                             while (j < index) {
                                 playerLetters[j].appendChild(
                                     playerLetters[j + 1].getElementsByClassName("tile")[0]
         rackBCR  = rack.getBoundingClientRect();
         bagBCR   = bag.getBoundingClientRect();
 
-        var from, index;
+        let from;
+        let index;
 
-        var p = movingTile.parentNode;
-        var oldP = movingTile;
-        var oldOldP = null;
+        let p = movingTile.parentNode;
+        let oldP = movingTile;
+        let oldOldP = null;
 
         while (p) {
             if (p === board) {
     }
 
     function makeLetter(letter, highlight) {
-        var tile = document.createElement("span");
+        const tile = document.createElement("span");
         tile.className = "tile";
         tile.appendChild(document.createElement("span"));
         tile.lastChild.className = "tile-letter";
     }
 
     function setTileParent(p, letter, highlight) {
-        var tile = p.getElementsByClassName("tile")[0];
+        let tile = p.getElementsByClassName("tile")[0];
         if (tile) {
             if (letter) {
                 setLetter(tile, letter, highlight);
     }
 
     function setBoard(board) {
-        for (var i = 0; i < 15 * 15; i++) {
+        for (let i = 0; i < 15 * 15; i++) {
             setCell(i, board[i]);
         }
     }
         );
     }
 
-    var pollingServer = false;
-    var pollingReady = false;
-    var retriedImmediately = false;
+    let pollingServer = false;
+    let pollingReady = false;
+    let retriedImmediately = false;
 
     function forceReload(msg) {
         needsRestart = true;
                 document.getElementById("panel").lastChild.textContent = _("To continue playing, click here");
             }
         );
-        throw e;
     }
 
     function fatalError(e) {
     }
 
     function chatMessage(sender, content) {
-        var msgDom = document.createElement("div");
+        const msgDom = document.createElement("div");
 
         msgDom.className = "msg";
 
 
     function handleReceivedData(data) {
         if (data instanceof Array) {
-            for (var i = 0; i < data.length; i++) {
-                handleReceivedData(data[i]);
-            }
+            data.forEach(handleReceivedData);
             return;
         }
 
                 participantPlaceholder = null;
             }
 
-            for (var i = 0; i < data.players.length; i++) {
-                var player = data.players[i];
-                var playerName = data.players[i].player;
+            for (let i = 0; i < data.players.length; i++) {
+                const player = data.players[i];
+                const playerName = data.players[i].player;
 
                 if (!tablePlayers[playerName]) {
-                    var before = null;
+                    let before = null;
 
-                    for (var j = 1;  j < participants.rows.length; j++) {
+                    for (let j = 1;  j < participants.rows.length; j++) {
                         if (playerName < participants.rows[j].cells[0].textContent) {
                             before = participants.rows[j];
                             break;
                         }
                     }
 
-                    var row = document.createElement("tr");
+                    const row = document.createElement("tr");
                     participants.insertBefore(row, before);
                     row.appendChild(document.createElement("td"));
                     row.lastChild.textContent = playerName;
                 }
 
                 if (Object.prototype.hasOwnProperty.call(player, "score")) {
-                    var scoreCell = tablePlayers[playerName].childNodes[2];
+                    const scoreCell = tablePlayers[playerName].childNodes[2];
                     scoreCell.textContent = player.score;
                     blink(scoreCell);
                 }
 
                 if (Object.prototype.hasOwnProperty.call(player, "rackCount")) {
-                    var countCell = tablePlayers[playerName].childNodes[1];
+                    const countCell = tablePlayers[playerName].childNodes[1];
                     countCell.textContent = player.rackCount;
                     blink(countCell);
                 }
             return;
         }
 
-        var thisRequestIsPolling = false;
-        var currentIndex = 0;
-        var expectedLength = 0;
+        let thisRequestIsPolling = false;
+        let currentIndex = 0;
+        let expectedLength = 0;
 
         if (!data.cmds || !data.cmds.length) {
             if (pollingServer) {
             data.version = VERSION;
 
             if (window.EventSource) {
-                eventSource = new EventSource('/:trivabble/sse/' + JSON.stringify(data));
+                eventSource = new EventSource("/:trivabble/sse/" + JSON.stringify(data));
 
                 eventSource.onopen = connectionReady;
 
             blockMove++;
         }
 
-        var xhr = new XMLHttpRequest();
+        const xhr = new XMLHttpRequest();
 
         xhr.open("POST", "/:trivabble", true);
         xhr.setRequestHeader("Content-Type", "text/plain");
                 connectionReady();
                 while (true) {
                     if (!expectedLength) {
-                        var i = currentIndex;
+                        let i = currentIndex;
                         while (i < xhr.responseText.length) {
                             if ("0123456789".indexOf(xhr.responseText.charAt(i)) === -1) {
                                 expectedLength = parseInt(xhr.responseText.substring(currentIndex, i));
                     }
 
                     if (expectedLength && (xhr.responseText.length >= currentIndex + expectedLength)) {
-                        var end = currentIndex + expectedLength;
+                        const end = currentIndex + expectedLength;
+                        let msgs;
+
                         try {
-                            var msgs = JSON.parse(
+                            msgs = JSON.parse(
                                 xhr.responseText.substring(
                                     currentIndex,
                                     end
         );
     }
 
-    var specialTypesText = {
+    const specialTypesText = {
         "doubleLetter" : _("Double\nLetter"),
         "doubleWord"   : _("Double\nWord"),
         "tripleLetter" : _("Triple\nLetter"),
         sendCmds();
     }
 
-    var audioTileLoaded = false, audioMsgLoaded = false, tilesSound, msgSound;
+    let audioTileLoaded = false;
+    let audioMsgLoaded = false;
+    let tilesSound;
+    let msgSound;
 
     function loadAudio() {
         if (!audioTileLoaded && tilesSound.checked) {
             return;
         }
 
-        var index = getFreeRackSpaceIndex();
+        const index = getFreeRackSpaceIndex();
         if (index === -1) {
             myAlert(_("You cannot take another tile: your rack is full."));
         } else {
     function initChat() {
         chatMessages.style.width = chatMessages.offsetWidth + "px";
 
-        var btn = document.getElementById("chat-btn");
-        var ta = document.getElementById("chat-ta");
+        const btn = document.getElementById("chat-btn");
+        const ta = document.getElementById("chat-ta");
 
         ta.onmouseup = function () {
             chatMessages.style.width = ta.offsetWidth + "px";
         audioNotification.preload = "auto";
         audioNotification.volume  = 1;
 
-        var audioSourceOGG = document.createElement("source");
+        let audioSourceOGG = document.createElement("source");
         audioSourceOGG.src = "notification.ogg";
 
-        var audioSourceMP3 = document.createElement("source");
+        let audioSourceMP3 = document.createElement("source");
         audioSourceMP3.src = "notification.mp3";
         audioNotification.appendChild(audioSourceOGG);
         audioNotification.appendChild(audioSourceMP3);
     }
 
     trivabble.applyL10n = function () {
-        var n = document.querySelectorAll("[data-l10n]");
-
-        for (var i = 0, len = n.length; i < len; i++) {
-            if (n[i].dataset.l10n === "text-content") {
-                n[i].textContent = _(n[i].textContent.trim());
+        for (const node of document.querySelectorAll("[data-l10n]")) {
+            if (node.dataset.l10n === "text-content") {
+                node.textContent = _(node.textContent.trim());
             } else {
-                n[i].setAttribute(n[i].dataset.l10n, _(n[i].getAttribute(n[i].dataset.l10n)));
+                node.setAttribute(node.dataset.l10n, _(node.getAttribute(node.dataset.l10n)));
             }
         }
 
 
         name.textContent = localStorage.trivabblePlayerName;
 
-        var letters = "ABCDEFGHIJKLMNO";
+        const letters = "ABCDEFGHIJKLMNO";
 
-        var doubleLetter = {
+        const doubleLetter = {
             "0,3" : true,
             "0,11": true,
             "2,6" : true,
             "6,12": true
         };
 
-        var cell;
+        let cell;
 
-        for (var i = 0; i < 7; i++) {
-            var span = document.createElement("span");
+        for (let i = 0; i < 7; i++) {
+            const span = document.createElement("span");
             span.className = "tile-placeholder";
             rack.appendChild(span);
             playerLetters.push(span);
         }
 
-        for (var i = 0; i < 15; i++) {
+        for (let i = 0; i < 15; i++) {
             board.rows[0].appendChild(document.createElement("th"));
             board.rows[0].lastChild.textContent = i + 1;
 
             board.appendChild(document.createElement("tr"));
             board.lastChild.appendChild(document.createElement("th"));
             board.lastChild.lastChild.textContent = letters[i];
-            for (var j = 0; j < 15; j++) {
+            for (let j = 0; j < 15; j++) {
                 cell = document.createElement("td");
                 boardCells.push(cell);
                 board.lastChild.appendChild(cell);
         board.appendChild(document.createElement("tr"));
         board.lastChild.appendChild(board.rows[0].cells[0].cloneNode(false));
 
-        for (var i = 0; i < 15; i++) {
+        for (let i = 0; i < 15; i++) {
             board.lastChild.appendChild(document.createElement("th"));
             board.lastChild.lastChild.textContent = i + 1;
         }
     }
 
     function initLang() {
-        var lang = localStorage.trivabbleLang || libD.lang;
-        libD.lang = lang;
+        const lang = libD.lang = localStorage.trivabbleLang || libD.lang;
 
-        var langSel = document.getElementById("select-lang");
+        const langSel = document.getElementById("select-lang");
         langSel.value = lang;
         langSel.onchange = langSelectionChange;
 
-        var script = document.createElement("script");
+        const script = document.createElement("script");
         script.src = "l10n/js/" + lang + ".js";
         script.onerror = trivabble.l10nError;
         document.getElementsByTagName("head")[0].appendChild(script);