(Mirrored here in case FL takes offense at implementing a sponsors’ perk on the client side…)

Assume the following:

  1. There’s someone on your friends list who you’d like to keep as a friend.
  2. They post status updates more frequently than you’d like, or perhaps containing content you’d prefer not to see (triggering, etc.).
  3. You prefer not to support FetLife in order to receive the “gag” function as a supporter’s perk. (Whether you’re cheap, broke, or just object to the way Baku runs things to the point that you’re unwilling to monetarily support him is up to you.)
  4. You have no qualms installing extensions into your browser of choice and accept that it’s legally Fair Use under US law (or under similar doctrine in your own home jurisdiction) to modify a website for your own viewing pleasure in any way you see fit.


  1. Install GreaseMonkey ( for Firefox or the compatible TamperMonkey ( for Chrome.
  2. Install the following script, replacing the “FL_ID_TO_BLOCK” part with the ID of the person you’d like to read less of. You can get the ID by grabbing the number from the end of the URL to their profile page.
  3. Profit! Well, no not really, because that would belie your modification being Fair Use. This is acceptable for personal, non-profit use ONLY.

That’s it. Refresh your news feed, and it should be less cluttered. Currently this script blocks only a single user and only status updates. Comments, Love’s, etc. aren’t blocked. Modifying it to block multiple users is left as an exercise, at least until such point as two or more people trip my annoy-o-meter; and I have to hack it up to block them all.

Extra credit: Modify this to support the semi-standardized format of tagging triggering posts à la: “#tw #whatever”, then blocking any posts with a collection of trigger words.

Extra extra credit: Get a critical mass of FL users to adopt Tumblr-like trigger word tagging as standard practice. (Good luck with that…)

IMPORTANT: This script is provided without any guarantee. If it breaks, you get to keep the pieces. The author is NOT prepared to provide any kind of support in its use or installation.

SPECIAL EXCEPTION: If I’ve personally seen you naked and/or tied up, I’m probably willing to help you install it. All others, please see the Googles…

// ==UserScript==
// @name Block_FL_User
// @namespace fl
// @description Block unwanted status updates
// @include
// @version 2
// @grant none
// ==/UserScript==
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// GNU General Public License for more details.

function gag() {
var posts = $('tr.status_created a[href="/users/FL_ID_TO_BLOCK"]');
posts.parent() .parent() .remove();

/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
that detects and handles AJAXed content.

Usage example:

waitForKeyElements (
, commentCallbackFunction

//--- Page-specific function to do what we want when the node is found.
function commentCallbackFunction (jNode) {
jNode.text ("This comment changed by waitForKeyElements().");

IMPORTANT: This function requires your script to have loaded jQuery.
function waitForKeyElements (
selectorTxt, /* Required: The jQuery selector string that
specifies the desired element(s).
actionFunction, /* Required: The code to run when elements are
found. It is passed a jNode to the matched
bWaitOnce, /* Optional: If false, will continue to scan for
new elements even after the first match is
iframeSelector /* Optional: If set, identifies the iframe to
) {
var targetNodes, btargetsFound;

if (typeof iframeSelector == "undefined")
targetNodes = $(selectorTxt);
targetNodes = $(iframeSelector).contents ()
.find (selectorTxt);

if (targetNodes && targetNodes.length > 0) {
btargetsFound = true;
/*--- Found target node(s). Go through each and act if they
are new.
targetNodes.each ( function () {
var jThis = $(this);
var alreadyFound = ('alreadyFound') || false;

if (!alreadyFound) {
//--- Call the payload function.
var cancelFound = actionFunction (jThis);
if (cancelFound)
btargetsFound = false;
else ('alreadyFound', true);
} );
else {
btargetsFound = false;

//--- Get the timer-control variable for this selector.
var controlObj = waitForKeyElements.controlObj || {};
var controlKey = selectorTxt.replace (/[^\w]/g, "_");
var timeControl = controlObj [controlKey];

//--- Now set or clear the timer as appropriate.
if (btargetsFound && bWaitOnce && timeControl) {
//--- The only condition where we need to clear the timer.
clearInterval (timeControl);
delete controlObj [controlKey]
else {
//--- Set a timer, if needed.
if ( ! timeControl) {
timeControl = setInterval ( function () {
waitForKeyElements ( selectorTxt,
controlObj [controlKey] = timeControl;
waitForKeyElements.controlObj = controlObj;

waitForKeyElements('tr.status_created', gag, false);



  • v1 : Initial release
  • v2 : Internalize waitForKeyElements script since loading from github seems to time out