feat: inject content script to handle follows from remote v4 Mastodon instances
This commit is contained in:
parent
b7259e0baa
commit
b61dbc4a57
2 changed files with 113 additions and 0 deletions
|
@ -144,6 +144,15 @@ function getInteractionType(url) {
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles changes to the URL of a tab
|
||||||
|
*/
|
||||||
|
function onTabUpdate() {
|
||||||
|
browser.tabs.executeScript(null, {
|
||||||
|
file: `/content_script/mastodonInject.js`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init AutoRemoteFollower module.
|
* Init AutoRemoteFollower module.
|
||||||
*
|
*
|
||||||
|
@ -154,6 +163,10 @@ function init() {
|
||||||
NetworkTools.webRequestListen(["http://*/*", "https://*/*"], "onBeforeRequest", (requestDetails) => {
|
NetworkTools.webRequestListen(["http://*/*", "https://*/*"], "onBeforeRequest", (requestDetails) => {
|
||||||
return handleWebRequest(requestDetails).catch(handleError).catch(console.error);
|
return handleWebRequest(requestDetails).catch(handleError).catch(console.error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
browser.tabs.onUpdated.addListener(onTabUpdate, {
|
||||||
|
properties: ["url"]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
100
src/content_script/mastodonInject.js
Normal file
100
src/content_script/mastodonInject.js
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
* @typedef {Object} VersionNumber
|
||||||
|
* @property {string} major
|
||||||
|
* @property {string} minor
|
||||||
|
* @property {string} patch
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parses a versionNumber string
|
||||||
|
* @returns {VersionNumber}
|
||||||
|
*/
|
||||||
|
function parseVersionNumber() {
|
||||||
|
const versionElement = document.querySelector(`.link-footer`).textContent
|
||||||
|
const versionNumber = versionElement.match(/v?(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)$/)
|
||||||
|
return versionNumber.groups
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replacement onClick handler for Follow button
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
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} timeout
|
||||||
|
*/
|
||||||
|
function waitForElement (selector, timeout) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
function getElement() {
|
||||||
|
return document.querySelector(selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
const element = getElement()
|
||||||
|
if(element){
|
||||||
|
return resolve(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new MutationObserver(() => {
|
||||||
|
const element = getElement()
|
||||||
|
if(element){
|
||||||
|
resolve(element)
|
||||||
|
observer.disconnect()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
})
|
||||||
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
reject()
|
||||||
|
}, timeout)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject replacement onClick handler for Follow button
|
||||||
|
*/
|
||||||
|
async function injectFollowButton () {
|
||||||
|
try {
|
||||||
|
const followButton = await waitForElement(`.account__header__tabs__buttons button.button`, 20000)
|
||||||
|
followButton.addEventListener(`click`, onClickFollow)
|
||||||
|
} catch {
|
||||||
|
// Follow button failed to appear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init () {
|
||||||
|
let versionNumber
|
||||||
|
|
||||||
|
try {
|
||||||
|
const initialStateObject = JSON.parse(document.getElementById(`initial-state`).innerHTML)
|
||||||
|
const version = initialStateObject?.meta?.version
|
||||||
|
if(!initialStateObject || !version){
|
||||||
|
// not a Mastodon server
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
versionNumber = parseVersionNumber(version)
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(Number.parseInt(versionNumber.major) >= 4){
|
||||||
|
await injectFollowButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
Loading…
Add table
Add a link
Reference in a new issue