There are 55 previous versions of this script.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name Facebook Invites
// @namespace FacebookInvites
// @description Invites your friends to the app if they've already allowed the app access. Adds an bulk add form in message threads.
// @include http://*.facebook.com/*
// @include http://forums.zynga.com/*
// ==/UserScript==
/*
window.friendsWithAppList = List of friends with this app.
window.friendsWithAppNotInvited = List of friends with this app we can invite.
window.friendsWithAppId = The app id where we retreived the list of friends from.
window.friendsInInviteDialog = friends in the invite dialog
*/
//var SUC_script_num = 43682; // Change this to the number given to the script by userscripts.org (check the address bar)
//try{function updateCheck(forced){if ((forced) || (parseInt(GM_getValue('SUC_last_update', '0')) + (86400000*7) <= (new Date().getTime()))){try{GM_xmlhttpRequest({method: 'GET',url: 'http://userscripts.org/scripts/source/'+SUC_script_num+'.meta.js?'+new Date().getTime(),headers: {'Cache-Control': 'no-cache'},onload: function(resp){var local_version, remote_version, rt, script_name;rt=resp.responseText;GM_setValue('SUC_last_update', new Date().getTime()+'');remote_version=parseInt(/@uso:version\s*(.*?)\s*$/m.exec(rt)[1]);local_version=parseInt(GM_getValue('SUC_current_version', '-1'));if(local_version!=-1){script_name = (/@name\s*(.*?)\s*$/m.exec(rt))[1];GM_setValue('SUC_target_script_name', script_name);if (remote_version > local_version){GM_setValue('SUC_current_version', remote_version);if(confirm('There is an update available for the Greasemonkey script "'+script_name+'."\nWould you like to go to the install page now?')){GM_openInTab('http://userscripts.org/scripts/show/'+SUC_script_num);}}else if (forced)alert('No update is available for "'+script_name+'."');}else GM_setValue('SUC_current_version', remote_version+'');}});}catch (err){if (forced)alert('An error occurred while checking for updates:\n'+err);}}}GM_registerMenuCommand(GM_getValue('SUC_target_script_name', '???') + ' - Manual Update Check', function(){updateCheck(true);});updateCheck(false);}catch(err){}
// Checkbox list: http://apps.facebook.com/dragonwars/recruit.php
// Picture list: http://apps.facebook.com/egghunt/invite.php
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
var nHtml={
FindByAttr:function(obj,tag,attr,className) {
if(attr=="className") { attr="class"; }
var q=document.evaluate(".//"+tag+"[@"+attr+"='"+className+"']",obj,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
if(q && q.singleNodeValue) { return q.singleNodeValue; }
return null;
},
FindByClassName:function(obj,tag,className) {
return this.FindByAttr(obj,tag,"className",className);
},
FindByXPath:function(obj,xpath) {
try {
var q=document.evaluate(xpath,obj,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
} catch(e) {
GM_log('bad xpath:'+xpath);
}
if(q && q.singleNodeValue) { return q.singleNodeValue; }
return null;
},
VisitUrl:function(url) {
window.setTimeout(function() {
document.location.href=url;
},500+Math.floor(Math.random()*500));
},
ClickWin:function(win,obj,evtName) {
var evt = win.document.createEvent("MouseEvents");
evt.initMouseEvent(evtName, true, true, win,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
return !obj.dispatchEvent(evt);
},
Click:function(obj) {
return this.ClickWin(window,obj,'click');
},
ClickTimeout:function(obj,millisec) {
window.setTimeout(function() {
return nHtml.ClickWin(window,obj,'click');
},millisec+Math.floor(Math.random()*500));
},
ClickUp:function(obj) {
this.ClickWin(window,obj,'mousedown');
this.ClickWin(window,obj,'mouseup');
this.ClickWin(window,obj,'click');
},
GetText:function(obj,depth) {
var txt='';
if(depth==undefined) { depth=0; }
if(depth>40) { return; }
if(obj.textContent!=undefined) { return obj.textContent; }
for(var o=0; o<obj.childNodes.length; o++) {
var child=obj.childNodes[o];
txt+=this.GetText(child,depth+1);
}
return txt;
}
};
FacebookInvites={
addMeUpto:0,
addMeUptoMax:0, // how many users do we try to add as friends on this page. Only 1 when we're on profile page.
addMeDone:{},
waitForAddMe:null,
waitForAddMeStarted:null,
bulkAddMeTimeout:null,
messObj:null,
allAppsId:"0ALLAPPS",
bulkAddOptions:{},
SetMessage:function(mess) {
if(!this.messObj) {
var content=document.getElementById('content');
if(!content) content=document.body;
if(content) {
var div=document.createElement('div');
div.style.paddingTop='48px';
div.innerHTML=mess;
content.insertBefore(div,content.childNodes[0]);
this.messObj=div;
} else {
GM_log('cannot find content div');
}
}
this.messObj.innerHTML=mess;
},
IsTooManySelected:function() {
var toomany=nHtml.FindByXPath(document,"//div[@class='toomany_selected']");
if(toomany && toomany.style.display!='none') {
GM_log('Too many friends selected');
return true;
}
return false;
},
InviteFriendsCheckBox:function(div,friendsHash,click) {
var inps=div.getElementsByTagName('input');
var friendsClicked=0;
var selected={};
for(var i=0; i<inps.length; i++) {
var inp=inps[i];
var val=""+inp.value;
if(inp.id!="ids[]") {
continue;
}
if(friendsHash!=null && !friendsHash[val]) {
continue;
}
if(selected[val]) { continue; }
var sel=true;
if(inp.parentNode.parentNode.className=="unselected_list") {
sel=false;
}
if(inp.parentNode.style.display=='none') { continue; }
if(click(sel,val)) {
selected[val]=1;
nHtml.Click(inp.parentNode);
friendsClicked++;
if(this.IsTooManySelected()) {
break;
}
}
}
return friendsClicked;
},
InviteFriendsPictures:function(div,friendsHash,click) {
var lis=div.getElementsByTagName('li');
var selected=0;
for(var l=0; l<lis.length; l++) {
var li=lis[l];
var as=li.getElementsByTagName('a');
if(as.length<1) { continue; }
var userid=""+li.getAttributeNode('userid').value;
if(friendsHash!=null && !friendsHash[userid]) {
continue;
}
if(click(li.className=='selected',userid)) {
nHtml.Click(as[0]);
selected++;
if(this.IsTooManySelected()) {
break;
}
}
}
return selected;
},
InviteFriendsClick:function(div,friendsHash,click) {
if(!this.IsFriendsDivPictures(div)) {
return this.InviteFriendsCheckBox(div,friendsHash,click);
}
return this.InviteFriendsPictures(div,friendsHash,click);
},
IsFriendsDivPictures:function(div) {
if(div.className.indexOf("condensed_multi_friend_selector")>=0) {
return false;
}
return true;
},
GetFriendsDiv:function() {
var friends2=nHtml.FindByClassName(document.body,"div","condensed_multi_friend_selector");
if(friends2) { return friends2; }
var friends=document.getElementById("friends");
return friends;
},
DoIFrame:function(url) {
var f=document.getElementById('FBInvitesFrame');
if(!f) {
f=document.createElement('iframe');
f.style.display='none';
f.id='FBInvitesFrame';
document.body.appendChild(f);
}
f.src=url;
return f;
},
previousStr:'this',
InviteFriends:function() {
if(document.getElementById('InviteFriendRefresh')) {
// we've already done this page.
return;
}
var friends=this.GetFriendsDiv();
if(!friends) {
return false;
}
var link=document.createElement('a');
link.href='javascript:;';
link.id='InviteFriendRefresh';
this.previousStr='this';
var appId=this.GetAppId();
var oldAppId=GM_getValue('appid','');
var linkMess=document.createElement('span');
linkMess.innerHTML='';
link.innerHTML="• Refresh your list of friends who are using this application.";
link.title="Go to the 'friends who are using this applications' page. This needs to be done before new friends will be selected here.";
if(!appId && !oldAppId) {
linkMess.innerHTML="Need to visit an application's invite page to collect a list of friends first!";
} else if(!appId) {
// we're in the facebook friends list or some other non-app thing.
link.innerHTML="";
this.previousStr='previous';
}
var friendsHash=this.GetFriendsWithApp();
var appFriendsHash=null;
if(appId && oldAppId) {
var lastSync=GM_getValue('FriendsWithAppSyncTime_'+appId,'');
if(lastSync!='') {
appFriendsHash=this.GetFriendsWithApp(appId);
friendsHash=appFriendsHash;
var lastSyncD=new Date();
lastSyncD.setTime(lastSync);
var alertStyle='';
var now=new Date().getTime();
if(lastSync<(now-86400*1000*3)) {
alertStyle="style='color: #f00'";
}
linkMess.innerHTML+=" <b "+alertStyle+">Friends list last refreshed on: "+lastSyncD.toString()+"</b><br />";
} else if(appId!=oldAppId) {
linkMess.innerHTML+=" <b>Warning! The list of friends are from another app.</b><br />";
this.previousStr='previous';
}
}
if(appFriendsHash==null && appId) {
// don't have anything in the memory for this app, first time user...
// this.VisitFriendsList();
// link.innerHTML="Important: "+link.innerHTML;
link.style.fontSize='15pt';
}
var css=document.createElement('style');
css.type='text/css';
css.innerHTML='#InviteFriendsDiv a { color: #008; } #InviteFriendsDiv a:hover { text-decoration: underline; }';
document.getElementsByTagName('head')[0].appendChild(css);
var managementDiv=document.createElement('div');
managementDiv.innerHTML="You can also grab the users from any page via the greasemonkey icon under 'user script commands'<br />";
if(appId) {
// we're in an app, not facebook. let's hide the friends management section.
managementDiv.style.display='none';
}
managementDiv.style.marginLeft='10px';
var managementLink=document.createElement('a');
managementLink.innerHTML='• Friends management';
managementLink.title='Open up the friends management area. More functions to handle friends ';
managementLink.addEventListener('click',function() {
managementDiv.style.display=managementDiv.style.display=='none'?'block':'none';
},false);
var linkDiv=document.createElement('div');
this.messObj=document.createElement("div");
this.messObj.style.fontSize='14pt';
linkDiv.id='InviteFriendsDiv';
linkDiv.appendChild(this.messObj);
linkDiv.appendChild(linkMess);
linkDiv.appendChild(link);
linkDiv.appendChild(document.createElement("br"));
linkDiv.appendChild(managementLink);
linkDiv.appendChild(document.createElement("br"));
linkDiv.appendChild(managementDiv);
linkDiv.style.border='2px solid #888';
linkDiv.style.padding='4px';
linkDiv.style.color='#444';
linkDiv.style.backgroundColor='#fff';
var clearLink=document.createElement('a');
clearLink.href='javascript:;';
clearLink.id='InviteFriendClear';
clearLink.innerHTML='Deselect';
var selectAllLink=document.createElement('a');
selectAllLink.innerHTML='Select';
var bull=document.createElement("font")
bull.innerHTML="• ";
linkDiv.appendChild(bull);
linkDiv.appendChild(selectAllLink);
linkDiv.appendChild(document.createTextNode(" / "));
linkDiv.appendChild(clearLink);
linkDiv.appendChild(document.createTextNode(" all friends."));
linkDiv.appendChild(document.createElement("br"));
var removeLink=document.createElement('a');
removeLink.innerHTML='Deselect';
var unionLink=document.createElement('a');
unionLink.innerHTML='Join';
unionLink.title='Only select friends using '+this.previousStr+' application and friends currently selected here.';
var addLink=document.createElement('a');
addLink.innerHTML='Select';
var bull=document.createElement("font")
bull.innerHTML="• ";
managementDiv.appendChild(bull);
managementDiv.appendChild(addLink);
managementDiv.appendChild(document.createTextNode(" / "));
managementDiv.appendChild(removeLink);
managementDiv.appendChild(document.createTextNode(" / "));
managementDiv.appendChild(unionLink);
managementDiv.appendChild(document.createTextNode(' Friends from the current list.'));
var copyLink=document.createElement('a');
copyLink.innerHTML='• Use the selected friends below as the current list.';
managementDiv.appendChild(document.createElement("br"));
managementDiv.appendChild(copyLink);
var useBufferLink=null;
if(appFriendsHash!=null) {
useBufferLink=document.createElement('a');
useBufferLink.innerHTML="• Use the previous application's friends list for select/deselect/join.";
managementDiv.appendChild(document.createElement("br"));
managementDiv.appendChild(useBufferLink);
}
joinRecentLink=document.createElement('a');
joinRecentLink.innerHTML="• Only include friends who are also in the first page of 'recently added friends'.";
linkDiv.appendChild(joinRecentLink);
linkDiv.appendChild(document.createElement("br"));
var randomLink=document.createElement('a');
randomLink.href='javascript:;';
randomLink.innerHTML='• Add random friends who are using '+this.previousStr+' application.';
linkDiv.appendChild(randomLink);
var detachLink=document.createElement('a');
detachLink.innerHTML='• Move this block to the top';
detachLink.title="If you're having visibility problems";
linkDiv.appendChild(document.createElement("br"));
linkDiv.appendChild(detachLink);
var contentDiv=document.getElementById('content');
if(!contentDiv) contentDiv=document.body;
var randomDialog=document.createElement('div');
randomDialog.innerHTML="<br /><br /><form><input type='checkbox' id='AddRandomFriendsAnyFriends' />Add any friends, not just people who're using the app.<br />Friends to add: <input id='AddRandomFriendsNum' size='4' value='1' /><input id='AddRandomFriendsButton' type='button' value='Add Random Friends' /></form>";
randomDialog.style.border="2px solid #888";
randomDialog.style.padding='4px';
randomDialog.style.position='fixed';
randomDialog.style.backgroundColor='#fff';
randomDialog.style.color='#000';
randomDialog.style.left=0;
randomDialog.style.top=0;
randomDialog.style.display="none";
contentDiv.appendChild(randomDialog);
var randomButton=document.getElementById('AddRandomFriendsButton');
if(!this.IsFriendsDivPictures(friends)) {
friends.parentNode.insertBefore(linkDiv,friends);
} else {
friends.parentNode.insertBefore(linkDiv,friends);
}
link.addEventListener('click',function() { FacebookInvites.VisitFriendsList(); },false);
copyLink.addEventListener('click',function() {
var friendsList=[];
friendsHash={};
FacebookInvites.InviteFriendsClick(friends,null,function(c,id) {
if(c) {
friendsHash[id]=1;
friendsList.push(id);
}
return false;
});
var friendsListStr=friendsList.join(',');
GM_setValue('FriendsWithApp',friendsListStr);
FacebookInvites.SetMessage("The list we're using now has "+friendsList.length+" friends.");
},false);
selectAllLink.addEventListener('click',function() {
FacebookInvites.InviteFriendsClick(friends,null,function(c) { return c?false:true; });
},false);
clearLink.addEventListener('click',function() {
FacebookInvites.InviteFriendsClick(friends,null,function(c) { return c?true:false; });
},false);
removeLink.addEventListener('click',function() {
FacebookInvites.InviteFriendsClick(friends,friendsHash,function(c) { return c?true:false; });
},false);
unionLink.addEventListener('click',function() {
FacebookInvites.InviteFriendsClick(friends,null,function(c,id) {
if(c) return friendsHash[id]?false:true;
return false;
});
},false);
if(useBufferLink!=null) {
useBufferLink.addEventListener('click',function() {
friendsHash=FacebookInvites.GetFriendsWithApp();
FacebookInvites.CalcInvitedHash(friendsHash);
},false);
}
joinRecentLink.addEventListener('click',function() {
// visit recent added friends in iframe,
var iframe=FacebookInvites.DoIFrame('http://www.facebook.com/friends/?added&ref=tn');
GM_log('Waiting for recent friends to load');
unsafeWindow.joinRecentLoadedLink=function() {
GM_log('Recent friends loaded');
var recentFriends=FacebookInvites.GetFriendsFromPage(iframe.contentDocument.body);
var ids=[];
for(var id in friendsHash) { ids.push(id); }
var t=0;
ids.forEach(function(id) {
if(!recentFriends[id]) {
friendsHash[id]=undefined;
} else {
t++;
}
});
FacebookInvites.InviteFriendsClick(friends,null,function(c) {
if(c) {
return true;
}
});
FacebookInvites.InviteFriendsClick(friends,null,function(c,id) {
var r=friendsHash[id]?true:false;
if(c) { r=r?false:true; GM_log('huh? something is still selected?'); }
return r;
});
FacebookInvites.SetMessage("The list we're using now has "+t+" friends.");
iframe.src='about:blank';
document.body.removeChild(joinRecentLoadedLink);
};
},false);
addLink.addEventListener('click',function() {
FacebookInvites.InviteFriendsClick(friends,friendsHash,function(c) { return c?false:true; });
},false);
randomLink.addEventListener('click',function() {
randomDialog.style.display='block';
},false);
detachLink.addEventListener('click',function() {
FacebookInvites.DetachDiv();
},false);
randomButton.addEventListener('click',function() {
randomDialog.style.display='none';
var randomNum=document.getElementById('AddRandomFriendsNum');
var wanted=parseInt(randomNum.value);
var friendsHashRandom={};
var added=0;
var anyFriends=document.getElementById('AddRandomFriendsAnyFriends').checked;
var friendsInDialog={}; // friends that are not selected in the dialog
FacebookInvites.InviteFriendsClick(friends,null,function(c,id) { if(!c) { friendsInDialog[id]=1; } return false; } );
var friendsArr=[];
var hashToUse=friendsHash;
if(anyFriends) {
hashToUse=friendsInDialog;
}
for(var f in hashToUse) {
friendsArr.push([f,Math.random()]);
}
friendsArr.sort(function(a,b) { return a[1]-b[1]; });
for(var fUpto=0; fUpto<friendsArr.length; fUpto++)
{
if(added>=wanted) {
break;
}
var f=friendsArr[fUpto][0];
if(!friendsInDialog[f]) { continue; }
friendsHashRandom[f]=""+friendsHash[f];
added++;
}
FacebookInvites.InviteFriendsClick(friends,friendsHashRandom,function(c,id) { return c?false:true; });
},false);
window.friendsWithAppId=oldAppId;
this.CalcInvitedHash(friendsHash);
this.InviteFriendsClick(friends,friendsHash,function(c,id) {
var r=c?false:true;
if(!appId) {
// can't find app id, we're in facebook, lets' not auto add all the friends.
return false;
}
return r;
});
return true;
},
GetInviteFriendsDiv:function() {
return document.getElementById('InviteFriendsDiv');
},
DetachDiv:function() {
var linkDiv=this.GetInviteFriendsDiv();
if(!linkDiv) { return; }
linkDiv.style.position='fixed';
linkDiv.style.left=0;
linkDiv.style.top='24px';
},
CalcInvitedHash:function(friendsHash) {
var friendsDiv=this.GetFriendsDiv();
var totalFriendsWithApp=0;
for(var f in friendsHash) {
totalFriendsWithApp++;
}
var invited=0;
var invitedHash={};
var friendsInInviteDialog={};
this.InviteFriendsClick(friendsDiv,null,function(c,id) {
if(friendsHash[id]) {
var r=c?false:true;
if(r) invitedHash[id]=1;
if(r) { invited++; }
}
friendsInInviteDialog[id]=1;
return false;
});
window.friendsWithAppList=friendsHash;
window.friendsWithAppNotInvited=invitedHash;
window.friendsInInviteDialog=friendsInInviteDialog;
this.SetMessage(" (Friends with "+this.previousStr+" application that you can invite:"+invited+" out of "+totalFriendsWithApp+")");
},
idRe:new RegExp('[^a-z]id=([0-9]+)','i'),
GetAppId:function() {
var builtBy=nHtml.FindByClassName(document.body,"span","page_built_by");
if(builtBy) {
var as=builtBy.getElementsByTagName("a");
if(as.length>0) {
var m=this.idRe.exec(as[0].href);
if(m && m.length>0) {
var id=m[1];
return id;
}
}
}
var appContentDiv=nHtml.FindByXPath(document.body,"//div[contains(@id,'app_content_')]");
if(appContentDiv) {
var m=/^app_content_([0-9]+)$/.exec(appContentDiv.id);
if(m && m.length>1) {
return m[1];
}
}
return null;
},
VisitFriendsList:function() {
var appid=this.GetAppId();
GM_setValue('appid',appid);
GM_setValue('FriendsWithApp','');
GM_setValue('InviteUrl',document.location.href);
document.location.href="http://www.facebook.com/social_graph.php?node_id="+appid+"&class=AppUserManager&edge_type=mutual&start=0"; //change suggested by Lox Myth - see http://userscripts.org/topics/34630#posts-166598
return true;
},
GetFriendsWithApp:function(appId) {
var friends=GM_getValue('FriendsWithApp'+(appId!=undefined?("_"+appId):''),'').split(/,/);
var friendsHash={};
for(var f=0; f<friends.length; f++) {
var n=friends[f];
if(n=="") { continue; }
friendsHash[n]=1;
}
return friendsHash;
},
AddFriendsWithApp:function() {
var inviteUrl=GM_getValue('InviteUrl','');
if(inviteUrl=='') { return; }
var content=document.getElementById('content');
if(!content) { return; }
var as=content.getElementsByTagName('a');
var nextUrl=null;
var friends=this.GetFriendsWithApp();
this.ClickClose();
// var ss=document.evaluate("//a[contains(@href,'/social_graph.php') and contains(@title,'Next')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null); //change suggested by Lox Myth - see http://userscripts.org/topics/34630#posts-166598
//it doesn't work with different localization
// suggested by: jcppkkk
var ss=document.evaluate("//span[@class!='UIPager_ButtonWrapper UIPager_ButtonDisabled']/a[@class='UIPager_Button UIPager_ButtonForward']",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if(ss.snapshotLength>0) {
var lastpager=ss.snapshotItem(ss.snapshotLength-1);
var numberRe=/^[\\s0-9]+$/;
if(!numberRe.exec(lastpager.innerHTML)) {
// we still have a "next" button.
nextUrl=lastpager.href;
}
}
var friendsAdded=0;
for(var aUpto=0; aUpto<as.length; aUpto++) {
var a=as[aUpto];
if(a.href.indexOf("/friends/")<0) { //change suggested by Austin Pereira - http://userscripts.org/topics/34741#posts-167127
continue;
}
var id;
var m=this.idRe.exec(a.href);
if(m && m.length>0) {
id=m[1];
} else { continue; }
if(friends[id]) { continue; }
var name=a.innerHTML;
friends[""+id]=1;
friendsAdded++;
}
var friendsListStr=this.SaveFriendsFromHash(friends);
var appid=GM_getValue('appid',0);
GM_setValue('FriendsWithApp_'+appid,friendsListStr);
GM_setValue('FriendsWithAppSyncTime_'+appid,(new Date()).getTime().toString() );
if(nextUrl!=null) {
nHtml.VisitUrl(nextUrl);
} else {
// cannot find "next" button, lets go back to app.
GM_setValue('InviteUrl','');
nHtml.VisitUrl(inviteUrl);
}
return friendsAdded>0?true:false;
},
SaveFriendsFromHash:function(friends) {
var friendsList=[];
for(var n in friends) {
if(n=="") {continue; }
friendsList.push(n);
}
var friendsListStr=friendsList.join(',');
GM_setValue('FriendsWithApp',friendsListStr);
return friendsListStr;
},
StartBulkAddMe:function() {
this.addMeUpto=0;
this.RestartAddMe();
},
AddMeLink:function(lp) {
if(document.getElementById("AddMeLinkDiv")) { return; }
if(!lp) lp=document.getElementById("all_threads");
// if(!lp) { lp=document.getElementById("see_all_posts"); }
if(!lp) {
return false;
}
var div=document.createElement('div');
div.id='AddMeLinkDiv';
var autoBulkAdd=FacebookInvites.GetAutoBulkAdd();
div.innerHTML="<form id='BulkAddMe'>Comment:<textarea id='bulkAddComment' name='comment' cols='40' rows='4' /></textarea><br />"+
"Friend List:<input id='bulkAddFriendList' />(exactly with capital letters)<br />"+
"<input id='bulkAddDelay' value='10' size='4' />seconds between adds<br />"+
"<input type='checkbox' id='BulkAddNewsFeed' />Publish to news feed<br />"+
"<input type='checkbox' id='BulkAddMeButtonPages' />Bulk add everyone here and the previous pages of this discussion board<br />"+
"<input type='checkbox' id='testBulkAddMeButton' title='Test Only, do not add, just go through the process.' />Test only<br />"+
"<input type='checkbox' id='popupToAddFriend' title='Popup profile to add friend' />Add user via the users' profile instead. (This makes sure that we can add this user first before trying to add.)<br />"+
"<input type='checkbox' id='BulkAddIgnoreErrors' />Ignore errors, continue even when facebook returns an errors<br />"+
"<input type='button' id='BulkAddMeButton' value='Bulk Add Everyone here' /><br />"+
"<input type='button' id='BulkAddMeProfileButton' value='"+(autoBulkAdd?"Disable ":"Enable")+" auto add on profile Page' title='Useful for pages that do not have the add friend feature or is outside of facebook.' />(Once enabled, you can click with the middle mouse button on any profile link to add them)<br />"+
"</form>";
div.style.border='1px solid #000';
div.style.padding='10px';
lp.parentNode.insertBefore(div,lp);
var bulkAddMeButton=document.getElementById('BulkAddMeButton');
bulkAddMeButton.addEventListener('click',function() {
FacebookInvites.StartBulkAddMe();
},false);
var bulkAddMeProfile=document.getElementById('BulkAddMeProfileButton');
bulkAddMeProfile.addEventListener('click',function() {
GM_setValue('autoBulkAdd_RemoveWhenFinished',false);
FacebookInvites.SetAutoBulkAdd(autoBulkAdd?false:true);
},false);
return true;
},
AddMeLinkAnyPage:function() {
if(document.getElementById("AddMeLinkDiv")) { return; }
var content=document.getElementById('content');
var p=document.createElement('p');
p.innerHTML="<br /><br />";
content.insertBefore(p,content.childNodes[0]);
return FacebookInvites.AddMeLink(content.childNodes[1]);
},
RestartAddMe:function() {
if(this.bulkAddMeTimeout!=null) {
window.clearTimeout(this.bulkAddMeTimeout);
this.bulkAddMeTimeout=null;
}
this.SetWaitForAddMe(null);
this.addMeDone={};
var o={};
o.friendList=document.getElementById('bulkAddFriendList').value.trim();
o.comment=document.getElementById('bulkAddComment').value;
o.delay=document.getElementById('bulkAddDelay').value;
o.testAddMe=document.getElementById('testBulkAddMeButton').checked;
o.ignoreErrors=document.getElementById('BulkAddIgnoreErrors').checked;
o.doPrevPages=document.getElementById('BulkAddMeButtonPages').checked;
o.newsFeed=document.getElementById('BulkAddNewsFeed').checked;
if(this.IsPopupToAddFriend()) {
GM_setValue('autoBulkAdd_RemoveWhenFinished',true);
FacebookInvites.SetAutoBulkAdd(true);
}
this.bulkAddOptions=o;
this.BulkAddMe();
},
IsPopupToAddFriend:function() {
var p=document.getElementById('popupToAddFriend');
if(p && p.checked) { return true; }
return false;
},
HasAddFriendDialog:function(a) {
var addFriendDialog=false;
if(a.href && a.href.indexOf('profile')>=0) {
addFriendDialog=true;
}
/*
var oncl=a.getAttribute('onclick');
if(oncl && oncl.indexOf('show_addfriend_dialog')>=0) {
addFriendDialog=true;
}
*/
return addFriendDialog;
},
FindNthPost:function(nth) {
var as=document.getElementsByTagName('a');
var upto=0;
for(var aUpto=0; aUpto<as.length; aUpto++) {
var a=as[aUpto];
var addFriendDialog=this.HasAddFriendDialog(a);
if(!addFriendDialog && a.href.indexOf('k=')<0) {
// this person is already our friend.
continue;
}
// author_post: used in discussions
// profile_link: used in reviews
if(!addFriendDialog && a.className!="author_post" && a.className!="profile_link") {
continue;
}
if(a.parentNode.className.indexOf("fb_menu")>=0 || a.innerHTML.indexOf('<img')>=0) {
continue;
}
var pn=a;
var presence=false;
while(pn && pn.tagName!="BODY") {
if(pn.id=="presence") {
presence=true;
}
pn=pn.parentNode;
}
if(presence) { continue; }
if(nth==upto++) { return a; }
}
return null;
},
ClickFriendListDropDown:function() {
GM_log('ClickFriendListDropDown');
var friendAdd=nHtml.FindByAttr(document,'span','class','FriendAddingTool_Menu');
if(friendAdd) {
var friendAddDropDown=nHtml.FindByAttr(friendAdd,'span','class','UIActionMenu_Text');
// show the drop down for friends' lists
if(friendAddDropDown) {
nHtml.ClickUp(friendAddDropDown);
} else {
GM_log('cannot find friend list drop down');
}
} else {
GM_log('cannot find the friends list drop down');
}
},
GetFriendListDropDown:function(div) {
if(!div) { GM_log('GetFriendListDropDown: no div'); }
return nHtml.FindByAttr(div,'div','class','FriendAddingTool_InnerMenu');
},
SelectFriendListDropDown:function(friendAddSelect,friendList) {
GM_log('SelectFriendListDropDown');
if(!friendAddSelect) { GM_log('Bad!, no friendAddSelect'); }
var friendListItem=nHtml.FindByXPath(friendAddSelect,".//a[string()='"+friendList+"']");
if(friendListItem) {
nHtml.ClickUp(friendListItem);
}
},
SkipButton:function() {
// skip reported suggest a friend dialogs from facebook.
var skip=document.getElementById('skip');
if(skip && skip.tagName=="INPUT") {
GM_log('Clicking skip button');
nHtml.Click(skip);
return true;
}
return false;
},
SetWaitForAddMe:function(v) {
this.waitForAddMe=v;
this.waitForAddMeStarted=(new Date()).getTime();
},
BulkAddMe:function() {
var waitMillis=150;
var error=document.getElementById('error');
if(error && !this.bulkAddOptions.ignoreErrors) {
var visible=true;
while(error.tagName!="BODY") {
if(error.style.display=="none") {
visible=false;
break;
}
error=error.parentNode;
}
if(visible) {
GM_log('Error found, bulk add aborted');
if(GM_getValue('autoBulkAdd_RemoveWhenFinished',false))
this.SetAutoBulkAdd(false);
return;
}
}
this.ClickClose();
//GM_log(this.waitForAddMe+","+this.addMeUpto);
var captcha=document.getElementById('captcha_session');
var cp=captcha;
while(cp && cp.tagName!="BODY") {
if(cp.tagName=="FORM") {
if(cp.action && cp.action.indexOf('edittopic')>=0) {
// ignore captcha for making forum posts.
captcha=undefined;
}
break;
}
cp=cp.parentNode;
}
var popDialogss=document.evaluate(".//div[contains(@id,'pop_content')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
//var popDialog=document.getElementById("pop_content");
var popDialog=null;
for(var popss=0; popss<popDialogss.snapshotLength; popss++) {
var pd=popDialogss.snapshotItem(popss);
var inps=pd.getElementsByTagName('INPUT');
if(!inps || inps.length==0) { continue; }
popDialog=pd;
break;
}
if(this.SkipButton()) {
// LoveYou43v3r reported that it got stuck in some skip dialogs.
waitMillis=10000;
} else if(captcha && popDialog) {
// yuck captcha, wait for the user to do something.
GM_log('found captcha, wait for user input');
waitMillis=2000;
} else if(this.waitForAddMe=="add") {
if(popDialog) {
var a=nHtml.FindByXPath(popDialog,".//a[contains(@href,'/addfriend.php')]");
if(!a) {
// maybe we've already added this friend.
var close=nHtml.FindByAttr(popDialog,"input","name","close");
if(close) {
this.waitForAddMe=null;
nHtml.Click(close);
} else {
GM_log('waiting for add friend popup');
}
} else {
nHtml.Click(a);
this.SetWaitForAddMe("message");
}
}
} else if(this.waitForAddMe=="message") {
var add=null;
if(popDialog) {
add=nHtml.FindByAttr(popDialog,"input","name",'connect');
var ok=nHtml.FindByAttr(popDialog,"input","name",'ok');
var ss=document.evaluate(".//input",popDialog,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if(ss.snapshotLength==1 && ok) {
// maybe the you are already connected message, just click ok
GM_log('Click ok button');
nHtml.Click(ok);
}
}
if(popDialog && add) {
var friendAddSelect=this.GetFriendListDropDown(document);
var friendList=this.bulkAddOptions.friendList;
if(!friendAddSelect && friendList.length>0) {
this.ClickFriendListDropDown();
} else {
if(friendList.length>0) {
this.SelectFriendListDropDown(friendAddSelect,friendList);
}
var newsFeed=nHtml.FindByXPath(popDialog,".//input[contains(@id,'news_feed_')]");
if(newsFeed) newsFeed.checked=this.bulkAddOptions.newsFeed;
var showComment=nHtml.FindByXPath(popDialog,".//a[contains(@onclick,'showMessage')]");
nHtml.Click(showComment);
var tas=popDialog.getElementsByTagName('textarea');
if(tas.length>0) {
tas[0].value=this.bulkAddOptions.comment;
}
var messLink=nHtml.FindByXPath(popDialog,".//a[contains(@onclick,'addMsgBox')]");
if(messLink) {
nHtml.Click(messLink);
}
if(this.bulkAddOptions.testAddMe) {
add=nHtml.FindByAttr(popDialog,"input","name","cancel");
}
if(add) {
var delay=this.bulkAddOptions.delay;
this.SetWaitForAddMe(null);
// this means that it goes into the else loop after clicking on connect which means that it ignores the "already connected" error
// therefore i've added the code to click on already connected in the else part of the if statement
waitMillis=1000*delay;
window.setTimeout(function() {
nHtml.Click(add);
},this.bulkAddOptions.testAddMe?1500:0);
}
}
}
if(this.waitForAddMe=="message" && (this.waitForAddMeStarted+15000)< ((new Date()).getTime()) ) {
var b1=document.getElementById('dialog_button1');
var b2=document.getElementById('dialog_button2');
if(b1 && !b2) {
GM_log('We are already friends with this person');
nHtml.Click(b1);
} else {
// 15 secs is up, still no dialog found.
GM_log('Skipping this user cause no add friend dialog is showing up.'+location.href);
}
this.SetWaitForAddMe(null);
}
} else {
while(1) {
if(this.addMeUptoMax>0 && this.addMeUpto>=this.addMeUptoMax) {
GM_log('FinishedBulkAddMe, max added:'+this.addMeUptoMax);
return;
}
if(!this.profilePageAdd) {
var a=this.FindNthPost(this.addMeUpto++);
if(a==null) {
if(!this.BulkAddMePrevPage()) {
if(GM_getValue('autoBulkAdd_RemoveWhenFinished',false))
this.SetAutoBulkAdd(false);
GM_log('FinishedBulkAddMe');
return;
}
this.addMeUpto=0;
waitMillis=12000;
break;
}
}
//error checking for already connected dialog - added by VX
var add=null;
if(popDialog) {
add=nHtml.FindByAttr(popDialog,"input","name",'connect');
var ok=nHtml.FindByAttr(popDialog,"input","name",'ok');
var ss=document.evaluate(".//input",popDialog,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if(ss.snapshotLength==1 && ok) {
// maybe the you are already connected message, just click ok
GM_log('Click ok button');
nHtml.Click(ok);
}
//click cancel on old dialog
popDialog=document.getElementById("pop_content");
if(popDialog) {
var cancel=nHtml.FindByAttr(popDialog,"input","name","cancel");
nHtml.Click(cancel);
}
}
// finished edit by vx
// var hasAddFriendDialog=this.HasAddFriendDialog(a);
// var ref=hasAddFriendDialog?a.getAttribute('onclick'):a.href;
var ref=a.href;
var idm=this.idRe.exec(a.href);
if(!idm) { continue; }
if(this.addMeDone[ref]) { continue; }
this.addMeDone[ref]=1;
this.ShowAddFriendDialog(idm[1],this.IsPopupToAddFriend());
if(this.IsPopupToAddFriend()) {
waitMillis=10000;
this.SetWaitForAddMe(null);
} else {
this.SetWaitForAddMe("message");
}
this.waitForAddMeStarted=(new Date()).getTime();
/*
nHtml.Click(a);
if(hasAddFriendDialog) {
this.waitForAddMe="message";
} else {
this.waitForAddMe="add";
}
*/
break;
}
}
if(this.bulkAddOptions.testAddMe && waitMillis<2000) { waitMillis=2000; }
this.bulkAddMeTimeout=window.setTimeout(function() { FacebookInvites.BulkAddMe(); },waitMillis);
},
ShowAddFriendDialog:function(uid,popupToAddFriend) {
// var addFriendClick=nHtml.FindByXPath(document,"//a[contains(@onclick,'ConnectDialog')]");
if(popupToAddFriend) {
//GM_log('no add friend dialog available, lets go to the profile page:'+uid);
GM_openInTab('http://www.facebook.com/profile.php?id='+uid);
/*
this.SetMessage('Facebook has not included the javascript to add friends from this page, have to open the profile page in a new tab.'+
"Enable auto add on the profile page if you have not done it.");
*/
} else
{
var a=document.createElement('script');
GM_log('showfriend:'+uid);
a.innerHTML='new ConnectDialog("'+uid+'", "friend_other", null, this, 0, "", -1.000000, "", "").show();';
// a.innerHTML='show_addfriend_dialog("'+uid+'", this, undefined, undefined, undefined, undefined, undefined, "profile_others");';
document.body.appendChild(a);
}
},
BulkAddMePrevPage:function() {
if(!this.bulkAddOptions.doPrevPages) {
return false;
}
var ss=document.evaluate("//a[contains(@onclick,'start')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var numberRe=/^[\\s0-9]+$/;
var onclickRe=new RegExp("start[\"\\s]*:\\s*[0-9]+");
var foundUpto=0;
var firstPagerLink=null;
for(var s=0; s<ss.snapshotLength; s++) {
var a=ss.snapshotItem(s);
var oncl=a.getAttribute('onclick');
if(!oncl) { continue; }
if(!onclickRe.exec(oncl)) {
continue;
}
if(numberRe.exec(a.textContent)) {
if(foundUpto>0) {
// only 1 pager link, it must be "prev" on the 2nd page, there won't be a "first" link.
nHtml.Click(firstPagerLink);
return true;
}
break;
}
if(foundUpto==0) {
firstPagerLink=a;
}
if(foundUpto==1) {
// the 2nd pager link with text
nHtml.Click(a);
return true;
}
foundUpto++;
}
GM_log('No previous link found');
return false;
},
ClearFriendsBuffer:function() {
this.SetMessage("0 Friends in the current list.");
this.SaveFriendsFromHash({});
},
GetFriendsFromPage:function(doc,profileRe) {
var as=doc.getElementsByTagName('a');
var imgRe=new RegExp("http://profile.ak.facebook.com/.*/[a-z]([0-9]+)_.*\\.jpg");
if(!profileRe) {
profileRe=new RegExp('.facebook.com.*friends.*id=([0-9]+)'); //change suggested by Austin Pereira - http://userscripts.org/topics/34741#posts-167127
}
var friendsFromPage={};
for(var aUpto=0; aUpto<as.length; aUpto++) {
var a=as[aUpto];
var ppid=a.parentNode.parentNode.id;
var ppclass=a.parentNode.parentNode.className;
// ignore profile links in the status update and notifications areas.
if(ppid.indexOf('notification_')>=0 || ppclass=='status_updates' || a.parentNode.className=='fb_menu_title' || a.parentNode.id=='friend_guesser') { continue; }
var profileM=profileRe.exec(unescape(a.href));
var id=null;
if(profileM && profileM.length>1) {
id=profileM[1];
} else {
var imgs=a.getElementsByTagName('img');
if(imgs && imgs.length>0) {
var imgM=imgRe.exec(imgs[0].src);
if(imgM && imgM.length>1) {
id=imgM[1];
}
}
}
if(id && !friendsFromPage[id]) {
GM_log('add friend to list:'+id);
friendsFromPage[id]=1;
}
}
return friendsFromPage;
},
/*
ShowAddFriendsFromPage:function() {
var div=document.createElement('div');
div.style.position='fixed';
div.style.left=0;
div.style.top=0;
div.innerHTML="<form>"+
"Next button: <input value='.facebook.com.*profile.php.*id=([0-9]+)' id='AddFriendsFromPageButton' />"+
"<input type='button' value='Go' id='AddFriendsFromPageButton' /><br /></form>";
document.body.appendChild(div);
var AddFriendsFromPageButton=document.getElementById('AddFriendsFromPageButton');
AddFriendsFromPageButton.addEventListener(function() {
var re=new RegExp(document.getElementById('AddFriendsFromPageButton').value);
FacebookInvites.GetFriendsFromPage(re,true);
},false);
},
*/
ClickAllFacebookFriendLinks:function() {
var ss=document.evaluate("//a[contains(@href,'.facebook.com')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var profileRe=new RegExp('facebook\.com/[^/]+$');
var profilePhpRe=new RegExp('facebook\.com/.*profile.php.*id=');
for(var s=0; s<ss.snapshotLength; s++) {
var a=ss.snapshotItem(s);
if(profileRe.exec(a.href) || profilePhpRe.exec(a.href)) {
GM_openInTab(a.href);
}
}
},
// add friends from any page
AddFriendsFromPage:function(info) {
if(info.pageUpto==undefined) {info.pageUpto=0; }
var friends=this.GetFriendsWithApp();
var addedFriends=0;
var friendsFromPage=this.GetFriendsFromPage(info.doc,info.profileRe);
for(var id in friendsFromPage) {
if(!friends[id]) {
friends[id]=1;
addedFriends++;
}
}
this.SaveFriendsFromHash(friends);
var totalFriends=0; for(var f in friends) { totalFriends++; }
GM_log('added '+addedFriends);
this.SetMessage("Added "+addedFriends+" to the current list, total:"+totalFriends);
if(info.doNextPage) {
var nextPage=nHtml.FindByXPath(document,".//a[contains(@class,'UIPager_ButtonForward')]");
if(nextPage) {
nHtml.Click(nextPage);
if(nextPage.parentNode.className.indexOf('Disabled')>=0) {
// no more next buttons
GM_log("No more next page buttons");
info.doNextPage=false;
}
} else {
var ss=document.evaluate("//a[contains(@onclick,'b:appfriends')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if(ss && ss.snapshotLength>0) {
var lastItem=ss.snapshotItem(ss.snapshotLength-1);
var numberRe=/^[\\s0-9]+$/;
var m=numberRe.exec(lastItem.innerHTML.trim());
if(!m) {
// last one is not a number so it's a "next" button.
nHtml.Click(lastItem);
} else {
GM_log("No more next page buttons");
info.doNextPage=false;
}
} else if(info.pageUpto==0) {
// we can't even find a next button on the first page, let's not click 'next'
GM_log('No next button on first page, do not do multiple pages.');
info.doNextPage=false;
}
}
if(info.doNextPage) {
GM_log('Wait for Next button');
window.setTimeout(function() {
info.pageUpto++;
FacebookInvites.AddFriendsFromPage(info);
},2000);
}
}
},
//////////////////////////////////////
profileIdRe:new RegExp('id=([0-9]+)'),
IterateButtons:function(func) {
var ss=document.evaluate("//*[contains(@class,'confirm_boxes') or contains(@class,'inputbutton') or @class='confirm']",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var info={
'func':func,
'ss':ss,
'sUpto':0,
'currentApp':'Unknown',
'currentAname':'',
'confirmUpto':0,
'nthButton':0
}
this.IterateButtonsNext(info);
},
IterateButtonsNext:function(info) {
var donext=this.IterateButtonsNext2(info);
if(donext)
this.IterateButtonsNext(info);
},
IterateButtonsNext2:function(info) {
// var ss=document.evaluate("//*[contains(@class,'confirm_boxes') or contains(@class,'inputbutton') or @class='confirm']",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
// var currentApp='Unknown';
// var currentAname='';
// var confirmUpto=0;
// var nthButton=0;
var ss=info.ss;
if(info.sUpto>=ss.snapshotLength) { return; }
// for(var s=0; s<ss.snapshotLength; s++) {
var sObj=ss.snapshotItem(info.sUpto);
info.sUpto++;
if(sObj.className.indexOf('BulkAddButton')>=0) {
return true;
}
if(sObj.className=='confirm') {
info.nthButton=0;
info.confirmUpto++;
return true;
}
if(sObj.className.indexOf('confirm_boxes')>=0) {
var aname=sObj.id;
var spans=sObj.getElementsByTagName('span');
if(spans.length>0) {
info.currentApp=spans[0].textContent.trim();
info.currentAname=aname;
}
return true;
}
var buttonValue=sObj.value;
var parent=sObj.parentNode;
while(parent && (parent.className==undefined || parent.className.indexOf('info')<0)) {
parent=parent.parentNode;
}
var profileHref=null;
var profileId=null;
if(parent) {
profileHref=nHtml.FindByXPath(parent,".//a[contains(@href,'profile.php')]");
if(profileHref) {
var pm=this.profileIdRe.exec(profileHref.href);
if(pm && pm.length>1) {
profileId=pm[1];
}
var nameInfo=profileHref.innerHTML.trim().split(new RegExp('\\s+'),2);
buttonValue=buttonValue.replace(profileHref.innerHTML+"'s",'');
buttonValue=buttonValue.replace(profileHref.innerHTML,'');
buttonValue=buttonValue.replace(nameInfo[0]+"'s",'');
buttonValue=buttonValue.replace(nameInfo[0],'');
}
} else {
GM_log('Cannot find parent to button: '+sObj.value);
}
var donext=false;
if(sObj.className.indexOf('inputbutton')>=0) {
donext=info.func(
{
'aname':info.currentAname,
'app':info.currentApp,
'obj':sObj,
'info':info,
'value':buttonValue,
'parent':parent,
'profileId':profileId,
'confirmUpto':info.confirmUpto,
'nthButton':info.nthButton
});
}
info.nthButton++;
return donext;
},
IsTest:function() {
var testBox=document.getElementById('BulkRequestsTest');
if(!testBox) { return false; }
var test=testBox?testBox.checked:false;
return test;
},
ClickAutoAcceptButton:function(obj) {
if(this.IsTest()) {
obj.style.border='3px solid #f00';
} else {
//var onclick=obj.getAttribute('onclick');
if(document.getElementById('BulkRequestsNewTab').checked) {
// var platformRe=new RegExp("click_add_platform_app[^;]+'(http[^']+)'");
var platformRe=/actions\[(http[^\]]+)\]/;
var m=platformRe.exec(obj.name);
if(m) {
var url=m[1].replace('&','&');
GM_log("Open in new tab:"+url);
GM_openInTab(url);
}
}
nHtml.Click(obj);
}
},
ClickAutoAccept:function(e) {
var target=e.target;
var appInfo=target.parentNode.id.split('_',2);
var app=appInfo[1];
app=unescape(app);
var nth=null;
var button=null;
var byText=null;
if(target.id=='BulkClickByTextButton') {
byText=document.getElementById('BulkClickByText').value.toLowerCase().trim();
if(byText=="") return;
} else {
if(e.target.value.substring(e.target.value.length-6)=='button') {
var nthM=/^([0-9]+)/.exec(e.target.value);
nth=parseInt(nthM[1])-1;
} else {
var buttonInfo=e.target.value.split(' x ',2);
button=buttonInfo[1];
}
}
var friendsClicked={};
this.IterateButtons(function(info) {
FacebookInvites.SkipButton();
var ok=false;
if(byText!=null && info.value.toLowerCase().indexOf(byText)>=0) {
ok=true;
}
if((
(app==FacebookInvites.allAppsId || info.app==app)
&& (info.value==button || info.nthButton==nth)
) || ok) {
if(info.profileId) {
friendsClicked[info.profileId]=1;
}
var friendList=document.getElementById('AcceptFriendList').value;
var friendAddSelect=FacebookInvites.GetFriendListDropDown(info.parent);
if(friendList.length>0) {
FacebookInvites.ClickFriendListDropDown(friendAddSelect);
window.setTimeout(function() {
// wait for the drop down.
friendAddSelect=FacebookInvites.GetFriendListDropDown(info.parent);
if(friendAddSelect) {
// we have a drop down
FacebookInvites.SelectFriendListDropDown(friendAddSelect,friendList);
}
window.setTimeout(function() {
FacebookInvites.ClickAutoAcceptButton(info.obj);
FacebookInvites.IterateButtonsNext(info.info);
},1000);
},3000);
return false;
}
FacebookInvites.ClickAutoAcceptButton(info.obj);
}
return true;
});
this.SaveFriendsFromHash(friendsClicked);
},
ClickBlockButton:function() {
var blockDiv=nHtml.FindByXPath(document,".//div[contains(@class,'dialog_buttons')]");
if(!blockDiv) { return; }
var block=nHtml.FindByXPath(blockDiv,".//input[@type='button']");
if(block) {
GM_log('block button pressed');
nHtml.Click(block);
return true;
}
return false;
},
SetBlockUpto:function(clicked,s) {
var clickedStr='';
for(var click in clicked) {
clickedStr+=click+"###";
}
GM_setValue('blockLinkClicked',clickedStr);
GM_setValue('blockLinkUpto',s);
},
GetBlockUpto:function(clicked) {
var clickedStr=GM_getValue('blockLinkClicked','');
var clickedArr=clickedStr.split('###');
for(var c=0; c<clickedArr.length; c++) {
clicked[clickedArr[c]]=1;
}
return GM_getValue('blockLinkUpto',-1);
},
BlockAllApps:function() {
var clicked={};
var s=this.GetBlockUpto(clicked);
if(s<0) { return; }
var stopBlockAll=document.getElementById('StopBlockAllApps');
if(!stopBlockAll) {
this.SetMessage("<a id='StopBlockAllApps'>Stop block all applications</a>");
stopBlockAll=document.getElementById('StopBlockAllApps');
stopBlockAll.addEventListener('click',function() {
FacebookInvites.SetBlockUpto({},-1);
},false);
}
var s=0;
var test=this.IsTest();
var ss=document.evaluate("//a[contains(@onclick,'block_app_dialog')]",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var obj=null;
while(1) {
if(s>=ss.snapshotLength) {
this.SetMessage('Done block all');
this.SetBlockUpto({},-1);
window.setTimeout(function() {
this.ClickBlockButton();
},5000);
return;
}
obj=ss.snapshotItem(s);
var onclick=obj.getAttribute('onclick');
if(!clicked[onclick]) {
clicked[onclick]=1;
break;
}
s++;
continue;
}
this.SetBlockUpto(clicked,s);
window.setTimeout(function() {
GM_log('click block:'+obj.getAttribute('onclick'));
if(test) {
obj.style.border='3px solid #f00';
} else {
nHtml.Click(obj);
}
window.setTimeout(function() {
if(!FacebookInvites.ClickBlockButton()) {
// clicking the block button will reload the page, we will run again when the page reloads.
FacebookInvites.BlockAllApps();
}
},3000);
},1000);
},
// add a link to auto accept all the friend requests on the page.
AddAutoAccept:function() {
var event=document.getElementById('friend_suggestion');
if(!event) event=document.getElementById('friend_add');
if(!event) event=document.getElementById('event_invite');
if(!event) { return; }
var mDiv=document.getElementById('BulkRequestsDiv');
if(mDiv) { return; }
mDiv=document.createElement('div');
var buttonTypes={};
var buttonsCount={};
var maxButtons={};
var appTypes={};
this.IterateButtons(function(info) {
var app=info.app;
var buttonValue=info.value;
appTypes[app]={'hash':info.aname};
if(buttonTypes[app]==undefined) {
buttonTypes[app]={};
}
if(buttonTypes[app][buttonValue]==undefined) {
buttonTypes[app][buttonValue]=0;
}
buttonTypes[app][buttonValue]++;
appTypes[FacebookInvites.allAppsId]={'hash':'','desc':'<b>All Applications</b>'};
var buttonUpto=info.nthButton;
if(!maxButtons[app] || buttonUpto>=maxButtons[app]) {
maxButtons[app]=buttonUpto+1;
if(!maxButtons[FacebookInvites.allAppsId] || buttonUpto>=maxButtons[FacebookInvites.allAppsId])
maxButtons[FacebookInvites.allAppsId]=buttonUpto+1;
}
return true;
});
mDiv.id='BulkRequestsDiv';
mDiv.innerHTML="<b>Bulk click requests...</b><br />"+
"Warning: buttons that take you to other places, you'll only go to one of those places, but all the buttons will be clicked and disappear.<br />"+
"Clicking on a bulk button here will save a list of those users, which can be used in the friends list page.<br />"+
"<input type='checkbox' id='BulkRequestsTest' />Test only(only highlights the buttons to be clicked)<br />"+
"<input type='checkbox' id='BulkRequestsNewTab' title='Open up new tab.' checked />Open up a new tab when clicking on something (Some applications need this to confirm that you've accepted)<br />"+
"Friend list: <input type='text' id='AcceptFriendList' /> (for when you're accepting friends)<br />"+
"<input id='BulkClickByTextButton' type='button' value='Click all buttons with this text:' /> <input type='text' id='BulkClickByText' /> <br />"+
"<a href='javascript:;' onclick='document.getElementById(\"nthConfirmDiv\").style.display=\"block\";'>Click by nth buttons.</a><br />"
;
mDiv.appendChild(document.createElement('br'));
mDiv.appendChild(document.createElement('br'));
var blockAllApps=document.createElement('A');
blockAllApps.innerHTML="Click on all 'Block application' links (becareful, facebook has no list of blocked applications)";
blockAllApps.addEventListener('click',function() {
FacebookInvites.SetBlockUpto({},0);
FacebookInvites.BlockAllApps();
},false);
mDiv.appendChild(blockAllApps);
mDiv.appendChild(document.createElement('br'));
mDiv.appendChild(document.createElement('br'));
var nthDiv=document.createElement('div');
nthDiv.id='nthConfirmDiv';
nthDiv.style.display='none';
var appsArr=[];
for(var app in appTypes) {
appsArr.push(app);
}
appsArr=appsArr.sort();
for(var a=0; a<appsArr.length; a++) {
var app=appsArr[a];
var d=document.createElement('div');
var appInfo=appTypes[app];
if(appInfo.desc) { appDesc=appInfo.desc; }
else { appDesc=app; }
d.innerHTML="<a href='#"+appInfo.hash+"'>"+appDesc+"</a> ";
var divId='ButtonApp_'+escape(app);
d.id=divId;
var buttons=buttonTypes[app];
var buttonsAdded=0;
if(buttons) {
for(var button in buttons) {
var count=buttons[button];
if(count<=1) { continue; }
var inp=document.createElement('input');
inp.type='button';
inp.className='inputbutton BulkAddButton';
inp.value=count+" x "+button;
inp.addEventListener('click',function(e) {
FacebookInvites.ClickAutoAccept(e);
},false);
d.appendChild(inp);
d.appendChild(document.createTextNode(' '));
buttonsAdded++;
}
}
var nthApp=document.createElement('DIV');
nthApp.id=divId;
nthApp.innerHTML=appDesc;
var maxButton=maxButtons[app];
for(var b=0; b<maxButton; b++) {
var inp=document.createElement('input');
inp.type='button';
inp.className='inputbutton BulkAddButton';
var suffix="th";
var b10=b%10;
if(b10==0) { suffix="st"; }
else if(b10==1) { suffix="nd"; }
else if(b10==3) { suffix="rd"; }
inp.value=(b+1)+suffix+" button";
inp.addEventListener('click',function(e) {
FacebookInvites.ClickAutoAccept(e);
},false);
nthApp.appendChild(inp);
nthApp.appendChild(document.createTextNode(' '));
}
nthApp.appendChild(document.createElement('BR'));
nthDiv.appendChild(nthApp);
if(buttonsAdded>0) {
mDiv.appendChild(d);
}
}
mDiv.appendChild(nthDiv);
event.parentNode.insertBefore(mDiv,event);
var BulkClickByTextButton=document.getElementById('BulkClickByTextButton');
BulkClickByTextButton.addEventListener('click',function(e) {
FacebookInvites.ClickAutoAccept(e);
},false);
},
// auto bulk add when we get to the profile page.
SetAutoBulkAdd:function(enabled) {
GM_setValue('autoBulkAdd_Enabled',enabled);
if(document.getElementById('bulkAddComment')) {
GM_setValue('autoBulkAdd_Comment',document.getElementById('bulkAddComment').value);
GM_setValue('autoBulkAdd_FriendList',document.getElementById('bulkAddFriendList').value);
GM_setValue('autoBulkAdd_Test',document.getElementById('testBulkAddMeButton').checked);
}
},
GetAutoBulkAdd:function() {
var enabled=GM_getValue('autoBulkAdd_Enabled',false);
if(enabled && document.getElementById('bulkAddComment')) {
document.getElementById('bulkAddComment').value=GM_getValue('autoBulkAdd_Comment','');
document.getElementById('bulkAddFriendList').value=GM_getValue('autoBulkAdd_FriendList','');
document.getElementById('testBulkAddMeButton').checked=GM_getValue('autoBulkAdd_Test',false);
}
return enabled;
},
//////////////////////////
UncheckShowNews:function() {
var chks = document.evaluate("/html[@id='facebook']/body//input[@value='news_feed']",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i =0; i < chks.snapshotLength; i++) { chks.snapshotItem(i).checked=false;}
},
// click the "close" buttons
ClickClose:function() {
var db=document.getElementById('dialog_buttons');
var chks = document.evaluate(".//input",document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if(chks.length==1) {
var inp=chks.snapshotItem(0);
if(inp.name=='close') {
// only one button and it says "close"
GM_log('Close button clicked');
nHtml.Click(inp);
}
}
},
profilePageAdd:false,
CheckPage:function() {
try{
if(unsafeWindow.top.joinRecentLoadedLink!=undefined && unsafeWindow.joinRecentLoadedLink==undefined) {
window.setTimeout(function() {
unsafeWindow.top.joinRecentLoadedLink();
},5000);
return;
}
}catch(e) {
GM_log('no permission probably:'+e);
return;
}
var href=document.location.href+document.location.hash;
var ok=false;
if(href.indexOf("/reqs.php")>=0) {
this.UncheckShowNews();
this.AddAutoAccept();
}
// if(href.indexOf("/profile.php")>=0) {
var profileStream=document.getElementById('profile_stream_container');
if(document.getElementById('profile_top_bar') && !profileStream) {
// we're not friends yet.
if(this.AddMeLinkAnyPage()) {
if(this.GetAutoBulkAdd()) {
// auto add this person.
this.addMeUptoMax=1;
this.StartBulkAddMe();
this.profilePageAdd=true;
}
}
}
if(href.indexOf("/social_graph.php")>=0) { //change suggested by Lox Myth - see http://userscripts.org/topics/34630#posts-166598
ok=this.AddFriendsWithApp();
} else {
this.AddMeLink();
ok=this.InviteFriends();
}
window.setTimeout(function() { FacebookInvites.CheckPage() },5000);
}
};
GM_registerMenuCommand('FB Invites - Show Bulk add friends dialog',function() {
FacebookInvites.AddMeLinkAnyPage();
});
GM_registerMenuCommand('FB Invites - Add all the friends on this page',function() {
var content=document.getElementById('content');
if(!content) content=document.body;
FacebookInvites.AddFriendsFromPage({'doc':content,'doNextPage':true});
});
GM_registerMenuCommand('FB Invites - Clear the current list of friends',function() {
FacebookInvites.ClearFriendsBuffer();
});
GM_registerMenuCommand('FB Invites - Detach the block if it is not visible',function() {
FacebookInvites.DetachDiv();
});
if(location.href.indexOf('facebook.com')<0) {
GM_registerMenuCommand('FB Invites - Open all facebook friend links here in new tabs',function() {
FacebookInvites.ClickAllFacebookFriendLinks();
});
}
window.addEventListener("load", function(e) {
window.GetFacebookInvites = function() {
return FacebookInvites;
}
FacebookInvites.CheckPage();
FacebookInvites.BlockAllApps();
}, false);
// join recent friends.
// test nth block, block buttons.
