Merge branch 'develop' into check_spelling
authorLaurent Mazet <mazet@softndesign.org>
Thu, 13 Aug 2020 09:41:32 +0000 (11:41 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 13 Aug 2020 09:41:32 +0000 (11:41 +0200)
1  2 
l10n/po/fr/trivabble.po
l10n/pot/trivabble.pot
public/index.html
public/trivabble.css
public/trivabble.js

index 0d0398b85df9f6f89966cf6ba51111babd6342b8,9edcab65cd6845d15330edc9c1351ab005b693ce..11b123444b19bc2311f85c4ead2ae1b8bf5922d9
@@@ -166,23 -166,8 +166,29 @@@ msgstr "Vous avez changé la langue du 
  msgid  "{0} changed the language of the board to {1}"
  msgstr "{0} a changé la langue du plateau en {1}"
  
 +msgid  "Check spelling for new words"
 +msgstr "Vérifier l'orthographe des mots nouveaux"
 +
 +msgid  "Incorrect spelling for {0} from {1}"
 +msgstr "Orthographe incorrecte pour {0} parmi {1}"
 +
 +msgid  "All words are correct: {0}"
 +msgstr "Tous les mots sont corrects : {0}"
 +
 +msgid  "No new word found"
 +msgstr "Aucun nouveau mot trouvé"
 +
 +msgid  "Incorrect dictionary file."
 +msgstr "Dictionaire incorrect."
 +
 +msgid  "Enable spell checker"
 +msgstr "Activer le vérificateur orthographique"
 +
 +msgid  "Spell checking requires Trivabble to download a dictionary. This dictionary is based on Aspell. Do you confirm?"
 +msgstr "La vérification orthographique nécessite que Trivabble télécharge un dictionnaire. Ce dictionnaire est construit grâce à Aspell. Confirmez-vous ?"
++
+ msgid  "Configuration"
+ msgstr "Options de configuration"
+ 
+ msgid  "Configuration window"
+ msgstr "Fenêtre de configuration"
index 912c1a4e38b33ec867592413b32321d818660559,484ac7447cc91ed9700c2b3c58357e7fd76858b2..89518c371d47fa43b68b5dceb80f5816438ef163
@@@ -172,23 -172,8 +172,29 @@@ msgstr "
  msgid  "{0} changed the language of the board to {1}"
  msgstr ""
  
 +msgid  "Check spelling for new words"
 +msgstr ""
 +
 +msgid  "Incorrect spelling for {0} from {1}"
 +msgstr ""
 +
 +msgid  "All words are correct: {0}"
 +msgstr ""
 +
 +msgid  "No new word found"
 +msgstr ""
 +
 +msgid  "Incorrect dictionary file."
 +msgstr ""
 +
 +msgid  "Enable spell checker"
 +msgstr ""
 +
 +msgid  "Spell checking requires Trivabble to download a dictionary. This dictionary is based on Aspell. Do you confirm?"
 +msgstr ""
++
+ msgid  "Configuration"
+ msgstr ""
+ 
+ msgid  "Configuration window"
+ msgstr ""
index f61707cbd46ec6123ae6d5de51fe30fbe62be2ef,4811d72d2c06e54d84077b99f68c647807ba9db4..46110936b6ca4535249bac3a8ce798a1641dd472
@@@ -69,8 -77,7 +77,9 @@@
              <p id="help-turn" data-l10n="text-content">Who's turn? Click on the Turn button!</p>
              <button id="clear-rack" class="minibutton" data-l10n="text-content">Put back all the tiles of&#10;your rack in the bag</button>
              <button id="show-rack" class="minibutton" data-l10n="text-content">Show my rack to other players</button>
 +            <button id="enable-spell-checker" class="minibutton" data-l10n="text-content">Enable spell checker</button>
 +            <button id="check-spelling" class="minibutton" data-l10n="text-content" style="display: none">Check spelling for new words</button>
+             <button id="modal-config-btn" class="text-content" data-l10n="text-content">Configuration</button>
          </div>
      </body>
  </html>
Simple merge
index f81d82fa5836b92ac1fd616516bc8ac5a1a46100,cde5a492a66e44e326a93ae314932b17ec069ef1..9163a600f05dc5f20319d85414be72987ef9effc
  
      }
  
 +    function getLetterFromBoard(row, col) {
 +        if ((row < 0) || (row >= 15) || (col < 0) || (col >= 15)) {
 +            return "";
 +        }
 +        try {
 +            const index = (row * 15) + col;
 +            const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
 +            const tile = tilePlaceholder.getElementsByClassName("tile")[0];
 +            return tile.firstChild.textContent;
 +        } catch (e) {
 +            return "";
 +        }
 +    }
 +
 +    function searchWordInLine(row, col, incRow, incCol) {
 +        
 +        const initLetter = getLetterFromBoard(row, col);
 +
 +        /* Look for first letter in line */
 +        while (getLetterFromBoard(row - incRow, col - incCol) !== "") {
 +            row -= incRow;
 +            col -= incCol;
 +        }
 +
 +        /* Look for last letter in line */
 +        const word = {letters: "", row: row, col: col, incRow: incRow, incCol: incCol};
 +        let letter;
 +        while ((letter = getLetterFromBoard(row, col)) !== "") {
 +            word.letters += letter;
 +            row += incRow;
 +            col += incCol;
 +        }
 +        return (word.letters === initLetter) ? null : word;
 +    }
 +    
 +    function isNewWord(newWord, words) {
 +        if (newWord === null) {
 +            return false;
 +        }
 +        for (const k of Object.keys(words)) {
 +            if ((words[k].letters === newWord.letters) &&
 +                (words[k].row === newWord.row) &&
 +                (words[k].col === newWord.col) &&
 +                (words[k].incRow === newWord.incRow) &&
 +                (words[k].incCol === newWord.incCol)) {
 +                return false;
 +            }
 +        }
 +        return true;
 +    }
 +
 +    function searchNewWords() {
 +
 +        const words = [];
 +        for (const i of Object.keys(currentTilePlayed)) {
 +
 +            /* Get board position */
 +            const row = Math.floor(i / 15);
 +            const col = i % 15;
 +
 +            /* Look for word in column */
 +            const newWordInCol = searchWordInLine(row, col, 1, 0);
 +            if (isNewWord(newWordInCol, words)) {
 +                words.push(newWordInCol);
 +            }
 +
 +            /* Look for word in row */
 +            const newWordInRow = searchWordInLine(row, col, 0, 1);
 +            if (isNewWord(newWordInRow, words)) {
 +                words.push(newWordInRow);
 +            }
 +
 +            /* Should we look for word in diag? */
 +
 +            /* If nothing found, it's a one letter word */
 +            if ((newWordInCol === null) && (newWordInRow === null)) {
 +                words.push({letters: getLetterFromBoard(row, col), row: row, col: col, incRow: 0, incCol: 0});
 +            }
 +        }
 +
 +        return words;
 +    }
 +
 +    function modifyTileClass(word, value, action) {
 +
 +        /* action: true for add, false for remove */
 +
 +        if (action) {
 +
 +            /* only for new words */
 +            for (let l = 0; l < word.letters.length; l++) {
 +                const index = ((word.row + (l * word.incRow)) * 15) + word.col + (l * word.incCol);
 +                const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
 +                const tile = tilePlaceholder.getElementsByClassName("tile")[0];
 +
 +                tile.classList.add(value);
 +            }
 +
 +        } else {
 +
 +            /* tiles on board */
 +            for (let index = 0; index < 15 * 15; index++) {
 +                const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
 +                const tile = tilePlaceholder.getElementsByClassName("tile")[0];
 +                if (typeof tile !== "undefined") {
 +                    tile.classList.remove(value);
 +                }
 +            }
 +
 +            /* tiles on rack */
 +            for (const tilePlaceholder of rack.getElementsByClassName("tile-placeholder")) {
 +                const tile = tilePlaceholder.getElementsByClassName("tile")[0];
 +                if (typeof tile !== "undefined") {
 +                    tile.classList.remove(value);
 +                }
 +            }
 +
 +            /* tile on the move */
 +            if (movingTile !== null) {
 +                movingTile.classList.remove(value);
 +            }
 +        }
 +    }
 +
 +    function checkSpelling() {
 +
 +        const newWords = searchNewWords();
 +        if (newWords.length === 0) {
 +            myAlert(_("No new word found"));
 +            return;
 +        }
 +
 +        /* Check if words are in dictionary */
 +        let words = [];
 +        let badWords = [];
 +        for (const k of Object.keys(newWords)) {
 +            const currentWord = newWords[k].letters.replace(/ /gu, "?");
 +            if (words.indexOf(currentWord) === -1) {
 +                words.push(currentWord);
 +            }
 +            modifyTileClass(newWords[k], "tile-spelling-ok", true);
 +            const pattern = "^" + newWords[k].letters.replace(/ /gu, ".") + "$";
 +            if (!dictionary.find(function (word) {return word.match(pattern);})) {
 +                if (badWords.indexOf(currentWord) === -1) {
 +                    badWords.push(currentWord);
 +                }
 +                modifyTileClass(newWords[k], "tile-spelling-nok", true);
 +            }
 +        }
 +        setTimeout(
 +            function () {
 +                modifyTileClass(null, "tile-spelling-ok", false);
 +                modifyTileClass(null, "tile-spelling-nok", false);
 +            }, 5000);
 +        words = words.join(", ").trim();
 +        badWords = badWords.join(", ").trim();
 +
 +        /* Advice on erroneous spelling */
 +        if (badWords.length > 0) {
 +            const msg = chatMessage("", format(_("Incorrect spelling for {0} from {1}"), badWords, words));
 +            msg.classList.add("error");
 +        } else {
 +            chatMessage("", format(_("All words are correct: {0}"), words));
 +        }
 +    }
 +
      function initChat() {
-         chatMessages.style.width = chatMessages.offsetWidth + "px";
- 
          const btn = document.getElementById("chat-btn");
  
          chatTextarea.onmouseup = function () {
          document.getElementById("join-game").onclick   = joinGame;
          document.getElementById("clear-rack").onclick  = clearRack;
          document.getElementById("show-rack").onclick   = showRack;
 +        document.getElementById("enable-spell-checker").onclick = enableSpellChecker;
 +        document.getElementById("check-spelling").onclick = checkSpelling;
          helpClear.onclick  = clearGame;
+ 
+       document.getElementById("modal-config-btn").onclick = showConfig;
+       document.getElementById("modal-close-btn").onclick = showConfig;
      }
  
      function initGame() {