kopia lustrzana https://github.com/lartsch/FediAct
add some try/catches so no irrelevant exceptions bubble up in ext. view, move script el to head (popup), move some code inject.js to separate function, bump version
rodzic
78221bb29d
commit
7d01ebc1fc
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "FediAct",
|
||||
"version": "0.9.1",
|
||||
"version": "0.9.2",
|
||||
"description": "Simplifies interactions on other Mastodon instances than your own. Visit https://github.com/lartsch/FediFollow-Chrome for more.",
|
||||
"manifest_version": 2,
|
||||
"content_scripts": [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "FediAct",
|
||||
"version": "0.9.1",
|
||||
"version": "0.9.2",
|
||||
"description": "Simplifies interactions on other Mastodon instances than your own. Visit https://github.com/lartsch/FediFollow-Chrome for more.",
|
||||
"manifest_version": 3,
|
||||
"content_scripts": [
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
var browser, chrome, settings;
|
||||
var enableConsoleLog = true;
|
||||
var logPrepend = "[FediAct]";
|
||||
var tokenInterval = 5
|
||||
const enableConsoleLog = true;
|
||||
const logPrepend = "[FediAct]";
|
||||
const tokenInterval = 3 // minutes
|
||||
|
||||
var tokenRegex = /"access_token":".*?",/gm;
|
||||
const tokenRegex = /"access_token":".*?",/gm;
|
||||
|
||||
// required settings keys with defauls
|
||||
var settingsDefaults = {
|
||||
const settingsDefaults = {
|
||||
fediact_homeinstance: null,
|
||||
fediact_showfollows: true
|
||||
}
|
||||
|
||||
function onError(error){
|
||||
console.error(`${logPrepend} Error: ${error}`);
|
||||
}
|
||||
|
||||
// wrapper to prepend to log messages
|
||||
function log(text) {
|
||||
if (enableConsoleLog) {
|
||||
|
@ -25,10 +21,15 @@ function log(text) {
|
|||
// get redirect url (it will be the url on the toot authors home instance)
|
||||
async function resolveToot(url) {
|
||||
return new Promise(async function(resolve) {
|
||||
var res = await fetch(url, {method: 'HEAD'})
|
||||
if (res.redirected) {
|
||||
resolve(res.url)
|
||||
} else {
|
||||
try {
|
||||
var res = await fetch(url, {method: 'HEAD'})
|
||||
if (res.redirected) {
|
||||
resolve(res.url)
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
} catch(e) {
|
||||
log(e)
|
||||
resolve(false)
|
||||
}
|
||||
});
|
||||
|
@ -37,8 +38,13 @@ async function resolveToot(url) {
|
|||
// fetch API token here (will use logged in session automatically)
|
||||
async function fetchBearerToken() {
|
||||
var url = "https://" + settings.fediact_homeinstance;
|
||||
var res = await fetch(url);
|
||||
var text = await res.text();
|
||||
try {
|
||||
var res = await fetch(url);
|
||||
var text = await res.text();
|
||||
} catch(e) {
|
||||
log(e)
|
||||
return false
|
||||
}
|
||||
if (text) {
|
||||
// dom parser is not available in background workers, so we use regex to parse the html....
|
||||
// for some reason, regex groups do also not seem to work in chrome background workers... the following is ugly but should work fine
|
||||
|
@ -49,10 +55,9 @@ async function fetchBearerToken() {
|
|||
if (indexOne > -1 && indexTwo > -1) {
|
||||
indexOne = indexOne + 16
|
||||
var token = content[0].substring(indexOne, indexTwo);
|
||||
console.log(token)
|
||||
if (token.length > 16) {
|
||||
settings.fediact_token = token;
|
||||
return;
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,13 +68,22 @@ async function fetchBearerToken() {
|
|||
}
|
||||
|
||||
async function fetchData() {
|
||||
settings = await (browser || chrome).storage.local.get(settingsDefaults);
|
||||
try {
|
||||
settings = await (browser || chrome).storage.local.get(settingsDefaults)
|
||||
} catch(e) {
|
||||
log(e)
|
||||
return false
|
||||
}
|
||||
if (settings.fediact_homeinstance) {
|
||||
await fetchBearerToken()
|
||||
} else {
|
||||
log("Home instance not set");
|
||||
}
|
||||
await (browser || chrome).storage.local.set(settings);
|
||||
try {
|
||||
await (browser || chrome).storage.local.set(settings)
|
||||
} catch {
|
||||
log(e)
|
||||
}
|
||||
}
|
||||
|
||||
// fetch api token right after install (mostly for debugging, when the ext. is reloaded)
|
||||
|
@ -96,7 +110,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|||
// if the tabId of the update event is the same like the tabId that started the listener in the first place AND when the update event is an URL
|
||||
if (tabId === sender.tab.id && changeInfo.url) {
|
||||
// ... then let the content script know about the change
|
||||
chrome.tabs.sendMessage(tabId, {urlchanged: changeInfo.url})
|
||||
try {
|
||||
chrome.tabs.sendMessage(tabId, {urlchanged: changeInfo.url})
|
||||
} catch(e) {
|
||||
log(e)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
var browser,chrome,a,t=!0,n="[FediAct]",o=/"access_token":".*?",/gm,e={fediact_homeinstance:null,fediact_showfollows:!0};function s(e){console.error(n+" Error: "+e)}function i(e){t&&console.log(n+" "+e)}async function r(n){return new Promise(async function(e){var t=await fetch(n,{method:"HEAD"});t.redirected?e(t.url):e(!1)})}async function c(){var e="https://"+a.fediact_homeinstance,e=await(await fetch(e)).text();if(e){e=e.match(o);if(e){var t=e[0].search(/"access_token":"/),n=e[0].search(/",/);if(-1<t&&-1<n){e=e[0].substring(t+=16,n);if(console.log(e),16<e.length)return void(a.fediact_token=e)}}}a.fediact_token=null,i("Token could not be found.")}async function d(){(a=await(browser||chrome).storage.local.get(e)).fediact_homeinstance?await c():i("Home instance not set"),await(browser||chrome).storage.local.set(a)}chrome.runtime.onInstalled.addListener(d),chrome.alarms.create("refresh",{periodInMinutes:1}),chrome.alarms.onAlarm.addListener(d),chrome.runtime.onMessage.addListener((e,a,t)=>{if(e.url)return r(e.url).then(t),!0;e.updatedsettings&&d(),e.running&&chrome.tabs.onUpdated.addListener(function(e,t,n){e===a.tab.id&&t.url&&chrome.tabs.sendMessage(e,{urlchanged:t.url})})});
|
||||
var browser,chrome,n;const a=!0,c="[FediAct]",t=3,r=/"access_token":".*?",/gm,s={fediact_homeinstance:null,fediact_showfollows:!0};function i(t){a&&console.log(c+" "+t)}async function o(a){return new Promise(async function(e){try{var t=await fetch(a,{method:"HEAD"});t.redirected?e(t.url):e(!1)}catch(t){i(t),e(!1)}})}async function d(){var t="https://"+n.fediact_homeinstance;try{var e=await(await fetch(t)).text()}catch(t){return i(t),!1}if(e){t=e.match(r);if(t){var e=t[0].search(/"access_token":"/),a=t[0].search(/",/);if(-1<e&&-1<a){t=t[0].substring(e+=16,a);if(16<t.length)return n.fediact_token=t,!0}}}n.fediact_token=null,i("Token could not be found.")}async function u(){try{n=await(browser||chrome).storage.local.get(s)}catch(t){return i(t),!1}n.fediact_homeinstance?await d():i("Home instance not set");try{await(browser||chrome).storage.local.set(n)}catch{i(e)}}chrome.runtime.onInstalled.addListener(u),chrome.alarms.create("refresh",{periodInMinutes:t}),chrome.alarms.onAlarm.addListener(u),chrome.runtime.onMessage.addListener((t,n,e)=>{if(t.url)return o(t.url).then(e),!0;t.updatedsettings&&u(),t.running&&chrome.tabs.onUpdated.addListener(function(t,e,a){if(t===n.tab.id&&e.url)try{chrome.tabs.sendMessage(t,{urlchanged:e.url})}catch(t){i(t)}})});
|
109
src/inject.js
109
src/inject.js
|
@ -120,7 +120,12 @@ async function makeRequest(method, url, extraheaders) {
|
|||
statusText: xhr.statusText
|
||||
});
|
||||
};
|
||||
xhr.send();
|
||||
try {
|
||||
xhr.send()
|
||||
} catch(e) {
|
||||
log(e)
|
||||
resolve(false)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -411,13 +416,18 @@ function resolveTootToExternalHome(tooturl) {
|
|||
// TODO: check if a delay is necessary here too
|
||||
if (tooturl) {
|
||||
return new Promise(resolve => {
|
||||
chrome.runtime.sendMessage({url: tooturl}, function(response) {
|
||||
if(response) {
|
||||
resolve(response);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
try {
|
||||
chrome.runtime.sendMessage({url: tooturl}, function(response) {
|
||||
if(response) {
|
||||
resolve(response);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
resolve(false)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false
|
||||
|
@ -738,6 +748,24 @@ async function processToots() {
|
|||
async function processFollow() {
|
||||
// for mastodon v3 - v4 does not show follow buttons / account cards on /explore
|
||||
async function process(el) {
|
||||
// wrapper for follow/unfollow action
|
||||
async function execFollow(action, id) {
|
||||
if (action == "follow") {
|
||||
var followed = await followHomeInstance(id)
|
||||
if (followed) {
|
||||
$(el).text("Unfollow");
|
||||
action = "unfollow"
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
var unfollowed = await unfollowHomeInstance(id)
|
||||
if (unfollowed) {
|
||||
$(el).text("Follow");
|
||||
action = "follow"
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
var fullHandle
|
||||
var action = "follow"
|
||||
// for mastodon v3 explore page
|
||||
|
@ -773,39 +801,12 @@ async function processFollow() {
|
|||
clicks++;
|
||||
if (clicks == 1) {
|
||||
timer = setTimeout(async function() {
|
||||
if (action == "follow") {
|
||||
var followed = await followHomeInstance(resolvedHandle[0])
|
||||
if (followed) {
|
||||
$(el).text("Unfollow");
|
||||
action = "unfollow"
|
||||
}
|
||||
} else {
|
||||
var unfollowed = await unfollowHomeInstance(resolvedHandle[0])
|
||||
if (unfollowed) {
|
||||
$(el).text("Follow");
|
||||
action = "follow"
|
||||
}
|
||||
}
|
||||
execFollow(action, resolvedHandle[0])
|
||||
clicks = 0;
|
||||
}, 350);
|
||||
} else {
|
||||
clearTimeout(timer);
|
||||
var done
|
||||
if (action == "follow") {
|
||||
var followed = await followHomeInstance(resolvedHandle[0])
|
||||
if (followed) {
|
||||
$(el).text("Unfollow");
|
||||
action = "unfollow"
|
||||
done = true
|
||||
}
|
||||
} else {
|
||||
var unfollowed = await unfollowHomeInstance(resolvedHandle[0])
|
||||
if (unfollowed) {
|
||||
$(el).text("Follow");
|
||||
action = "follow"
|
||||
done = true
|
||||
}
|
||||
}
|
||||
var done = await execFollow(action, resolvedHandle[0])
|
||||
if (done) {
|
||||
var saveText = $(el).text()
|
||||
var redirectUrl = 'https://' + settings.fediact_homeinstance + '/@' + resolvedHandle[1]
|
||||
|
@ -828,7 +829,9 @@ async function processFollow() {
|
|||
}
|
||||
}
|
||||
}
|
||||
// create css selector from selector array
|
||||
var allFollowPaths = followButtonPaths.join(",")
|
||||
// one domnodeappear to rule them all
|
||||
$(document).DOMNodeAppear(async function(e) {
|
||||
process($(e.target))
|
||||
}, allFollowPaths)
|
||||
|
@ -930,21 +933,32 @@ async function checkSite() {
|
|||
}
|
||||
|
||||
function urlChangeMonitor() {
|
||||
// send message to initialize onUpdated listener (this way we do not need to bind the listener for ALL sites)
|
||||
chrome.runtime.sendMessage({running: true})
|
||||
// then wait for any url changes
|
||||
// wait for any url change messages from background script
|
||||
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
if (request.urlchanged) {
|
||||
// reset already processed elements
|
||||
processed = []
|
||||
}
|
||||
});
|
||||
// send message to initialize onUpdated listener in background script (this way it gets the tabid and we do not need to bind the listener for ALL sites)
|
||||
try {
|
||||
chrome.runtime.sendMessage({running: true})
|
||||
return true
|
||||
} catch(e) {
|
||||
log(e)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// run wrapper
|
||||
async function run() {
|
||||
// get settings
|
||||
settings = await (browser || chrome).storage.local.get(settingsDefaults);
|
||||
// get setting
|
||||
try {
|
||||
settings = await (browser || chrome).storage.local.get(settingsDefaults)
|
||||
} catch(e) {
|
||||
log(e)
|
||||
return false
|
||||
}
|
||||
if (settings) {
|
||||
// validate settings
|
||||
if (checkSettings()) {
|
||||
|
@ -953,9 +967,12 @@ async function run() {
|
|||
if (fedireply) {
|
||||
processReply()
|
||||
} else {
|
||||
urlChangeMonitor();
|
||||
processFollow();
|
||||
processToots();
|
||||
if (urlChangeMonitor()) {
|
||||
processFollow()
|
||||
processToots()
|
||||
} else {
|
||||
log("Failed to initialize background script.")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log("Will not process this site.")
|
||||
|
@ -966,4 +983,4 @@ async function run() {
|
|||
}
|
||||
}
|
||||
|
||||
run()
|
||||
run()
|
File diff suppressed because one or more lines are too long
|
@ -13,6 +13,8 @@
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
<script src="lib/jquery-3.6.1.min.js"></script>
|
||||
<script src="popup.min.js"></script>
|
||||
</head>
|
||||
<body style="min-width: 300px">
|
||||
<div id="mhi-wrapper">
|
||||
|
@ -58,7 +60,5 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="lib/jquery-3.6.1.min.js"></script>
|
||||
<script src="popup.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
64
src/popup.js
64
src/popup.js
|
@ -1,6 +1,6 @@
|
|||
|
||||
// required settings keys with defauls
|
||||
var settings = {
|
||||
const settingsDefaults = {
|
||||
fediact_homeinstance: null,
|
||||
fediact_alert: false,
|
||||
fediact_mode: "blacklist",
|
||||
|
@ -14,23 +14,28 @@ var settings = {
|
|||
}
|
||||
|
||||
// fix for cross-browser storage api compatibility
|
||||
var browser, chrome;
|
||||
var browser, chrome, settings;
|
||||
const enableConsoleLog = true;
|
||||
const logPrepend = "[FediAct]";
|
||||
|
||||
function onError(error){
|
||||
console.error(`[FediAct] Error: ${error}`);
|
||||
// wrapper to prepend to log messages
|
||||
function log(text) {
|
||||
if (enableConsoleLog) {
|
||||
console.log(logPrepend + ' ' + text)
|
||||
}
|
||||
}
|
||||
|
||||
// this performs loading the settings into the popup, reacting to changes and saving changes
|
||||
function popupTasks(settings) {
|
||||
|
||||
function popupTasks() {
|
||||
// function to show confirmation when settings were updated successfully
|
||||
function showConfirmation() {
|
||||
$("span#indicator").show();
|
||||
setTimeout(function() {
|
||||
$("span#indicator").hide();
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function updateSettings(){
|
||||
// get all current values and write them to the local storage
|
||||
async function updateSettings(){
|
||||
// update settings values
|
||||
settings.fediact_homeinstance = $("input#homeinstance").val().trim();
|
||||
settings.fediact_alert = $("input#alert").is(':checked');
|
||||
|
@ -43,11 +48,16 @@ function popupTasks(settings) {
|
|||
settings.fediact_redirects = $("input#redirects").is(':checked');
|
||||
settings.fediact_enabledelay = $("input#delay").is(':checked');
|
||||
// write to storage
|
||||
const waitForSaved = (browser || chrome).storage.local.set(settings);
|
||||
try {
|
||||
await (browser || chrome).storage.local.set(settings)
|
||||
} catch {
|
||||
log(e)
|
||||
return false
|
||||
}
|
||||
// show saved indicator after successful save
|
||||
waitForSaved.then(showConfirmation(), onError);
|
||||
showConfirmation()
|
||||
}
|
||||
|
||||
// restore form based on loaded settings
|
||||
function restoreForm() {
|
||||
// set all default/configured values and show fields accordingly
|
||||
$("input#homeinstance").val(settings.fediact_homeinstance);
|
||||
|
@ -77,20 +87,34 @@ function popupTasks(settings) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(async function() {
|
||||
$(document).ready(function() {
|
||||
// restore the form values
|
||||
restoreForm();
|
||||
// perform storage actions on form submit
|
||||
$("form#fediact-settings").on('submit', function(e){
|
||||
// prevent default
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
// update settings
|
||||
updateSettings();
|
||||
chrome.runtime.sendMessage({updatedsettings: true});
|
||||
});
|
||||
});
|
||||
|
||||
updateSettings()
|
||||
try {
|
||||
chrome.runtime.sendMessage({updatedsettings: true})
|
||||
} catch(e) {
|
||||
log(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
(browser || chrome).storage.local.get(settings).then(popupTasks, onError)
|
||||
async function loadAndRun() {
|
||||
try {
|
||||
settings = await (browser || chrome).storage.local.get(settingsDefaults)
|
||||
} catch(e) {
|
||||
log(e)
|
||||
return false
|
||||
}
|
||||
if (settings) {
|
||||
popupTasks()
|
||||
}
|
||||
}
|
||||
|
||||
loadAndRun()
|
|
@ -1 +1 @@
|
|||
var browser,chrome,t={fediact_homeinstance:null,fediact_alert:!1,fediact_mode:"blacklist",fediact_whitelist:null,fediact_blacklist:null,fediact_target:"_self",fediact_autoaction:!0,fediact_showfollows:!0,fediact_redirects:!0,fediact_enabledelay:!0};function i(t){console.error("[FediAct] Error: "+t)}function e(t){function e(){t.fediact_homeinstance=$("input#homeinstance").val().trim(),t.fediact_alert=$("input#alert").is(":checked"),t.fediact_mode=$("select#mode").val(),t.fediact_whitelist=$("textarea#whitelist_content").val(),t.fediact_blacklist=$("textarea#blacklist_content").val(),t.fediact_target=$("select#target").val(),t.fediact_autoaction=$("input#autoaction").is(":checked"),t.fediact_showfollows=$("input#showfollows").is(":checked"),t.fediact_redirects=$("input#redirects").is(":checked"),t.fediact_enabledelay=$("input#delay").is(":checked"),(browser||chrome).storage.local.set(t).then(($("span#indicator").show(),void setTimeout(function(){$("span#indicator").hide()},1500)),i)}$(document).ready(async function(){$("input#homeinstance").val(t.fediact_homeinstance),$("textarea#blacklist_content").val(t.fediact_blacklist),$("textarea#whitelist_content").val(t.fediact_whitelist),$("select#mode").val(t.fediact_mode),$("select#target").val(t.fediact_target),$("input#alert").prop("checked",t.fediact_alert),$("input#autoaction").prop("checked",t.fediact_autoaction),$("input#showfollows").prop("checked",t.fediact_showfollows),$("input#redirects").prop("checked",t.fediact_redirects),$("input#delay").prop("checked",t.fediact_enabledelay),("whitelist"==$("select#mode").val()?$("div#whitelist_input"):$("div#blacklist_input")).show(),$("select#mode").change(function(){("whitelist"==$("select#mode").val()?($("div#blacklist_input").hide(),$("div#whitelist_input")):($("div#whitelist_input").hide(),$("div#blacklist_input"))).show()}),$("form#fediact-settings").on("submit",function(t){t.preventDefault(),e(),chrome.runtime.sendMessage({updatedsettings:!0})})})}(browser||chrome).storage.local.get(t).then(e,i);
|
||||
const t={fediact_homeinstance:null,fediact_alert:!1,fediact_mode:"blacklist",fediact_whitelist:null,fediact_blacklist:null,fediact_target:"_self",fediact_autoaction:!0,fediact_showfollows:!0,fediact_redirects:!0,fediact_enabledelay:!0};var browser,chrome,a;const i=!0,c="[FediAct]";function l(t){i&&console.log(c+" "+t)}function n(){async function i(){a.fediact_homeinstance=$("input#homeinstance").val().trim(),a.fediact_alert=$("input#alert").is(":checked"),a.fediact_mode=$("select#mode").val(),a.fediact_whitelist=$("textarea#whitelist_content").val(),a.fediact_blacklist=$("textarea#blacklist_content").val(),a.fediact_target=$("select#target").val(),a.fediact_autoaction=$("input#autoaction").is(":checked"),a.fediact_showfollows=$("input#showfollows").is(":checked"),a.fediact_redirects=$("input#redirects").is(":checked"),a.fediact_enabledelay=$("input#delay").is(":checked");try{await(browser||chrome).storage.local.set(a)}catch{return l(e),!1}$("span#indicator").show(),setTimeout(function(){$("span#indicator").hide()},1500)}$(document).ready(function(){$("input#homeinstance").val(a.fediact_homeinstance),$("textarea#blacklist_content").val(a.fediact_blacklist),$("textarea#whitelist_content").val(a.fediact_whitelist),$("select#mode").val(a.fediact_mode),$("select#target").val(a.fediact_target),$("input#alert").prop("checked",a.fediact_alert),$("input#autoaction").prop("checked",a.fediact_autoaction),$("input#showfollows").prop("checked",a.fediact_showfollows),$("input#redirects").prop("checked",a.fediact_redirects),$("input#delay").prop("checked",a.fediact_enabledelay),("whitelist"==$("select#mode").val()?$("div#whitelist_input"):$("div#blacklist_input")).show(),$("select#mode").change(function(){("whitelist"==$("select#mode").val()?($("div#blacklist_input").hide(),$("div#whitelist_input")):($("div#whitelist_input").hide(),$("div#blacklist_input"))).show()}),$("form#fediact-settings").on("submit",function(t){t.preventDefault(),i();try{chrome.runtime.sendMessage({updatedsettings:!0})}catch(t){l(t)}})})}async function d(){try{a=await(browser||chrome).storage.local.get(t)}catch(t){return l(t),!1}a&&n()}d();
|
Ładowanie…
Reference in New Issue