3 Commits
v0.1 ... v0.2

Author SHA1 Message Date
Jack Case
432c8f09ee much more stable link attribute setting 2025-10-26 10:36:27 -04:00
Jack Case
b1f4ad61ff ResultLinks data structure 2025-10-26 09:54:31 -04:00
Jack Case
0423ed8807 working on better defining the page links datastructure 2025-10-25 20:32:21 -04:00
2 changed files with 75 additions and 25 deletions

View File

@@ -1,45 +1,97 @@
const ddg_result_selector = "a[data-testid=\"result-title-a\""
const ddg_result_list_selector = "ol.react-results--main"
let result_list_node
let result_list_observer
const page_links = new Map()
class SearchLink { class SearchLink {
constructor(link_node) { constructor(link_node) {
this.node = link_node this.node = link_node
this.target = link_node.getAttribute("href") this.target = link_node.getAttribute("href")
this.url = new URL(link_node.getAttribute("href"))
this.checked = false this.checked = false
this.result = undefined this.result = undefined
} }
} }
function check_links(links) { class ResultLinks extends Map {
// map domains to paths and their associated nodes
set(domain, path, search_link) {
if(!super.get(domain)) {
const nested_map = new Map()
nested_map.set(path, search_link)
super.set(domain, nested_map)
} else {
super.get(domain).set(path, search_link)
}
}
setNode(link_node) {
const search_link = new SearchLink(link_node)
this.set(search_link.url.hostname, search_link.url.pathname, search_link)
}
get(domain, path="/") {
return super.get(domain).get(path)
}
getDomain(domain) {
return super.get(domain)
}
getUrl(url) {
const urlobj = new URL(url)
return this.get(urlobj.hostname, urlobj.pathname)
}
getSearchLinks() {
// return an iterator over the nested SearchLink objects
const domain_value_iterator = super.values()
const search_link_iterator = domain_value_iterator.flatMap((domain_map) => {
return domain_map.values()
})
return search_link_iterator
}
}
const ddg_result_selector = "a[data-testid=\"result-title-a\""
const ddg_result_list_selector = "ol.react-results--main"
let result_list_node
let result_list_observer
const page_links = new ResultLinks()
function check_links(search_links) {
// send a message to background script with a list of URLs to check // send a message to background script with a list of URLs to check
browser.runtime.sendMessage({type: "check", urls: links}) const urls = search_links.map((search_link) => {
links.forEach((link) => {page_links.get(link).checked = true}) search_link.checked = true
return search_link.target
})
browser.runtime.sendMessage({type: "check", urls: urls.toArray()})
} }
async function message_listener(message) { async function message_listener(message) {
// handle slop reports returned from the background script // handle slop reports returned from the background script
if(message.type === "check_result") { if(message.type === "check_result") {
console.log(message.url, message.result) if (message.domain) {
const link = page_links.get(message.url) const paths = page_links.getDomain(message.domain)
if ( message.result.slop_domain ) { paths.forEach((search_link) => {
search_link.node.setAttribute("style", "color: red;")
search_link.result = message.result
})
} else if (message.url) {
const link = page_links.getUrl(message.url)
link.node.setAttribute("style", "color: red;") link.node.setAttribute("style", "color: red;")
}
link.result = message.result link.result = message.result
} }
}
} }
function get_initial_links() { function get_initial_links() {
// get links from initial page load // get links from initial page load
const links = document.querySelectorAll(ddg_result_selector) const links = document.querySelectorAll(ddg_result_selector)
links.forEach((node) => { links.forEach((node) => {
const link = new SearchLink(node) page_links.setNode(node)
page_links.set(link.target, link)
}) })
const link_targets = page_links.keys().toArray() const link_targets = page_links.getSearchLinks()
check_links(link_targets) check_links(link_targets)
} }
@@ -47,15 +99,13 @@ function update_links() {
// the result list has updated, add new links and check them // the result list has updated, add new links and check them
const links = document.querySelectorAll(ddg_result_selector) const links = document.querySelectorAll(ddg_result_selector)
links.forEach((node) => { links.forEach((node) => {
const link = new SearchLink(node) page_links.setNode(node)
if (page_links.has(link.target)) return })
page_links.set(link.target, link) const link_iter = page_links.getSearchLinks().filter((search_link) => {
return !(search_link.checked)
}) })
const link_arr = page_links.keys().filter((key) => {
return !(page_links.get(key).checked)
}).toArray()
check_links(link_arr) check_links(link_iter)
} }
function setup_result_observer() { function setup_result_observer() {

View File

@@ -198,7 +198,7 @@ async function message_listener(message, sender) {
let remote_slop = await check_remote_slop(not_found_local) let remote_slop = await check_remote_slop(not_found_local)
remote_slop.forEach((result) => { remote_slop.forEach((result) => {
browser.tabs.sendMessage(tabid, { type: "check_result", url: result.url, result: result }) browser.tabs.sendMessage(tabid, { type: "check_result", domain: result.domain_name, result: result })
}) })
} }
} }