diff --git a/src/inject.js b/src/inject.js index 31117d6..5140150 100644 --- a/src/inject.js +++ b/src/inject.js @@ -678,9 +678,9 @@ async function processToots() { e.stopImmediatePropagation(); redirectTo(resolveAndAction[0]+"?fedireply") }) - var clicks = 0; - var timer; $([favButton, boostButton, bookmarkButton]).each(function() { + var clicks = 0; + var timer; $(this).on("click", async function(e) { // prevent default and immediate propagation e.preventDefault(); diff --git a/src/inject.min.js b/src/inject.min.js index bb0b624..9c8a5fe 100644 --- a/src/inject.min.js +++ b/src/inject.min.js @@ -1 +1 @@ -const e=["div.account__header button.logo-button","div.public-account-header a.logo-button","div.account-card a.logo-button","div.directory-card a.icon-button","div.detailed-status a.logo-button"],o=["div.account__header__tabs__name small","div.public-account-header__tabs__name small","div.detailed-status span.display-name__account","div.display-name > span"],a=/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/,i=/^(https?:\/\/(www\.)?.*\..*?\/)((@\w+(@([\w-]+\.)+?\w+)?)|explore|following|followers)\/?(\d+)?\/?$/,t=/^(https?:\/\/(www\.)?.*\..*?\/)((@\w+(@([\w-]+\.)+?\w+)?)|explore|public|public\/local)\/?(\d+)?\/?$/,n=/^(?:https?:\/\/(www\.)?.*\..*?\/)(@\w+(?:@([\w-]+\.)+?\w+)?)\/\d+\/?$/,f=/^[^@]*@(?\w+)(@(?([\w-]+\.)+?\w+))?\/?$/,l=!0,r="[FediFollow]",M=200,s="/api/v1/instance",d="/api/v1/statuses",c="/api/v2/search",u="/api/v1/accounts",h=500;var browser,chrome,w,p,m={};const v={fedifollow_homeinstance:null,fedifollow_alert:!1,fedifollow_mode:"blacklist",fedifollow_whitelist:null,fedifollow_blacklist:null,fedifollow_target:"_self",fedifollow_autoaction:!0,fedifollow_token:null,fedifollow_showfollows:!0,fedifollow_redirects:!0,fedifollow_enabledelay:!0};var g=window.location.href;function b(t){l&&console.log(r+" "+t)}!function(a){a.fn.DOMNodeAppear=function(e,o){var t=a(this);if(!(o=o||"function"==typeof t.selector&&t.selector))return!1;a(document).on("animationstart webkitAnimationStart oanimationstart MSAnimationStart",function(t){"nodeInserted"==t.originalEvent.animationName&&a(t.target).is(o)&&"function"==typeof e&&e(t)})},jQuery.fn.onAppear=jQuery.fn.DOMNodeAppear}(jQuery);var _=function(t){for(var e,o=window.location.search.substring(1).split("&"),a=0;a{setTimeout(function(){t()},h-e)}),w=t),new Promise(function(t,e){let o=new XMLHttpRequest;if(o.open(i,n),o.timeout=3e3,l)for(var a in l)o.setRequestHeader(a,l[a]);o.onload=function(){200<=this.status&&this.status<300?t(o.responseText):t(!1)},o.onerror=function(){e({status:this.status,statusText:o.statusText})},o.send()})}function k(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function T(t,e,o){return t.replace(new RegExp(k(e),"g"),o)}function O(t){var e;m.fedifollow_redirects?(m.fedifollow_alert&&alert("Redirecting..."),e=window.open(t,m.fedifollow_target),b("Redirected to "+t),e?e.focus():b("Could not open new window. Please allow popups for this website.")):b("Redirects disabled.")}async function A(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+u+"/"+t+"/follow",m.tokenheader);if(t)return!(!(t=JSON.parse(t)).following&&!t.requested&&(b("Follow failed."),1))}else b("Auto-action disabled.")}async function S(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+u+"/"+t+"/unfollow",m.tokenheader);if(t)return!(t=JSON.parse(t)).following&&!t.requested||(b("Unfollow failed."),!1)}else b("Auto-action disabled.")}async function x(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/reblog",m.tokenheader);if(t)return!!JSON.parse(t).reblogged||(b("Boost failed."),!1)}else b("Auto-action disabled.")}async function R(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unreblog",m.tokenheader);if(t)return!JSON.parse(t).reblogged||(b("Unboost failed."),!1)}else b("Auto-action disabled.")}async function U(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/favourite",m.tokenheader);if(t)return!!JSON.parse(t).favourited||(b("Favourite failed."),!1)}else b("Auto-action disabled.")}async function E(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unfavourite",m.tokenheader);if(t)return!JSON.parse(t).favourited||(b("Unfavourite failed."),!1)}else b("Auto-action disabled.")}async function q(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/bookmark",m.tokenheader);if(t)return!!JSON.parse(t).bookmarked||(b("Bookmark failed."),!1)}else b("Auto-action disabled.")}async function F(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unbookmark",m.tokenheader);if(t)return!JSON.parse(t).bookmarked||(b("Unbookmark failed."),!1)}else b("Auto-action disabled.")}async function j(t){var e="https://"+m.fedifollow_homeinstance+u+"/relationships?";for(const n of t)e+="id[]="+n.toString()+"&";var o=await y("GET",e,m.tokenheader),a=Array(t.length).fill(!1);if(o)for(var o=JSON.parse(o),i=0;i{var o=setInterval(function(){var t=$("body").html();t==a?(changing=!1,e(!0),clearInterval(o)):a=t},100)}),$(document).find("div.entry > div.status").each(function(){o($(this))})}),$(document).DOMNodeAppear(async function(t){var t=$(t.target),a=$("body").html();await new Promise(e=>{var o=setInterval(function(){var t=$("body").html();t==a?(changing=!1,e(!0),clearInterval(o)):a=t},100)}),t.find("div.status").each(async function(){document.body.contains($(this)[0])&&o($(this))}),z(t,{subtree:!0,childList:!0},["div.status"],function(t,e){o($(t))})},"article, div.entry > div.status")):b("There are no toots on this site")}async function I(){var t;i.test(g.split("?")[0])?(t=e.join(","),$(document).DOMNodeAppear(async function(t){!async function(i){var t,n,l,r,s="follow";if($(i).closest("div.account-card").length)t=$(i).closest("div.account-card").find("div.display-name > span").text().trim();else for(const e of o)if($(e).length){t=$(e).text().trim();break}t&&((n=await G(t))?(m.fedifollow_showfollows&&(await j([n[0]]))[0]&&($(i).text("Unfollow"),s="unfollow"),l=0,$(i).off(),$(i).unbind(),$(i).on("click",async function(t){var e,o,a;t.preventDefault(),t.stopImmediatePropagation(),1==++l?r=setTimeout(async function(){"follow"==s?await A(n[0])&&($(i).text("Unfollow"),s="unfollow"):await S(n[0])&&($(i).text("Follow"),s="follow"),l=0},350):(clearTimeout(r),"follow"==s?await A(n[0])&&($(i).text("Unfollow"),s="unfollow",e=!0):await S(n[0])&&($(i).text("Follow"),s="follow",e=!0),e?(o=$(i).text(),a="https://"+m.fedifollow_homeinstance+"/@"+n[1],$(i).text("Redirecting..."),setTimeout(function(){O(a),$(i).text(o)},1e3)):b("Action failed."),l=0)}).on("dblclick",function(t){t.preventDefault(),t.stopImmediatePropagation()})):b("Could not resolve user home ID."))}($(t.target))},t)):b("Not a profile URL.")}async function D(){setTimeout(function(){g!=window.location.href&&(g=window.location.href,I(),P()),D()},300)}function J(t){var e,o=[];for(e of t.split(/\r?\n/))e=e.trim(),a.test(e)?o.push(e):b("Removed invalid domain "+e+" from blacklist/whitelist.");return[...new Set(o)]}function L(){if(null==m.fedifollow_homeinstance||!m.fedifollow_homeinstance)return b("Mastodon home instance is not set."),!1;if(!m.fedifollow_token)return b("No API token available. Are you logged in to your home instance? If yes, wait for 1-2 minutes and reload page."),!1;if(m.tokenheader={Authorization:"Bearer "+m.fedifollow_token},!a.test(m.fedifollow_homeinstance))return b("Instance setting is not a valid domain name."),!1;if($.inArray(m.fedifollow_mode,["blacklist","whitelist"])<0&&(m.fedifollow_mode="blacklist"),$.inArray(m.fedifollow_target,["_blank","_self"])<0&&(m.fedifollow_target="_blank"),"whitelist"==m.fedifollow_mode){if(m.fedifollow_whitelist=J(m.fedifollow_whitelist),m.fedifollow_whitelist.length<1)return b("Whitelist is empty or invalid."),!1}else m.fedifollow_blacklist=J(m.fedifollow_blacklist);return!0}async function Q(){if(location.hostname!=m.fedifollow_homeinstance||(p=_("fedireply"))){if("whitelist"==m.fedifollow_mode){if($.inArray(location.hostname,m.fedifollow_whitelist)<0)return b("Current site is not in whitelist."),!1}else if(-1<$.inArray(location.hostname,m.fedifollow_blacklist))return b("Current site is in blacklist."),!1;var t=await y("GET",location.protocol+"//"+location.hostname+s,null);if(t)if(JSON.parse(t).uri)return!0;b("Does not look like a Mastodon instance.")}else b("Current site is your home instance.");return!1}async function X(){(m=await(browser||chrome).storage.local.get(v))?L()&&(await Q()?(p?B:(I(),P(),D))():b("Will not process this site.")):b("Could not load settings.")}X(); \ No newline at end of file +const e=["div.account__header button.logo-button","div.public-account-header a.logo-button","div.account-card a.logo-button","div.directory-card a.icon-button","div.detailed-status a.logo-button"],o=["div.account__header__tabs__name small","div.public-account-header__tabs__name small","div.detailed-status span.display-name__account","div.display-name > span"],a=/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/,i=/^(https?:\/\/(www\.)?.*\..*?\/)((@\w+(@([\w-]+\.)+?\w+)?)|explore|following|followers)\/?(\d+)?\/?$/,t=/^(https?:\/\/(www\.)?.*\..*?\/)((@\w+(@([\w-]+\.)+?\w+)?)|explore|public|public\/local)\/?(\d+)?\/?$/,n=/^(?:https?:\/\/(www\.)?.*\..*?\/)(@\w+(?:@([\w-]+\.)+?\w+)?)\/\d+\/?$/,s=/^[^@]*@(?\w+)(@(?([\w-]+\.)+?\w+))?\/?$/,l=!0,r="[FediFollow]",M=200,f="/api/v1/instance",d="/api/v1/statuses",c="/api/v2/search",u="/api/v1/accounts",h=500;var browser,chrome,w,p,m={};const v={fedifollow_homeinstance:null,fedifollow_alert:!1,fedifollow_mode:"blacklist",fedifollow_whitelist:null,fedifollow_blacklist:null,fedifollow_target:"_self",fedifollow_autoaction:!0,fedifollow_token:null,fedifollow_showfollows:!0,fedifollow_redirects:!0,fedifollow_enabledelay:!0};var g=window.location.href;function b(t){l&&console.log(r+" "+t)}!function(a){a.fn.DOMNodeAppear=function(e,o){var t=a(this);if(!(o=o||"function"==typeof t.selector&&t.selector))return!1;a(document).on("animationstart webkitAnimationStart oanimationstart MSAnimationStart",function(t){"nodeInserted"==t.originalEvent.animationName&&a(t.target).is(o)&&"function"==typeof e&&e(t)})},jQuery.fn.onAppear=jQuery.fn.DOMNodeAppear}(jQuery);var _=function(t){for(var e,o=window.location.search.substring(1).split("&"),a=0;a{setTimeout(function(){t()},h-e)}),w=t),new Promise(function(t,e){let o=new XMLHttpRequest;if(o.open(i,n),o.timeout=3e3,l)for(var a in l)o.setRequestHeader(a,l[a]);o.onload=function(){200<=this.status&&this.status<300?t(o.responseText):t(!1)},o.onerror=function(){e({status:this.status,statusText:o.statusText})},o.send()})}function k(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function T(t,e,o){return t.replace(new RegExp(k(e),"g"),o)}function O(t){var e;m.fedifollow_redirects?(m.fedifollow_alert&&alert("Redirecting..."),e=window.open(t,m.fedifollow_target),b("Redirected to "+t),e?e.focus():b("Could not open new window. Please allow popups for this website.")):b("Redirects disabled.")}async function A(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+u+"/"+t+"/follow",m.tokenheader);if(t)return!(!(t=JSON.parse(t)).following&&!t.requested&&(b("Follow failed."),1))}else b("Auto-action disabled.")}async function S(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+u+"/"+t+"/unfollow",m.tokenheader);if(t)return!(t=JSON.parse(t)).following&&!t.requested||(b("Unfollow failed."),!1)}else b("Auto-action disabled.")}async function x(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/reblog",m.tokenheader);if(t)return!!JSON.parse(t).reblogged||(b("Boost failed."),!1)}else b("Auto-action disabled.")}async function R(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unreblog",m.tokenheader);if(t)return!JSON.parse(t).reblogged||(b("Unboost failed."),!1)}else b("Auto-action disabled.")}async function U(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/favourite",m.tokenheader);if(t)return!!JSON.parse(t).favourited||(b("Favourite failed."),!1)}else b("Auto-action disabled.")}async function E(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unfavourite",m.tokenheader);if(t)return!JSON.parse(t).favourited||(b("Unfavourite failed."),!1)}else b("Auto-action disabled.")}async function q(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/bookmark",m.tokenheader);if(t)return!!JSON.parse(t).bookmarked||(b("Bookmark failed."),!1)}else b("Auto-action disabled.")}async function F(t){if(m.fedifollow_autoaction){t=await y("POST","https://"+m.fedifollow_homeinstance+d+"/"+t+"/unbookmark",m.tokenheader);if(t)return!JSON.parse(t).bookmarked||(b("Unbookmark failed."),!1)}else b("Auto-action disabled.")}async function j(t){var e="https://"+m.fedifollow_homeinstance+u+"/relationships?";for(const n of t)e+="id[]="+n.toString()+"&";var o=await y("GET",e,m.tokenheader),a=Array(t.length).fill(!1);if(o)for(var o=JSON.parse(o),i=0;i{var o=setInterval(function(){var t=$("body").html();t==a?(changing=!1,e(!0),clearInterval(o)):a=t},100)}),$(document).find("div.entry > div.status").each(function(){o($(this))})}),$(document).DOMNodeAppear(async function(t){var t=$(t.target),a=$("body").html();await new Promise(e=>{var o=setInterval(function(){var t=$("body").html();t==a?(changing=!1,e(!0),clearInterval(o)):a=t},100)}),t.find("div.status").each(async function(){document.body.contains($(this)[0])&&o($(this))}),z(t,{subtree:!0,childList:!0},["div.status"],function(t,e){o($(t))})},"article, div.entry > div.status")):b("There are no toots on this site")}async function I(){var t;i.test(g.split("?")[0])?(t=e.join(","),$(document).DOMNodeAppear(async function(t){!async function(i){var t,n,l,r,s="follow";if($(i).closest("div.account-card").length)t=$(i).closest("div.account-card").find("div.display-name > span").text().trim();else for(const e of o)if($(e).length){t=$(e).text().trim();break}t&&((n=await G(t))?(m.fedifollow_showfollows&&(await j([n[0]]))[0]&&($(i).text("Unfollow"),s="unfollow"),l=0,$(i).off(),$(i).unbind(),$(i).on("click",async function(t){var e,o,a;t.preventDefault(),t.stopImmediatePropagation(),1==++l?r=setTimeout(async function(){"follow"==s?await A(n[0])&&($(i).text("Unfollow"),s="unfollow"):await S(n[0])&&($(i).text("Follow"),s="follow"),l=0},350):(clearTimeout(r),"follow"==s?await A(n[0])&&($(i).text("Unfollow"),s="unfollow",e=!0):await S(n[0])&&($(i).text("Follow"),s="follow",e=!0),e?(o=$(i).text(),a="https://"+m.fedifollow_homeinstance+"/@"+n[1],$(i).text("Redirecting..."),setTimeout(function(){O(a),$(i).text(o)},1e3)):b("Action failed."),l=0)}).on("dblclick",function(t){t.preventDefault(),t.stopImmediatePropagation()})):b("Could not resolve user home ID."))}($(t.target))},t)):b("Not a profile URL.")}async function D(){setTimeout(function(){g!=window.location.href&&(g=window.location.href,I(),P()),D()},300)}function J(t){var e,o=[];for(e of t.split(/\r?\n/))e=e.trim(),a.test(e)?o.push(e):b("Removed invalid domain "+e+" from blacklist/whitelist.");return[...new Set(o)]}function L(){if(null==m.fedifollow_homeinstance||!m.fedifollow_homeinstance)return b("Mastodon home instance is not set."),!1;if(!m.fedifollow_token)return b("No API token available. Are you logged in to your home instance? If yes, wait for 1-2 minutes and reload page."),!1;if(m.tokenheader={Authorization:"Bearer "+m.fedifollow_token},!a.test(m.fedifollow_homeinstance))return b("Instance setting is not a valid domain name."),!1;if($.inArray(m.fedifollow_mode,["blacklist","whitelist"])<0&&(m.fedifollow_mode="blacklist"),$.inArray(m.fedifollow_target,["_blank","_self"])<0&&(m.fedifollow_target="_blank"),"whitelist"==m.fedifollow_mode){if(m.fedifollow_whitelist=J(m.fedifollow_whitelist),m.fedifollow_whitelist.length<1)return b("Whitelist is empty or invalid."),!1}else m.fedifollow_blacklist=J(m.fedifollow_blacklist);return!0}async function Q(){if(location.hostname!=m.fedifollow_homeinstance||(p=_("fedireply"))){if("whitelist"==m.fedifollow_mode){if($.inArray(location.hostname,m.fedifollow_whitelist)<0)return b("Current site is not in whitelist."),!1}else if(-1<$.inArray(location.hostname,m.fedifollow_blacklist))return b("Current site is in blacklist."),!1;var t=await y("GET",location.protocol+"//"+location.hostname+f,null);if(t)if(JSON.parse(t).uri)return!0;b("Does not look like a Mastodon instance.")}else b("Current site is your home instance.");return!1}async function X(){(m=await(browser||chrome).storage.local.get(v))?L()&&(await Q()?(p?B:(I(),P(),D))():b("Will not process this site.")):b("Could not load settings.")}X(); \ No newline at end of file