get rid of page action, start working on browser action popup

This commit is contained in:
Jack Case
2025-11-05 20:03:41 +00:00
parent 3753d103e4
commit f6bfb1aa4d
8 changed files with 66 additions and 67 deletions

View File

@@ -13,12 +13,6 @@
"*://*.duckduckgo.com/*" "*://*.duckduckgo.com/*"
], ],
"page_action": {
"default_icon": "icons/virus-slash.png",
"default_title": "report slop",
"show_matches": ["<all_urls>"]
},
"browser_action": { "browser_action": {
"default_icon": "icons/virus-slash.png", "default_icon": "icons/virus-slash.png",
"default_title": "Slop Farmer", "default_title": "Slop Farmer",

View File

@@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"@types/firefox-webext-browser": "^143.0.0" "@types/firefox-webext-browser": "^143.0.0",
"typescript": "^5.9.3"
} }
} }

View File

@@ -9,9 +9,9 @@
</head> </head>
<body> <body>
<form id="login-form"> <form id="login-form">
<label for="email" id="username">user:</label> <label for="email" id="username">username</label>
<input type="text" name="username" required /> <input type="text" name="username" required />
<label for="password" id="password">password:</label> <label for="password" id="password">password</label>
<input type="password" name="password" required /> <input type="password" name="password" required />
<button id="login-button">login</button> <button id="login-button">login</button>
</form> </form>

29
src/browser-action.ts Normal file
View File

@@ -0,0 +1,29 @@
import { API_URL } from "common"
const login_form = document.getElementById("login-form") as HTMLFormElement
const login_status = document.getElementById("login-status")
if (localStorage.getItem("accessToken")) {
login_status.setAttribute("style", "visibility: visible;")
}
login_form.addEventListener("submit", (event) => { event.preventDefault(); submit_login_form() })
async function submit_login_form() {
const login_url = new URL("/login", API_URL)
const request = new Request(login_url,
{
method: "POST",
body: new FormData(login_form)
})
const response = await fetch(request)
if (response.ok) {
const body = await response.json()
const token = body.access_token
localStorage.setItem("accessToken", token)
const status_el = document.getElementById("login-status")
status_el.setAttribute("style", "visibility: visible;")
}
}

1
src/common.ts Normal file
View File

@@ -0,0 +1 @@
export const API_URL: string = "https://api.slopfarmer.jack-case.pro"

View File

@@ -1,15 +1,6 @@
const API_URL: string = "https://api.slopfarmer.jack-case.pro" import { API_URL } from "common"
let access_token: string let access_token: string
const login_form = document.getElementById("login-form") as HTMLFormElement
if(login_form) {
const login_status = document.getElementById("login-status")
if (localStorage.getItem("accessToken")) {
login_status.setAttribute("style", "visibility: visible;")
}
login_form.addEventListener("submit", (event) => {event.preventDefault(); submit_login_form()})
}
function setup_storage_db() { function setup_storage_db() {
/* create indexeddb object store to retain objects in the form of /* create indexeddb object store to retain objects in the form of
* {"domain": "domain.tld", * {"domain": "domain.tld",
@@ -18,7 +9,7 @@ function setup_storage_db() {
* "page/2" * "page/2"
* ] * ]
* } * }
*/ */
let db let db
const db_request = window.indexedDB.open("SlopDB", 1) const db_request = window.indexedDB.open("SlopDB", 1)
@@ -36,7 +27,7 @@ function setup_storage_db() {
db_request.onupgradeneeded = (event) => { db_request.onupgradeneeded = (event) => {
console.log(event) console.log(event)
db = event.target.result db = event.target.result
const slop_store = db.createObjectStore("slop", {keyPath: "domain"}) const slop_store = db.createObjectStore("slop", { keyPath: "domain" })
} }
} }
@@ -60,7 +51,7 @@ async function get_slop_store(readwrite: boolean) {
} }
}) })
return await slop_store_promise return await slop_store_promise
} }
async function insert_slop(domain: string, path: string, report: boolean = true) { async function insert_slop(domain: string, path: string, report: boolean = true) {
@@ -80,12 +71,12 @@ async function insert_slop(domain: string, path: string, report: boolean = true)
// domain exists, add this path // domain exists, add this path
result.paths.add(path) result.paths.add(path)
} }
else { else {
// create a new domain object // create a new domain object
const paths_set = new Set() const paths_set = new Set()
paths_set.add(path) paths_set.add(path)
result = {domain: domain, paths: paths_set} result = { domain: domain, paths: paths_set }
} }
// persist to indexeddb // persist to indexeddb
@@ -96,16 +87,16 @@ async function insert_slop(domain: string, path: string, report: boolean = true)
} }
} }
if(report) { if (report) {
const report_url = new URL("/report", API_URL) const report_url = new URL("/report", API_URL)
const request = new Request(report_url, const request = new Request(report_url,
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Bearer": get_access_token() "Bearer": get_access_token()
}, },
body: JSON.stringify({slop_urls: [new URL(path, "http://"+domain).toString()]}) body: JSON.stringify({ slop_urls: [new URL(path, "http://" + domain).toString()] })
}) })
fetch(request) fetch(request)
} }
@@ -125,7 +116,7 @@ async function check_local_slop(url: string) {
}) })
const slop_object = await known_slop const slop_object = await known_slop
let result = {slop_domain: false, slop_path: false} let result = { slop_domain: false, slop_path: false }
if (slop_object) { if (slop_object) {
// domain was found // domain was found
result.slop_domain = true result.slop_domain = true
@@ -140,10 +131,10 @@ async function check_local_slop(url: string) {
async function check_remote_slop(urls: string[]) { async function check_remote_slop(urls: string[]) {
const check_url = new URL("/check", API_URL) const check_url = new URL("/check", API_URL)
const request = new Request(check_url, {method: "POST", headers: { "Content-Type": "application/json", "Bearer": get_access_token() }, body: JSON.stringify({slop_urls: urls})}) const request = new Request(check_url, { method: "POST", headers: { "Content-Type": "application/json", "Bearer": get_access_token() }, body: JSON.stringify({ slop_urls: urls }) })
const response = await fetch(request) const response = await fetch(request)
let domain_objects = await response.json() let domain_objects = await response.json()
domain_objects.forEach((domain: any) => {insert_slop(domain.domain_name, "/", false)}) domain_objects.forEach((domain: any) => { insert_slop(domain.domain_name, "/", false) })
return domain_objects return domain_objects
} }
@@ -157,21 +148,21 @@ async function on_button_clicked_handler(tab: any) {
await insert_slop(domain, path) await insert_slop(domain, path)
// @ts-ignore // @ts-ignore
update_page_action_icon({frameId: 0, tabId: tab.id, url: tab.url}) update_page_action_icon({ frameId: 0, tabId: tab.id, url: tab.url })
} }
async function update_page_action_icon(details: browser.webNavigation._OnCommittedDetails) { async function update_page_action_icon(details: browser.webNavigation._OnCommittedDetails) {
if(details.frameId != 0) { if (details.frameId != 0) {
return return
} }
const is_slop = await check_local_slop(details.url) const is_slop = await check_local_slop(details.url)
if(is_slop.slop_path) { if (is_slop.slop_path) {
browser.pageAction.setIcon({ browser.pageAction.setIcon({
path: "icons/virus_red.png", path: "icons/virus_red.png",
tabId: details.tabId tabId: details.tabId
}) })
} }
else if(is_slop.slop_domain) { else if (is_slop.slop_domain) {
browser.pageAction.setIcon({ browser.pageAction.setIcon({
path: "icons/virus_yellow.png", path: "icons/virus_yellow.png",
tabId: details.tabId tabId: details.tabId
@@ -191,7 +182,7 @@ async function message_listener(message: any, sender: any) {
if (message.type === "check") { if (message.type === "check") {
let check_promises = new Array() let check_promises = new Array()
let not_found_local = new Array() let not_found_local = new Array()
message.urls.forEach((url: string) => { message.urls.forEach((url: string) => {
check_promises.push(check_local_slop(url).then(async (result) => { check_promises.push(check_local_slop(url).then(async (result) => {
if (result.slop_domain) { if (result.slop_domain) {
@@ -220,32 +211,9 @@ function get_access_token() {
return access_token return access_token
} }
async function submit_login_form() {
const login_url = new URL("/login", API_URL) browser.runtime.onInstalled.addListener(on_install_handler)
browser.runtime.onStartup.addListener(get_access_token)
const request = new Request(login_url, browser.pageAction.onClicked.addListener(on_button_clicked_handler)
{ browser.webNavigation.onCommitted.addListener(update_page_action_icon)
method: "POST", browser.runtime.onMessage.addListener(message_listener)
body: new FormData(login_form)
})
const response = await fetch(request)
if(response.ok) {
const body = await response.json()
const token = body.access_token
localStorage.setItem("accessToken", token)
const status_el = document.getElementById("login-status")
status_el.setAttribute("style", "visibility: visible;")
}
}
if(!login_form) {
browser.runtime.onInstalled.addListener(on_install_handler)
browser.runtime.onStartup.addListener(get_access_token)
browser.pageAction.onClicked.addListener(on_button_clicked_handler)
browser.webNavigation.onCommitted.addListener(update_page_action_icon)
browser.runtime.onMessage.addListener(message_listener)
}

View File

@@ -5,6 +5,7 @@
"noImplicitAny": true, "noImplicitAny": true,
"lib": ["ES7", "DOM"], "lib": ["ES7", "DOM"],
"sourceMap": true, "sourceMap": true,
"target": "esnext" "target": "esnext",
"baseUrl": "src/"
} }
} }

View File

@@ -6,3 +6,8 @@
version "143.0.0" version "143.0.0"
resolved "https://registry.yarnpkg.com/@types/firefox-webext-browser/-/firefox-webext-browser-143.0.0.tgz#29413c9f393d4c4b5622d4a74182ff0219e98620" resolved "https://registry.yarnpkg.com/@types/firefox-webext-browser/-/firefox-webext-browser-143.0.0.tgz#29413c9f393d4c4b5622d4a74182ff0219e98620"
integrity sha512-865dYKMOP0CllFyHmgXV4IQgVL51OSQQCwSoihQ17EwugePKFSAZRc0EI+y7Ly4q7j5KyURlA7LgRpFieO4JOw== integrity sha512-865dYKMOP0CllFyHmgXV4IQgVL51OSQQCwSoihQ17EwugePKFSAZRc0EI+y7Ly4q7j5KyURlA7LgRpFieO4JOw==
typescript@^5.9.3:
version "5.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==