Skip to content

Instantly share code, notes, and snippets.

@dsiddy
Last active December 15, 2015 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsiddy/86853cc89d6e868e0236 to your computer and use it in GitHub Desktop.
Save dsiddy/86853cc89d6e868e0236 to your computer and use it in GitHub Desktop.
hide /Star Wars/-related posts on Facebook
// ==UserScript==
// @match https://www.facebook.com/*
// ==/UserScript==
// My very first user script!
// @see https://www.chromium.org/developers/design-documents/user-scripts
// @see http://wiki.greasespot.net/Metadata_Block
// Note that match patterns require a path component. I ran into trouble earlier by leaving off the trailing slash.
// @see https://developer.chrome.com/extensions/match_patterns
var searches = [
'Star Wars',
'The Force Awakens',
'Episode VII'
// et c.
].map(function(search) { return new RegExp(search, 'i') });
// 'There is no way to stop or break a forEach() loop other than by throwing an exception. . . . If you are testing the array elements for a predicate and need a [B]oolean return value, you can use every() or some() instead.'
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description
function isStarWarsRelated(postText) {
return searches.some(function(search) {
return ( postText.match(search) !== null );
});
}
function getStoryNode(contentNode) {
var node = contentNode;
while(node) {
var attribute = node.attributes.getNamedItem('data-ft') || null;
if( (attribute !== null) && ( Object.keys( JSON.parse(attribute.value) ).indexOf('fbfeed_location') !== -1 ) ) {
break;
} else {
node = node.parentNode;
}
}
return (node.tagName !== 'HTML')
? node
: null;
}
function filterPosts() {
// @see https://coderwall.com/p/jcmzxw/iterate-over-queryselectorall-result
[].forEach.call(
document.querySelectorAll('.userContentWrapper'),
function(post) {
if( isStarWarsRelated(post.textContent) ) {
var storyNode = getStoryNode(post);
// Note that this merely hides posts; it doesn't remove them from the DOM.
if(storyNode !== null) { storyNode.style.display = 'none' }
}
}
);
}
// Filter initially, on page load.
document.addEventListener('DOMContentLoaded', filterPosts);
// @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
var observer = new MutationObserver(function(mutations) {
// Filter whenever Facebook loads new content asynchronously.
mutations.forEach(function(mutation) { filterPosts() })
});
observer.observe(document, {
childList: true,
subtree: true
});
@dsiddy
Copy link
Author

dsiddy commented Dec 15, 2015

Well, it only took 14 revisions, but it's much prettier now --- and it targets all content blocks, not just those on the News Feed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment