// ==UserScript==
// @name           mutetwitter
// @namespace      http://code.ninjawedding.org/mutetwitter/
// @description    Heuristic to remove LoudTwitter spam from a LiveJournal friends page.
// @include        http://*.livejournal.com/friends*
// ==/UserScript==

// By nakoudo@ninjawedding.org
// This code is dedicated to the public domain.
// Formal dedication at http://creativecommons.org/licenses/publicdomain/.

function containsLoudTwitterLink(entry) {
  var links = document.evaluate(".//a[contains(@href, 'loudtwitter.com')]", entry, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  return links.snapshotLength > 0;
}

function hasTwitterInTitle(entry) {
  var captions = document.evaluate(".//td[@class='caption']", entry, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  var alternatives = ['loudtwitter', 'tweets', 'twitter', 'tweet'];

  for(var i = 0; i < captions.snapshotLength; i++) {
    var text = captions.snapshotItem(i).innerHTML.toLowerCase();
  
    for (var j = 0; j < alternatives.length; j++) {
      if (text.match(alternatives[j])) {
        return true;
      }
    }
  }

  return false;
}

function isLoudTwitter(entry) {
  var heuristics = [
    containsLoudTwitterLink,
    hasTwitterInTitle
  ]

  for (var i = 0; i < heuristics.length; i++) {
    if ((heuristics[i])(entry)) {
      return true;
    }
  }

  return false;
}

var entries = document.evaluate(
    "//table[@class='entrybox']",
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);

for (var i = 0; i < entries.snapshotLength; i++) {
  var entry = entries.snapshotItem(i);
  if (isLoudTwitter(entry)) {
    entry.parentNode.removeChild(entry);
  }
}
