Compare commits
No commits in common. "99180035e3d974aa4adfcb15d9d516b705e5089d" and "809943edcc01fc3c81ec59ebdfabfb7f8669656a" have entirely different histories.
99180035e3
...
809943edcc
|
@ -35,10 +35,9 @@ const sourceDir = toAbsolutePath("../source");
|
||||||
await fsp.mkdir(outDir, {recursive: true});
|
await fsp.mkdir(outDir, {recursive: true});
|
||||||
|
|
||||||
// Write the WebExtension manifest file.
|
// Write the WebExtension manifest file.
|
||||||
const manifest = createManifest(browser);
|
|
||||||
await fsp.writeFile(
|
await fsp.writeFile(
|
||||||
path.join(outDir, "manifest.json"),
|
path.join(outDir, "manifest.json"),
|
||||||
JSON.stringify(manifest),
|
JSON.stringify(createManifest(browser)),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Write the web-ext configuration file.
|
// Write the web-ext configuration file.
|
||||||
|
@ -74,7 +73,6 @@ const options: esbuild.BuildOptions = {
|
||||||
$browser: JSON.stringify(browser),
|
$browser: JSON.stringify(browser),
|
||||||
$dev: JSON.stringify(dev),
|
$dev: JSON.stringify(dev),
|
||||||
$test: JSON.stringify(test),
|
$test: JSON.stringify(test),
|
||||||
$version: JSON.stringify(manifest.version),
|
|
||||||
},
|
},
|
||||||
entryPoints: [
|
entryPoints: [
|
||||||
path.join(sourceDir, "background/setup.ts"),
|
path.join(sourceDir, "background/setup.ts"),
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import {Component, render} from "preact";
|
import {Component, render} from "preact";
|
||||||
import {
|
import {log, pluralize, querySelectorAll} from "../../utilities/exports.js";
|
||||||
log,
|
|
||||||
makeIntercoolerRequest,
|
|
||||||
pluralize,
|
|
||||||
querySelectorAll,
|
|
||||||
} from "../../utilities/exports.js";
|
|
||||||
|
|
||||||
export function runGroupListSubscribeButtonFeature(): void {
|
export function runGroupListSubscribeButtonFeature(): void {
|
||||||
const count = addSubscribeButtonsToGroupList();
|
const count = addSubscribeButtonsToGroupList();
|
||||||
|
@ -19,6 +14,14 @@ function addSubscribeButtonsToGroupList(): number {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const csrfToken = document.querySelector<HTMLMetaElement>(
|
||||||
|
'meta[name="csrftoken"]',
|
||||||
|
)?.content;
|
||||||
|
if (csrfToken === undefined) {
|
||||||
|
log("No CSRF token found", true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (const listItem of querySelectorAll<HTMLLIElement>(
|
for (const listItem of querySelectorAll<HTMLLIElement>(
|
||||||
".group-list li:not(.trx-group-list-subscribe-button)",
|
".group-list li:not(.trx-group-list-subscribe-button)",
|
||||||
|
@ -31,7 +34,14 @@ function addSubscribeButtonsToGroupList(): number {
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = document.createDocumentFragment();
|
const button = document.createDocumentFragment();
|
||||||
render(<SubscribeButton group={group} listItem={listItem} />, button);
|
render(
|
||||||
|
<SubscribeButton
|
||||||
|
csrfToken={csrfToken}
|
||||||
|
group={group}
|
||||||
|
listItem={listItem}
|
||||||
|
/>,
|
||||||
|
button,
|
||||||
|
);
|
||||||
|
|
||||||
const activity =
|
const activity =
|
||||||
listItem.querySelector(".group-list-activity") ?? undefined;
|
listItem.querySelector(".group-list-activity") ?? undefined;
|
||||||
|
@ -49,6 +59,7 @@ function addSubscribeButtonsToGroupList(): number {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
csrfToken: string;
|
||||||
listItem: HTMLLIElement;
|
listItem: HTMLLIElement;
|
||||||
group: string;
|
group: string;
|
||||||
};
|
};
|
||||||
|
@ -69,15 +80,21 @@ class SubscribeButton extends Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
clickHandler = async () => {
|
clickHandler = async () => {
|
||||||
const {group} = this.props;
|
const {csrfToken, group} = this.props;
|
||||||
const {isSubscribed} = this.state;
|
const {isSubscribed} = this.state;
|
||||||
|
|
||||||
const response = await makeIntercoolerRequest(
|
const response = await window.fetch(
|
||||||
`https://tildes.net/api/web/group/${group}/subscribe`,
|
`https://tildes.net/api/web/group/${group}/subscribe`,
|
||||||
{
|
{
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-Token": csrfToken,
|
||||||
|
"X-IC-Request": "true",
|
||||||
|
},
|
||||||
method: isSubscribed ? "DELETE" : "PUT",
|
method: isSubscribed ? "DELETE" : "PUT",
|
||||||
|
referrer: "https://tildes.net",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
log(`Unexpected status code: ${response.status}`, true);
|
log(`Unexpected status code: ${response.status}`, true);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,5 +12,4 @@ declare global {
|
||||||
const $browser: "chromium" | "firefox";
|
const $browser: "chromium" | "firefox";
|
||||||
const $dev: boolean;
|
const $dev: boolean;
|
||||||
const $test: boolean;
|
const $test: boolean;
|
||||||
const $version: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ export * from "./components/link.js";
|
||||||
export * from "./elements.js";
|
export * from "./elements.js";
|
||||||
export * from "./globals.js";
|
export * from "./globals.js";
|
||||||
export * from "./groups.js";
|
export * from "./groups.js";
|
||||||
export * from "./http.js";
|
|
||||||
export * from "./logging.js";
|
export * from "./logging.js";
|
||||||
export * from "./query-selectors.js";
|
export * from "./query-selectors.js";
|
||||||
export * from "./report-a-bug.js";
|
export * from "./report-a-bug.js";
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
import {log} from "./logging.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make an HTTP request to the Tildes API that is normally used by Intercooler.
|
|
||||||
* This should only be used when using HTML elements from Tildes itself isn't
|
|
||||||
* feasible.
|
|
||||||
* @param url The API URL to call.
|
|
||||||
* @param request Any extra request details, note that some of these values will
|
|
||||||
* be overridden by the ones required to make a proper Intercooler request.
|
|
||||||
*/
|
|
||||||
export async function makeIntercoolerRequest(
|
|
||||||
url: string,
|
|
||||||
request: RequestInit,
|
|
||||||
): Promise<Response> {
|
|
||||||
if (!url.startsWith("https://tildes.net")) {
|
|
||||||
throw new Error(`Can't make Intercooler request to non-Tildes URL: ${url}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const csrfToken = document.querySelector<HTMLMetaElement>(
|
|
||||||
'meta[name="csrftoken"]',
|
|
||||||
)!.content;
|
|
||||||
|
|
||||||
const ic: RequestInit = {
|
|
||||||
headers: {
|
|
||||||
// Change the user agent and add an extra header so it's clear this isn't
|
|
||||||
// a request actually sent by Intercooler but by Tildes ReExtended.
|
|
||||||
"User-Agent": `Tildes ReExtended (${$browser}, version ${$version})`,
|
|
||||||
"X-CSRF-Token": csrfToken,
|
|
||||||
"X-IC-Request": "true",
|
|
||||||
"X-TRX-Request": "true",
|
|
||||||
},
|
|
||||||
referrer: "https://tildes.net",
|
|
||||||
};
|
|
||||||
|
|
||||||
request.headers =
|
|
||||||
request.headers === undefined
|
|
||||||
? ic.headers
|
|
||||||
: {
|
|
||||||
...request.headers,
|
|
||||||
// Apply the Intercooler headers last so they can't be overridden.
|
|
||||||
...ic.headers,
|
|
||||||
};
|
|
||||||
|
|
||||||
request.referrer = request.referrer ?? ic.referrer;
|
|
||||||
|
|
||||||
// Explicitly log the request because content script HTTP calls don't show up
|
|
||||||
// in the Network DevTools.
|
|
||||||
log("Making Intercooler request:");
|
|
||||||
log(request);
|
|
||||||
return window.fetch(url, request);
|
|
||||||
}
|
|
Loading…
Reference in New Issue