Merge branch 'hueyy-fix/v4_bugs'

This commit is contained in:
rugk 2022-12-13 11:37:28 +01:00
commit 5e014f3a52
No known key found for this signature in database
GPG key ID: BE52D11B43801061
5 changed files with 69 additions and 42 deletions

View file

@ -156,11 +156,11 @@
}, },
"optionRedirectInMainWindow": { "optionRedirectInMainWindow": {
"message": "Verhindere die Nutzung eines Popups.", "message": "In aktuellem Tab umleiten.",
"description": "This is an option shown in the add-on settings." "description": "This is an option shown in the add-on settings."
}, },
"optionRedirectInMainWindowDescr": { "optionRedirectInMainWindowDescr": {
"message": "Verhindert die Benutzung eines extra Fensters und leitet stattdessen die Hauptseite um.", "message": "Verhindert die Benutzung eines extra Tabs und leitet stattdessen die Hauptseite um.",
"description": "This is an option shown in the add-on settings." "description": "This is an option shown in the add-on settings."
}, },

View file

@ -156,11 +156,11 @@
}, },
"optionRedirectInMainWindow": { "optionRedirectInMainWindow": {
"message": "Prevent popup usage.", "message": "Redirect in main window.",
"description": "This is an option shown in the add-on settings." "description": "This is an option shown in the add-on settings."
}, },
"optionRedirectInMainWindowDescr": { "optionRedirectInMainWindowDescr": {
"message": "Prevents the use of an extra window and instead redirects the action on the main page.", "message": "Prevents the use of an extra tab and instead redirects the action on the main page.",
"description": "This is an option shown in the add-on settings." "description": "This is an option shown in the add-on settings."
}, },
"translatorCredit": { "translatorCredit": {

View file

@ -155,8 +155,8 @@ async function onTabUpdate(tabId, changeInfo) {
const ownMastodon = await AddonSettings.get("ownMastodon"); const ownMastodon = await AddonSettings.get("ownMastodon");
const currentURL = new URL(changeInfo.url); const currentURL = new URL(changeInfo.url);
if (ownMastodon.server !== currentURL.hostname){ if (ownMastodon.server !== currentURL.hostname){
browser.tabs.executeScript({ browser.tabs.executeScript(tabId, {
file: "/content_script/mastodonInject.js" file: "/content_script/mastodonInject.js",
}); });
} }
} }

View file

@ -1,7 +1,5 @@
"use strict"; "use strict";
const TIMEOUT_DURATION = 20000;
/** /**
* Replacement onClick handler for Follow button. * Replacement onClick handler for Follow button.
* *
@ -26,10 +24,14 @@ function onClickInteract(event) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
const articleElement = event.target.closest("article[data-id]"); const articleElement = event.target.closest("article[data-id]");
const getId = () => {
const rawId = articleElement.getAttribute("data-id");
return rawId.slice(0, 2) === "f-" ? rawId.slice(2) : rawId;
};
const tootId = ( const tootId = (
articleElement === null articleElement === null
? window.location.pathname.split("/").slice(-1)[0] ? window.location.pathname.split("/").slice(-1)[0]
: articleElement.getAttribute("data-id") : getId()
); );
// activate AutoRemoteFollow // activate AutoRemoteFollow
window.open(`/interact/${tootId}`, "_blank"); window.open(`/interact/${tootId}`, "_blank");
@ -40,12 +42,12 @@ function onClickInteract(event) {
* *
* @param {string} selector * @param {string} selector
* @param {boolean} [multiple=false] * @param {boolean} [multiple=false]
* @param {number} timeoutDuration * @param {number} [timeoutDuration=200000]
* @see {@link https://github.com/storybookjs/test-runner/blob/6d41927154e8dd1e4c9e7493122e24e2739a7a0f/src/setup-page.ts#L134} * @see {@link https://github.com/storybookjs/test-runner/blob/6d41927154e8dd1e4c9e7493122e24e2739a7a0f/src/setup-page.ts#L134}
* from which this was adapted * from which this was adapted
* @returns {Promise} * @returns {Promise}
*/ */
function waitForElement(selector, multiple = false, timeoutDuration) { function waitForElement(selector, multiple = false, timeoutDuration = 200000) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const getElement = () => ( const getElement = () => (
multiple multiple
@ -59,14 +61,14 @@ function waitForElement(selector, multiple = false, timeoutDuration) {
}, timeoutDuration); }, timeoutDuration);
const element = getElement(); const element = getElement();
if (isElementFound(element)){ if (isElementFound(element)) {
window.clearTimeout(timeout); window.clearTimeout(timeout);
return resolve(element); return resolve(element);
} }
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
const element = getElement(); const element = getElement();
if (isElementFound(element)){ if (isElementFound(element)) {
window.clearTimeout(timeout); window.clearTimeout(timeout);
resolve(element); resolve(element);
observer.disconnect(); observer.disconnect();
@ -89,7 +91,7 @@ function waitForElement(selector, multiple = false, timeoutDuration) {
*/ */
async function injectFollowButton() { async function injectFollowButton() {
try { try {
const followButton = await waitForElement("#mastodon .account__header__tabs__buttons button:first-of-type", false, TIMEOUT_DURATION); const followButton = await waitForElement("#mastodon .account__header__tabs__buttons button:first-of-type", false);
followButton.addEventListener("click", onClickFollow); followButton.addEventListener("click", onClickFollow);
} catch (error) { } catch (error) {
// Follow button failed to appear // Follow button failed to appear
@ -103,22 +105,30 @@ async function injectFollowButton() {
*/ */
async function injectInteractionButtons() { async function injectInteractionButtons() {
const INJECTED_REPLY_CLASS = "mastodon-simplified-federation-injected-interaction"; const INJECTED_REPLY_CLASS = "mastodon-simplified-federation-injected-interaction";
const replyButtons = await waitForElement( const TIMELINE_SELECTOR = "#mastodon .item-list[role='feed'] article[data-id] .status__action-bar button"; // timeline / user profile
"#mastodon .item-list[role='feed'] article[data-id] .status__action-bar button," + const STATUS_NO_REPLIES_SELECTOR = "#mastodon .detailed-status__wrapper .detailed-status__action-bar button"; // status with no replies
"#mastodon .detailed-status__wrapper .detailed-status__action-bar button", const STATUS_WITH_REPLIES_SELECTOR = "#mastodon .status__wrapper .status__action-bar button"; // status with replies
true, try {
TIMEOUT_DURATION, const replyButtons = await waitForElement([
); TIMELINE_SELECTOR,
replyButtons.forEach((button) => { STATUS_NO_REPLIES_SELECTOR,
try { STATUS_WITH_REPLIES_SELECTOR,
if (!button.classList.contains(INJECTED_REPLY_CLASS)){ ].join(","), true,);
button.addEventListener("click", onClickInteract); replyButtons.forEach((button) => {
button.classList.add(INJECTED_REPLY_CLASS); try {
if (!button.classList.contains(INJECTED_REPLY_CLASS)) {
button.addEventListener("click", onClickInteract);
button.classList.add(INJECTED_REPLY_CLASS);
}
} catch (error) {
// Failed to inject interaction buttons
} }
} catch (error) { });
// Interaction buttons failed to appear } catch (error) {
} // Interaction buttons failed to appear
}); }
} }
/** /**
@ -126,23 +136,40 @@ async function injectInteractionButtons() {
* *
* @returns {void} * @returns {void}
*/ */
function initInjections() {
injectFollowButton().catch(console.error);
injectInteractionButtons().catch(console.error);
}
/**
* Initialise script and re-run if there are changes.
*
* @returns {void}
*/
async function init() { async function init() {
injectFollowButton(); const MASTODON_INJECTED_CLASS = "mastodon-simplified-federation-injected";
if (document.body.classList.contains(MASTODON_INJECTED_CLASS)) {
// init has already run
return;
}
document.body.classList.add(MASTODON_INJECTED_CLASS);
initInjections();
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
Promise.allSettled([ initInjections();
injectInteractionButtons(),
]);
}); });
const feedElement = await waitForElement( // monitor only the main column in the Mastodon UI
"#mastodon .item-list[role='feed']", const mainColumn = await waitForElement(
"#mastodon .ui",
false, false,
TIMEOUT_DURATION
); );
observer.observe(feedElement, { observer.observe(mainColumn, {
childList: true, subtree: true, childList: true,
subtree: true,
}); });
} }
init(); init().catch(console.error);

View file

@ -71,10 +71,10 @@
<li> <li>
<div class="line"> <div class="line">
<input class="setting save-on-change" type="checkbox" id="redirectInMainWindow" name="redirectInMainWindow"> <input class="setting save-on-change" type="checkbox" id="redirectInMainWindow" name="redirectInMainWindow">
<label data-i18n="__MSG_optionRedirectInMainWindow__" for="redirectInMainWindow">Prevent popup usage</label> <label data-i18n="__MSG_optionRedirectInMainWindow__" for="redirectInMainWindow">Redirect in current tab.</label>
</div> </div>
<div class="line indent"> <div class="line indent">
<span data-i18n="__MSG_optionRedirectInMainWindowDescr__" class="helper-text">Prevents the use of an extra window and instead redirects the action on the main page.</span> <span data-i18n="__MSG_optionRedirectInMainWindowDescr__" class="helper-text">Prevents the use of an extra tab and instead redirects the action on the main page.</span>
</div> </div>
<div class="message-container line indent"> <div class="message-container line indent">
<div id="redirectInMainWindowPermissionInfo" aria-label="info message" data-i18n data-i18n-aria-label="__MSG_ariaMessageInfo__" class="message-box info invisible fade-hide"> <div id="redirectInMainWindowPermissionInfo" aria-label="info message" data-i18n data-i18n-aria-label="__MSG_ariaMessageInfo__" class="message-box info invisible fade-hide">