]> git.sesse.net Git - remoteglot/blobdiff - www/js/remoteglot.js
Improve a comment in onSnapEnd.
[remoteglot] / www / js / remoteglot.js
index c96335feb62baeacd88435fcc65c91c6375920b2..a402d0004b2067129ff3fe0e738552672d2cee77 100644 (file)
@@ -380,9 +380,7 @@ let sync_server_clock = function(server_date_string) {
 let clear_arrows = function() {
        for (let i = 0; i < arrows.length; ++i) {
                if (arrows[i].svg) {
-                       if (arrows[i].svg.parentElement) {
-                               arrows[i].svg.parentElement.removeChild(arrows[i].svg);
-                       }
+                       arrows[i].svg.remove();
                        delete arrows[i].svg;
                }
        }
@@ -506,11 +504,12 @@ let position_arrow = function(arrow) {
                return;
        }
 
-       let zoom_factor = document.getElementById("board").getBoundingClientRect().width / 400.0;
+       let board_width = parseInt(document.querySelector(".board-b72b1").style.width, 10);
+       let zoom_factor = board_width / 400.0;
        let line_width = arrow.line_width * zoom_factor;
        let arrow_size = arrow.arrow_size * zoom_factor;
 
-       let square_width = document.querySelector(".square-a8").getBoundingClientRect().width;
+       let square_width = board_width / 8;
        let from_y, to_y, from_x, to_x;
        if (board.orientation() === 'black') {
                from_y = (arrow.from_row + 0.5)*square_width;
@@ -527,8 +526,8 @@ let position_arrow = function(arrow) {
        let SVG_NS = "http://www.w3.org/2000/svg";
        let XHTML_NS = "http://www.w3.org/1999/xhtml";
        let svg = document.createElementNS(SVG_NS, "svg");
-       svg.setAttribute("width", /** @type{number} */ (document.getElementById("board").getBoundingClientRect().width));
-       svg.setAttribute("height", /** @type{number} */ (document.getElementById("board").getBoundingClientRect().height));
+       svg.setAttribute("width", board_width);
+       svg.setAttribute("height", board_width);
        svg.setAttribute("style", "position: absolute");
        svg.setAttribute("position", "absolute");
        svg.setAttribute("version", "1.1");
@@ -631,7 +630,7 @@ let find_nonstupid_moves = function(data, margin, invert) {
        let pv_score = undefined;
        for (let move in data['refutation_lines']) {
                let line = data['refutation_lines'][move];
-               let score = compute_score_sort_key(line['score'], line['depth'], invert, false);
+               let score = compute_score_sort_key(line['score'], line['depth'], invert);
                if (move == data['pv'][0]) {
                        pv_score = score;
                }
@@ -839,6 +838,8 @@ let update_refutation_lines = function() {
        tbl.replaceChildren();
 
        if (display_lines.length < 2) {
+               // Update the move highlight, as we've rewritten all the HTML.
+               update_move_highlight();
                return;
        }
 
@@ -897,8 +898,11 @@ let update_refutation_lines = function() {
                        continue;
                }
 
-               let move = "<a class=\"move\" href=\"javascript:show_line(" + display_lines.length + ", " + 0 + ");\">" + line['move'] + "</a>";
-               move_td.innerHTML = move;
+               let move_link = document.createElement("a");
+               move_link.classList.add("move");
+               move_link.setAttribute("href", "javascript:show_line(" + display_lines.length + ", 0)");
+               move_link.textContent = line['move'];
+               move_td.appendChild(move_link);
 
                let score_td = document.createElement("td");
                tr.appendChild(score_td);
@@ -1223,6 +1227,9 @@ let update_board = function() {
                return;
        }
 
+       if (clock_timer !== null) {
+               clearTimeout(clock_timer);
+       }
        update_clock();
 
        // The score.
@@ -1395,7 +1402,17 @@ let update_sparkline = function(data) {
                                scores.push(last_score);
                        }
                        if (data['score']) {
-                               scores.push(compute_plot_score(data['score']));
+                               let score = compute_plot_score(data['score']);
+                               scores.push(score);
+                               if (score < min_score) min_score = score;
+                               if (score > max_score) max_score = score;
+                       }
+                       if (max_score - min_score < 100) {
+                               if (Math.abs(max_score) >= Math.abs(min_score)) {
+                                       max_score = min_score + 100;
+                               } else {
+                                       min_score = max_score - 100;
+                               }
                        }
 
                        const h = scorespark.getBoundingClientRect().height;
@@ -1416,16 +1433,16 @@ let update_sparkline = function(data) {
                                let color;
                                if (scores[i] === 0) {
                                        color = [0.5, 0.5, 0.5];
-                                       rect.setAttributeNS(null, 'y', base_y - 1);
+                                       rect.setAttributeNS(null, 'y', base_y);
                                        rect.setAttributeNS(null, 'height', 1);
                                } else if (scores[i] > 0) {
                                        color = [0.2, 0.4, 0.8];
                                        rect.setAttributeNS(null, 'y', base_y - extent);
-                                       rect.setAttributeNS(null, 'height', extent);
+                                       rect.setAttributeNS(null, 'height', extent + 1);
                                } else {
                                        color = [1.0, 0.267, 0.267];
                                        rect.setAttributeNS(null, 'y', base_y);
-                                       rect.setAttributeNS(null, 'height', -extent);
+                                       rect.setAttributeNS(null, 'height', -extent + 1);
                                }
                                let hlcolor = [color[0], color[1], color[2]];
                                if (scores[i] !== 0) { 
@@ -1441,7 +1458,7 @@ let update_sparkline = function(data) {
                                rect.addEventListener('mouseenter', (e) => draw_hover(e, hlcolor, tooltip));
                                rect.addEventListener('mousemove', (e) => draw_hover(e, hlcolor, tooltip));
                                rect.addEventListener('mouseleave', (e) => hide_hover(e, color));
-                               rect.addEventListener('click', (e) => show_line(0, i + first_move_num - 1));
+                               rect.addEventListener('click', (e) => { hide_hover(e, color); show_line(0, i + first_move_num - 1) });
                                scorespark.appendChild(rect);
                        }
                }
@@ -1491,7 +1508,7 @@ let update_num_viewers = function(num_viewers) {
 }
 
 let update_clock = function() {
-       clearTimeout(clock_timer);
+       clock_timer = null;
 
        let data = displayed_analysis_data || current_analysis_data;
        if (!data) return;
@@ -1810,37 +1827,51 @@ let update_historic_analysis = function() {
  * @param {string} fen
  */
 let update_imbalance = function(fen) {
-       let hiddenboard = new Chess(fen);
        let imbalance = {'k': 0, 'q': 0, 'r': 0, 'b': 0, 'n': 0, 'p': 0};
-       for (let row = 0; row < 8; ++row) {
-               for (let col = 0; col < 8; ++col) {
-                       let col_text = String.fromCharCode('a1'.charCodeAt(0) + col);
-                       let row_text = String.fromCharCode('a1'.charCodeAt(1) + row);
-                       let square = col_text + row_text;
-                       let contents = hiddenboard.get(square);
-                       if (contents !== null) {
-                               if (contents.color === 'w') {
-                                       ++imbalance[contents.type];
-                               } else {
-                                       --imbalance[contents.type];
-                               }
-                       }
+       for (const c of fen) {
+               if (c === ' ') {
+                       // End of board
+                       break;
+               }
+               if (c != c.toUpperCase()) {
+                       --imbalance[c];
+               } else if (c != c.toLowerCase()) {
+                       ++imbalance[c.toLowerCase()];
                }
        }
-       let white_imbalance = '';
-       let black_imbalance = '';
+
+       let white_imbalance = document.getElementById('whiteimbalance');
+       let black_imbalance = document.getElementById('blackimbalance');
+       white_imbalance.textContent = '';
+       black_imbalance.textContent = '';
        for (let piece in imbalance) {
                for (let i = 0; i < imbalance[piece]; ++i) {
-                       white_imbalance += '<img src="' + svg_pieces['w' + piece.toUpperCase()] + '" alt="" style="width: 15px;height: 15px;" class="imbalance-piece">';
-                       white_imbalance += '<img src="' + svg_pieces['b' + piece.toUpperCase()] + '" alt="" style="width: 15px;height: 15px;" class="imbalance-inverted-piece">';
+                       let i1 = document.createElement('img');
+                       i1.src = svg_pieces['w' + piece.toUpperCase()];
+                       i1.setAttribute('alt', piece.toUpperCase());
+                       i1.classList.add('imbalance-piece');
+                       white_imbalance.appendChild(i1);
+
+                       let i2 = document.createElement('img');
+                       i2.src = svg_pieces['b' + piece.toUpperCase()];
+                       i2.setAttribute('alt', piece.toUpperCase());
+                       i2.classList.add('imbalance-inverted-piece');
+                       white_imbalance.appendChild(i2);
                }
                for (let i = 0; i < -imbalance[piece]; ++i) {
-                       black_imbalance += '<img src="' + svg_pieces['b' + piece.toUpperCase()] + '" alt="" style="width: 15px;height: 15px;" class="imbalance-piece">';
-                       black_imbalance += '<img src="' + svg_pieces['w' + piece.toUpperCase()] + '" alt="" style="width: 15px;height: 15px;" class="imbalance-inverted-piece">';
+                       let i1 = document.createElement('img');
+                       i1.src = svg_pieces['b' + piece.toUpperCase()];
+                       i1.setAttribute('alt', piece.toUpperCase());
+                       i1.classList.add('imbalance-piece');
+                       black_imbalance.appendChild(i1);
+
+                       let i2 = document.createElement('img');
+                       i2.src = svg_pieces['w' + piece.toUpperCase()];
+                       i2.setAttribute('alt', piece.toUpperCase());
+                       i2.classList.add('imbalance-inverted-piece');
+                       black_imbalance.appendChild(i2);
                }
        }
-       document.getElementById('whiteimbalance').innerHTML = white_imbalance;
-       document.getElementById('blackimbalance').innerHTML = black_imbalance;
 }
 
 /** Mark the currently selected move in red.
@@ -1993,7 +2024,11 @@ let explore_hash = function(fen) {
        fetch(backend_hash_url + "?fen=" + fen, { signal })
                .then((response) => response.json())
                .then((data) => { show_explore_hash_results(data, fen); })
-               .catch((err) => {});
+               .catch((err) => {
+                       // Truncate the lines, since we already cleared the display.
+                       display_lines = [ display_lines[0], display_lines[1] ];
+                       update_move_highlight();
+               });
 }
 
 /** Process the JSON response from a hash probe request.
@@ -2030,12 +2065,12 @@ let onDragStart = function(source, piece, position, orientation) {
 }
 
 let mousedownSquare = function(e) {
-       if (!e.target || !e.target.matches('.square-55d63')) {
+       if (!e.target || !e.target.closest('.square-55d63')) {
                return;
        }
 
        reverse_dragging_from = null;
-       let square = e.target.getAttribute('data-square');
+       let square = e.target.closest('.square-55d63').getAttribute('data-square');
 
        let pseudogame = new Chess(display_fen);
        if (pseudogame.game_over() === true) {
@@ -2060,13 +2095,13 @@ let mousedownSquare = function(e) {
 }
 
 let mouseupSquare = function(e) {
-       if (!e.target || !e.target.matches('.square-55d63')) {
+       if (!e.target || !e.target.closest('.square-55d63')) {
                return;
        }
        if (reverse_dragging_from === null) {
                return;
        }
-       let source = e.target.getAttribute('data-square');
+       let source = e.target.closest('.square-55d63').getAttribute('data-square');
        let target = reverse_dragging_from;
        reverse_dragging_from = null;
        if (onDrop(source, target) !== 'snapback') {
@@ -2175,6 +2210,8 @@ let onSnapEnd = function(source, target) {
                promotion: 'q' // NOTE: always promote to a queen for example simplicity
        });
 
+       // Move ahead on the line we're on -- this includes history if we've
+       // gone backwards.
        if (current_display_line &&
            current_display_move < current_display_line.pv.length - 1 &&
            current_display_line.pv[current_display_move + 1] === move.san) {
@@ -2184,8 +2221,9 @@ let onSnapEnd = function(source, target) {
 
        // Walk down the displayed lines until we find one that starts with
        // this move, then select that. Note that this gives us a good priority
-       // order (history first, then PV, then multi-PV lines).
-       for (let i = 0; i < display_lines.length; ++i) {
+       // order (PV, then multi-PV lines; history was already dealt with above,
+       // as it's the only line that originates backwards).
+       for (let i = 1; i < display_lines.length; ++i) {
                if (i == 1 && current_display_line) {
                        // Do not choose PV if not on it.
                        continue;
@@ -2199,6 +2237,9 @@ let onSnapEnd = function(source, target) {
 
        // Shouldn't really be here if we have hash probes, but there's really
        // nothing we can do.
+       // FIXME: Just make a new line, probably (even if we don't have hash moves).
+       // As it is, we can actually drag (but not click) such a move in the UI,
+       // but it has no effect on what we're probing.
 }
 // End of dragging-related code.
 
@@ -2305,10 +2346,9 @@ let compute_plot_score = function(score) {
  * @param score The score digest tuple.
  * @param {?number} depth Depth the move has been computed to, or null.
  * @param {boolean} invert Whether black is to play.
- * @param {boolean=} depth_secondary_key
  * @return {number}
  */
-let compute_score_sort_key = function(score, depth, invert, depth_secondary_key) {
+let compute_score_sort_key = function(score, depth, invert) {
        let s;
        if (!score) {
                return -10000000;
@@ -2332,11 +2372,7 @@ let compute_score_sort_key = function(score, depth, invert, depth_secondary_key)
        }
        if (s) {
                if (invert) s = -s;
-               if (depth_secondary_key) {
-                       return s * 200 + (depth || 0);
-               } else {
-                       return s;
-               }
+               return s;
        } else {
                return null;
        }