Last active
September 3, 2024 18:06
-
-
Save jcguu95/41681b9b5deafe1ba6cbd1b7cc1f1af7 to your computer and use it in GitHub Desktop.
Remove Instagram Unfollowed Content
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Remove Instagram Unfollowed Content | |
// @version 2024-03-02 | |
// @author Jin-Cheng Guu | |
// @match https://www.instagram.com/* | |
// @description Remove unfollowed content from the instagram main page. | |
// ==/UserScript== | |
(function() { | |
let blacklist = [ | |
// Remove all unfollowed content. | |
'Follow', | |
// Ban your favorite texts. | |
'your.acquaintance.id.1', | |
'your.acquaintance.id.2', | |
]; | |
function findsBannedText (element) { | |
let blacklistedText = ''; | |
let text = element.textContent.trim(); | |
let bannedText = blacklist.find (x => (x === text)); | |
if (bannedText) { | |
// console.log("Found banned text in node.", bannedText, element) | |
return bannedText; | |
} | |
// No banned text found so far; search through its children recursively. | |
let children = element.children; | |
if (children.length > 0) { | |
for (let i = 0; i < children.length; i++) { | |
bannedText = findsBannedText(children[i]) | |
if (bannedText) { | |
// console.log("Found banned text in node. ", bannedText, children[i]); | |
return bannedText; | |
} | |
} | |
} else { | |
return false; | |
} | |
}; | |
function removeChildren (node) { | |
// Remove all children of node. | |
console.log("Remove all children of the node: ", node) | |
let children = node.children; | |
for (let i = 0; i < children.length; i++) { | |
children[i].remove(); | |
} | |
} | |
// | |
function getAll (element, tag) { | |
let result = []; | |
if (element.tagName === tag) { | |
result.push(element); | |
} | |
let children = element.children; | |
for (let i = 0; i < children.length; i++) { | |
result = result.concat(getAll(children[i], tag)); | |
} | |
return result; | |
} | |
function cleanAll (tag) { | |
getAll(document.body, tag).forEach ( | |
article => { | |
let bannedtext = findsBannedText(article); | |
if (bannedtext) { | |
console.log("handling node because of text: ", article, bannedtext); | |
// we do not remove the unwelcome node itself as that crashes the page. | |
removeChildren(article); | |
}}) | |
} | |
// One-time Clean | |
cleanAll('ARTICLE'); // Remove posts. | |
cleanAll('LI'); // Remove stories. | |
// Clean after each click. | |
let waitLength = 500 | |
document.onclick = function (event) { | |
setTimeout(() => { cleanAll('ARTICLE'); // Remove posts. | |
cleanAll('LI'); // Remove stories. | |
}, | |
waitLength); | |
}; | |
// | |
// Make observer that constantly check for new articles. | |
// | |
function makeObserver () { | |
let callback = (mutationList, observer) => { | |
for (const mutation of mutationList) { | |
if (mutation.type === "childList" && | |
mutation.addedNodes.length > 0) { | |
let addedNode = mutation.addedNodes[0]; | |
let bannedText = findsBannedText(addedNode); | |
if (addedNode.tagName === 'ARTICLE' && bannedText) { | |
console.log("Handling node because of text: ", addedNode, bannedText); | |
// We do not remove the unwelcome node itself as that crashes the page. | |
removeChildren(addedNode); | |
} | |
} | |
} | |
}; | |
return new MutationObserver(callback); | |
} | |
let config = { attributes: true, childList: true, subtree: true }; | |
let observer = makeObserver(); | |
observer.observe(document.body, config); | |
// observer.disconnect(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment