Fix Threads dynamic post discovery
This commit is contained in:
parent
a6689e2975
commit
134157bc71
5 changed files with 28 additions and 8 deletions
|
|
@ -75,8 +75,12 @@ export class DefinitionEngine {
|
||||||
|
|
||||||
private extractText(post: Element): string {
|
private extractText(post: Element): string {
|
||||||
for (const selector of this.definition.post.textSelectors) {
|
for (const selector of this.definition.post.textSelectors) {
|
||||||
const content = post.matches(selector) ? post : post.querySelector(selector);
|
const matches = Array.from(post.querySelectorAll(selector));
|
||||||
if (content) return visibleText(content, this.definition.post.excludedSelectors ?? []);
|
const contents = post.matches(selector) ? [post, ...matches] : matches;
|
||||||
|
for (const content of contents) {
|
||||||
|
const text = visibleText(content, this.definition.post.excludedSelectors ?? []);
|
||||||
|
if (text) return text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
"https://threads.net/*",
|
"https://threads.net/*",
|
||||||
"https://www.threads.net/*"
|
"https://www.threads.net/*"
|
||||||
],
|
],
|
||||||
"requiredSelectors": ["[data-pressable-container=\"true\"], [role=\"article\"], article"],
|
"requiredSelectors": ["[role=\"article\"], article"],
|
||||||
"post": {
|
"post": {
|
||||||
"rootSelectors": ["[data-pressable-container=\"true\"]", "[role=\"article\"]", "article"],
|
"rootSelectors": ["[role=\"article\"]", "article"],
|
||||||
"textSelectors": ["span[dir=\"auto\"]:not(a span):not(time span):not([role=\"button\"] span)"],
|
"textSelectors": ["span[dir=\"auto\"]"],
|
||||||
"excludedSelectors": ["button", "[role=\"button\"]", "time", "svg"],
|
"excludedSelectors": ["button", "[role=\"button\"]", "time", "svg", "a span", "time span", "[role=\"button\"] span"],
|
||||||
"permalinkSelectors": ["a[href*=\"/post/\"]"]
|
"permalinkSelectors": ["a[href*=\"/post/\"]"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ addSubscriptionButton?.addEventListener("click", async () => {
|
||||||
refreshSubscriptionsButton?.addEventListener("click", async () => {
|
refreshSubscriptionsButton?.addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
const response = await chrome.runtime.sendMessage({ type: "REFRESH_SUBSCRIPTIONS" });
|
const response = await chrome.runtime.sendMessage({ type: "REFRESH_SUBSCRIPTIONS" });
|
||||||
|
if (!response) throw new Error("The background page did not respond. Reload the extension and try again.");
|
||||||
if (response?.error) throw new Error(response.error);
|
if (response?.error) throw new Error(response.error);
|
||||||
currentSettings = response.settings;
|
currentSettings = response.settings;
|
||||||
renderSubscriptions(currentSettings);
|
renderSubscriptions(currentSettings);
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,21 @@ describe("DefinitionEngine", () => {
|
||||||
expect(observed).toContain("content warning revealed text");
|
expect(observed).toContain("content warning revealed text");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("discovers Threads posts appended after observation starts", async () => {
|
||||||
|
document.body.innerHTML = '<main><div role="article"><span dir="auto">Initial post</span></div></main>';
|
||||||
|
const threads = BUILTIN_DEFINITIONS.find((candidate) => candidate.id === "threads")!;
|
||||||
|
const engine = new DefinitionEngine(threads);
|
||||||
|
const observed: string[] = [];
|
||||||
|
const stop = engine.observe((posts) => observed.push(...posts.map((post) => post.text)));
|
||||||
|
const post = document.createElement("div");
|
||||||
|
post.setAttribute("role", "article");
|
||||||
|
post.innerHTML = '<span dir="auto">Scrolled-in post</span>';
|
||||||
|
document.querySelector("main")?.append(post);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
stop();
|
||||||
|
expect(observed).toContain("scrolled-in post");
|
||||||
|
});
|
||||||
|
|
||||||
it("discovers Threads posts from stable semantic/data selectors and permalink IDs", () => {
|
it("discovers Threads posts from stable semantic/data selectors and permalink IDs", () => {
|
||||||
document.body.innerHTML = readFileSync("tests/fixtures/threads-feed.html", "utf8");
|
document.body.innerHTML = readFileSync("tests/fixtures/threads-feed.html", "utf8");
|
||||||
const threads = BUILTIN_DEFINITIONS.find((candidate) => candidate.id === "threads")!;
|
const threads = BUILTIN_DEFINITIONS.find((candidate) => candidate.id === "threads")!;
|
||||||
|
|
@ -71,7 +86,7 @@ describe("DefinitionEngine", () => {
|
||||||
|
|
||||||
it("selects Threads on current and legacy domains", () => {
|
it("selects Threads on current and legacy domains", () => {
|
||||||
const threads = BUILTIN_DEFINITIONS.find((candidate) => candidate.id === "threads")!;
|
const threads = BUILTIN_DEFINITIONS.find((candidate) => candidate.id === "threads")!;
|
||||||
document.body.innerHTML = '<div data-pressable-container="true"></div>';
|
document.body.innerHTML = '<div role="article" data-pressable-container="true"></div>';
|
||||||
for (const url of ["https://threads.com/home", "https://www.threads.com/@alice/post/ABC123", "https://threads.net/home", "https://www.threads.net/@alice/post/ABC123"]) {
|
for (const url of ["https://threads.com/home", "https://www.threads.com/@alice/post/ABC123", "https://threads.net/home", "https://www.threads.net/@alice/post/ABC123"]) {
|
||||||
expect(selectDefinition([threads], url)).toBe(threads);
|
expect(selectDefinition([threads], url)).toBe(threads);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
tests/fixtures/threads-feed.html
vendored
2
tests/fixtures/threads-feed.html
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
<main>
|
<main>
|
||||||
<div data-pressable-container="true">
|
<div role="article" data-pressable-container="true">
|
||||||
<a href="/@alice"><span dir="auto">alice</span></a>
|
<a href="/@alice"><span dir="auto">alice</span></a>
|
||||||
<a href="/@alice/post/ABC123"><time><span dir="auto">12h</span></time></a>
|
<a href="/@alice/post/ABC123"><time><span dir="auto">12h</span></time></a>
|
||||||
<span dir="auto">First Threads post with <span>visible text</span></span>
|
<span dir="auto">First Threads post with <span>visible text</span></span>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue