// ==UserScript==
// @name Imgur Mirror (Modified)
// @version 1
// @description Switches all imgur links to the mirror site http://kageurufu.net/imgur
// @author Ad3m
// @include *://*/*
// @exclude *://imgur.com/*
// @exclude *://*.imgur.com/*
// @grant none
// @namespace https://greasyfork.org/users/159159
// ==/UserScript==
// Wait for Elements by fuzetsu https://greasyfork.org/tr/scripts/5679-wait-for-elements
/**
* @param sel - the selector you want to wait for
* @param action - the callback that will be executed when element/s matching the given selector are found, it is passed the array of found elements
* @param stopLooking - if true the function will stop looking for more elements after the first match
*/
function waitForElems(sel, action, stopLooking) {
var tick;
var id = 'fke' + Math.floor(Math.random() * 12345);
var type = window.MutationObserver ? 'M' : 'S';
var lastMutation = Date.now();
var lastCall = Date.now();
var queuedCall;
function throttle(func) {
var now = Date.now();
clearTimeout(queuedCall);
// less than 100ms since last mutation
if(now - lastMutation < 100) {
// 500ms or more since last query
if(now - lastCall >= 500) {
func();
} else {
queuedCall = setTimeout(func, 100);
}
} else {
func();
}
lastMutation = now;
}
function findElem(sel) {
lastCall = Date.now();
var found = [].filter.call(document.querySelectorAll(sel), function(elem) {
return elem.dataset[id] !== 'y';
});
if(found.length > 0) {
if(stopLooking) {
type === 'M' ? tick.disconnect() : clearInterval(tick);
}
found.forEach(function(elem) {
elem.dataset[id] = 'y';
action(elem);
});
}
}
if(type === 'M') {
tick = new MutationObserver(throttle.bind(null, findElem.bind(null, sel)));
tick.observe(document.body, { subtree: true, childList: true });
} else {
tick = setInterval(findElem.bind(null, sel), 300);
}
findElem(sel);
return {
type: type,
stop: function() {
if(type === 'M') {
tick.disconnect();
} else {
clearInterval(tick);
}
}
};
}
/**
* @param regex - should match the site you're waiting for
* @param action - the callback that will be executed when a matching url is visited
* @param stopLooking - if true the function will stop waiting for another url match after the first match
*/
function waitForUrl(regex, action, stopLooking) {
function checkUrl(urlTest) {
var url = window.location.href;
if(url !== lastUrl && urlTest(url)) {
if(stopLooking) {
clearInterval(tick);
}
lastUrl = url;
action();
}
lastUrl = url;
}
var urlTest = (typeof regex === 'function' ? regex : regex.test.bind(regex)),
tick = setInterval(checkUrl.bind(null, urlTest), 300),
lastUrl;
checkUrl(urlTest);
return tick;
}
// Wait for Elements by fuzetsu https://greasyfork.org/tr/scripts/5679-wait-for-elements
//FIX LINK
(function() {
'use strict';
var regex2 = /((https?:\/\/)?(?:i?m?\.)?imgur\.com\/(.*?(?:png|jpeg|jpg|gifv|gif|mp4)))|.*/ig;
var getNewLink2 = function(imgurLink2, fixLink) {
var urlz = imgurLink2.replace(regex2, '$1');
return urlz;
};
waitForElems('img,a', function(node) {
var isImg = node.nodeName === 'IMG';
var prop = isImg ? 'src' : 'href';
var newLink = getNewLink2(node[prop], isImg);
if(newLink) {
node[prop] = newLink;
if (node.dataset.hrefUrl) {
node.dataset.hrefUrl = newLink;
}
if (node.dataset.outboundUrl) {
node.dataset.outboundUrl = newLink;
}
}
});
})();
//FIX LINK
// Imgur Mirror by kufii https://greasyfork.org/tr/scripts/18806-imgur-mirror
(function() {
'use strict';
var regex = /imgur\.com\/(?!a\/|gallery\/)(?:r\/[a-z0-9_]+\/)?([a-z0-9]+)(\.+[a-z0-9]+)?/i;
var getNewLink = function(imgurLink, useGif) {
var match = imgurLink.match(regex);
if (match) {
var file = match[1];
if (match[2] === null) {
return 'http://kageurufu.net/imgur/?' + file + '.png';
}
if (match[2] == '.gif') {
return 'http://kageurufu.net/imgur/?' + file + '.gifv';
}
else {
return null;
}
}
};
waitForElems('img,a', function(node) {
var isImg = node.nodeName === 'IMG';
var prop = isImg ? 'src' : 'href';
var newLink = getNewLink(node[prop], isImg);
if(newLink) {
if (prop == 'src') { newLink = newLink.replace(/\.(gifv)($|\?)/, '.gif'); }
//console.log(newLink);
//console.log(prop);
node[prop] = newLink;
if (node.dataset.hrefUrl) {
node.dataset.hrefUrl = newLink;
}
if (node.dataset.outboundUrl) {
node.dataset.outboundUrl = newLink;
}
}
});
})();
// Imgur Mirror by kufii https://greasyfork.org/tr/scripts/18806-imgur-mirror
changeLinks();
document.addEventListener('scroll', changeLinks);
document.addEventListener('click', changeLinks);
function changeLinks() {
var list = document.querySelectorAll('[href*="imgur.com"]');
for (var i = 0; i < list.length; i++) {
var node = list.item(i);
node.setAttribute('href', node.getAttribute('href')
.replace('m.imgur.com/a/', 'kageurufu.net/imgur/?a/')
.replace('imgur.com/a/', 'kageurufu.net/imgur/?a/')
.replace('m.imgur.com/gallery/', 'kageurufu.net/imgur/?a/')
.replace('imgur.com/gallery/', 'kageurufu.net/imgur/?a/')
.replace('https://', 'http://'));
node.setAttribute('href', node.getAttribute('href')
.replace('i.imgur.com/', 'kageurufu.net/imgur/?')
.replace('imgur.com/', 'kageurufu.net/imgur/?')
.replace('https://', 'http://'));
}
list = document.querySelectorAll('[src*="imgur.com"]');
for (i = 0; i < list.length; i++) {
var node = list.item(i);
node.setAttribute('src', node.getAttribute('src')
.replace('imgur.com/a/', 'kageurufu.net/imgur/?a/')
.replace('imgur.com/gallery/', 'kageurufu.net/imgur/?a/')
.replace('https://', 'http://'));
node.setAttribute('src', node.getAttribute('src')
.replace('i.imgur.com/', 'kageurufu.net/imgur/?')
.replace('imgur.com/', 'kageurufu.net/imgur/?')
.replace('https://', 'http://'));
}
}
// Reddit Link Hijack Remover by jmesmon https://greasyfork.org/tr/scripts/20752-reddit-link-hijack-remover
(function () {
'use strict';
if (window.location.host == "www.reddit.com") {
function cl(ac) {
var a = ac.querySelectorAll('a[data-href-url]');
var ct_out = 0, ct_aff = 0, ct = 0, ct_in;
for (var i = 0; i < a.length; i++) {
/*
// This is reddit's function to determine the url, which is stored in `o`.
// It then hooks window unload to call sendBeacon with the url in `o` or
// modifies the href attribute (if sendBeacon is disabled in config or unsupported by the browser).
function o(e) {
var t = $(e),
r = Date.now(),
o;
return t.attr('data-inbound-url')
? o = t.attr('data-inbound-url')
: !n && t.attr('data-outbound-expiration') > r && (o = t.attr('data-outbound-url')),
o && (i ? s = o : e.href = o),
!0
}
*/
// Some minimal counting so we can tell things are working
if (a[i].getAttribute('data-inbound-url')) {
ct_in++;
}
if (a[i].getAttribute('data-affiliate-url')) {
ct_aff++;
}
if (a[i].getAttribute('data-outbound-url') || a[i].getAttribute('data-outbound-expiration')) {
ct_out++;
}
// Goals:
// - make sure `o` stays undefined.
// - avoid ever getting this function called
// Removing all the relevent attributes gets us both of those
// Unclear what the purpose of these is, but they are being used to
// re-write urls (and trigger entry to the fn above), so remove.
a[i].removeAttribute('data-inbound-url');
// Doesn't appear that reddit is injecting these affiliate links
// anymore, but no reason to remove this
a[i].removeAttribute('data-affiliate-url');
// We don't actually need to remove this, but it does short circuit
// the condition quicker & cleans up the html, so do it.
a[i].removeAttribute('data-outbound-expiration');
a[i].removeAttribute('data-outbound-url');
ct++;
}
console.log('>>>');
console.log('Outbound redirects removed: ' + ct_out);
console.log('Inbound redirects removed: ' + ct_out);
console.log('Affiliate redirects removed: ' + ct_aff);
console.log('Total redirects removed: ' + ct);
console.log('<<<');
}
var tbls = document.querySelector('#siteTable');
var obs = new MutationObserver(function (r, self) {
for (var i = 0; i < r.length; i++) {
var ad = r[i].addedNodes;
for (var j = 0; j < ad.length; j++) {
var n = ad[j];
cl(n);
}
}
});
obs.observe(tbls, {
childList: true
});
// TODO: consider patching out window.navigator.sendBeacon (which reddit only uses for this link tracking)
// TODO: consider blocking the recent_srs cookie used for tracking
cl(document);
}
}) ();
// Reddit Link Hijack Remover by jmesmon https://greasyfork.org/tr/scripts/20752-reddit-link-hijack-remover