Merge pull request #82 from hueyy/feature/support_v4

feat: inject content script to handle follows from remote v4 Mastodon instances
This commit is contained in:
rugk 2022-11-23 23:59:50 +01:00 committed by GitHub
commit 415a50fac1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 0 deletions

View file

@ -144,6 +144,17 @@ function getInteractionType(url) {
return [null, null];
}
/**
* Handles changes to the URL of a tab.
*
* @returns {void}
*/
function onTabUpdate() {
browser.tabs.executeScript({
file: "/content_script/mastodonInject.js"
});
}
/**
* Init AutoRemoteFollower module.
*
@ -154,6 +165,10 @@ function init() {
NetworkTools.webRequestListen(["http://*/*", "https://*/*"], "onBeforeRequest", (requestDetails) => {
return handleWebRequest(requestDetails).catch(handleError).catch(console.error);
});
browser.tabs.onUpdated.addListener(onTabUpdate, {
properties: ["url"]
});
}
init();

View file

@ -0,0 +1,81 @@
"use strict";
/**
* Replacement onClick handler for Follow button.
*
* @param {Event} event
* @returns {void}
*/
function onClickFollow(event) {
event.stopPropagation();
event.preventDefault();
const username = window.location.pathname.split("/").slice(-1)[0];
// activate AutoRemoteFollow
window.open(`/users/${username}/remote_follow`, "_blank");
}
/**
* Wait for element to appear.
*
* @param {string} selector
* @param {number} timeoutDuration
* @see {@link https://github.com/storybookjs/test-runner/blob/6d41927154e8dd1e4c9e7493122e24e2739a7a0f/src/setup-page.ts#L134}
* from which this was adapted
* @returns {Promise}
*/
function waitForElement(selector, timeoutDuration) {
return new Promise((resolve, reject) => {
const getElement = () => document.querySelector(selector);
const timeout = window.setTimeout(() => {
reject(new Error("waitForElement timed out"));
}, timeoutDuration);
const element = getElement();
if(element){
window.clearTimeout(timeout);
return resolve(element);
}
const observer = new MutationObserver(() => {
const element = getElement();
if(element){
window.clearTimeout(timeout);
resolve(element);
observer.disconnect();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
return null;
});
}
/**
* Inject replacement onClick handler for Follow button.
*
* @returns {void}
*/
async function injectFollowButton() {
try {
const followButton = await waitForElement(".account__header__tabs__buttons button:first-of-type", 20000);
followButton.addEventListener("click", onClickFollow);
} catch (error) {
// Follow button failed to appear
}
}
/**
* Initialise injection for Mastodon Follow button.
*
* @returns {void}
*/
async function init() {
await injectFollowButton();
}
init();