From fa45fa6eadd51297f90e3445d740bd423466e45d Mon Sep 17 00:00:00 2001 From: Anatoli Makarevich Date: Wed, 14 Aug 2024 16:10:07 +0200 Subject: [PATCH 1/3] Remove obsolete function isChessComVersion2 --- ext/src/bg/analysis.js | 2 +- ext/src/bg/background.js | 25 +++++++------------------ ext/src/bg/getpgn.js | 26 +++++++++++++------------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/ext/src/bg/analysis.js b/ext/src/bg/analysis.js index c1a4264..aa5f63e 100644 --- a/ext/src/bg/analysis.js +++ b/ext/src/bg/analysis.js @@ -3,4 +3,4 @@ chrome.runtime.onMessage.addListener(async function(pgn, sender, sendResponse){ $("input[name='analyse']").prop("checked", true); $(".submit")[0].click(); sendResponse(undefined); -}); \ No newline at end of file +}); diff --git a/ext/src/bg/background.js b/ext/src/bg/background.js index c06f494..ac8d125 100755 --- a/ext/src/bg/background.js +++ b/ext/src/bg/background.js @@ -1,13 +1,3 @@ -function isChessComVersion2(url) { - if (url.indexOf('livechess/game') >= 0) { - return true; - } - if (url.indexOf('live.chess.com') >= 0) { - return true; - } - return false; -} - function isChessGames(url) { if (url.indexOf('chessgames.com') >= 0) { return true; @@ -47,13 +37,13 @@ function getGameId(url) { if (refIndex >= 0) { return url.slice(refIndex + 'game/daily/'.length); } - + // chesstempo.com var refIndex = url.indexOf('chesstempo.com/gamedb/game/'); if (refIndex >= 0) { return url.slice(refIndex + 'chesstempo.com/gamedb/game/'.length).split('/')[0]; } - + // live chess.com game refIndex = url.indexOf('#'); var ref = refIndex >= 0 ? url.slice(refIndex + 1) : ''; @@ -67,7 +57,7 @@ chrome.action.onClicked.addListener(async function(tab) { var onDone = function(pgn) { if (!pgn) return; - if (tab.url.indexOf("live#a=") > -1 || + if (tab.url.indexOf("live#a=") > -1 || (pgn.indexOf('[Result ') > -1 && pgn.indexOf('[Result "*"]') < 0) || (pgn.indexOf('[Result "*"]') > -1 && pgn.indexOf(' won on time') > -1)) // chess.com oddity where games can be lost on time but Result is not updated { @@ -91,18 +81,18 @@ chrome.action.onClicked.addListener(async function(tab) { }; if (isChessGames(tab.url)) { // chessgames.com - var gameId = getGameId(tab.url); + var gameId = getGameId(tab.url); var results = await getPgn(tab.id, "chessGames", gameId); - onDone(results); + onDone(results); } else if (isChessTempo(tab.url)) { // chesstempo.com var gameId = getGameId(tab.url); var results = await getPgn(tab.id, "chessTempo", gameId); - onDone(results); + onDone(results); } else if (isChessDB(tab.url)) { // chess-db.com var results = await getPgn(tab.id, "chessDB"); - onDone(results); + onDone(results); } else { // chess.com var results = await getPgn(tab.id, "chessCom"); @@ -118,4 +108,3 @@ async function notFinished(tabId, site, ...args) { return await chrome.tabs.sendMessage(tabId, {action: "notFinished", site, actionArgs: args}); } - diff --git a/ext/src/bg/getpgn.js b/ext/src/bg/getpgn.js index 7ceb441..bd3915b 100644 --- a/ext/src/bg/getpgn.js +++ b/ext/src/bg/getpgn.js @@ -11,7 +11,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { .then(sendResponse); return true; } - + if (request.action !== "getPgn") { return false; } @@ -24,12 +24,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { pgnFunc(...(request.actionArgs || [])) .then(sendResponse); - return true; + return true; }); // chess.com -async function getCurrentPgn_chessCom() { +async function getCurrentPgn_chessCom() { debuglog("getCurrentPgn_chessCom"); var pgn = await openShareDialog() @@ -59,7 +59,7 @@ async function getCurrentPgn_chessGames(gameId) { } // chess-db.com -async function getCurrentPgn_chessDB() { +async function getCurrentPgn_chessDB() { var pgn = null; var pgnInput = $('input[name="pgn"]'); if (pgnInput) @@ -71,7 +71,7 @@ async function getCurrentPgn_chessDB() { } // chessTempo.com -async function getCurrentPgn_chessTempo(gameId) { +async function getCurrentPgn_chessTempo(gameId) { debuglog('getCurrentPgn_chessTempo(' + gameId + ')'); if (!gameId || gameId === '') { // if the gameId is not defined, try to get it from the link @@ -84,7 +84,7 @@ async function getCurrentPgn_chessTempo(gameId) { debuglog("gameId = " + gameId); } - var pgn = await $.ajax({ + var pgn = await $.ajax({ url: $('form.ct-download-pgn-form')[0].action, type: 'POST', data : 'gameids=' + gameId, @@ -101,7 +101,7 @@ async function getCurrentPgn_chessTempo(gameId) { } async function openPgnTab() { - debuglog("openPgnTab"); + debuglog("openPgnTab"); var pgnDiv = document.querySelector('div.share-menu-tab-selector-component > div:nth-child(1)') || document.querySelector('div.alt-share-menu-tab.alt-share-menu-tab-image-component') @@ -113,7 +113,7 @@ async function openPgnTab() { document.querySelector(".icon-download"); if (!pgnTab) { var headerElements = document.querySelectorAll( - ".share-menu-dialog-component header *") || document; + ".share-menu-dialog-component header *") || document; pgnTab = Array.from(headerElements).filter( (x) => x.textContent == "PGN")[0]; } @@ -138,7 +138,7 @@ async function openShareDialog() { document.querySelector("button[data-test='download']") || document.querySelector("#shareMenuButton") || document.querySelector(".icon-font-chess.share.icon-font-primary") || - document.querySelector(".icon-font-chess.share") || + document.querySelector(".icon-font-chess.share") || document.querySelector(".icon-share"); if (shareButton) { return new Promise((resolve, reject) => { @@ -159,7 +159,7 @@ function closeShareDialog() { document.querySelector(".icon-font-chess.x.icon-font-primary") || document.querySelector(".icon-font-chess.x.icon-font-secondary") || document.querySelector(".icon-font-chess.x.ui_outside-close-icon") || - document.querySelector("#chessboard_ShareMenuGlobalDialogCloseButton") + document.querySelector("#chessboard_ShareMenuGlobalDialogCloseButton") if (closeButton) { closeButton.click(); } else @@ -169,7 +169,7 @@ function closeShareDialog() { } async function copyPgn() { - debuglog("copyPgn"); + debuglog("copyPgn"); var pgnDiv = document.querySelector('div.alt-share-menu-tab.alt-share-menu-tab-gif-component') || document.querySelector('div.alt-share-menu-tab.alt-share-menu-tab-image-component') @@ -197,7 +197,7 @@ async function copyPgn() { debuglog("could not find disable analysis radio button!"); } - var textarea = + var textarea = document.querySelector("#live_ShareMenuPgnContentTextareaId") || document.querySelector("textarea[name=pgn]") || document.querySelector(".form-textarea-component.pgn-download-textarea") || @@ -221,7 +221,7 @@ async function popuptoast(message) { return Promise.resolve(); } -function debuglog(message) +function debuglog(message) { var logDebugMessages = false; if (logDebugMessages) { From 25532f571c8a3d0d6180d029f559aca9ee595ad0 Mon Sep 17 00:00:00 2001 From: Anatoli Makarevich Date: Wed, 14 Aug 2024 22:12:14 +0200 Subject: [PATCH 2/3] Inject review button to chess.com --- ext/css/getpgn.css | 42 +++++++++++++++++++++++++++++++++++++- ext/icons/lichess_logo.svg | 3 +++ ext/manifest.json | 17 ++++++++++++++- ext/src/bg/background.js | 16 +++++++++++++-- ext/src/bg/getpgn.js | 41 +++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 ext/icons/lichess_logo.svg diff --git a/ext/css/getpgn.css b/ext/css/getpgn.css index fbbbc89..ffbfb44 100644 --- a/ext/css/getpgn.css +++ b/ext/css/getpgn.css @@ -16,4 +16,44 @@ -webkit-box-shadow: 0px 0px 24px -1px rgba(56, 56, 56, 1); -moz-box-shadow: 0px 0px 24px -1px rgba(56, 56, 56, 1); box-shadow: 0px 0px 24px -1px rgba(56, 56, 56, 1); -} \ No newline at end of file +} + +.lichess-review-button { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 14px 22px; + white-space: nowrap; + + border-radius: 5px; + border: 0; + outline: none; + + background-color: #33312e; + + font-family: -apple-system, "system-ui", "Segoe UI", system-ui, Helvetica, Arial, sans-serif; + font-size: 16px; + font-weight: 600; + color: #949494; +} + +.lichess-review-button:hover { + background-color: #44413b; +} + +.lichess-review-button__icon { + width: 20px; + height: 20px; + display: block; + margin-right: 8px; + flex-shrink: 0; + + background-image: url('chrome-extension://__MSG_@@extension_id__/icons/lichess_logo.svg'); + background-size: contain; + background-repeat: no-repeat; +} + +.lichess-review-button__text { + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/ext/icons/lichess_logo.svg b/ext/icons/lichess_logo.svg new file mode 100644 index 0000000..399e36e --- /dev/null +++ b/ext/icons/lichess_logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/ext/manifest.json b/ext/manifest.json index 36c4a85..02e32ef 100755 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -24,7 +24,7 @@ "js/jquery-3.5.1.min.js", "src/bg/analysis.js" ], - "matches": [ + "matches": [ "https://*.lichess.org/paste" ] }, @@ -67,5 +67,20 @@ }, "permissions": [ "activeTab" + ], + "web_accessible_resources": [ + { + "resources": [ + "icons/lichess_logo.svg" + ], + "matches": [ + "https://www.chess.com/*", + "https://www.chessgames.com/*", + "https://chessgames.com/*", + "https://chess-db.com/*", + "https://chesstempo.com/*", + "https://old.chesstempo.com/*" + ] + } ] } diff --git a/ext/src/bg/background.js b/ext/src/bg/background.js index ac8d125..4590e9c 100755 --- a/ext/src/bg/background.js +++ b/ext/src/bg/background.js @@ -53,7 +53,7 @@ function getGameId(url) { return ''; } -chrome.action.onClicked.addListener(async function(tab) { +async function runAnalysis(tab) { var onDone = function(pgn) { if (!pgn) return; @@ -98,7 +98,7 @@ chrome.action.onClicked.addListener(async function(tab) { var results = await getPgn(tab.id, "chessCom"); onDone(results); } -}); +} async function getPgn(tabId, site, ...args) { return await chrome.tabs.sendMessage(tabId, {action: "getPgn", site, actionArgs: args}); @@ -108,3 +108,15 @@ async function notFinished(tabId, site, ...args) { return await chrome.tabs.sendMessage(tabId, {action: "notFinished", site, actionArgs: args}); } + +// Here we handle click on the pinned extension icon +chrome.action.onClicked.addListener(async function(tab) { + await runAnalysis(tab); +}); + +// Here we handle click on the injected button +chrome.runtime.onMessage.addListener(async function(request, sender){ + if (request.action === "openReview") { + await runAnalysis(sender.tab) + } +}); diff --git a/ext/src/bg/getpgn.js b/ext/src/bg/getpgn.js index bd3915b..fa650c7 100644 --- a/ext/src/bg/getpgn.js +++ b/ext/src/bg/getpgn.js @@ -228,3 +228,44 @@ function debuglog(message) console.log(message); } } + +function injectButton(buttonsContainer) { + if(buttonsContainer.querySelector(".lichess-review-button")) { + return; + } + + var button = document.createElement("button"); + button.innerHTML = ` + + Game Review + ` + button.className = "lichess-review-button"; + + button.onclick = function() { + chrome.runtime.sendMessage(chrome.runtime.id, { + id: chrome.runtime.id, + action: "openReview" + }) + }; + + buttonsContainer.appendChild(button); +} + +function observeDOM() { + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + var buttonsContainer = document.querySelector(".game-review-buttons-component"); + + if (buttonsContainer) { + injectButton(buttonsContainer); + observer.disconnect(); + } + }); + }); + + observer.observe(document.body, { childList: true, subtree: true }); +} + +if (window.location.origin === "https://www.chess.com") { + observeDOM() +} From 4d5f0e96406aebdeaa1e39dd0ff46347a8597165 Mon Sep 17 00:00:00 2001 From: Anatoli Makarevich Date: Wed, 14 Aug 2024 22:25:14 +0200 Subject: [PATCH 3/3] Clean up obsolete message param --- ext/src/bg/getpgn.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/src/bg/getpgn.js b/ext/src/bg/getpgn.js index fa650c7..d71d706 100644 --- a/ext/src/bg/getpgn.js +++ b/ext/src/bg/getpgn.js @@ -243,7 +243,6 @@ function injectButton(buttonsContainer) { button.onclick = function() { chrome.runtime.sendMessage(chrome.runtime.id, { - id: chrome.runtime.id, action: "openReview" }) };