There are 11 previous versions of this script.
// Now shoosh!, v0.4.3
// Copyright (c) 2008, Vitor Peres
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
// Updated: Thu May 28 20:11:26 2009
//
// ==UserScript==
// @name Now shoosh!
// @namespace http://userscripts.org/scripts/show/33629
// @description A boon to twitter sanity, "Now shoosh!" allows you to mute people you don't really wanna read right now.
// @include http://twitter.com/
// @include http://twitter.com/home
// ==/UserScript==
function $(id) {
return document.getElementById(id);
}
function $x(xPath, parent) {
var result = [];
var scope = parent ? parent : document;
var data = document.evaluate(xPath, scope, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i = 0; i < data.snapshotLength; i++) {
var datum = data.snapshotItem(i);
result.push(datum);
}
return result;
}
function contactsInTimeline(timeline) {
var contacts = [];
for(var i = 0; i < toots.length; i++) {
var toot = toots[i];
contacts.push(getAuthorName(toot));
}
return contacts;
}
function getTimeline() {
return $x("/html/body[@id='home']/div[@id='container']/table/tbody/tr/td[@id='content']/div/div[3]/ol[@id='timeline']//li");
}
function muteToot(toot) {
toot.style.visible = false;
toot.style.display = 'none';
}
function onMuteUser(contact) {
muteUser(contact);
sayNoMore(contact);
addContactToMutedDisplayList(contact, getContactImageURL(contact));
}
function muteUser(contact) {
var users = retrieveMutedContacts();
users.push(contact);
storeMutedContacts(users);
}
function sayNoMore(contact) {
var toots = filterTootsFromContact(contact);
toots.forEach(muteToot);
}
function makeMutable(toot) {
var body = $x("id('" + toot.id + "')/span[2]")[0];
var contents = $x("id('" + toot.id + "')/span[2]/span[1]")[0];
var container = document.createElement('span');
var mute = container.appendChild(document.createElement('a'));
mute.href = 'javascript:;';
mute.appendChild(document.createTextNode('(mute) '));
mute.style.fontSize = 'small';
mute.addEventListener('click', (function(a) { return function() { onMuteUser(a);} })(getAuthorName(toot)), false);
body.insertBefore(container, contents);
}
function getAuthorElement(toot) {
var xpath = "id('" + toot.id + "')/span[2]/strong/a";
return $x(xpath)[0];
}
function getAuthorName(toot) {
return getAuthorElement(toot).innerHTML;
}
function retrieveMutedContacts(contacts) {
var users = GM_getValue('mutedContacts', null);
if(users) {
return users.split(';');
}
else {
return [];
}
}
function storeMutedContacts(contacts) {
GM_setValue('mutedContacts', contacts.join(';'));
}
function findMutedInTimeline(contacts) {
var allmuted = retrieveMutedContacts();
return contacts.filter(function(c) { return allmuted.indexOf(c) != -1; });
}
function addContactToMutedDisplayList(contact, img_url) {
var list = getMutedDisplayList();
var tr = list.appendChild(document.createElement('tr'));
var imgcont = tr.appendChild(document.createElement('td'));
imgcont.setAttribute('class', 'vcard');
imgcont.setAttribute('valign', 'top');
var link = imgcont.appendChild(document.createElement('a'));
link.href = 'http://twitter.com/' + contact;
var img = link.appendChild(document.createElement('img'));
img.src = img_url;
var name = tr.appendChild(document.createElement('td'));
name.setAttribute('valign', 'top');
name.appendChild(document.createTextNode(contact));
var unmcont = tr.appendChild(document.createElement('td'));
unmcont.setAttribute('valign', 'top');
var unmute = unmcont.appendChild(document.createElement('a'));
unmute.setAttribute('class', 'section-links');
unmute.href = 'javascript:;';
unmute.addEventListener('click', (function(c) { return function() { onUnmuteContact(c); } })(contact), false);
unmute.appendChild(document.createTextNode('unmute'));
}
function onUnmuteContact(contact) {
filterTootsFromContact(contact).forEach(function OUC_showToot(t) {
t.style.display = 'table-row';
t.style.visible = 'true';
});
removeFromMutedDisplayList(contact);
unmuteContact(contact);
}
function unmuteContact(contact) {
var contacts = retrieveMutedContacts();
var unmuted = contacts.filter(function(mc) { return contact != mc; });
storeMutedContacts(unmuted);
}
function removeFromMutedDisplayList(contact) {
var isContact = function(row) {
return row.childNodes[1].innerHTML == contact;
};
var list = getMutedDisplayList();
var entries = $x('./tr', list);
var entry = entries.filter(isContact)[0];
list.removeChild(entry);
}
function filterTootsFromContact(contact, toots) {
var toots = toots ? toots : getTimeline();
return toots.filter(function(t) { return getAuthorName(t) == contact; });
}
function getMutedDisplayList() {
var pane = $x("//div[@id='muted_pane']")[0];
if(pane) {
return $x("./table[@id='muted_list']", pane)[0];
}
else {
return createMutedDisplayList();
}
}
function createMutedDisplayList() {
var sidepane = $('side');
var pane = sidepane.appendChild(document.createElement('div'));
pane.id = 'muted_pane';
pane.setAttribute('class', 'section');
var header = pane.appendChild(document.createElement('div'));
header.setAttribute('class', 'section-header');
var title = header.appendChild(document.createElement('h1'));
title.appendChild(document.createTextNode('Muted People'));
var list = pane.appendChild(document.createElement('table'));
list.id = 'muted_list';
list.cellPadding = 0;
list.cellSpacing = 0;
return list;
}
function getContactImageURL(contact, alltoots) {
var base = 'http://twitter.com/users/show/';
var req = new XMLHttpRequest();
var img = null;
alltoots = toots ? toots : getTimeline();
var toots = filterTootsFromContact(contact, alltoots);
if(toots.length > 0) {
img = $x("id('" + toots[0].id + "')/span[1]/a/img")[0].src;
}
else {
req.open('GET', base + contact + '.json', false);
req.send(null);
if(req.status == 200) {
var details = eval("[" + req.responseText + "]")[0];
img = details["profile_image_url"];
}
}
img = img.replace(/_normal\./, '_mini.');
return img;
}
function showMutedList(toots) {
retrieveMutedContacts().forEach(function SMC_addToList(c) {
addContactToMutedDisplayList(c, getContactImageURL(c))
});
}
/* This was added to provide GreaseKit support, as my wife is desperate with so
* much crap invading her life.
* Taken from: http://groups.google.com/group/greasekit-users/browse_thread/thread/d8135ac1f006493e?pli=1
*/
var Cookie = {
PREFIX:'_greasekit',
get: function(name, defaultValue) {
var nameEQ = escape(Cookie._buildName(name)) + "=", ca =
document.cookie.split(';');
for (var i = 0, c; i < ca.length; i++) {
c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return defaultValue;
},
set: function(name, value, options){
options = (options || {});
if (options.expiresInOneYear) {
var today = new Date();
today.setFullYear(today.getFullYear()+1, today.getMonth, today.getDay());
options.expires = today;
}
var curCookie = escape(Cookie._buildName(name)) + "=" + escape(value) +
((options.expires) ? "; expires=" + options.expires.toGMTString() : "") +
((options.path) ? "; path=" + options.path : "") +
((options.domain) ? "; domain=" + options.domain : "") +
((options.secure) ? "; secure" : "");
document.cookie = curCookie;
},
hasCookie: function( name ){
return document.cookie.indexOf( escape(Cookie._buildName(name)) ) > -1;
},
_buildName: function(name){
return Cookie.PREFIX + '_' + name;
}
};
if(typeof GM_getValue === "undefined") GM_getValue = Cookie.get;
if(typeof GM_setValue === "undefined") GM_setValue = Cookie.set;
/* Where the magic happens */
var toots = getTimeline();
toots.forEach(makeMutable);
var contacts = contactsInTimeline(toots);
findMutedInTimeline(contacts).forEach(sayNoMore);
showMutedList(toots);
