By Thlayli
Has 20 other scripts.
// ==UserScript==
// @name StumbleUpon Best Friends
// @namespace thlayli.detrave.net
// @description Adds a section for Best Friends on SU
// @include http://*.stumbleupon.com/friends/*
// @include http://*.stumbleupon.com/fans/*
// @version 2.3
// ==/UserScript==
// auto-update variables
var script_title = 'StumbleUpon Best Friends';
var source_location = 'http://thlayli.detrave.net/su-bestfriends.user.js';
var version_holder = 'http://thlayli.detrave.net/su-bestfriends.version.txt';
var current_version = '2.3';
var latest_version = '';
var manual_check = true;
var lastupdatecheck = GM_getValue('Updated', 'never');
GM_registerMenuCommand('Update - '+script_title, CheckVersion);
CheckForUpdate();
var editFlag = 0;
var aboutFlag = 0;
var fullFriends = 1;
var fullFans = 1;
var mutualBfs = 0;
var fanBfs = 0;
var whatsNew = xpath(document, "//a[contains(@href, 'stumbleupon.com/prefs/' )]");
var isYourPage = (whatsNew.snapshotLength > 0) ? 1 : 0;
var allFriends = xpath(document,'//dl');
if(isYourPage == 1){
// get logged in name
var thisStumbler = document.getElementById('search').firstChild.nextSibling.firstChild.nextSibling.textContent.replace('Hello ','');
var friendsPref = GM_getValue(thisStumbler,'');
var friendsList = (friendsPref.indexOf(';')) ? friendsPref.split(';') : new Array();
friendsList = friendsList.sort(sortFriends);
var friendsCount = friendsList.length;
if(friendsList[0] == '')
var friendsCount=0;
//create bf section
if(document.location.pathname.indexOf('/fans/') == -1){
var mfBar = xpath(document, "//h2[contains(., ' mutual friends')]").snapshotItem(0);
if(document.location.pathname.indexOf('/all/') == -1){
var fanContent = xpath(document,"//h2[contains(., 'You are a fan of ')]").snapshotItem(0);
if(fanContent){
fanContent = fanContent.nextSibling.nextSibling.nextSibling.nextSibling;
//check for "Who are they?" link
if(fanContent.textContent.indexOf('see their favorites') != -1)
fanContent = fanContent.nextSibling.nextSibling;
}
}
}else{
var mfBar = xpath(document, "//h2[contains(., ' fans')]").snapshotItem(0);
}
var mfLinks = mfBar.nextSibling.nextSibling;
var mfContent = mfBar.nextSibling.nextSibling.nextSibling.nextSibling;
//check for "Who are they?" link
if(mfContent.textContent.indexOf('sharing your discoveries') != -1)
mfContent = mfContent.nextSibling.nextSibling;
var bfBar = mfBar.cloneNode(true);
var bfLinks = mfLinks.cloneNode(true);
var bfContent = mfContent.cloneNode(true);
var bfSpacer = document.createElement('div');
bfSpacer.className = 'clear pdgTopLg';
bfContent.innerHTML = '\n';
mfBar.parentNode.insertBefore(bfSpacer,mfBar.previousSibling);
mfBar.parentNode.insertBefore(bfBar,bfSpacer);
mfBar.parentNode.insertBefore(bfLinks,bfSpacer);
mfBar.parentNode.insertBefore(bfContent,bfSpacer);
bfText = (friendsCount!=1) ? 'friends' : 'friend';
bfBar.innerHTML = 'Your ' + friendsCount + ' best ' + bfText;
bfLinks.innerHTML = '<ul class="cmds"><li class="textlink"><a href="javascript:void(0);" class="textlink" id="edit_bf">Edit best friends</a></li><li class="textlink"><span class="bullet" id="cancel_bullet" style="display: none;"> •</span><a href="javascript:void(0);" class="textlink" id="cancel_edit" style="display: none;">Cancel edit</a></li></ul><div class="clear"><!-- --></div>';
//create full content sections
var fullFriendsContent = mfContent.cloneNode(true);
fullFriendsContent.style.display = 'none';
fullFriendsContent.id = 'full_friends';
mfContent.parentNode.insertBefore(fullFriendsContent,mfContent);
if(fanContent){
var fullFansContent = fanContent.cloneNode(true);
fullFansContent.style.display = 'none';
fullFansContent.id = 'full_fans';
fanContent.parentNode.insertBefore(fullFansContent,fanContent);
}
var moreFans = xpath(document, "//a[contains(@href, 'friends/all/#nm')]").snapshotItem(0);
if(moreFans){
moreFans.href = 'javascript: void(0);';
moreFans.wrappedJSObject.addEventListener('click', toggleFanLists, true);
}
var moreFriends = xpath(document, "//a[contains(., 'Show more friends')]").snapshotItem(0);
if(moreFriends){
moreFriends.href = 'javascript: void(0);';
moreFriends.wrappedJSObject.addEventListener('click', toggleFriendLists, true);
}
//check for About Link modification
if(mfContent.firstChild.nextSibling.firstChild.nextSibling.firstChild.href.indexOf('/about/') != -1)
var aboutFlag = 1;
//edit & cancel event listeners
document.getElementById('edit_bf').wrappedJSObject.addEventListener('click', editFriends, true);
document.getElementById('cancel_edit').wrappedJSObject.addEventListener('click', cancelEdit, true);
//retrieve full list
if(document.location.pathname.indexOf('/friends/all/') == -1 && document.location.pathname.indexOf('/fans/') == -1){
var allLocation = document.location.href.replace(/\/fans\//ig,'')+'all/';
GM_xmlhttpRequest({
method: 'GET',
url: allLocation,
headers: {
'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
'Accept': 'text/html',
},
onload: function(responseDetails) {
//split content from all friends page and fill full content section
var tempContent = responseDetails.responseText.split('class="listPeople">');
tempFriendContent = tempContent[1].split('</div>');
fullFriendsContent.innerHTML = tempFriendContent[0];
removeDupes(fullFriendsContent);
if(tempContent[2] && fullFansContent){
tempFansContent = tempContent[2].split('</div>');
fullFansContent.innerHTML = tempFansContent[0];
removeDupes(fullFansContent);
}
if(moreFriends)
toggleFriendLists();
if(moreFans)
toggleFanLists();
fixAboutLinks();
insertFullLists();
updateNumbers();
}
});
}else{
writeBfs();
}
}
function removeDupes(section){
allFriends = xpath(section,'dl');
var offset = 0;
var toRemove = new Array();
for(n=friendsList.length-1;n>=0;n--){
for(i=0;i<allFriends.snapshotLength;i++){
var linkName = allFriends.snapshotItem(i).firstChild.nextSibling.nextSibling.nextSibling.firstChild.textContent.replace(/^\s+|\s+$/g,'');
if(friendsList[n].split(',')[0] == linkName){
//count bfs
if(section.id=='full_friends')
mutualBfs++;
if(section.id=='full_fans')
fanBfs++;
// check online status
if(allFriends.snapshotItem(i).firstChild.nextSibling.nextSibling.nextSibling.firstChild.lastChild.nodeName == 'IMG'){
var tempFriend = friendsList[n];
friendsList.splice(n,1);
friendsList.splice(friendsList.length - offset, 0, tempFriend+',online');
offset++;
}
toRemove.push(i);
break;
}
}
}
//remove nodes
for(r=0;r<toRemove.length;r++)
allFriends.snapshotItem(toRemove[r]).parentNode.removeChild(allFriends.snapshotItem(toRemove[r]));
}
function fixAboutLinks(){
if(aboutFlag==1){
var docLinks = xpath(document,'//a');
for(i=0;i<docLinks.snapshotLength;i++){
if(docLinks.snapshotItem(i).href.match(/^http:\/\/www|^http:\/\/buzz.stumbleupon|^javascript|.group.stumbleupon.com|about\/$/i) == null && docLinks.snapshotItem(i).href.indexOf('stumbleupon.com/') != -1 && docLinks.snapshotItem(i).href.indexOf('http://'+thisStumbler.toLowerCase()) == -1 && docLinks.snapshotItem(i).href.split('/').length < 5)
docLinks.snapshotItem(i).href = docLinks.snapshotItem(i).href + 'about/';
}
}
}
function insertFullLists(){
if(document.location.pathname.indexOf('/friends/all/') == -1){
if(moreFriends){
mfContent.parentNode.removeChild(mfContent);
document.getElementById('full_friends').style.display = 'block';
}
if(fanContent){
fanContent.parentNode.removeChild(fanContent);
document.getElementById('full_fans').style.display = 'block';
}
}
writeBfs();
}
function writeBfs(){
allFriends = xpath(document,'//dl');
for(i=friendsList.length-1;i>=0;i--){
var bf = friendsList[i].split(',');
var bfOnline = '';
var bfAbout = '';
if(bf.length >= 3){
var bfName = bf[0];
var bfTitle = bf[1];
var bfImg = bf[2];
if(bf[3])
bfOnline = ' <img style="vertical-align: middle; width: 6px; height: 6px;" title="Online now" alt="Online now" src="http://cdn.stumble-upon.com/images/icon_online.gif"/>';
if(aboutFlag == 1)
bfAbout = 'about/';
var newBf = document.createElement('dl');
newBf.className = 'bf';
newBf.innerHTML = '\n<dd class="thumbnail"><a title="'+bfTitle+'" href="http://'+bfName+'.stumbleupon.com/'+bfAbout+'"><img alt="'+bfTitle+'" src="http://cdn.stumble-upon.com/'+bfImg+'.jpg"/></a></dd>\n<dt><a href="http://'+bfName+'.stumbleupon.com/'+bfAbout+'">'+bfName+bfOnline+'</a></dt>';
bfContent.appendChild(newBf);
}
}
}
function updateNumbers(){
if(mutualBfs > 0){
var plural = (mutualBfs == 1) ? 'friend' : 'friends';
var mutualLabel = xpath(document, "//h2[contains(., ' mutual friends')]").snapshotItem(0);
var mutualNumber = mutualLabel.innerHTML.split(' ')[1];
mutualLabel.innerHTML = 'Your ' + (mutualNumber - mutualBfs) + ' mutual friends <span style="font-size: 12px;">(not including ' + mutualBfs + ' best ' + plural + ')</span>';
}
if(fanBfs > 0){
var plural = (fanBfs == 1) ? 'friend' : 'friends';
var yourFansLabel = xpath(document, "//h2[contains(., 'You are a fan of ')]").snapshotItem(0);
var yourFansNumber = yourFansLabel.innerHTML.split(' ')[5];
yourFansLabel.innerHTML = 'You are a fan of ' + (yourFansNumber - fanBfs) + ' people <span style="font-size: 12px;">(not including ' + fanBfs + ' best ' + plural + ')</span>';
}
if((friendsList.length - mutualBfs - fanBfs) > 0 && fanContent){
var plural = ((friendsList.length - mutualBfs - fanBfs) == 1) ? 'friend' : 'friends';
var fansLabel = xpath(document, "//h2[contains(., ' fans')]").snapshotItem(0);
fansLabel.innerHTML += ' <span style="font-size: 12px;">(including ' + (friendsList.length - mutualBfs - fanBfs) + ' best ' + plural + ')</span>';
}
}
function toggleFriendLists(){
var fullFriendsList = xpath(document.getElementById('full_friends'),'dl');
if(fullFriends == 1){
moreFriends.innerHTML = 'Show more friends';
fullFriends = 0;
for(i=15;i<fullFriendsList.snapshotLength;i++)
fullFriendsList.snapshotItem(i).style.display = 'none';
}else{
moreFriends.innerHTML = 'Show less friends';
fullFriends = 1;
for(i=15;i<fullFriendsList.snapshotLength;i++)
fullFriendsList.snapshotItem(i).style.display = 'block';
}
}
function toggleFanLists(){
var fullFansList = xpath(document.getElementById('full_fans'),'dl');
if(fullFans == 1){
moreFans.innerHTML = 'Show more fans';
fullFans = 0;
for(i=15;i<fullFansList.snapshotLength;i++)
fullFansList.snapshotItem(i).style.display = 'none';
}else{
moreFans.innerHTML = 'Show less fans';
fullFans = 1;
for(i=15;i<fullFansList.snapshotLength;i++)
fullFansList.snapshotItem(i).style.display = 'block';
}
}
function markFriend(evt){
if(evt){
var elem = (evt.target) ? evt.target : evt.srcElement;
if(elem.nodeName == 'IMG'){
if(!elem.style.border)
elem.style.border='3px solid';
else
elem.style.border='';
}else{
if(!elem.parentNode.previousSibling.previousSibling.firstChild.firstChild.style.border)
elem.parentNode.previousSibling.previousSibling.firstChild.firstChild.style.border="3px solid";
else
elem.parentNode.previousSibling.previousSibling.firstChild.firstChild.style.border="";
}
}
return false;
}
function cancelEdit(){
window.location.reload();
}
function editFriends(){
allFriends = xpath(document,'//dl');
if(editFlag == 0){
//edit
if(fanContent){
if(moreFriends){
fullFriends = 0;
toggleFriendLists();
}
if(moreFans){
fullFans = 0;
toggleFanLists();
}
}
document.getElementById('edit_bf').innerHTML = 'Save best friends';
document.getElementById('cancel_edit').style.display = 'inline';
document.getElementById('cancel_bullet').style.display = 'inline';
for(i=1;i<allFriends.snapshotLength;i++){
if(allFriends.snapshotItem(i).childNodes.length < 6){
allFriends.snapshotItem(i).wrappedJSObject.addEventListener('click', markFriend, false);
allFriends.snapshotItem(i).innerHTML = (aboutFlag == 0) ? allFriends.snapshotItem(i).innerHTML.replace(/href=\"http:\/\/([^\.]+).stumbleupon.com\/\"/g,'href="javascript:void(0);" alt="$1"') : allFriends.snapshotItem(i).innerHTML.replace(/href=\"http:\/\/([^\.]+).stumbleupon.com\/about\/\"/g,'href="javascript:void(0);" alt="$1"')
allFriends.snapshotItem(i).firstChild.nextSibling.setAttribute('style', 'padding-bottom: 6px;');
}
}
editFlag=1;
}else{
//save
document.getElementById('edit_bf').innerHTML = 'Edit best friends';
document.getElementById('cancel_edit').style.display = 'none';
document.getElementById('cancel_bullet').style.display = 'none';
for(i=1;i<allFriends.snapshotLength;i++){
var firstLink = allFriends.snapshotItem(i).firstChild.nextSibling.firstChild;
if(allFriends.snapshotItem(i).childNodes.length < 6)
allFriends.snapshotItem(i).wrappedJSObject.removeEventListener('click', markFriend, false);
if(allFriends.snapshotItem(i).className == 'bf'){
//remove best friend
if(allFriends.snapshotItem(i).firstChild.nextSibling.firstChild.firstChild.style && allFriends.snapshotItem(i).firstChild.nextSibling.firstChild.firstChild.style.border){
var linkName = allFriends.snapshotItem(i).firstChild.nextSibling.nextSibling.nextSibling.firstChild.textContent.replace(/^\s+|\s+$/g,"");
for(n=0;n<friendsList.length;n++){
if(friendsList[n].split(',')[0]==linkName)
friendsList.splice(n,1);
}
}
}else{
//add best friend
if(allFriends.snapshotItem(i).firstChild.nextSibling.firstChild.firstChild.style.border){
var friendImg = firstLink.firstChild.src.replace(/http:\/\/cdn\.stumble-upon\.com\/|\.jpg/ig,''); //add code to deal with no avatar
friendsList.push(firstLink.getAttribute('alt')+','+firstLink.title+','+friendImg);
}
}
}
editFlag=0;
if(friendsList[0] == '')
friendsList.shift();
friendsPref = (friendsList.length > 0) ? friendsList.join(';').replace(/,online/ig,'') : '';
GM_setValue(thisStumbler,friendsPref);
window.location.reload();
}
}
function sortFriends(a,b){
a = a.toLowerCase();
b = b.toLowerCase();
if (a<b) return 1;
if (a>b) return -1;
return 0;
}
function xpath(obj,query) {
return document.evaluate(query, obj, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}
// Userscript Auto-Update - http://userscripts.org/scripts/show/22372 - edited July 18 2008 by Nathan Blume
function GetNewVersion() {
var today = new Date();
GM_setValue('Updated', String(today));
window.location = source_location;
}
function CheckForUpdate(){
var today = new Date();
var one_day = 24 * 60 * 60 * 1000; //One day in milliseconds
if(lastupdatecheck != 'never'){
today = today.getTime(); //Get today's date
lastupdatecheck = new Date(lastupdatecheck).getTime();
var interval = (today - lastupdatecheck) / one_day; //Find out how many days have passed
if(interval >= 7){
manual_check = false;
CheckVersion();
}
}else{
lastupdatecheck = new Date(lastupdatecheck).getTime();
manual_check = false;
CheckVersion();
}
}
function CheckVersion(){
GM_xmlhttpRequest({
method: 'GET',
url: version_holder,
headers: {'Content-type':'application/x-www-form-urlencoded'},
onload: function(responseDetails){
var latest_version = responseDetails.responseText.match(/version=([0-9\.]+)/);
if(latest_version[1] != null && latest_version[1] != 'undefined'){
if(current_version != latest_version[1]){
if(confirm('A more recent version of ' + script_title + ' (' + latest_version[1] + ') has been found.\nWould you like to get it now?'))
GetNewVersion();
else
AskForReminder();
}else{
SkipWeeklyUpdateCheck();
if(manual_check == true)
alert('You have the latest version of ' + script_title + '.');
}
}else{
alert('Sorry, there was problem checking for the update.\nPlease try again later.');
}
}
});
}
function AskForReminder(){
if(confirm('Would you like to be reminded in 24 hours ?\n(Cancel to be reminded in one week.)')){
var today = new Date();
today = today.getTime();
var sixdays_ms = 6 * 24 * 60 * 60 * 1000;
var sda_ms = today - sixdays_ms;
var sixdaysago = new Date(sda_ms)
GM_setValue('Updated', String(sixdaysago));
}else{
SkipWeeklyUpdateCheck();
}
}
function SkipWeeklyUpdateCheck(){
var today = new Date();
GM_setValue('Updated', String(today));
}