Porównaj commity

...

75 Commity

Autor SHA1 Wiadomość Data
Lartsch 22e3be13cb
Update README.md 2023-05-15 16:56:29 +02:00
Lartsch 97f9c10872
Update README.md 2023-05-15 16:56:19 +02:00
Lartsch 053af951bc
Merge pull request #65 from wlonkly/firefox-animations
namespace animations to avoid conflicts
2023-04-06 08:51:51 +02:00
Lartsch e0fbc804cc
Update README.md 2023-04-06 08:50:56 +02:00
Lartsch 6a9028afe0
Update README.md 2023-04-06 08:50:20 +02:00
Rich Lafferty 2289637543
minify 2023-01-22 00:02:19 -04:00
Rich Lafferty 8766852c9d
namespace animations 2023-01-22 00:02:19 -04:00
Lartsch 75cd8bb25a
Merge pull request #60 from ZeroEcks/main
Fix title of menu item to prevent confusion about the name of the plugin
2023-01-14 12:35:13 +00:00
Melody 7050e7b735
Fix title of menu item to prevent confusion about the name of the plugin 2023-01-09 13:17:23 +10:00
Lartsch f42eb8fd28
Merge pull request #53 from Freeplayg/main
Add https:// hint to Home Server Domain input
2023-01-02 20:33:08 +01:00
Freeplayg 15d59f96ea 5px in outline property wasn't needed 2023-01-02 14:31:23 -05:00
Freeplayg 6889c46fc0 Add https:// hint to Home Server Domain input 2023-01-02 12:25:44 -05:00
lartsch 2522f3f05c move in if 2022-12-29 11:12:33 -05:00
lartsch 0e20ff2f98 fix toot buttons in feed views when returning from redirect in "_self" mode, bump version 2022-12-29 10:47:09 -05:00
lartsch f23e7be502 improve 429 prevention (async limit), add ua 2022-12-29 10:10:59 -05:00
lartsch 95ec910c99 remove debug change 2022-12-29 06:41:53 -05:00
lartsch b6e75774b9 fix spinner icon for some browsers (switch to svg) 2022-12-29 06:40:21 -05:00
lartsch 90ad7818f4 increase api delay a little, use new Date.now() 2022-12-29 05:22:35 -05:00
lartsch 0276c2e06a increase API delay a little 2022-12-29 05:18:04 -05:00
lartsch 8926e8ad80 add content-type check, add cross browser prefixes 2022-12-29 05:11:29 -05:00
Lartsch 80cbbdf631
Merge pull request #47 from Freeplayg/main
Firefox prefences page fixes (for now w/ a temp fix)
2022-12-29 10:57:01 +01:00
Freeplayg 79a2e068a0 Firefox prefences page fixes (w/ a temp fix)
- Fixed unreadable text in dark mode
- Temporary fix for the height, still have no idea what to really do about that
2022-12-28 20:11:10 -05:00
Lartsch 8a347f3afd
Update readme 2022-12-27 13:07:41 +01:00
Lartsch 7e56a3dc86
Update readme 2022-12-27 13:06:00 +01:00
Lartsch 5508847693
Update README.md 2022-12-25 21:28:51 +01:00
Lartsch 5f2ebeaa43
Update README.md 2022-12-25 21:26:34 +01:00
Lartsch 34a1e3964c
Update README.md 2022-12-25 21:07:36 +01:00
Lartsch 5c4f23ac75
Update README.md 2022-12-25 21:06:59 +01:00
Lartsch 7f6fd11715
Update README.md 2022-12-25 21:06:06 +01:00
Lartsch e87bd47439
Update README.md 2022-12-25 21:04:32 +01:00
lartsch 8624ca560f use closure 2022-12-25 14:47:28 -05:00
lartsch 222b6b9809 bump version 2022-12-25 14:22:47 -05:00
lartsch 999b0ded7b fix modal related stuff 2022-12-25 14:21:48 -05:00
lartsch 89f4d7d423 adjust styles, change descriptions 2022-12-25 06:45:20 -05:00
Lartsch d59b6d0ea5
Merge pull request #39 from Freeplayg/main
Fix accessability issue in extension popup
2022-12-25 12:32:07 +01:00
Lartsch df1115891d
Merge pull request #40 from MarckK/patch-1
Small edit
2022-12-24 23:45:32 +01:00
Kara de la Marck e1b24eeb11
Small edit
Thank you for this browser extension!
2022-12-24 14:28:20 -05:00
Freeplayg 1d77003d08 Fix accessability issue 2022-12-24 11:03:26 -05:00
Lartsch 6c9209ce61
Update README.md 2022-12-24 12:44:51 +01:00
Lartsch f600741d1f
Update README.md 2022-12-24 12:44:17 +01:00
Lartsch b9aa91c130
Merge pull request #37 from LeviSnoot/main
(fix)updated media
2022-12-24 12:43:50 +01:00
Lartsch b1fa9f1f94
Merge pull request #38 from Freeplayg/main
Using a loading icon instead of resolving text
2022-12-24 12:42:13 +01:00
Freeplayg 115ba5503a Using a loading icon instead of resolving text 2022-12-23 22:26:58 -05:00
Levi c734b16252 (fix)version number for new media 2022-12-23 12:44:28 +01:00
Levi dfff64b98c (fix)updated media 2022-12-23 12:42:14 +01:00
Lartsch 4bc6b568df
Merge pull request #34 from Freeplayg/main
Improvements to the modal menu
2022-12-22 10:35:18 +01:00
Lartsch ababef902c
Merge pull request #36 from Freeplayg/patch-1
Update tooltip name
2022-12-22 10:27:31 +01:00
Freeplay 6a83649c98
Update tooltip name 2022-12-21 20:48:04 -05:00
Freeplayg 712e0c08c5 .hide class wasn't needed oops 2022-12-21 20:00:12 -05:00
Freeplayg 2d9a99ead3 Also forgot to compile, oops 2022-12-21 19:25:51 -05:00
Freeplayg 2c99b76e41 Forgot about when failed, oops 2022-12-21 19:25:17 -05:00
Freeplayg e2d0ec34a6 Improvements to the modal menu 2022-12-21 19:16:52 -05:00
lartsch 3a5809d73d change "Unresolved" to an "X" to save space 2022-12-21 09:00:15 -05:00
lartsch 379b67569b move all requests to background, support polls behind CWs, add important to some CSS 2022-12-21 08:47:07 -05:00
lartsch 7d774079ef Merge branch 'main' of https://github.com/Lartsch/FediFollow-Chrome 2022-12-21 06:09:55 -05:00
lartsch de4f1ad1dd add descriptions for deny/allow mode 2022-12-21 06:09:53 -05:00
Lartsch 1b545b7750
Update README.md 2022-12-21 11:58:30 +01:00
Lartsch 3aed3ee81c
Update README.md 2022-12-20 18:19:06 -05:00
lartsch 608e336141 re-add line for firefox 2022-12-20 18:15:11 -05:00
lartsch 85dab0ce6a add indicator in modal if when action was successful/not, always turn off specific event handler only 2022-12-20 18:10:33 -05:00
lartsch d99d7bf48c Add "Copy URL" and "Copy home URL" to modal 2022-12-20 17:58:46 -05:00
lartsch 4616f38bda Merge branch 'main' of https://github.com/Lartsch/FediFollow-Chrome 2022-12-20 17:37:13 -05:00
lartsch 65f560b110 "padding" for options 2022-12-20 17:37:12 -05:00
Lartsch 2dbce769f0
Update README.md 2022-12-20 23:29:44 +01:00
Lartsch 42f51bd72a
Update README.md 2022-12-20 23:28:20 +01:00
Lartsch 4e296ec9dc
Update README.md 2022-12-20 23:27:47 +01:00
Lartsch 5c3a948907
Update README.md 2022-12-20 23:24:40 +01:00
lartsch 8f2450f79b remove line, re-add meta viewport 2022-12-20 17:14:06 -05:00
lartsch 4718d82610 remove blank line, commented line 2022-12-20 15:22:04 -05:00
lartsch 6ccd307c6e Merge branch 'main' of https://github.com/Lartsch/FediFollow-Chrome 2022-12-20 15:16:20 -05:00
lartsch ff0a65943e cross-browser css prefixes 2022-12-20 15:16:18 -05:00
Lartsch 0efe348b1d
Update README.md 2022-12-20 20:15:27 +01:00
Lartsch 9321998193
Update README.md 2022-12-20 19:18:06 +01:00
Lartsch e6bee33825
Update README.md 2022-12-20 19:17:23 +01:00
lartsch 250e0b0ec0 bump version 2022-12-20 13:02:49 -05:00
16 zmienionych plików z 690 dodań i 342 usunięć

Wyświetl plik

@ -1,52 +1,46 @@
> **Note**
> LOOKING FOR AN ACTIVE MAINTAINER TO TAKE CARE OF THIS PROJECT!
> FediAct requires some major updates/rewriting to resolve issues, increase performance/reliability and to be easier to maintain, for which I do not have time currently. Please leave a message/issue.
# FediAct (v0.9.8)
A Chrome/Firefox extension that simplifies follow and post interactions on Mastodon servers other than your own.
**Features**:
- Supports Mastodon v3 + v4 (some features v4 only)
- Follow, boost, bookmark, reply, fav, vote polls and mute/block on external servers while only being logged in to your home server
- Show following status and toot status (boosted, faved, bookmarked) on external servers
- Show following state and toot state (boosted, faved, bookmarked, voted) on external servers
- Single click to execute action only, double click to redirect to content on home server
- Reply button on external servers always redirects to home server and enters reply-mode
- Hide muted content on external servers if enabled
- Customizable
**Supported browsers**:
- All up-to-date Chromium browsers, including Kiwi and Yandex browsers on Android
- Up-to-date Firefox (v107+), including Firefox Nightly on Android
**Important notes**:
- Data is processed locally only
- Performance depends on your home server and to some degree on the external server you are browsing (read more [below](#additional-notes))
- Some toots cannot be resolved to your home (in cases where searching for the post manually would not work either)
- Needs nothing more than your home server domain to work
## Navigation
* [Installation](#installation)
* [Setup](#setup)
* [FAQ](#faq)
* [Screenshots / GIFs](#screenshots--gifs)
* [Manual installation](#manual-installation)
* [Install in Firefox for Android](#install-in-firefox-for-android)
* [Additional notes](#additional-notes)
* [Todos / Planned features](#todos--planned-features)
* [Contributing](#contributing)
- [Installation](#installation)
- [Setup](#setup)
- [FAQ](#faq)
- [Screenshots / GIFs](#screenshots--gifs)
- [Manual installation](#manual-installation)
- [Install in Firefox for Android](#install-in-firefox-for-android)
- [Additional notes](#additional-notes)
- [Todos / Planned features](#todos--planned-features)
- [Contributing](#contributing)
## Installation
[link-chrome]: https://chrome.google.com/webstore/detail/fediact/lmpcajpkjcclkjbliapfjfolocffednm 'Version published on Chrome Web Store'
[link-firefox]: https://addons.mozilla.org/en-US/firefox/addon/fediact/ 'Version published on Mozilla Add-ons'
[<img src="https://raw.githubusercontent.com/alrra/browser-logos/90fdf03c/src/chrome/chrome.svg" width="48" alt="Chrome" valign="middle">][link-chrome] [<img valign="middle" src="https://img.shields.io/chrome-web-store/v/lmpcajpkjcclkjbliapfjfolocffednm.svg?label=%20">][link-chrome]
and other Chromium browsers
[<img src="https://raw.githubusercontent.com/alrra/browser-logos/90fdf03c/src/chrome/chrome.svg" width="48" alt="Chrome" valign="middle">][link-chrome] [<img valign="middle" src="https://img.shields.io/chrome-web-store/v/lmpcajpkjcclkjbliapfjfolocffednm.svg?label=%20">&nbsp;&nbsp;Chrome Webstore][link-chrome]
All up-to-date Chromium browsers, including Kiwi and Yandex browsers on Android
[<img src="https://raw.githubusercontent.com/alrra/browser-logos/90fdf03c/src/firefox/firefox.svg" width="48" alt="Firefox" valign="middle">][link-firefox] [<img valign="middle" src="https://img.shields.io/amo/v/fediact.svg?label=%20%20">][link-firefox]
including Nightly for Android
[<img src="https://raw.githubusercontent.com/alrra/browser-logos/90fdf03c/src/firefox/firefox.svg" width="48" alt="Firefox" valign="middle">][link-firefox] [<img valign="middle" src="https://img.shields.io/amo/v/fediact.svg?label=%20%20">&nbsp;&nbsp;Mozilla Addon Store][link-firefox]
Up-to-date Firefox (v107+), including Firefox Nightly on Android
> **Note**
>
> - **If webstore release is outdated, use the [manual installation method](#manual-installation) to install the latest version**
> - **Special installation steps for [Firefox on Android](#install-in-firefox-for-android)**
If you like this addon, please consider donating: [paypal.me/lartsch](https://paypal.me/lartsch)
**Please note:**
- If webstore release is outdated, use the [manual installation method](#manual-installation) to install the latest version
- Special installation steps for [Firefox on Android](#install-in-firefox-for-android)
- Chrome store updates take 1-2 days longer
- If you like this addon, please consider donating: [paypal.me/lartsch](https://paypal.me/lartsch)
## Setup
@ -54,37 +48,43 @@ If you like this addon, please consider donating: [paypal.me/lartsch](https://pa
2. Click the extension icon or open its settings page
3. Set your home server domain (required)
4. Check out the other settings (optional)
5. Click the "Submit" button to save
5. Click the "Save" button to save
If you have set your home server correctly, you can now interact on other Mastodon servers. If FediAct is running, a small icon will be displayed in the bottom right corner. Also, it is indicated while content is resolving / could not be resolved.
If you have set your home server correctly, you can now interact on other Mastodon servers.
**Please note:** It is NOT recommended to disable the API delay, since most servers use rate limiting and might block your IP if requests happen too frequent, which will lead to FediAct not working anymore.
**Please note:**
- If FediAct is running, a small icon will be displayed in the bottom right corner
- Also, it is indicated while content is resolving or when it could not be resolved
- Performance depends on your home server and the external server you are browsing (read more [below](#additional-notes))
- Some toots can't be resolved to your home (e.g. when searching the post manually wouldn't work either)
- It's NOT recommended to disable the API delay (servers use rate limiting and might block your IP)
## FAQ
**Why does it need permission for all websites?**
The addon needs to determine whether or not the site you are currently browsing is a Mastodon server. For that to work, it requires access to all sites. Otherwise, each existing Mastodon server would have to be explicitly added.
> The addon needs to determine whether or not the site you are currently browsing is a Mastodon server. For that to work, it requires access to all sites. Otherwise, each existing Mastodon server would have to be explicitly added.
**Can I use this on Android?**
Yes! There are three options that I am aware of: Kiwi Browser (Chromium with add-on support), Yandex Browser and Firefox Nightly (see [below](#install-in-firefox-for-android))
> Yes! There are three options that I am aware of: Kiwi Browser, Yandex Browser and Firefox Nightly (see [below](#install-in-firefox-for-android))
**Can I use this on iOS?**
Currently not in a reliable way, but:
- It's possible that Orion Browser can soon be used (see issue [#16](https://github.com/Lartsch/FediAct/issues/16))
- There are plans for Safari support (see issue [#17](https://github.com/Lartsch/FediAct/issues/17))
> Currently not in a reliable way, but:
> - It's possible that Orion Browser can soon be used (see issue [#16](https://github.com/Lartsch/FediAct/issues/16))
> - There are plans for Safari support (see issue [#17](https://github.com/Lartsch/FediAct/issues/17))
**Can you add feature XY?**
Feel free to create an issue here on GitHub and I will look into it.
> Feel free to create an issue here on GitHub and I will look into it.
**Is this safe to use?**
This project is open source. Anyone with some programming knowledge can check out the source code, either here on GitHub or by extracting the addon file from the addon stores.
Considering the implementation, I am not aware of any risks. Efforts were made to prevent servers from abusing this addon to perform actions on the user's behalf (which already was a really specific and rather low risk). All data is stored in your browser locally. The only sensitive data it stores is your API token. This token is **only** sent to your home server. No other data ever leaves your device. As far as I know, external servers cannot access the requests made by FediAct and can therefore not gain your token.
**Is this safe to use?**
> This project is open source. Anyone with some programming knowledge can check out the source code, either here on GitHub or by extracting the addon file from the addon stores. You can also make improvements.
> Considering the implementation, I am not aware of any risks. Efforts were made to prevent servers from abusing this addon to perform actions on the user's behalf. It does not require your username or password. All data is stored in your browser locally, with the API token being the only sensitive data. This token is **only** sent to your home server. No other data ever leaves your device. All requests are made from the background script, out-of-scope for websites you visit.
## Screenshots / GIFs
v0.8.0
v0.9.8
<details>
<summary>Extension popup / settings</summary>
<img src="https://github.com/lartsch/FediAct/blob/main/img/settings.png?raw=true">
@ -142,6 +142,7 @@ I included all of the default add-ons in the custom collection, so you will not
- That a toot is set to unlisted on its original server may play a role
3. There can be delays because API calls have to be made and it is tries to avoid error 429 (too many requests). Especially if a page has many toots or you are scrolling through a feed really fast.
4. If the extension fails to resolve content, the affected buttons will behave as if the extension weren't active (popup modal) and a notice ("Unresolved") is added to the toot
5. If "Collect errors" is enabled (Chrome), there can be uncatched errors being displayed for FediAct. This is not relevant to functionality.
## Todos / Planned features
Check out the [GitHub project](https://github.com/users/Lartsch/projects/2) to see planned features and todos. They are sorted from most important to least important.
@ -150,5 +151,6 @@ Check out the [GitHub project](https://github.com/users/Lartsch/projects/2) to s
Feel free to create [issues](https://github.com/Lartsch/FediAct/issues) for bugs and feature suggestions. Even better: Create pull requests for whatever improvements you can make! :)
## Thanks to...
@raikasdev because I stole his fix for cross-browser storage API support
@rosemarydotworld because I customized and use his awesome jQuery.DOMNodeAppear where MutationObservers and delegation failed
- @raikasdev because I stole his fix for cross-browser storage API support
- @rosemarydotworld because I customized and use his awesome jQuery.DOMNodeAppear where MutationObservers and delegation failed
- All the direct [contributors](https://github.com/Lartsch/FediAct/graphs/contributors) to this repository!

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "FediAct",
"version": "0.9.8.2",
"version": "0.9.8.7",
"description": "Simplifies interactions on other Mastodon instances than your own. Visit https://github.com/lartsch/FediAct for more.",
"manifest_version": 2,
"content_scripts": [
@ -37,7 +37,7 @@
"browser_action": {
"default_popup": "src/popup.html",
"default_icon": "src/icon/48.png",
"default_title": "FediFollow settings"
"default_title": "FediAct settings"
},
"icons": {
"48": "src/icon/48.png"

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 38 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 15 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 6.2 MiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.4 MiB

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "FediAct",
"version": "0.9.8.2",
"version": "0.9.8.7",
"description": "Simplifies interactions on other Mastodon instances than your own. Visit https://github.com/lartsch/FediAct for more.",
"manifest_version": 3,
"content_scripts": [
@ -36,9 +36,9 @@
"action": {
"default_popup": "src/popup.html",
"default_icon": "src/icon/48.png",
"default_title": "FediFollow settings"
"default_title": "FediAct settings"
},
"icons": {
"48": "src/icon/48.png"
}
}
}

Wyświetl plik

@ -1,17 +1,16 @@
var browser, chrome, settings
const enableConsoleLog = true
const enableConsoleLog = false
const logPrepend = "[FediAct]"
const tokenInterval = 1 // minutes
const mutesApi = "/api/v1/mutes"
const blocksApi = "/api/v1/blocks"
const domainBlocksApi = "/api/v1/domain_blocks"
const timeout = 15000
const tokenRegex = /"access_token":".*?",/gm
// required settings keys with defauls
const settingsDefaults = {
fediact_homeinstance: null
fediact_homeinstance: null,
fediact_token: null
}
// wrapper to prepend to log messages
@ -22,7 +21,7 @@ function log(text) {
}
// get redirect url (it will be the url on the toot authors home instance)
async function resolveToot(url) {
async function resolveExternalTootHome(url) {
return new Promise(async function(resolve) {
try {
const controller = new AbortController()
@ -44,6 +43,60 @@ async function resolveToot(url) {
})
}
// get redirect url (it will be the url on the toot authors home instance)
async function generalRequest(data) {
return new Promise(async function(resolve) {
try {
const controller = new AbortController()
const timeoutId = setTimeout(() => {
log("Timed out")
controller.abort()
}, timeout)
if (data[3]) {
// json body provided, post as body to target
data[2]["User-Agent"] = "FediAct Service"
data[2]["Content-Type"] = "application/json"
var res = await fetch(data[1], {
method: data[0],
signal: controller.signal,
// if json body is provided, there is also header data
headers: data[2],
body: JSON.stringify(data[3])
})
} else if (data[2]) {
// header data provided
data[2]["User-Agent"] = "FediAct Service"
var res = await fetch(data[1], {
method: data[0],
signal: controller.signal,
headers: data[2]
})
} else {
var res = await fetch(data[1], {
method: data[0],
signal: controller.signal,
headers: {"User-Agent": "FediAct Service"}
})
}
clearTimeout(timeoutId)
if (res.status >= 200 && res.status < 300 ) {
const contentType = res.headers.get("content-type")
if (contentType && contentType.indexOf("application/json") !== -1) {
var restext = await res.text()
resolve(restext)
} else {
resolve(false)
}
} else {
resolve(false)
}
} catch(e) {
log(e)
resolve(false)
}
})
}
// fetch API token here (will use logged in session automatically)
async function fetchBearerToken() {
return new Promise(async function(resolve) {
@ -85,51 +138,59 @@ async function fetchBearerToken() {
// this is only done here in the bg script so we have data available on load of pages without first performing 3 (!) requests
// otherwise this would lead to problems with element detection / low performance (espcially v3 instances)
// mutes/blocks are updated in content script on page context changes and after performing mutes/block actions
async function fetchMutesAndBlocks() {
function fetchMutesAndBlocks() {
return new Promise(async function(resolve) {
// set empty initially
[settings.fediact_mutes, settings.fediact_blocks, settings.fediact_domainblocks] = [[],[],[]]
var [mutes, blocks, domainblocks] = await Promise.all([
fetch("https://" + settings.fediact_homeinstance + mutesApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + blocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + domainBlocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json())
])
if (mutes.length) {
settings.fediact_mutes.push(...mutes.map(acc => acc.acct))
try {
// set empty initially
[settings.fediact_mutes, settings.fediact_blocks, settings.fediact_domainblocks] = [[],[],[]]
var [mutes, blocks, domainblocks] = await Promise.all([
fetch("https://" + settings.fediact_homeinstance + mutesApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + blocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + domainBlocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json())
])
if (mutes.length) {
settings.fediact_mutes.push(...mutes.map(acc => acc.acct))
}
if (blocks.length) {
settings.fediact_blocks.push(...blocks.map(acc => acc.acct))
}
if (domainblocks.length) {
settings.fediact_domainblocks = domainblocks
}
resolve(true)
} catch {
resolve(false)
}
if (blocks.length) {
settings.fediact_blocks.push(...blocks.map(acc => acc.acct))
}
if (domainblocks.length) {
settings.fediact_domainblocks = domainblocks
}
resolve(true)
})
}
async function fetchData() {
async function fetchData(token, mutesblocks) {
return new Promise(async function(resolve) {
var resolved = false
try {
settings = await (browser || chrome).storage.local.get(settingsDefaults)
if (settings.fediact_homeinstance) {
if (token || mutesblocks) {
if (token || !(settings.fediact_token)) {
await fetchBearerToken()
}
if (mutesblocks) {
await fetchMutesAndBlocks()
}
try {
await (browser || chrome).storage.local.set(settings)
resolved = true
} catch {
log(e)
}
}
} else {
log("Home instance not set")
}
} catch(e) {
log(e)
resolve(false)
return
}
if (settings.fediact_homeinstance) {
await fetchBearerToken()
await fetchMutesAndBlocks()
} else {
log("Home instance not set")
resolve(false)
return
}
try {
await (browser || chrome).storage.local.set(settings)
resolve(true)
} catch {
log(e)
}
resolve(resolved)
})
}
@ -147,21 +208,30 @@ async function reloadListeningScripts() {
}
// fetch api token right after install (mostly for debugging, when the ext. is reloaded)
chrome.runtime.onInstalled.addListener(fetchData)
chrome.runtime.onInstalled.addListener(function(){fetchData(true, true)})
// and also every 3 minutes
chrome.alarms.create('refresh', { periodInMinutes: tokenInterval })
chrome.alarms.onAlarm.addListener(fetchData)
chrome.alarms.onAlarm.addListener(function(){fetchData(true, true)})
// different listeners for inter-script communication
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// the content script gave us an url to perform a 302 redirect with
if(request.url) {
resolveToot(request.url).then(sendResponse)
if(request.externaltoot) {
resolveExternalTootHome(request.externaltoot).then(sendResponse)
return true
}
// the content script gave us an url to perform a 302 redirect with
if(request.requestdata) {
generalRequest(request.requestdata).then(sendResponse)
return true
}
// immediately fetch api token after settings are updated
if (request.updatedsettings) {
fetchData().then(reloadListeningScripts)
fetchData(true, true).then(reloadListeningScripts)
return true
}
if (request.updatemutedblocked) {
fetchData(false, true).then(sendResponse)
return true
}
// when the content script starts to process on a site, listen for tab changes (url)

Wyświetl plik

@ -1 +1 @@
var browser,chrome,i;const n=!0,a="[FediAct]",t=1,c="/api/v1/mutes",s="/api/v1/blocks",o="/api/v1/domain_blocks",r=15e3,d=/"access_token":".*?",/gm,u={fediact_homeinstance:null};function h(t){n&&console.log(a+" "+t)}async function f(i){return new Promise(async function(e){try{const a=new AbortController;var t=setTimeout(()=>{h("Timed out"),a.abort()},r),n=await fetch(i,{method:"HEAD",signal:a.signal});clearTimeout(t),n.redirected?e(n.url):e(!1)}catch(t){h(t),e(!1)}})}async function l(){return new Promise(async function(e){var t="https://"+i.fediact_homeinstance;try{var n=await(await fetch(t)).text()}catch(t){return h(t),void e(!1)}if(n){t=n.match(d);if(t){var n=t[0].search(/"access_token":"/),a=t[0].search(/",/);if(-1<n&&-1<a){t=t[0].substring(n+=16,a);if(16<t.length)return i.fediact_token=t,void e(!0)}}}i.fediact_token=null,h("Token could not be found."),e(!1)})}async function m(){return new Promise(async function(t){[i.fediact_mutes,i.fediact_blocks,i.fediact_domainblocks]=[[],[],[]];var[e,n,a]=await Promise.all([fetch("https://"+i.fediact_homeinstance+c,{headers:{Authorization:"Bearer "+i.fediact_token}}).then(t=>t.json()),fetch("https://"+i.fediact_homeinstance+s,{headers:{Authorization:"Bearer "+i.fediact_token}}).then(t=>t.json()),fetch("https://"+i.fediact_homeinstance+o,{headers:{Authorization:"Bearer "+i.fediact_token}}).then(t=>t.json())]);e.length&&i.fediact_mutes.push(...e.map(t=>t.acct)),n.length&&i.fediact_blocks.push(...n.map(t=>t.acct)),a.length&&(i.fediact_domainblocks=a),t(!0)})}async function g(){return new Promise(async function(n){try{i=await(browser||chrome).storage.local.get(u)}catch(t){return h(t),void n(!1)}if(i.fediact_homeinstance){await l(),await m();try{await(browser||chrome).storage.local.set(i),n(!0)}catch{h(e)}}else h("Home instance not set"),n(!1)})}async function _(){chrome.tabs.query({},async function(t){for(var e=0;e<t.length;++e)try{chrome.tabs.sendMessage(t[e].id,{updatedfedisettings:!0})}catch(t){continue}})}chrome.runtime.onInstalled.addListener(g),chrome.alarms.create("refresh",{periodInMinutes:t}),chrome.alarms.onAlarm.addListener(g),chrome.runtime.onMessage.addListener((t,a,e)=>t.url?(f(t.url).then(e),!0):t.updatedsettings?(g().then(_),!0):void(t.running&&chrome.tabs.onUpdated.addListener(async function(t,e,n){if(t===a.tab.id&&e.url)try{await chrome.tabs.sendMessage(t,{urlchanged:e.url})}catch(t){h(t)}})));
var browser,chrome,c;const a=!1,n="[FediAct]",t=1,i="/api/v1/mutes",s="/api/v1/blocks",o="/api/v1/domain_blocks",r=15e3,d=/"access_token":".*?",/gm,u={fediact_homeinstance:null,fediact_token:null};function h(t){a&&console.log(n+" "+t)}async function f(i){return new Promise(async function(e){try{const n=new AbortController;var t=setTimeout(()=>{h("Timed out"),n.abort()},r),a=await fetch(i,{method:"HEAD",signal:n.signal});clearTimeout(t),a.redirected?e(a.url):e(!1)}catch(t){h(t),e(!1)}})}async function l(c){return new Promise(async function(e){try{const i=new AbortController;var t,a,n=setTimeout(()=>{h("Timed out"),i.abort()},r);t=c[3]?(c[2]["User-Agent"]="FediAct Service",c[2]["Content-Type"]="application/json",await fetch(c[1],{method:c[0],signal:i.signal,headers:c[2],body:JSON.stringify(c[3])})):c[2]?(c[2]["User-Agent"]="FediAct Service",await fetch(c[1],{method:c[0],signal:i.signal,headers:c[2]})):await fetch(c[1],{method:c[0],signal:i.signal,headers:{"User-Agent":"FediAct Service"}}),clearTimeout(n),200<=t.status&&t.status<300&&(a=t.headers.get("content-type"))&&-1!==a.indexOf("application/json")?e(await t.text()):e(!1)}catch(t){h(t),e(!1)}})}async function m(){return new Promise(async function(e){var t="https://"+c.fediact_homeinstance;try{var a=await(await fetch(t)).text()}catch(t){return h(t),void e(!1)}if(a){t=a.match(d);if(t){var a=t[0].search(/"access_token":"/),n=t[0].search(/",/);if(-1<a&&-1<n){t=t[0].substring(a+=16,n);if(16<t.length)return c.fediact_token=t,void e(!0)}}}c.fediact_token=null,h("Token could not be found."),e(!1)})}function g(){return new Promise(async function(t){try{[c.fediact_mutes,c.fediact_blocks,c.fediact_domainblocks]=[[],[],[]];var[e,a,n]=await Promise.all([fetch("https://"+c.fediact_homeinstance+i,{headers:{Authorization:"Bearer "+c.fediact_token}}).then(t=>t.json()),fetch("https://"+c.fediact_homeinstance+s,{headers:{Authorization:"Bearer "+c.fediact_token}}).then(t=>t.json()),fetch("https://"+c.fediact_homeinstance+o,{headers:{Authorization:"Bearer "+c.fediact_token}}).then(t=>t.json())]);e.length&&c.fediact_mutes.push(...e.map(t=>t.acct)),a.length&&c.fediact_blocks.push(...a.map(t=>t.acct)),n.length&&(c.fediact_domainblocks=n),t(!0)}catch{t(!1)}})}async function y(n,i){return new Promise(async function(t){var a=!1;try{if((c=await(browser||chrome).storage.local.get(u)).fediact_homeinstance){if(n||i){!n&&c.fediact_token||await m(),i&&await g();try{await(browser||chrome).storage.local.set(c),a=!0}catch{h(e)}}}else h("Home instance not set")}catch(t){h(t)}t(a)})}async function p(){chrome.tabs.query({},async function(t){for(var e=0;e<t.length;++e)try{chrome.tabs.sendMessage(t[e].id,{updatedfedisettings:!0})}catch(t){continue}})}chrome.runtime.onInstalled.addListener(function(){y(!0,!0)}),chrome.alarms.create("refresh",{periodInMinutes:t}),chrome.alarms.onAlarm.addListener(function(){y(!0,!0)}),chrome.runtime.onMessage.addListener((t,n,e)=>t.externaltoot?(f(t.externaltoot).then(e),!0):t.requestdata?(l(t.requestdata).then(e),!0):t.updatedsettings?(y(!0,!0).then(p),!0):t.updatemutedblocked?(y(!1,!0).then(e),!0):void(t.running&&chrome.tabs.onUpdated.addListener(async function(t,e,a){if(t===n.tab.id&&e.url)try{await chrome.tabs.sendMessage(t,{urlchanged:e.url})}catch(t){h(t)}})));

Wyświetl plik

@ -2,6 +2,21 @@
Normal stylings
*/
:root { /* Modal Vars */
--bg: #eee;
--fg: #494949;
--border: rgba(120,120,130,0.3);
--hover: rgba(100,100,130,0.2);
--confirmation: rgb(38, 133, 0);
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #24262d;
--fg: white;
}
}
/* Styles for the mute/block modal popup */
.fediactmodal {
@ -15,53 +30,98 @@
background-color: rgba(0,0,0,0.4);
margin: 0;
padding: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 1rem;
-webkit-animation: fa_fadeIn .2s;
animation: fa_fadeIn .2s;
}
.fediactmodalinner {
background-color: #494949;
border: 1px solid #888;
width: 50%;
background-color: var(--bg);
border: 1px solid var(--border);
width: 80%;
max-width: 300px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
margin: 0;
padding: 0;
margin: auto;
padding: .4em;
border-radius: 8px;
-webkit-animation: fa_scaleInSmall .2s;
animation: fa_scaleInSmall .2s;
}
.fediactmodallist {
width: 100%;
margin: 0;
padding: 0;
}
.fediactmodalitem {
position: relative;
display: block;
padding: .7em;
border-radius: 6px;
cursor: pointer;
width: 100%;
padding: 5px 10px;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: background-color .4s;
-o-transition: background-color .4s;
transition: background-color .4s;
}
.fediactmodalitem:hover, .fediactmodalitem:focus-within {
background-color: var(--hover);
}
.fediactmodallink {
font-size: 16px;
cursor: pointer;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
cursor: pointer;
text-decoration: none;
color: white;
color: var(--fg);
margin: -.7em;
padding: .7em;
border-radius: inherit;
-webkit-box-shadow: inset 0 0 0 var(--confirmation);
box-shadow: inset 0 0 0 var(--confirmation);
-webkit-transition: padding .2s, color .2s, -webkit-box-shadow .2s cubic-bezier(.2,.2,0,1);
transition: padding .2s, color .2s, -webkit-box-shadow .2s cubic-bezier(.2,.2,0,1);
-o-transition: padding .2s, color .2s, box-shadow .2s cubic-bezier(.2,.2,0,1);
transition: padding .2s, color .2s, box-shadow .2s cubic-bezier(.2,.2,0,1);
transition: padding .2s, color .2s, box-shadow .2s cubic-bezier(.2,.2,0,1), -webkit-box-shadow .2s cubic-bezier(.2,.2,0,1);
}
.fediactmodallink span:not(:first-of-type) {
position: absolute;
right: .7em;
font-size: .8em;
padding: .2em .4em;
border-radius: 4px;
background-color: white;
color: var(--confirmation);
-webkit-animation: fa_scaleInFadeSmall .2s;
animation: fa_scaleInFadeSmall .2s;
}
.fediactmodallink.activated {
-webkit-box-shadow: inset 300px 0 0 var(--confirmation);
box-shadow: inset 300px 0 0 var(--confirmation);
color: white;
font-weight: 600;
}
/* Styles for "resolving..." indicator */
.fediactprocessing {
color: white;
padding-right: 10px;
padding-left: 10px
display: inline-block;
height: 1.2em;
width: 1.2em;
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCA0MCA0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7IiB4PSIwcHgiIHk9IjBweCI+CiAgICA8ZGVmcz4KICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWwogICAgICAgICAgICBALXdlYmtpdC1rZXlmcmFtZXMgc3BpbiB7CiAgICAgICAgICAgICAgZnJvbSB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTM1OWRlZykKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQGtleWZyYW1lcyBzcGluIHsKICAgICAgICAgICAgICBmcm9tIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0zNTlkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN2ZyB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7CiAgICAgICAgICAgICAgICAtd2Via2l0LWFuaW1hdGlvbjogc3BpbiAxLjVzIGxpbmVhciBpbmZpbml0ZTsKICAgICAgICAgICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuOwogICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDEuNXMgbGluZWFyIGluZmluaXRlOwogICAgICAgICAgICB9CiAgICAgICAgXV0+PC9zdHlsZT4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJvdXRlciI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwwQzIyLjIwNTgsMCAyMy45OTM5LDEuNzg4MTMgMjMuOTkzOSwzLjk5MzlDMjMuOTkzOSw2LjE5OTY4IDIyLjIwNTgsNy45ODc4MSAyMCw3Ljk4NzgxQzE3Ljc5NDIsNy45ODc4MSAxNi4wMDYxLDYuMTk5NjggMTYuMDA2MSwzLjk5MzlDMTYuMDA2MSwxLjc4ODEzIDE3Ljc5NDIsMCAyMCwwWiIgc3R5bGU9ImZpbGw6YmxhY2s7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNNS44NTc4Niw1Ljg1Nzg2QzcuNDE3NTgsNC4yOTgxNSA5Ljk0NjM4LDQuMjk4MTUgMTEuNTA2MSw1Ljg1Nzg2QzEzLjA2NTgsNy40MTc1OCAxMy4wNjU4LDkuOTQ2MzggMTEuNTA2MSwxMS41MDYxQzkuOTQ2MzgsMTMuMDY1OCA3LjQxNzU4LDEzLjA2NTggNS44NTc4NiwxMS41MDYxQzQuMjk4MTUsOS45NDYzOCA0LjI5ODE1LDcuNDE3NTggNS44NTc4Niw1Ljg1Nzg2WiIgc3R5bGU9ImZpbGw6cmdiKDIxMCwyMTAsMjEwKTsiLz4KICAgICAgICA8L2c+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwzMi4wMTIyQzIyLjIwNTgsMzIuMDEyMiAyMy45OTM5LDMzLjgwMDMgMjMuOTkzOSwzNi4wMDYxQzIzLjk5MzksMzguMjExOSAyMi4yMDU4LDQwIDIwLDQwQzE3Ljc5NDIsNDAgMTYuMDA2MSwzOC4yMTE5IDE2LjAwNjEsMzYuMDA2MUMxNi4wMDYxLDMzLjgwMDMgMTcuNzk0MiwzMi4wMTIyIDIwLDMyLjAxMjJaIiBzdHlsZT0iZmlsbDpyZ2IoMTMwLDEzMCwxMzApOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksMjguNDkzOUMzMC4wNTM2LDI2LjkzNDIgMzIuNTgyNCwyNi45MzQyIDM0LjE0MjEsMjguNDkzOUMzNS43MDE5LDMwLjA1MzYgMzUuNzAxOSwzMi41ODI0IDM0LjE0MjEsMzQuMTQyMUMzMi41ODI0LDM1LjcwMTkgMzAuMDUzNiwzNS43MDE5IDI4LjQ5MzksMzQuMTQyMUMyNi45MzQyLDMyLjU4MjQgMjYuOTM0MiwzMC4wNTM2IDI4LjQ5MzksMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxMDEsMTAxLDEwMSk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMy45OTM5LDE2LjAwNjFDNi4xOTk2OCwxNi4wMDYxIDcuOTg3ODEsMTcuNzk0MiA3Ljk4NzgxLDIwQzcuOTg3ODEsMjIuMjA1OCA2LjE5OTY4LDIzLjk5MzkgMy45OTM5LDIzLjk5MzlDMS43ODgxMywyMy45OTM5IDAsMjIuMjA1OCAwLDIwQzAsMTcuNzk0MiAxLjc4ODEzLDE2LjAwNjEgMy45OTM5LDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoMTg3LDE4NywxODcpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTUuODU3ODYsMjguNDkzOUM3LjQxNzU4LDI2LjkzNDIgOS45NDYzOCwyNi45MzQyIDExLjUwNjEsMjguNDkzOUMxMy4wNjU4LDMwLjA1MzYgMTMuMDY1OCwzMi41ODI0IDExLjUwNjEsMzQuMTQyMUM5Ljk0NjM4LDM1LjcwMTkgNy40MTc1OCwzNS43MDE5IDUuODU3ODYsMzQuMTQyMUM0LjI5ODE1LDMyLjU4MjQgNC4yOTgxNSwzMC4wNTM2IDUuODU3ODYsMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxNjQsMTY0LDE2NCk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMzYuMDA2MSwxNi4wMDYxQzM4LjIxMTksMTYuMDA2MSA0MCwxNy43OTQyIDQwLDIwQzQwLDIyLjIwNTggMzguMjExOSwyMy45OTM5IDM2LjAwNjEsMjMuOTkzOUMzMy44MDAzLDIzLjk5MzkgMzIuMDEyMiwyMi4yMDU4IDMyLjAxMjIsMjBDMzIuMDEyMiwxNy43OTQyIDMzLjgwMDMsMTYuMDA2MSAzNi4wMDYxLDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoNzQsNzQsNzQpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksNS44NTc4NkMzMC4wNTM2LDQuMjk4MTUgMzIuNTgyNCw0LjI5ODE1IDM0LjE0MjEsNS44NTc4NkMzNS43MDE5LDcuNDE3NTggMzUuNzAxOSw5Ljk0NjM4IDM0LjE0MjEsMTEuNTA2MUMzMi41ODI0LDEzLjA2NTggMzAuMDUzNiwxMy4wNjU4IDI4LjQ5MzksMTEuNTA2MUMyNi45MzQyLDkuOTQ2MzggMjYuOTM0Miw3LjQxNzU4IDI4LjQ5MzksNS44NTc4NloiIHN0eWxlPSJmaWxsOnJnYig1MCw1MCw1MCk7Ii8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K') no-repeat center center;
background-size: 1em 1em;
padding-left: 10px; /* for instances where action bar is not full width */
padding-right: 10px;
}
/* Styles for unresolved indicator */
.fediactunresolved {
display: inline-block;
height: 1.2em;
width: 1.2em;
color: orange;
font-weight: bold;
padding-right: 10px;
padding-left: 10px
}
@ -73,8 +133,8 @@
}
.fediactvoted > a {
font-weight: bold;
color: orange
font-weight: bold !important;
color: orange !important;
}
/* Inserted in the bottom right of any external instance where FediAct is running */
@ -84,8 +144,8 @@
width: 32px;
position: fixed;
z-index: 99998;
bottom: 15px;
right: 10px;
bottom: 50px;
right: 20px;
background: url('data:image/png;base64,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');
background-size: 32px 32px;
cursor: pointer;
@ -118,42 +178,97 @@
color: blue !important;
}
/* keyframes fa_*/
/*
@-webkit-keyframes fa_fadeIn {
from {
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
@keyframes fa_fadeIn {
from {
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
@-webkit-keyframes fa_fadeOut {
to {
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
@keyframes fa_fadeOut {
to {
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
@-webkit-keyframes fa_scaleInSmall {
from {
-webkit-transform: scale(.98);
transform: scale(.98);
}
}
@keyframes fa_scaleInSmall {
from {
-webkit-transform: scale(.98);
transform: scale(.98);
}
}
@-webkit-keyframes fa_scaleInFadeSmall {
from {
-webkit-transform: scale(.98);
transform: scale(.98);
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
@keyframes fa_scaleInFadeSmall {
from {
-webkit-transform: scale(.98);
transform: scale(.98);
-webkit-filter: opacity(0);
filter: opacity(0);
}
}
/*
We insert these styles for the DOMNodeAppeared function as separate stylesheet (see manifest) to fix
Firefox blocking script-inserted <style> elements due to the site's CSP (long time bug)
*/
@-moz-keyframes nodeInserted {
@-moz-keyframes fa_nodeInserted {
from {
opacity: 1;
} to {
opacity: 1;
}
}
@-webkit-keyframes nodeInserted {
@-webkit-keyframes fa_nodeInserted {
from {
opacity: 1;
} to {
opacity: 1;
}
}
@-ms-keyframes nodeInserted {
@-ms-keyframes fa_nodeInserted {
from {
opacity: 1;
} to {
opacity: 1;
}
}
@-o-keyframes nodeInserted {
@-o-keyframes fa_nodeInserted {
from {
opacity: 1;
} to {
opacity: 1;
}
}
@keyframes nodeInserted {
from {
@keyframes fa_nodeInserted {
from {
opacity: 1;
} to {
opacity: 1;
@ -170,15 +285,15 @@ div.account-card a.logo-button,
div.directory-card a.icon-button,
div.detailed-status a.logo-button,
button.remote-button,
script#initial-state {
-webkit-animation-name: nodeInserted !important;
script#initial-state {
-webkit-animation-name: fa_nodeInserted !important;
-webkit-animation-duration: 0.001s !important;
-ms-animation-name: nodeInserted !important;
-ms-animation-name: fa_nodeInserted !important;
-ms-animation-duration: 0.001s !important;
-moz-animation-name: nodeInserted !important;
-moz-animation-name: fa_nodeInserted !important;
-moz-animation-duration: 0.001s !important;
-o-animation-name: nodeInserted !important;
-o-animation-name: fa_nodeInserted !important;
-o-animation-duration: 0.001s !important;
animation-name: nodeInserted !important;
animation-name: fa_nodeInserted !important;
animation-duration: 0.001s !important;
}

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -7,7 +7,7 @@ const profileNamePaths = ["div.account__header__tabs__name small", "div.public-a
const domainRegex = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/
const handleExtractUrlRegex = /^(?<domain>https?:\/\/(?:\.?[a-z0-9-]+)+(?:\.[a-z]+){1})?\/?@(?<handle>\w+)(?:@(?<handledomain>(?:[\w-]+\.)+?\w+))?(?:\/(?<tootid>\d+))?\/?$/
const handleExtractUriRegex = /^(?<domain>https?:\/\/(?:\.?[a-z0-9-]+)+(?:\.[a-z]+){1})(?:\/users\/)(?<handle>\w+)(?:(?:\/statuses\/)(?<tootid>\d+))?\/?$/
const enableConsoleLog = true
const enableConsoleLog = false
const logPrepend = "[FediAct]"
const instanceApi = "/api/v1/instance"
const statusApi = "/api/v1/statuses"
@ -17,10 +17,10 @@ const mutesApi = "/api/v1/mutes"
const blocksApi = "/api/v1/blocks"
const domainBlocksApi = "/api/v1/domain_blocks"
const pollsApi = "/api/v1/polls"
const apiDelay = 500
const apiDelay = 600
const maxTootCache = 200
const modalHtml = '<div class="fediactmodal"><div class="fediactmodalinner"><ul class="fediactmodallist"></ul></div></div>'
const timeout = 15000
const maxAsyncRequests = 10
// settings keys with defauls
var settings = {}
@ -79,7 +79,7 @@ function log(text) {
// catch all animationstart events
$(document).on('animationstart webkitAnimationStart oanimationstart MSAnimationStart', function(e){
// check if the animatonname equals our animation and if the element is one of our selectors
if (e.originalEvent.animationName == 'nodeInserted' && $(e.target).is(selector)) {
if (e.originalEvent.animationName == 'fa_nodeInserted' && $(e.target).is(selector)) {
if (typeof callback == 'function') {
// return the complete object in the callback
callback(e)
@ -125,69 +125,60 @@ var getUrlParameter = function getUrlParameter(sParam) {
return false
}
// promisified xhr for api calls
async function makeRequest(method, url, extraheaders, jsonbody) {
// try to prevent error 429 too many request by delaying home instance requests
if (~url.indexOf(settings.fediact_homeinstance) && settings.fediact_enabledelay) {
// get current time
var currenttime = Date.now()
// get difference of current time and time of last request
var difference = currenttime - tmpSettings.lasthomerequest
// if difference is smaller than our set api delay value...
if (difference < apiDelay) {
// ... then wait the time required to reach the api delay value...
await new Promise(resolve => {
setTimeout(function() {
resolve()
}, apiDelay-difference)
})
}
// TODO: move this to the top? or get new Date.now() here?
tmpSettings.lasthomerequest = currenttime
const asyncLimit = (fn, n) => {
let pendingPromises = []
return async function (...args) {
while (pendingPromises.length >= n) {
await Promise.race(pendingPromises).catch(() => {})
}
const p = fn.apply(this, args)
pendingPromises.push(p)
await p.catch(() => {})
pendingPromises = pendingPromises.filter(pending => pending !== p)
return p
}
// return a new promise...
return new Promise(function (resolve) {
// create xhr
let xhr = new XMLHttpRequest()
// open it with the method and url specified
xhr.open(method, url)
// set timeout
xhr.timeout = timeout
// set extra headers if any were given
if (extraheaders) {
for (var key in extraheaders) {
xhr.setRequestHeader(key, extraheaders[key])
}
// promisified xhr for api calls
function makeRequest(method, url, extraheaders, jsonbody) {
return new Promise(async function(resolve) {
// try to prevent error 429 too many request by delaying home instance requests
if (~url.indexOf(settings.fediact_homeinstance) && settings.fediact_enabledelay) {
// get current time
var currenttime = Date.now()
// get difference of current time and time of last request
var difference = currenttime - tmpSettings.lasthomerequest
// if difference is smaller than our set api delay value...
if (difference < apiDelay) {
// ... then wait the time required to reach the api delay value...
await new Promise(resolve => {
setTimeout(function() {
resolve()
}, apiDelay-difference)
})
}
tmpSettings.lasthomerequest = Date.now()
}
// on load, check if status is OK...
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
// is ok, resolve promise with response
resolve(xhr.responseText)
} else {
// nope, resolve false
resolve(false)
}
}
xhr.ontimeout = function() {
log("Timed out")
resolve(false)
try {
await chrome.runtime.sendMessage({requestdata: [method, url, extraheaders, jsonbody]}, function(response) {
if(response) {
resolve(response)
} else {
resolve(false)
}
})
} catch (e) {
// if we encounter an error here, it is likely since the extension context got invalidated, so reload the page
log(e)
log("Reloading page, extension likely got updated or reloaded.")
location.reload()
}
// on any error, resolve false
xhr.onerror = function() {
log("Request to " + url + " failed.")
resolve(false)
}
// send the request
if (jsonbody) {
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify(jsonbody))
} else {
xhr.send()
}
})
})
}
// wrap so there are never more than 10 concurrent requests
const requestAsyncLimited = asyncLimit(makeRequest, maxAsyncRequests)
// Escape characters used for regex
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
@ -202,6 +193,16 @@ function replaceAll(str, find, replace) {
function redirectTo(url) {
// check if redirects are enabled at all
if (settings.fediact_redirects) {
if (settings.fediact_target == "_self") {
/* If browser back button was used, flush cache */
(function () {
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload();
}
};
})()
}
// check if alert before redirect is enabled and show the prompt if so
if (settings.fediact_alert) {
if (!confirm("Redirecting to " + url)) {
@ -228,89 +229,94 @@ function redirectTo(url) {
// =-=-=-=-= INTERACTIONS =-=-=-=-=
// =-=-=-=-==-=-=-=-==-=-=-=-==-=-=
async function executeAction(id, action, polldata) {
async function executeAction(data, action, polldata) {
var requestUrl, condition, jsonbody, after
var method = "POST"
switch (action) {
case 'copy':
// special action. only copy to clipboard and return
navigator.clipboard.writeText(data)
return true
case 'domainblock':
requestUrl = 'https://' + settings.fediact_homeinstance + domainBlocksApi + "?domain=" + id
requestUrl = 'https://' + settings.fediact_homeinstance + domainBlocksApi + "?domain=" + data
condition = function(response) {if(response){return true}}
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'domainunblock':
requestUrl = 'https://' + settings.fediact_homeinstance + domainBlocksApi + "?domain=" + id
requestUrl = 'https://' + settings.fediact_homeinstance + domainBlocksApi + "?domain=" + data
condition = function(response) {if(response){return true}}
method = "DELETE"
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'mute':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/mute"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/mute"
condition = function(response) {return response.muting}
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'unmute':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/unmute"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/unmute"
condition = function(response) {return !response.muting}
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'block':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/block"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/block"
condition = function(response) {return response.blocking}
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'unblock':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/unblock"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/unblock"
condition = function(response) {return !response.blocking}
after = function() {updateMutedBlocked()}
after = async function() {await updateMutedBlocked()}
break
case 'vote':
requestUrl = 'https://' + settings.fediact_homeinstance + pollsApi + "/" + id + "/votes"
requestUrl = 'https://' + settings.fediact_homeinstance + pollsApi + "/" + data + "/votes"
condition = function(response) {return response.voted}
jsonbody = polldata
break
case 'follow':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/follow"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/follow"
condition = function(response) {return response.following || response.requested}
break
case 'boost':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/reblog"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/reblog"
condition = function(response) {return response.reblogged}
break
case 'favourite':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/favourite"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/favourite"
condition = function(response) {return response.favourited}
break
case 'bookmark':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/bookmark"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/bookmark"
condition = function(response) {return response.bookmarked}
break
case 'unfollow':
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + id + "/unfollow"
requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/" + data + "/unfollow"
condition = function(response) {return !response.following && !response.requested}
break
case 'unboost':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/unreblog"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/unreblog"
condition = function(response) {return !response.reblogged}
break
case 'unfavourite':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/unfavourite"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/unfavourite"
condition = function(response) {return !response.favourited}
break
case 'unbookmark':
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + id + "/unbookmark"
requestUrl = 'https://' + settings.fediact_homeinstance + statusApi + "/" + data + "/unbookmark"
condition = function(response) {return !response.bookmarked}
break
default:
log("No valid action specified."); break
log("No valid action specified.")
return
}
if (requestUrl) {
var response = await makeRequest(method, requestUrl, tmpSettings.tokenheader, jsonbody)
var response = await requestAsyncLimited(method, requestUrl, tmpSettings.tokenheader, jsonbody)
if (response) {
// convert to json object
response = JSON.parse(response)
if (condition(response)) {
if (after !== undefined) {
after()
await after()
}
return true
}
@ -328,7 +334,7 @@ async function isFollowingHomeInstance(ids) {
requestUrl += "id[]=" + id.toString() + "&"
}
// make the request
var responseFollowing = await makeRequest("GET", requestUrl, tmpSettings.tokenheader, null)
var responseFollowing = await requestAsyncLimited("GET", requestUrl, tmpSettings.tokenheader, null)
// fill response array according to id amount with false
const follows = Array(ids.length).fill(false)
// parse the response
@ -400,7 +406,7 @@ function checkAllMutedBlocked(handle) {
// Return the user id on the users home instance
async function resolveHandleToHome(handle) {
var requestUrl = 'https://' + settings.fediact_homeinstance + accountsApi + "/search?q=" + handle + "&resolve=true&limit=1&exclude_unreviewed=false"
var searchResponse = await makeRequest("GET", requestUrl, tmpSettings.tokenheader, null)
var searchResponse = await requestAsyncLimited("GET", requestUrl, tmpSettings.tokenheader, null)
if (searchResponse) {
searchResponse = JSON.parse(searchResponse)
if (searchResponse[0].id) {
@ -414,7 +420,7 @@ async function resolveHandleToHome(handle) {
// resolve a toot to the users home instance
async function resolveTootToHome(searchstring) {
var requestUrl = 'https://' + settings.fediact_homeinstance + searchApi + "/?q=" + searchstring + "&resolve=true&limit=1&exclude_unreviewed=false"
var response = await makeRequest("GET", requestUrl, tmpSettings.tokenheader, null)
var response = await requestAsyncLimited("GET", requestUrl, tmpSettings.tokenheader, null)
if (response) {
response = JSON.parse(response)
// do we have a status as result?
@ -443,7 +449,7 @@ function resolveTootToExternalHome(tooturl) {
if (tooturl) {
return new Promise(async function(resolve) {
try {
await chrome.runtime.sendMessage({url: tooturl}, function(response) {
await chrome.runtime.sendMessage({externaltoot: tooturl}, function(response) {
if(response) {
resolve(response)
} else {
@ -519,24 +525,28 @@ function addToProcessedToots(toot) {
return tmpSettings.processed.length - 1
}
async function updateMutedBlocked() {
// set empty initially
[settings.fediact_mutes, settings.fediact_blocks, settings.fediact_domainblocks] = [[],[],[]]
var [mutes, blocks, domainblocks] = await Promise.all([
fetch("https://" + settings.fediact_homeinstance + mutesApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + blocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json()),
fetch("https://" + settings.fediact_homeinstance + domainBlocksApi, {headers: {"Authorization": "Bearer "+settings.fediact_token}}).then((response) => response.json())
])
if (mutes.length) {
settings.fediact_mutes.push(...mutes.map(acc => acc.acct))
}
if (blocks.length) {
settings.fediact_blocks.push(...blocks.map(acc => acc.acct))
}
if (domainblocks.length) {
settings.fediact_domainblocks = domainblocks
}
updateSettings()
function updateMutedBlocked() {
return new Promise(async function(resolve) {
try {
await chrome.runtime.sendMessage({updatemutedblocked: true}, async function(response) {
if (response) {
if (!await getSettings()) {
// but reload if settings are invalid
location.reload()
} else {
resolve(true)
}
} else {
resolve(false)
}
})
} catch (e) {
// if we encounter an error here, it is likely since the extension context got invalidated, so reload the page
log(e)
log("Reloading page, extension likely got updated or reloaded.")
location.reload()
}
})
}
function showModal(settings) {
@ -544,26 +554,51 @@ function showModal(settings) {
var baseEl = $(modalHtml)
var appendTo = $(baseEl).find("ul")
for (const entry of settings) {
var nameUppercase = entry[0].charAt(0).toUpperCase() + entry[0].slice(1);
var append = "<li class='fediactmodalitem'><a class='fediactmodallink' fediactaction='" + entry[0] + "' fediactid='" + entry[1] + "'>" + nameUppercase + "</a></li>"
var append = "<li class='fediactmodalitem'><a class='fediactmodallink' fediactaction='" + entry[0] + "' fediactdata='" + entry[1] + "'><span>" + entry[2] + "</span></a></li>"
$(appendTo).append($(append))
}
$("body").append($(baseEl))
function handleModalEvent(e) {
async function handleModalEvent(e) {
if (e.originalEvent.isTrusted) {
if ($(e.target).is(".fediactmodal li, .fediactmodal li a")) {
if ($(e.target).is(".fediactmodal li")) {
e.target = $(e.target).find("a")
if ($(e.target).is(".fediactmodal li, .fediactmodal li *")) {
if (!$(e.target).is(".fediactmodal li a")) {
if ($(e.target).find("a").length) {
e.target = $(e.target).find("a")
} else {
e.target = $(e.target).closest("a")
}
}
var action = $(e.target).attr("fediactaction")
var id = $(e.target).attr("fediactid")
var done = executeAction(id, action, null)
var data = $(e.target).attr("fediactdata")
var done = await executeAction(data, action, null)
if (done) {
$(e.target).addClass("activated")
$(e.target).append("<span>Done!</span>")
$(baseEl).css("animation", "fadeOut .2s .7s forwards")
$(baseEl).find(".fediactmodalinner").css("animation", "scaleInFade .2s .7s forwards reverse")
await new Promise(resolve => {
setTimeout(function() {
resolve()
}, 1000)
})
$(baseEl).remove()
$("body").off()
$("body").off("click", handleModalEvent)
} else {
alert("Failed to " + action)
$(e.target).css("--confirmation", "red")
$(e.target).addClass("activated")
$(e.target).append("<span>Failed</span>")
$(baseEl).css("animation", "fadeOut .2s .7s forwards")
$(baseEl).find(".fediactmodalinner").css("animation", "scaleInFade .2s .7s forwards reverse")
await new Promise(resolve => {
setTimeout(function() {
resolve()
}, 1000)
})
$(baseEl).remove()
$("body").off("click", handleModalEvent)
}
} else if ($(e.target).is(".fediactmodalinner")) {
$.noop()
} else {
$(baseEl).remove()
$("body").off("click", handleModalEvent)
@ -578,14 +613,18 @@ function addFediElements() {
$("body").append("<div class='fediacticon'></div>")
$("body").append("<div class='fediactsettings_onsite'><div class='fediactsettings_onsite_inner'><a href='https://" + settings.fediact_homeinstance + "' target='" + settings.fediact_target + "'>Go home</a></div></div>")
function fediSettingsHandler(e) {
if (e.originalEvent.isTrusted) {
if ($(e.target).is("div.fediacticon")) {
$("div.fediacticon").hide()
$("div.fediactsettings_onsite").show()
} else {
$("div.fediactsettings_onsite").hide()
$("div.fediacticon").show()
try {
if (e.originalEvent.isTrusted) {
if ($(e.target).is("div.fediacticon")) {
$("div.fediacticon").hide()
$("div.fediactsettings_onsite").show()
} else {
$("div.fediactsettings_onsite").hide()
$("div.fediacticon").show()
}
}
} catch {
$.noop()
}
}
$("body").on("click", fediSettingsHandler)
@ -767,6 +806,7 @@ async function processToots() {
addFediElements()
// extra step for detailed status elements to select the correct parent
if ($(el).is("div.detailed-status") && $(el).closest("div.focusable").length) {
var isDetailed = true
el = $(el).closest("div.focusable")
}
// get toot data
@ -783,6 +823,7 @@ async function processToots() {
// do we have one of those?
if (internalIdentifier) {
var homeResolveStrings = []
var hasHiddenPoll = false
// check if id is already cached
var cacheIndex = isInProcessedToots(internalIdentifier)
// get all button elements of this toot
@ -790,14 +831,26 @@ async function processToots() {
if (!$(favButton).length) {
favButton = $(el).find("a.icon-button:has(i.fa-star), a.detailed-status__link:has(i.fa-star)")
}
$("<span class='fediactprocessing'>Resolving...</span>").insertAfter($(favButton))
if (isDetailed) {
$("<div class='detailed-status__button fediactprocessingdetailed'><span class='fediactprocessing'></span></div>").insertAfter($(favButton).parent())
} else {
$("<span class='fediactprocessing'></span>").insertAfter($(favButton))
}
var boostButton = $(el).find("button:has(i.fa-retweet)").first()
if (!$(boostButton).length) {
boostButton = $(el).find("a.icon-button:has(i.fa-retweet), a.detailed-status__link:has(i.fa-retweet)")
}
var bookmarkButton = $(el).find("button:has(i.fa-bookmark)").first()
var replyButton = $(el).find("button:has(i.fa-reply), button:has(i.fa-reply-all), a.icon-button:has(i.fa-reply), a.icon-button:has(i.fa-reply-all)").first()
var spoilerButton = $(el).find('button[class*="show-more"]').first()
var voteButton = $(el).find("div.poll button").first()
if ($(spoilerButton).length) {
$(spoilerButton).click()
if ($(el).find("div.poll").length) {
hasHiddenPoll = true
}
$(spoilerButton).click()
}
var moreButton = $(el).find("button:has(i.fa-ellipsis-h,i.fa-ellipsis-fw,i.fa-ellipsis-v)").first()
// handles process when a vote button is clicked
async function pollAction(id, redirect, e) {
@ -834,6 +887,9 @@ async function processToots() {
var actionExecuted = await executeAction(id, action, null)
if (actionExecuted) {
if (cacheIndex) {
console.log(cacheIndex)
console.log(tmpSettings.processed[cacheIndex])
console.log(tmpSettings.processed)
// set interacted to true
tmpSettings.processed[cacheIndex][11] = true
}
@ -874,17 +930,46 @@ async function processToots() {
// handles initialization of element styles
function initStyles(tootdata) {
// always remove any existing "Unresolved" indicator from the element first
$(el).find(".fediactunresolved").remove()
$(el).find(".fediactprocessing").remove()
$(el).find(".fediactunresolveddetailed, .fediactunresolved").remove()
$(el).find(".fediactprocessingdetailed, .fediactprocessing").remove()
// is the toot unresolved?
if (!tootdata[1]) {
// yes, then add the Unresolved indicator
$("<span class='fediactunresolved'>Unresolved</span>").insertAfter($(favButton))
if (isDetailed) {
$("<div class='detailed-status__button fediactunresolveddetailed'><span class='fediactunresolved'>X</span></div>").insertAfter($(favButton).parent())
} else {
$("<span class='fediactunresolved'>X</span>").insertAfter($(favButton))
}
} else {
// otherwise start processing button styles (if enabled OR if the toot was already interacted with, to restore the state while still on the same page)
// first enable the bookmark button (is disabled on external instances)
$(bookmarkButton).removeClass("disabled").removeAttr("disabled")
$(moreButton).removeClass("disabled").removeAttr("disabled")
// special care for polls that are hidden behind a CW
if (tootdata[13]) {
// click initially to show content
$(spoilerButton).click()
$(spoilerButton).find("span").text("Show less")
// set voteButton
voteButton = $(el).find("div.poll button").first()
// set handling for all new clicks
$(spoilerButton).on("click", function(e) {
// prevent default etc.
e.preventDefault()
e.stopImmediatePropagation()
var spanText = $(spoilerButton).find("span")
if ($(spanText).text() == "Show less") {
$(spanText).text("Show more")
} else {
$(spanText).text("Show less")
}
// toggle the css manually to hide/show the content/poll
toggleInlineCss($(el).find("div.poll").first(),[["display","block","none"]], "fedihideshow")
toggleInlineCss($(el).find("div.status__content__text").first(),[["display","block","none"]], "fedihideshow")
})
// click again so it is hidden by default, like usually
$(spoilerButton).click()
}
$(voteButton).removeAttr("disabled")
// set the toot buttons to active, depending on the state of the resolved toot and if the element already has the active class
if (tootdata[4]) {
@ -932,20 +1017,22 @@ async function processToots() {
if (e.originalEvent.isTrusted) {
var modalLinks = []
if (isBlocked(tootdata[1])) {
modalLinks.push(["unblock",tootdata[6]])
modalLinks.push(["unblock",tootdata[6],"Unblock user"])
} else {
modalLinks.push(["block",tootdata[6]])
modalLinks.push(["block",tootdata[6],"Block user"])
}
if (isMuted(tootdata[1])) {
modalLinks.push(["unmute",tootdata[6]])
modalLinks.push(["unmute",tootdata[6],"Unmute user"])
} else {
modalLinks.push(["mute",tootdata[6]])
modalLinks.push(["mute",tootdata[6],"Mute user"])
}
if (isDomainBlocked(tootdata[1])) {
modalLinks.push(["domainunblock",domain])
modalLinks.push(["domainunblock",domain,"Unblock domain"])
} else {
modalLinks.push(["domainblock",domain])
modalLinks.push(["domainblock",domain,"Block domain"])
}
modalLinks.push(["copy",tootdata[12],"Copy URL"])
modalLinks.push(["copy",tootdata[7],"Copy home URL"])
showModal(modalLinks)
}
})
@ -1092,8 +1179,9 @@ async function processToots() {
// set the redirect to home instance URL in @ format
var redirectUrl = 'https://' + settings.fediact_homeinstance + "/@" + resolvedToot[0] + "/" + resolvedToot[1]
// prepare the cache entry / toot data entry
var fullEntry = [internalIdentifier, ...resolvedToot, redirectUrl, true, ...poll, false]
// 0: internal identifier; 1: toot home acct / false 2: toot home id 3: toot reblogged 4: toot favourited 5: toot bookmarked 6: home account id 7: redirect url 8: ??? crap! 9: poll id / false 10: poll voted 11: interacted
var fullEntry = [internalIdentifier, ...resolvedToot, redirectUrl, true, ...poll, false, homeResolveString, hasHiddenPoll]
// 0: internal identifier; 1: toot home acct / false 2: toot home id 3: toot reblogged 4: toot favourited 5: toot bookmarked 6: home account id
// 7: redirect url 8: ??? crap! 9: poll id / false 10: poll voted 11: interacted 12: original URL that was resolved 13: has hidden poll?
}
}
}
@ -1175,7 +1263,7 @@ async function processProfile() {
} else if (action == "unfollow" && response) {
if ($(icon).length) {
$(icon).removeClass("fa-user").addClass("fa-user-plus")
$(el).contents().filter((_, node) => node.nodeType === 3).remove();
$(el).contents().filter((_, node) => node.nodeType === 3).remove()
$(el).attr("title","Follow")
} else {
$(el).text("Follow")
@ -1209,7 +1297,7 @@ async function processProfile() {
// do we have a full handle?
if (fullHandle) {
if (!tmpSettings.processedFollow.includes(fullHandle)) {
$("<span class='fediactprocessing'>Resolving...&nbsp;&nbsp;</span>").insertBefore($(el))
$("<span class='fediactprocessing'></span>").insertBefore($(el))
// yes, so resolve it to a user id on our homeinstance
var resolvedHandle = await resolveHandleToHome(fullHandle)
if (resolvedHandle) {
@ -1219,6 +1307,7 @@ async function processProfile() {
}
var domainsplit = fullHandle.split("@")
var domain = domainsplit.pop() || domainsplit.pop()
var redirectUrl = 'https://' + settings.fediact_homeinstance + '/@' + resolvedHandle[1]
// successfully resolved
// ... then check if user is already following
var isFollowing = await isFollowingHomeInstance([resolvedHandle[0]])
@ -1240,20 +1329,21 @@ async function processProfile() {
if (e.originalEvent.isTrusted) {
var modalLinks = []
if (isBlocked(fullHandle)) {
modalLinks.push(["unblock",resolvedHandle[0]])
modalLinks.push(["unblock",resolvedHandle[0],"Unblock user"])
} else {
modalLinks.push(["block",resolvedHandle[0]])
modalLinks.push(["block",resolvedHandle[0],"Block user"])
}
if (isMuted(fullHandle)) {
modalLinks.push(["unmute",resolvedHandle[0]])
modalLinks.push(["unmute",resolvedHandle[0],"Unmute user"])
} else {
modalLinks.push(["mute",resolvedHandle[0]])
modalLinks.push(["mute",resolvedHandle[0],"Mute user"])
}
if (isDomainBlocked(fullHandle)) {
modalLinks.push(["domainunblock",domain])
modalLinks.push(["domainunblock",domain,"Unblock domain"])
} else {
modalLinks.push(["domainblock",domain])
modalLinks.push(["domainblock",domain,"Block domain"])
}
modalLinks.push(["copy",redirectUrl,"Copy home URL"])
showModal(modalLinks)
}
})
@ -1275,7 +1365,6 @@ async function processProfile() {
clearTimeout(timer)
var done = await execFollow(resolvedHandle[0])
if (done) {
var redirectUrl = 'https://' + settings.fediact_homeinstance + '/@' + resolvedHandle[1]
if ($(icon).length) {
var classes = $(icon).attr("class")
$(icon).removeClass("fa-user").removeClass("fa-user-plus").addClass("fa-arrow-right")
@ -1412,7 +1501,8 @@ async function checkSite() {
// last check - and probably the most accurate to determine if it actually is mastadon
var requestUrl = location.protocol + '//' + location.hostname + instanceApi
// call instance api to confirm its mastodon and get normalized handle uri
var response = await makeRequest("GET", requestUrl, null, null)
var response = await requestAsyncLimited("GET", requestUrl, null, null)
// todo: add basic check for "mastodon" string in response
if (response) {
var uri = JSON.parse(response).uri
if (uri) {
@ -1424,7 +1514,7 @@ async function checkSite() {
}
// at this point, we know that it's mastodon and the background processor should start running
if (!backgroundProcessor()) {
log("Could not start background process")
log("Could not start background processor.")
return false
}
// if option is enabled, check if logged in on that instance and stop
@ -1453,7 +1543,11 @@ async function backgroundProcessor() {
tmpSettings.isProcessing = []
$(".fediacticon").remove()
$(".fediactsettings_onsite").remove()
$("body").off("click", fediSettingsHandler)
try {
$("body").off("click", fediSettingsHandler)
} catch {
$.noop()
}
// rerun getSettings to keep mutes/blocks up to date while not reloading the page
if (!await getSettings()) {
// but reload if settings are invalid
@ -1483,6 +1577,7 @@ function getSettings() {
} catch(e) {
log(e)
resolve(false)
return
}
if (settings) {
// validate settings
@ -1497,14 +1592,6 @@ function getSettings() {
})
}
async function updateSettings() {
await (browser || chrome).storage.local.set(settings)
if (!await getSettings()) {
// but reload if settings are invalid
location.reload()
}
}
// run wrapper
async function run() {
// validate settings

2
src/inject.min.js vendored

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="chrome://browser/content/extension.css">
<meta name="color-scheme" content="dark light">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="lib/jquery-3.6.1.min.js"></script>
<script src="popup.min.js"></script>
<link rel="stylesheet" href="popup_styles.min.css">
@ -12,23 +13,26 @@
<div id="mhi-containers">
<form id="fediact-settings">
<div class="scroller">
<fieldset>
<fieldset aria-labelledby="homeServerDomainLabel">
<div class="row">
<label for="homeinstance">
<h1>Home Server Domain</h1>
<legend id="homeServerDomainLabel"><h1>Home Server Domain</h1></legend>
<span>
Make sure you are logged in to your home server
</span>
</label>
<input type="text" id="homeinstance" name="homeinstance" placeholder="example.social">
<div class="text-input-container">
<span>https://</span>
<input type="text" id="homeinstance" name="homeinstance" placeholder="example.social">
</div>
</div>
</fieldset>
<fieldset>
<h2>Redirect Settings</h2>
<legend>Redirect Settings</legend>
<div class="row">
<label for="redirects">Enable
<span>
Redirect to home server on double-click / reply
Redirect on double click and reply
</span>
</label>
<input type="checkbox" id="redirects" name="redirects">
@ -44,17 +48,17 @@
<div class="row">
<label for="target">Open in...</label>
<select name="target" id="target" selected="_blank">
<option id="target_blank" value="_blank">New tab</option>
<option id="target_self" value="_self">Same tab</option>
<option id="target_blank" value="_blank">New tab&nbsp;</option>
<option id="target_self" value="_self">Same tab&nbsp;</option>
</select>
</div>
</fieldset>
<fieldset>
<h2>Other Settings</h2>
<legend>Other Settings</legend>
<div class="row">
<label for="autoaction">Actions
<span>
Enable following, boosting, etc. from logged out servers
Enable follow, boost, etc. on other servers
</span>
</label>
<input type="checkbox" id="autoaction" name="autoaction">
@ -77,7 +81,7 @@
</div>
</fieldset>
<fieldset>
<h2>Mode</h2>
<legend>Mode</legend>
<div class="row">
<label for="runifloggedin">Ignore sessions
<span>
@ -88,12 +92,19 @@
</div>
</fieldset>
<fieldset>
<h2>Filtered servers</h2>
<legend>Filtered servers</legend>
<div class="row">
<label for="mode">Mode</label>
<label for="mode">Mode
<span class="hide" id="allowlabel">
Only run on the following domains...
</span>
<span class="hide" id="denylabel">
Run on all domains except the following...
</span>
</label>
<select name="mode" id="mode" selected="blacklist">
<option id="blacklist" value="blacklist">Denylist</option>
<option id="whitelist" value="whitelist">Allowlist</option>
<option id="blacklist" value="blacklist">Denylist&nbsp;</option>
<option id="whitelist" value="whitelist">Allowlist&nbsp;</option>
</select>
</div>
<div class="row">
@ -110,7 +121,6 @@
<input type="submit" value="Save">
<span id="indicator" style="display:none">Settings saved!</span>
<span><a target="_blank" href="https://github.com/lartsch/FediAct">More info / help on Github</a></span>
</div>
</form>
</div>

Wyświetl plik

@ -76,17 +76,23 @@ function popupTasks() {
// both containers are hidden by default
if ($("select#mode").val() == "whitelist") {
$("div#whitelist_input").removeClass("hide")
$("span#allowlabel").removeClass("hide")
} else {
$("div#blacklist_input").removeClass("hide")
$("span#denylabel").removeClass("hide")
}
// check changes of the select to update whitelist/blacklist input
$("select#mode").change(function() {
if ($("select#mode").val() == "whitelist") {
$("div#blacklist_input").addClass("hide")
$("span#denylabel").addClass("hide")
$("div#whitelist_input").removeClass("hide")
$("span#allowlabel").removeClass("hide")
} else {
$("div#whitelist_input").addClass("hide")
$("span#allowlabel").addClass("hide")
$("div#blacklist_input").removeClass("hide")
$("span#denylabel").removeClass("hide")
}
})
}

2
src/popup.min.js vendored
Wyświetl plik

@ -1 +1 @@
const t={fediact_homeinstance:null,fediact_alert:!1,fediact_mode:"blacklist",fediact_whitelist:null,fediact_blacklist:null,fediact_target:"_self",fediact_autoaction:!0,fediact_redirects:!0,fediact_enabledelay:!0,fediact_hidemuted:!1,fediact_runifloggedin:!1};var browser,chrome,i;const a=!0,c="[FediAct]";function d(e){a&&console.log(c+" "+e)}function n(){async function t(){i.fediact_homeinstance=$("input#homeinstance").val().trim().toLowerCase(),i.fediact_alert=$("input#alert").is(":checked"),i.fediact_mode=$("select#mode").val(),i.fediact_whitelist=$("textarea#whitelist_content").val(),i.fediact_blacklist=$("textarea#blacklist_content").val(),i.fediact_target=$("select#target").val(),i.fediact_autoaction=$("input#autoaction").is(":checked"),i.fediact_redirects=$("input#redirects").is(":checked"),i.fediact_enabledelay=$("input#delay").is(":checked"),i.fediact_hidemuted=$("input#hidemuted").is(":checked"),i.fediact_runifloggedin=$("input#runifloggedin").is(":checked");try{await(browser||chrome).storage.local.set(i)}catch{return d(e),!1}$("span#indicator").show(),setTimeout(function(){$("span#indicator").hide()},1500)}$(document).ready(function(){$("input#homeinstance").val(i.fediact_homeinstance),$("textarea#blacklist_content").val(i.fediact_blacklist),$("textarea#whitelist_content").val(i.fediact_whitelist),$("select#mode").val(i.fediact_mode),$("select#target").val(i.fediact_target),$("input#alert").prop("checked",i.fediact_alert),$("input#autoaction").prop("checked",i.fediact_autoaction),$("input#redirects").prop("checked",i.fediact_redirects),$("input#delay").prop("checked",i.fediact_enabledelay),$("input#hidemuted").prop("checked",i.fediact_hidemuted),$("input#runifloggedin").prop("checked",i.fediact_runifloggedin),("whitelist"==$("select#mode").val()?$("div#whitelist_input"):$("div#blacklist_input")).removeClass("hide"),$("select#mode").change(function(){("whitelist"==$("select#mode").val()?($("div#blacklist_input").addClass("hide"),$("div#whitelist_input")):($("div#whitelist_input").addClass("hide"),$("div#blacklist_input"))).removeClass("hide")}),$("form#fediact-settings").on("submit",async function(e){e.preventDefault(),t();try{await chrome.runtime.sendMessage({updatedsettings:!0})}catch(e){d(e)}})})}async function l(){try{i=await(browser||chrome).storage.local.get(t)}catch(e){return d(e),!1}i&&n()}l();
const t={fediact_homeinstance:null,fediact_alert:!1,fediact_mode:"blacklist",fediact_whitelist:null,fediact_blacklist:null,fediact_target:"_self",fediact_autoaction:!0,fediact_redirects:!0,fediact_enabledelay:!0,fediact_hidemuted:!1,fediact_runifloggedin:!1};var browser,chrome,i;const a=!0,c="[FediAct]";function d(e){a&&console.log(c+" "+e)}function l(){async function t(){i.fediact_homeinstance=$("input#homeinstance").val().trim().toLowerCase(),i.fediact_alert=$("input#alert").is(":checked"),i.fediact_mode=$("select#mode").val(),i.fediact_whitelist=$("textarea#whitelist_content").val(),i.fediact_blacklist=$("textarea#blacklist_content").val(),i.fediact_target=$("select#target").val(),i.fediact_autoaction=$("input#autoaction").is(":checked"),i.fediact_redirects=$("input#redirects").is(":checked"),i.fediact_enabledelay=$("input#delay").is(":checked"),i.fediact_hidemuted=$("input#hidemuted").is(":checked"),i.fediact_runifloggedin=$("input#runifloggedin").is(":checked");try{await(browser||chrome).storage.local.set(i)}catch{return d(e),!1}$("span#indicator").show(),setTimeout(function(){$("span#indicator").hide()},1500)}$(document).ready(function(){$("input#homeinstance").val(i.fediact_homeinstance),$("textarea#blacklist_content").val(i.fediact_blacklist),$("textarea#whitelist_content").val(i.fediact_whitelist),$("select#mode").val(i.fediact_mode),$("select#target").val(i.fediact_target),$("input#alert").prop("checked",i.fediact_alert),$("input#autoaction").prop("checked",i.fediact_autoaction),$("input#redirects").prop("checked",i.fediact_redirects),$("input#delay").prop("checked",i.fediact_enabledelay),$("input#hidemuted").prop("checked",i.fediact_hidemuted),$("input#runifloggedin").prop("checked",i.fediact_runifloggedin),("whitelist"==$("select#mode").val()?($("div#whitelist_input").removeClass("hide"),$("span#allowlabel")):($("div#blacklist_input").removeClass("hide"),$("span#denylabel"))).removeClass("hide"),$("select#mode").change(function(){("whitelist"==$("select#mode").val()?($("div#blacklist_input").addClass("hide"),$("span#denylabel").addClass("hide"),$("div#whitelist_input").removeClass("hide"),$("span#allowlabel")):($("div#whitelist_input").addClass("hide"),$("span#allowlabel").addClass("hide"),$("div#blacklist_input").removeClass("hide"),$("span#denylabel"))).removeClass("hide")}),$("form#fediact-settings").on("submit",async function(e){e.preventDefault(),t();try{await chrome.runtime.sendMessage({updatedsettings:!0})}catch(e){d(e)}})})}async function n(){try{i=await(browser||chrome).storage.local.get(t)}catch(e){return d(e),!1}i&&l()}n();

Wyświetl plik

@ -2,7 +2,7 @@ html, body {
margin: 0;
height: var(--popup-height);
min-width: 300px;
max-height: 900px;
}
html {
--highlight: rgba(130,130,150,0.1);
@ -11,17 +11,21 @@ html {
--border: rgba(120,120,130,0.3);
--border-2: rgba(130,130,150,0.3);
--radius: 12px;
--popup-height: 400px;
overflow: hidden !important;
--popup-height: 450px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 100%;
}
body {
/* width: 300px; */
flex-grow: 1;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
min-height: var(--popup-height);
overflow: hidden;
}
.hide {
display: none;
@ -37,35 +41,53 @@ h2 {
display: contents;
}
form {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 100%;
}
.scroller {
height: 0;
overflow-y: auto;
flex-grow: 1;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
padding: 10px;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
fieldset {
border: 0;
padding: 0;
margin: 0;
all: unset;
display: block;
}
fieldset > h2, summary {
legend {
all: unset;
}
fieldset > legend, summary {
margin-inline: .6em;
padding-top: .6em;
margin-bottom: .4em;
font-weight: 700;
}
.row {
background-color: var(--highlight);
padding: .8em;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-bottom: 2px;
position: relative;
gap: .4em;
-webkit-transition: background-color .1s;
-o-transition: background-color .1s;
transition: background-color .1s;
}
.row:hover, .row:focus-within {
@ -81,7 +103,9 @@ fieldset > h2, summary {
}
label {
width: 0;
flex-grow: 9999;
-webkit-box-flex: 9999;
-ms-flex-positive: 9999;
flex-grow: 9999;
}
label::before { /* Make entire .row clickable */
content: "";
@ -94,16 +118,35 @@ label span {
opacity: .7;
margin-top: .2em;
}
input[type="text"] {
.text-input-container {
width: 100%;
display: flex;
border: 1px solid var(--border);
border-radius: calc(var(--radius) / 2);
overflow: hidden;
}
.text-input-container span {
padding: .7em;
background-color: var(--highlight);
}
.text-input-container input {
border: 0 !important;
border-radius: 0 !important;
outline: 0;
}
.text-input-container:focus-within {
outline: auto; /* This is the browser's default focus outline */
}
input, textarea, select {
border: 1px solid var(--border);
padding: .7em;
border-radius: calc(var(--radius) / 2);
font-size: inherit;
flex-grow: 1;
box-sizing: border-box;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-webkit-box-sizing: border-box;
box-sizing: border-box;
position: relative;
z-index: 2;
}
@ -124,17 +167,27 @@ select {
}
.footer {
padding: 10px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
border-top: 1px dashed var(--border-2);
position: relative;
background-color: var(--highlight);
box-shadow: 0 0 24px rgba(0,0,0,0.1);
-webkit-box-shadow: 0 0 24px rgba(0,0,0,0.1);
box-shadow: 0 0 24px rgba(0,0,0,0.1);
}
[type="submit"] {
flex-grow: 0;
-webkit-box-flex: 0;
-ms-flex-positive: 0;
flex-grow: 0;
padding-inline: 2em;
}
[type="submit"]:not(:hover):not(:focus) {
@ -142,7 +195,9 @@ select {
}
.footer span {
width: 0;
flex-grow: 1;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
text-align: right;
padding-inline: 1em;
}
@ -152,7 +207,9 @@ select {
color: inherit;
}
#indicator {
order: -1;
-webkit-box-ordinal-group: 0;
-ms-flex-order: -1;
order: -1;
width: calc(100% + 20px);
font-weight: 600;
padding: .7em;
@ -165,5 +222,6 @@ select {
@media (prefers-color-scheme: dark) {
body {
color: white;
background-color: #1c1b22;
}
}

Wyświetl plik

@ -1 +1 @@
html,body{margin:0;height:var(--popup-height);min-width:300px}html{--highlight:rgba(130,130,150,0.1);--confirmation:#268500;--hover:rgba(120,120,130,0.15);--border:rgba(120,120,130,0.3);--border-2:rgba(130,130,150,0.3);--radius:12px;--popup-height:400px;overflow:hidden !important;display:flex;flex-direction:column;height:100%}body{flex-grow:1;min-height:var(--popup-height);overflow:hidden}.hide{display:none}h1{font-size:1em;margin-block:.2em}h2{font-size:1em}#mhi-wrapper,#mhi-containers{display:contents}form{display:flex;flex-direction:column;height:100%}.scroller{height:0;overflow-y:auto;flex-grow:1;padding:10px;box-sizing:border-box}fieldset{border:0;padding:0;margin:0}fieldset>h2,summary{margin-inline:.6em;margin-bottom:.4em}.row{background-color:var(--highlight);padding:.8em;box-sizing:border-box;display:flex;flex-wrap:wrap;margin-bottom:2px;position:relative;gap:.4em;transition:background-color .1s}.row:hover,.row:focus-within{background:var(--hover)}.row:first-of-type{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.row:last-of-type{border-bottom-left-radius:var(--radius);border-bottom-right-radius:var(--radius)}label{width:0;flex-grow:9999}label::before{content:"";position:absolute;inset:0}label span{display:block;font-size:.9em;opacity:.7;margin-top:.2em}input[type="text"]{width:100%}input,textarea,select{border:1px solid var(--border);padding:.7em;border-radius:calc(var(--radius) / 2);font-size:inherit;flex-grow:1;box-sizing:border-box;position:relative;z-index:2}.textarea-container{width:calc(100% - .14em);border-radius:inherit}textarea{resize:vertical;width:100%}select{margin-block:-.8em;padding-block:.4em;border:0;background:0;text-align:right}.footer{padding:10px;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;border-top:1px dashed var(--border-2);position:relative;background-color:var(--highlight);box-shadow:0 0 24px rgba(0,0,0,0.1)}[type="submit"]{flex-grow:0;padding-inline:2em}[type="submit"]:not(:hover):not(:focus){background:0}.footer span{width:0;flex-grow:1;text-align:right;padding-inline:1em}.footer a{opacity:.7;text-underline-offset:.2em;color:inherit}#indicator{order:-1;width:calc(100% + 20px);font-weight:600;padding:.7em;margin:-10px;margin-bottom:8px;background-color:var(--confirmation);text-align:center;color:white}@media(prefers-color-scheme:dark){body{color:white}}
html,body{margin:0;height:var(--popup-height);min-width:300px;max-height:900px}html{--highlight:rgba(130,130,150,0.1);--confirmation:#268500;--hover:rgba(120,120,130,0.15);--border:rgba(120,120,130,0.3);--border-2:rgba(130,130,150,0.3);--radius:12px;--popup-height:450px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:100%}body{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;min-height:var(--popup-height)}.hide{display:none}h1{font-size:1em;margin-block:.2em}h2{font-size:1em}#mhi-wrapper,#mhi-containers{display:contents}form{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:100%}.scroller{height:0;overflow-y:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;padding:10px;-webkit-box-sizing:border-box;box-sizing:border-box}fieldset{all:unset;display:block}legend{all:unset}fieldset>legend,summary{margin-inline:.6em;padding-top:.6em;margin-bottom:.4em;font-weight:700}.row{background-color:var(--highlight);padding:.8em;-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-bottom:2px;position:relative;gap:.4em;-webkit-transition:background-color .1s;-o-transition:background-color .1s;transition:background-color .1s}.row:hover,.row:focus-within{background:var(--hover)}.row:first-of-type{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.row:last-of-type{border-bottom-left-radius:var(--radius);border-bottom-right-radius:var(--radius)}label{width:0;-webkit-box-flex:9999;-ms-flex-positive:9999;flex-grow:9999}label::before{content:"";position:absolute;inset:0}label span{display:block;font-size:.9em;opacity:.7;margin-top:.2em}.text-input-container{width:100%;display:flex;border:1px solid var(--border);border-radius:calc(var(--radius) / 2);overflow:hidden}.text-input-container span{padding:.7em;background-color:var(--highlight)}.text-input-container input{border:0 !important;border-radius:0 !important;outline:0}.text-input-container:focus-within{outline:auto}input,textarea,select{border:1px solid var(--border);padding:.7em;border-radius:calc(var(--radius) / 2);font-size:inherit;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;z-index:2}.textarea-container{width:calc(100% - .14em);border-radius:inherit}textarea{resize:vertical;width:100%}select{margin-block:-.8em;padding-block:.4em;border:0;background:0;text-align:right}.footer{padding:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;border-top:1px dashed var(--border-2);position:relative;background-color:var(--highlight);-webkit-box-shadow:0 0 24px rgba(0,0,0,0.1);box-shadow:0 0 24px rgba(0,0,0,0.1)}[type="submit"]{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding-inline:2em}[type="submit"]:not(:hover):not(:focus){background:0}.footer span{width:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:right;padding-inline:1em}.footer a{opacity:.7;text-underline-offset:.2em;color:inherit}#indicator{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1;width:calc(100% + 20px);font-weight:600;padding:.7em;margin:-10px;margin-bottom:8px;background-color:var(--confirmation);text-align:center;color:white}@media(prefers-color-scheme:dark){body{color:white;background-color:#1c1b22}}