From e18564d49f578529b7d3c8763339d9a03e3b91fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= Date: Fri, 17 Jan 2025 14:53:22 +0100 Subject: [PATCH 1/5] Always set local storage url MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Löfgren --- wikiweaver-ext/options/options.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wikiweaver-ext/options/options.js b/wikiweaver-ext/options/options.js index 58b4291..5538943 100644 --- a/wikiweaver-ext/options/options.js +++ b/wikiweaver-ext/options/options.js @@ -18,8 +18,9 @@ async function save(e) { e.preventDefault(); const urlElem = document.querySelector("#url"); + const url = new URL(urlElem.value.toLowerCase() || urlElem.placeholder); - await Settings.local.Set("url", urlElem.value.toLowerCase() || urlElem.placeholder); + await Settings.local.Set("url", url.toString()); await Settings.local.Set("autoOpenStartPage", document.querySelector("#auto-open-start-page").checked); // TODO: show saved succeeded in some way From 831e0a5063c8bb259a96300da93d126ff8bb8b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= Date: Fri, 17 Jan 2025 14:55:14 +0100 Subject: [PATCH 2/5] Add "join lobby"-button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The browser extension will insert a join lobby button on the wikiweaverserver domain specified by the user. When pressed, this will join the currently open lobby with stored username. The user most have specified a username beforehand. Note: it uses the activeTab permission (instead of permission on allurls) to be able to insert itself on only the currently active tab. Thismeans that the user must be on the website and open (or have open) theextension. The current tab is only part of the activeTab permissionbased on user interaction, e.g. opening the extension. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#activetab_permission Signed-off-by: Victor Löfgren --- wikiweaver-ext/background.js | 14 +++++++++ wikiweaver-ext/content/join-lobby.js | 31 +++++++++++++++++++ wikiweaver-ext/manifest-chrome.json | 1 + wikiweaver-ext/manifest-firefox.json | 1 + wikiweaver-ext/options/options.js | 18 +++++++++++ wikiweaver-ext/popup/popup.js | 9 ++++-- .../cmd/main/wikiweaver-server.go | 6 ++++ 7 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 wikiweaver-ext/content/join-lobby.js diff --git a/wikiweaver-ext/background.js b/wikiweaver-ext/background.js index a116056..f5b3419 100644 --- a/wikiweaver-ext/background.js +++ b/wikiweaver-ext/background.js @@ -310,4 +310,18 @@ chrome.runtime.onInstalled.addListener(async () => { await Settings.session.Defaults({ connected: false, }); + + const url = await Settings.local.Get("url"); + + if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["join-lobby"] })).length <= 0) { + const scripts = [ + { + id: "join-lobby", + js: ["/content/join-lobby.js"], + matches: [`${url}/*`], + } + ] + + await chrome.scripting.registerContentScripts(scripts); + } }); diff --git a/wikiweaver-ext/content/join-lobby.js b/wikiweaver-ext/content/join-lobby.js new file mode 100644 index 0000000..c1d471e --- /dev/null +++ b/wikiweaver-ext/content/join-lobby.js @@ -0,0 +1,31 @@ +const fragment = document.createDocumentFragment(); + +const div = document.createElement("div"); +div.classList.add("flex-horizontal-container") + +// TODO: There is probably a better way to do all this +const btn = document.createElement("btn"); +btn.id = "join-lobby"; +btn.classList.add("button", "box", "text"); +btn.onclick = HandleJoinLobbyClicked; +btn.style = "margin-top: 0.5rem; background: var(--green);"; +btn.textContent = "join"; + +const reference = document.getElementById("leaderboard-wrapper"); +const parent = document.getElementById("sidepane"); + +fragment.appendChild(div); +div.appendChild(btn); +parent.insertBefore(fragment, reference); + +async function HandleJoinLobbyClicked() { + const { username } = await chrome.storage.local.get(); + + let code = window.location.hash.replace("#", "").toLocaleLowerCase().trim(); + + await chrome.runtime.sendMessage({ + type: "connect", + code, + username, + }); +} diff --git a/wikiweaver-ext/manifest-chrome.json b/wikiweaver-ext/manifest-chrome.json index 727e923..598c041 100644 --- a/wikiweaver-ext/manifest-chrome.json +++ b/wikiweaver-ext/manifest-chrome.json @@ -16,6 +16,7 @@ "default_popup": "popup/popup.html" }, "permissions": [ + "activeTab", "scripting", "storage", "tabs", diff --git a/wikiweaver-ext/manifest-firefox.json b/wikiweaver-ext/manifest-firefox.json index 599c03a..9d28b33 100644 --- a/wikiweaver-ext/manifest-firefox.json +++ b/wikiweaver-ext/manifest-firefox.json @@ -15,6 +15,7 @@ "default_popup": "popup/popup.html" }, "permissions": [ + "activeTab", "scripting", "storage", "tabs", diff --git a/wikiweaver-ext/options/options.js b/wikiweaver-ext/options/options.js index 5538943..b48c280 100644 --- a/wikiweaver-ext/options/options.js +++ b/wikiweaver-ext/options/options.js @@ -24,6 +24,24 @@ async function save(e) { await Settings.local.Set("autoOpenStartPage", document.querySelector("#auto-open-start-page").checked); // TODO: show saved succeeded in some way + + if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["join-lobby"] })).length > 0) { + await chrome.scripting.unregisterContentScripts({ ids: ["join-lobby"] }); + } + + // For some reason keeping the port here made it so the script was not + // injected at localhost, when the server was set to http://localhost:3000 + url.port = ""; + + const scripts = [ + { + id: "join-lobby", + js: ["/content/join-lobby.js"], + matches: [`${url.origin}/*`], + } + ] + + await chrome.scripting.registerContentScripts(scripts); } document.addEventListener("DOMContentLoaded", () => init(), false); diff --git a/wikiweaver-ext/popup/popup.js b/wikiweaver-ext/popup/popup.js index 295cf66..a1ec638 100644 --- a/wikiweaver-ext/popup/popup.js +++ b/wikiweaver-ext/popup/popup.js @@ -297,6 +297,9 @@ async function HandleMessageConnect(msg) { data.connectionStatus = ConnectionStatus.DISCONNECTED; await UnregisterContentScripts(); } + + document.getElementById("code").textContent = msg.Code; + document.getElementById("username").textContent = msg.Username; } chrome.runtime.onMessage.addListener(async (msg) => { @@ -322,12 +325,14 @@ const ContentScripts = [ ]; async function RegisterContentScripts() { - if ((await chrome.scripting.getRegisteredContentScripts()).length <= 0) { + if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["content"] })).length <= 0) { await chrome.scripting.registerContentScripts(ContentScripts); } } async function UnregisterContentScripts() { - await chrome.scripting.unregisterContentScripts(); + if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["content"] })).length > 0) { + await chrome.scripting.unregisterContentScripts({ ids: ["content"] }); + } } diff --git a/wikiweaver-server/cmd/main/wikiweaver-server.go b/wikiweaver-server/cmd/main/wikiweaver-server.go index e34926f..8a177f6 100644 --- a/wikiweaver-server/cmd/main/wikiweaver-server.go +++ b/wikiweaver-server/cmd/main/wikiweaver-server.go @@ -639,6 +639,8 @@ type JoinFromExtRequest struct { type JoinToExtResponse struct { Success bool + Code string + Username string UserID string AlreadyInLobby bool } @@ -724,6 +726,8 @@ func handleExtJoin(w http.ResponseWriter, r *http.Request) { if alreadyInLobby || globalState.Dev { successResponse := JoinToExtResponse{ Success: true, + Code: lobby.Code, + Username: otherWithSameUsername.Username, UserID: otherWithSameUsername.UserID, AlreadyInLobby: alreadyInLobby, } @@ -788,6 +792,8 @@ func handleExtJoin(w http.ResponseWriter, r *http.Request) { successResponse := JoinToExtResponse{ Success: true, + Code: lobby.Code, + Username: extClient.Username, UserID: userID, AlreadyInLobby: false, } From 941128bdecf2d67ec2dbdf2a0941a300296217f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= Date: Fri, 17 Jan 2025 15:52:51 +0100 Subject: [PATCH 3/5] Unhide button instead of creating a new one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Löfgren --- wikiweaver-ext/content/join-lobby.js | 20 ++------------------ wikiweaver-web/style.css | 5 +++++ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/wikiweaver-ext/content/join-lobby.js b/wikiweaver-ext/content/join-lobby.js index c1d471e..1329df8 100644 --- a/wikiweaver-ext/content/join-lobby.js +++ b/wikiweaver-ext/content/join-lobby.js @@ -1,22 +1,6 @@ -const fragment = document.createDocumentFragment(); - -const div = document.createElement("div"); -div.classList.add("flex-horizontal-container") - -// TODO: There is probably a better way to do all this -const btn = document.createElement("btn"); -btn.id = "join-lobby"; -btn.classList.add("button", "box", "text"); +const btn = document.getElementById("join-button"); btn.onclick = HandleJoinLobbyClicked; -btn.style = "margin-top: 0.5rem; background: var(--green);"; -btn.textContent = "join"; - -const reference = document.getElementById("leaderboard-wrapper"); -const parent = document.getElementById("sidepane"); - -fragment.appendChild(div); -div.appendChild(btn); -parent.insertBefore(fragment, reference); +btn.hidden = false; async function HandleJoinLobbyClicked() { const { username } = await chrome.storage.local.get(); diff --git a/wikiweaver-web/style.css b/wikiweaver-web/style.css index b35cd6d..67939fa 100644 --- a/wikiweaver-web/style.css +++ b/wikiweaver-web/style.css @@ -142,6 +142,11 @@ img { background: var(--blue); } +#join-button { + background: var(--green); + margin-top: 0.5rem; +} + #leaderboard-wrapper { overflow-x: auto; flex-shrink: 0; From 0963f2a610175416acd75fceac962dfbbba3c900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= Date: Thu, 23 Jan 2025 11:56:39 +0100 Subject: [PATCH 4/5] Ask for permission instead of active tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make our hostname the default host permission. Add all urls as optional permissions so that we can ask for any url dynamically. When a user saves a new url in the options, ask for host permissions on that particular url. Signed-off-by: Victor Löfgren --- wikiweaver-ext/manifest-chrome.json | 7 +++++-- wikiweaver-ext/manifest-firefox.json | 7 +++++-- wikiweaver-ext/options/options.js | 28 ++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/wikiweaver-ext/manifest-chrome.json b/wikiweaver-ext/manifest-chrome.json index 598c041..a31813e 100644 --- a/wikiweaver-ext/manifest-chrome.json +++ b/wikiweaver-ext/manifest-chrome.json @@ -16,14 +16,17 @@ "default_popup": "popup/popup.html" }, "permissions": [ - "activeTab", "scripting", "storage", "tabs", "webNavigation" ], "host_permissions": [ - "*://*.wikipedia.org/*" + "*://*.wikipedia.org/*", + "https://wikiweaver.stuffontheinter.net" + ], + "optional_permissions": [ + "" ], "background": { "type": "module", diff --git a/wikiweaver-ext/manifest-firefox.json b/wikiweaver-ext/manifest-firefox.json index 9d28b33..5f5ac5a 100644 --- a/wikiweaver-ext/manifest-firefox.json +++ b/wikiweaver-ext/manifest-firefox.json @@ -15,14 +15,17 @@ "default_popup": "popup/popup.html" }, "permissions": [ - "activeTab", "scripting", "storage", "tabs", "webNavigation" ], "host_permissions": [ - "*://*.wikipedia.org/*" + "*://*.wikipedia.org/*", + "https://wikiweaver.stuffontheinter.net/*" + ], + "optional_permissions": [ + "" ], "background": { "type": "module", diff --git a/wikiweaver-ext/options/options.js b/wikiweaver-ext/options/options.js index b48c280..ca01ecb 100644 --- a/wikiweaver-ext/options/options.js +++ b/wikiweaver-ext/options/options.js @@ -20,29 +20,41 @@ async function save(e) { const urlElem = document.querySelector("#url"); const url = new URL(urlElem.value.toLowerCase() || urlElem.placeholder); - await Settings.local.Set("url", url.toString()); await Settings.local.Set("autoOpenStartPage", document.querySelector("#auto-open-start-page").checked); - // TODO: show saved succeeded in some way + // For some reason keeping the port here made it so the script was not + // injected at localhost, when the server was set to http://localhost:3000 + const port = url.port; + url.port = ""; + + const host = `${url.origin}/*`; + + // We must request permissions as the first async function we call in this + // user input handler for it to work. + // See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/request + // and https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/User_actions + await chrome.permissions.request({ origins: [host] }); + + // What a mess... + url.port = port; + await Settings.local.Set("url", url.origin); if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["join-lobby"] })).length > 0) { await chrome.scripting.unregisterContentScripts({ ids: ["join-lobby"] }); } - // For some reason keeping the port here made it so the script was not - // injected at localhost, when the server was set to http://localhost:3000 - url.port = ""; - const scripts = [ { id: "join-lobby", js: ["/content/join-lobby.js"], - matches: [`${url.origin}/*`], + matches: [host], } ] await chrome.scripting.registerContentScripts(scripts); + + // TODO: show saved succeeded in some way } document.addEventListener("DOMContentLoaded", () => init(), false); -document.querySelector("form").addEventListener("submit", save); +document.querySelector("#submit").addEventListener("click", save); From 9db36a87c84571a3ae9af4bb4858152f8062b485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= Date: Sun, 16 Feb 2025 15:30:09 +0100 Subject: [PATCH 5/5] Rebase fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Löfgren --- wikiweaver-ext/background.js | 3 ++- wikiweaver-ext/content/join-lobby.js | 8 +++----- wikiweaver-ext/options/options.js | 8 +++++--- wikiweaver-web/index.html | 3 +++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/wikiweaver-ext/background.js b/wikiweaver-ext/background.js index f5b3419..dfd58b1 100644 --- a/wikiweaver-ext/background.js +++ b/wikiweaver-ext/background.js @@ -138,7 +138,8 @@ async function UpdateBadge(connected) { } async function TryConnectToLobby(msg) { - const { code, username } = msg; + const { code } = msg; + const username = msg.username ?? await Settings.local.Get("username"); const { url } = await Settings.local.Get(); const userid = await Settings.session.Get(["userid-for-lobby", code], ""); diff --git a/wikiweaver-ext/content/join-lobby.js b/wikiweaver-ext/content/join-lobby.js index 1329df8..6bc3505 100644 --- a/wikiweaver-ext/content/join-lobby.js +++ b/wikiweaver-ext/content/join-lobby.js @@ -1,15 +1,13 @@ const btn = document.getElementById("join-button"); -btn.onclick = HandleJoinLobbyClicked; +btn.onclick = JoinLobby; btn.hidden = false; -async function HandleJoinLobbyClicked() { - const { username } = await chrome.storage.local.get(); - +async function JoinLobby() { let code = window.location.hash.replace("#", "").toLocaleLowerCase().trim(); await chrome.runtime.sendMessage({ type: "connect", code, - username, }); } + diff --git a/wikiweaver-ext/options/options.js b/wikiweaver-ext/options/options.js index ca01ecb..a8540a9 100644 --- a/wikiweaver-ext/options/options.js +++ b/wikiweaver-ext/options/options.js @@ -20,8 +20,6 @@ async function save(e) { const urlElem = document.querySelector("#url"); const url = new URL(urlElem.value.toLowerCase() || urlElem.placeholder); - await Settings.local.Set("autoOpenStartPage", document.querySelector("#auto-open-start-page").checked); - // For some reason keeping the port here made it so the script was not // injected at localhost, when the server was set to http://localhost:3000 const port = url.port; @@ -37,7 +35,6 @@ async function save(e) { // What a mess... url.port = port; - await Settings.local.Set("url", url.origin); if ((await chrome.scripting.getRegisteredContentScripts({ ids: ["join-lobby"] })).length > 0) { await chrome.scripting.unregisterContentScripts({ ids: ["join-lobby"] }); @@ -53,6 +50,11 @@ async function save(e) { await chrome.scripting.registerContentScripts(scripts); + // After the other stuff is done, store all values + + await Settings.local.Set("url", url.origin); + await Settings.local.Set("autoOpenStartPage", document.querySelector("#auto-open-start-page").checked); + // TODO: show saved succeeded in some way } diff --git a/wikiweaver-web/index.html b/wikiweaver-web/index.html index 1b76ade..53e5831 100644 --- a/wikiweaver-web/index.html +++ b/wikiweaver-web/index.html @@ -39,6 +39,9 @@ +
+ +