// ==UserScript==
// @name UnFuck Facebook
// @namespace sizzlemctwizzle
// @description Fixed recent activity removal again.
// @version 2.8.1.1
// @require http://sizzlemctwizzle.com/updater.php?id=11992
// @include http://*.facebook.com/*
// @include https://*.facebook.com/*
// ==/UserScript==
// Start of Graphical Settings code == http://github.com/sizzlemctwizzle/GM_config/raw/master/gm_config.js
// The GM_config constructor
function GM_configStruct() {
// call init() if settings were passed to constructor
if (arguments.length)
GM_configInit(this, arguments);
}
// This is the initializer function
function GM_configInit(config, args) {
var settings = null;
// If the id has changed we must modify the default style
if (config.id != 'GM_config')
config.css.basic = config.css.basic.replace(/#GM_config/gm, '#' + config.id);
// loop through GM_config.init() arguments
for (var i = 0, l = args.length, arg; i < l; ++i) {
arg = args[i];
// An element to use as the config window
if (typeof arg.appendChild == "function") {
config.frame = arg;
continue;
}
switch (typeof arg) {
case 'object':
for (var j in arg) { // could be a callback functions or settings object
if (typeof arg[j] != "function") { // we are in the settings object
settings = arg; // store settings object
break; // leave the loop
} // otherwise it must be a callback function
config["on" + j.charAt(0).toUpperCase() + j.slice(1)] = arg[j];
}
break;
case 'function': // passing a bare function is set to open callback
config.onOpen = arg;
break;
case 'string': // could be custom CSS or the title string
if (arg.indexOf('{') != -1 && arg.indexOf('}') != -1)
config.css.stylish = arg;
else
config.title = arg;
break;
}
}
if (settings) {
var stored = config.read(); // read the stored settings
for (var id in settings) // for each setting create a field object
config.fields[id] = new GM_configField(settings[id], stored[id], id);
}
}
GM_configStruct.prototype = {
// Support old method of initalizing
init: function() { GM_configInit(this, arguments); },
// call GM_config.open() from your script to open the menu
open: function () {
// Die if the menu is already open on this page
// You can have multiple instances but they can't be open at the same time
var match = document.getElementById(this.id);
if (match && (match.tagName == "IFRAME" || match.childNodes.length > 0)) return;
// Sometime "this" gets overwritten so create an alias
var config = this;
// Function to build the mighty config window :)
function buildConfigWin (body, head) {
var frameBody = body,
create = config.create,
fields = config.fields,
configId = config.id;
// Append the style which is our default style plus the user style
head.appendChild(
create('style', {
type: 'text/css',
textContent: config.css.basic + config.css.stylish
}));
// Add header and title
frameBody.appendChild(create('div', {
id: configId + '_header',
className: 'config_header block center',
textContent: config.title
}));
// Append elements
var section = frameBody,
secNum = 0; // Section count
// loop through fields
for (var id in fields) {
var field = fields[id].settings;
if (field.section) { // the start of a new section
section = frameBody.appendChild(create('div', {
className: 'section_header_holder',
id: configId + '_section_' + secNum
}));
if (typeof field.section[0] == "string")
section.appendChild(create('div', {
className: 'section_header center',
id: configId + '_section_header_' + secNum,
innerHTML: field.section[0]
}));
if (typeof field.section[1] == "string")
section.appendChild(create('p', {
className: 'section_desc center',
id: configId + '_section_desc_' + secNum,
innerHTML: field.section[1]
}));
++secNum;
}
// Create field elements and append to current section
section.appendChild(fields[id].toNode(configId));
}
// Add save and close buttons
frameBody.appendChild(create('div',
{id: configId + '_buttons_holder'},
create('button', {
id: configId + '_saveBtn',
textContent: 'Save',
title: 'Save settings',
className: 'saveclose_buttons',
onclick: function () { config.save() }
}),
create('button', {
id: configId + '_closeBtn',
textContent: 'Close',
title: 'Close window',
className: 'saveclose_buttons',
onclick: function () { config.close() }
}),
create('div',
{className: 'reset_holder block'},
// Reset link
create('a', {
id: configId + '_resetLink',
textContent: 'Reset to defaults',
href: '#',
title: 'Reset fields to default values',
className: 'reset',
onclick: function(e) { e.preventDefault(); config.reset() }
})
)));
config.center(); // Show and center iframe
window.addEventListener('resize', config.center, false); // Center frame on resize
if (config.onOpen)
config.onOpen(config.frame.contentDocument || config.frame.ownerDocument,
config.frame.contentWindow || window,
config.frame); // Call the open() callback function
// Close frame on window close
window.addEventListener('beforeunload', function () {
config.close();
}, false);
// Now that everything is loaded, make it visible
config.frame.style.display = "block";
}
// Either use the element passed to init() or create an iframe
var defaultStyle = 'position:fixed; top:0; left:0; opacity:0; display:none; z-index:999;' +
'width:75%; height:75%; max-height:95%; max-width:95%;' +
'border:1px solid #000000; overflow:auto; bottom: auto;' +
'right: auto; margin: 0; padding: 0;';
if (this.frame) {
this.frame.id = this.id;
this.frame.setAttribute('style', defaultStyle);
buildConfigWin(this.frame, this.frame.ownerDocument.getElementsByTagName('head')[0]);
} else {
// Create frame
document.body.appendChild((this.frame = this.create('iframe', {
id: this.id,
style: defaultStyle
})));
this.frame.src = 'about:blank'; // In WebKit src can't be set until it is added to the page
// we wait for the iframe to load before we can modify it
this.frame.addEventListener('load', function(e) {
var frame = config.frame;
var body = frame.contentDocument.getElementsByTagName('body')[0];
body.id = config.id; // Allows for prefixing styles with "#GM_config"
buildConfigWin(body, frame.contentDocument.getElementsByTagName('head')[0]);
}, false);
}
},
save: function () {
var fields = this.fields;
for (id in fields) {
var field = fields[id],
val = field.toValue();
if (val === null) { // invalid value encountered
this.readVals = {};
return;
} else if (field.settings.type != "button")
this.readVals[id] = val;
}
this.write();
if (this.onSave)
this.onSave(); // Call the save() callback function
},
close: function() {
// If frame is an iframe then remove it
if (this.frame.contentDocument) {
this.remove(this.frame);
this.frame = null;
} else { // else wipe its content
this.frame.innerHTML = "";
this.frame.style.display = "none";
}
// Null out all the fields so we don't leak memory
var fields = this.fields;
for (id in fields)
fields[id].node = null;
if (this.onClose)
this.onClose(); // Call the close() callback function
},
set: function (name, val) {
this.fields[name].value = val;
},
get: function (name) {
return this.fields[name].value;
},
write: function (store, obj) {
try {
this.setValue(store || this.id, this.stringify(obj || this.readVals));
} catch(e) {
this.log("GM_config failed to save settings!");
}
this.readVals = {};
},
read: function (store) {
try {
var rval = this.parser(this.getValue(store || this.id, '{}'));
} catch(e) {
this.log("GM_config failed to read saved settings!");
var rval = {};
}
return rval;
},
reset: function () {
var fields = this.fields,
doc = this.frame.contentDocument || this.frame.ownerDocument,
type;
for (id in fields) {
var node = fields[id].node,
field = fields[id].settings,
noDefault = typeof field['default'] == "undefined",
type = field.type;
switch (type) {
case 'checkbox':
node.checked = noDefault ? GM_configDefaultValue(type) : field['default'];
break;
case 'select':
if (field['default']) {
for (var i = 0, len = node.options.length; i < len; ++i)
if (node.options[i].value == field['default'])
node.selectedIndex = i;
} else
node.selectedIndex = 0;
break;
case 'radio':
var radios = node.getElementsByTagName('input');
for (var i = 0, len = radios.length; i < len; ++i)
if (radios[i].value == field['default'])
radios[i].checked = true;
break;
case 'button' :
break;
default:
node.value = noDefault ? GM_configDefaultValue(type) : field['default'];
break;
}
}
},
create: function () {
switch(arguments.length) {
case 1:
var A = document.createTextNode(arguments[0]);
break;
default:
var A = document.createElement(arguments[0]),
B = arguments[1];
for (var b in B) {
if (b.indexOf("on") == 0)
A.addEventListener(b.substring(2), B[b], false);
else if (",style,accesskey,id,name,src,href,which".indexOf("," +
b.toLowerCase()) != -1)
A.setAttribute(b, B[b]);
else
A[b] = B[b];
}
for (var i = 2, len = arguments.length; i < len; ++i)
A.appendChild(arguments[i]);
}
return A;
},
center: function () {
var node = this.frame,
style = node.style,
beforeOpacity = style.opacity;
if (style.display == 'none') style.opacity = '0';
style.display = '';
style.top = Math.floor((window.innerHeight / 2) - (node.offsetHeight / 2)) + 'px';
style.left = Math.floor((window.innerWidth / 2) - (node.offsetWidth / 2)) + 'px';
style.opacity = '1';
},
remove: function (el) {
if (el && el.parentNode) el.parentNode.removeChild(el);
},
// Define some default properties
onOpen: null,
onSave: null,
onClose: null,
id: 'GM_config',
fields: {},
readVals: {},
title: 'User Script Settings',
css: {
basic: "#GM_config * { font-family: arial,tahoma,myriad pro,sans-serif; }"
+ '\n' + "#GM_config { background: #FFF; }"
+ '\n' + "#GM_config input[type='radio'] { margin-right: 8px; }"
+ '\n' + "#GM_config .indent40 { margin-left: 40%; }"
+ '\n' + "#GM_config .field_label { font-weight: bold; font-size: 12px; margin-right: 6px; }"
+ '\n' + "#GM_config .block { display: block; }"
+ '\n' + "#GM_config .saveclose_buttons { margin: 16px 10px 10px; padding: 2px 12px; }"
+ '\n' + "#GM_config .reset, #GM_config .reset a,"
+ '\n' + "#GM_config_buttons_holder { text-align: right; color: #000; }"
+ '\n' + "#GM_config .config_header { font-size: 20pt; margin: 0; }"
+ '\n' + "#GM_config .config_desc, #GM_config .section_desc, #GM_config .reset { font-size: 9pt; }"
+ '\n' + "#GM_config .center { text-align: center; }"
+ '\n' + "#GM_config .section_header_holder { margin-top: 8px; }"
+ '\n' + "#GM_config .config_var { margin: 0 0 4px; }"
+ '\n' + "#GM_config .section_header { font-size: 13pt; background: #414141; color: #FFF;"
+ '\n' + "border: 1px solid #000; margin: 0; }"
+ '\n' + "#GM_config .section_desc { font-size: 9pt; background: #EFEFEF; color: #575757;"
+ '\n' + "border: 1px solid #CCC; margin: 0 0 6px; }",
stylish: ""
}
};
// Define a bunch of API stuff
(function() {
var isGM = typeof GM_getValue != 'undefined' &&
typeof GM_getValue('a', 'b') != 'undefined',
setValue, getValue, stringify, parser;
// Define value storing and reading API
if (!isGM) {
setValue = function (name, value) {
return localStorage.setItem(name, value);
};
getValue = function(name, def){
var s = localStorage.getItem(name);
return s == null ? def : s
};
// We only support JSON parser outside GM
stringify = JSON.stringify;
parser = JSON.parse;
} else {
setValue = GM_setValue;
getValue = GM_getValue;
stringify = typeof JSON == "undefined" ?
function(obj) {
return obj.toSource();
} : JSON.stringify;
parser = typeof JSON == "undefined" ?
function(jsonData) {
return (new Function('return ' + jsonData + ';'))();
} : JSON.parse;
}
GM_configStruct.prototype.isGM = isGM;
GM_configStruct.prototype.setValue = setValue;
GM_configStruct.prototype.getValue = getValue;
GM_configStruct.prototype.stringify = stringify;
GM_configStruct.prototype.parser = parser;
GM_configStruct.prototype.log = isGM ? GM_log : (window.opera ? opera.postError : console.log);
})();
function GM_configDefaultValue(type) {
var value;
if (type.indexOf('unsigned ') == 0)
type = type.substring(9);
switch (type) {
case 'radio': case 'select':
value = settings.options[0];
break;
case 'checkbox':
value = false;
break;
case 'int': case 'integer':
case 'float': case 'number':
value = 0;
break;
default:
value = '';
}
return value;
}
function GM_configField(settings, stored, id) {
// Store the field's settings
this.settings = settings;
this.id = id;
// if a setting was passed to init but wasn't stored then
// if a default value wasn't passed through init() then
// use default value for type
// else use the default value passed through init()
// else use the stored value
var value = typeof stored == "undefined" ?
typeof settings['default'] == "undefined" ?
GM_configDefaultValue(settings.type)
: settings['default']
: stored;
// Store the field's value
this.value = value;
}
GM_configField.prototype = {
create: GM_configStruct.prototype.create,
node: null,
toNode: function(configId) {
var field = this.settings,
value = this.value,
options = field.options,
id = this.id,
create = this.create;
var retNode = create('div', { className: 'config_var',
id: configId + '_' + this.id + '_var',
title: field.title || '' });
if (field.type != "hidden" &&
field.type != "button" &&
typeof field.label == "string")
retNode.appendChild(create('span', {
textContent: field.label,
id: configId + '_' + this.id +'_field_label',
className: 'field_label'
}));
switch (field.type) {
case 'textarea':
retNode.appendChild((this.node = create('textarea', {
id: configId + '_field_' + this.id,
innerHTML: value,
cols: (field.cols ? field.cols : 20),
rows: (field.rows ? field.rows : 2)
})));
break;
case 'radio':
var wrap = create('div', {
id: configId + '_field_' + id
});
this.node = wrap;
for (var i = 0, len = options.length; i < len; ++i) {
wrap.appendChild(create('span', {
textContent: options[i]
}));
wrap.appendChild(create('input', {
value: options[i],
type: 'radio',
name: id,
checked: options[i] == value ? true : false
}));
}
retNode.appendChild(wrap);
break;
case 'select':
var wrap = create('select', {
id: configId + '_field_' + id
});
this.node = wrap;
for (var i in options)
wrap.appendChild(create('option', {
textContent: options[i],
value: i,
selected: options[i] == value ? true : false
}));
retNode.appendChild(wrap);
break;
case 'checkbox':
retNode.appendChild((this.node = create('input', {
id: configId + '_field_' + id,
type: 'checkbox',
value: value,
checked: value
})));
break;
case 'button':
var btn = create('input', {
id: configId + '_field_' + id,
type: 'button',
value: field.label,
size: (field.size ? field.size : 25),
title: field.title || ''
});
this.node = btn;
if (field.script)
btn.addEventListener('click', function () {
var scr = field.script;
typeof scr == 'function' ? setTimeout(scr, 0) : eval(scr);
}, false);
retNode.appendChild(btn);
break;
case 'hidden':
retNode.appendChild((this.node = create('input', {
id: configId + '_field_' + id,
type: 'hidden',
value: value
})));
break;
default:
// type = text, int, or float
retNode.appendChild((this.node = create('input', {
id: configId + '_field_' + id,
type: 'text',
value: value,
size: (field.size ? field.size : 25)
})));
}
return retNode;
},
toValue: function() {
var node = this.node,
field = this.settings,
type = field.type,
unsigned = false,
rval;
if (type.indexOf('unsigned ') == 0) {
type = type.substring(9);
unsigned = true;
}
switch (type) {
case 'checkbox':
this.value = node.checked;
break;
case 'select':
this.value = node[node.selectedIndex].value;
break;
case 'radio':
var radios = node.getElementsByTagName('input');
for (var i = 0, len = radios.length; i < len; ++i)
if (radios[i].checked)
this.value = radios[i].value;
break;
case 'button':
break;
case 'int': case 'integer':
var num = Number(node.value);
if (isNaN(num) || Math.ceil(num) != Math.floor(num) ||
(unsigned && num < 0)) {
alert('Field labeled "' + field.label + '" expects a ' +
(unsigned ? 'positive ' : '') + 'integer value.');
return null;
}
this.value = num;
break;
case 'float': case 'number':
var num = Number(node.value);
if (isNaN(num) || (unsigned && num < 0)) {
alert('Field labeled "' + field.label + '" expects a ' +
(unsigned ? 'positive ' : '') + 'number value.');
return null;
}
this.value = num;
break;
default:
this.value = node.value;
break;
}
return this.value; // value read successfully
}
};
// End of Graphical Settings code
// UnFuck Facebook Settings
var GM_config = new GM_configStruct('UnFuck Facebook', {
appReq: {
section: ['Invite Blocking', 'Check the types of invites you want to block automatically'],
label: 'Application',
type: 'checkbox',
title: 'Still broke at the moment :(',
'default': false
},
fanReq: {
label: 'Fan Page',
type: 'checkbox',
'default': false
},
groupReq: {
label: 'Group',
type: 'checkbox',
'default': false
},
eventReq: {
label: 'Event',
type: 'checkbox',
'default': false
},
appHide: {
section: ['Home Settings', 'Control what appears in your stream'],
label: 'Hide App Stories',
type: 'checkbox',
'default': true
},
fanHide: {
label: 'Hide Fan Stories',
type: 'checkbox',
'default': false
},
appBlock: {
label: 'Block App Stories',
title: 'Prevent apps from showing up in your stream in the future',
type: 'checkbox',
'default': false
},
wallStory: {
label: 'Hide Wall Stories',
title: 'Hide the one-sided wall conversations',
type: 'checkbox',
'default': true
},
addFriend: {
label: 'Hide New Friend Stories',
title: 'Hide the "Someone is now friends with someone." stories',
type: 'checkbox',
'default': false
},
showStat: {
label: 'Show status on home page',
type: 'checkbox',
'default': true
},
statOnly: {
label: 'Default to status-only Home Feed',
type: 'checkbox',
'default': false
},
columns: {
label: 'Number of Columns',
title: 'Make the home page one to three columns',
type: 'radio',
options: ['One', 'Two', 'Three'],
'default': 'Two'
},
noStuff: {
label: 'Show right column above feed in one column mode',
title: 'This option does nothing in two or three column mode',
type: 'checkbox',
'default': true
},
suggest: {
label: 'Hide suggestions',
type: 'checkbox',
'default': true
},
chatSide: {
label: 'Show Chat Sidebar',
type: 'checkbox',
'default': false
},
profBoxes: {
section: ['Profile Settings', 'Control what appears on profiles'],
label: 'Hide Application Boxes',
type: 'checkbox',
'default': true
},
appTabs: {
label: 'Hide Application Tabs',
type: 'checkbox',
'default': false
},
wideCom: {
section: ['General Settings'],
label: 'Wide Comments',
type: 'checkbox',
'default': true
},
homeLink: {
label: 'Show Home link in Nav Bar',
type: 'checkbox',
'default': true
},
recentHide: {
section: ['Advance Feature'],
label: 'Automatically remove "Recent Activity" Stories from your profile',
type: 'checkbox',
title: 'Remove those one-liner stories Facebook publishes automatically everytime you do anything',
'default': false
}
},
'#GM_config .config_header { color: #3B5998 !important; } #GM_config .section_header { background-color: #3B5998 !important; } #GM_config .section_desc { color: #999999 !important; } #GM_config .field_label, #GM_config .config_var span { color: #3E5A88 !important; font-size: 12px !important; } #GM_config_header a { color: #3B5998 !important; font-size: 12px !important; display: block !important; } #GM_config_section_0 .config_var, #GM_config_section_0 .section_desc { display: none !important; } #GM_config_section_header_0 { text-decoration: line-through !important; }',
{
open: function(doc) {
var id = doc.getElementById,
disableOpt = function(op) {
var el = id('GM_config_field_'+op);
el.checked = false;
el.disabled = true;
el.parentNode.title = "This shit is broke right now :("
el.parentNode.firstChild.setAttribute('style', 'text-decoration: line-through;');
};
disableOpt('appReq');
disableOpt('fanReq');
disableOpt('groupReq');
disableOpt('eventReq');
disableOpt('addFriend');
disableOpt('statOnly');
id('GM_config_header').appendChild(create('a',{href:'http://userscripts.org/scripts/show/11992',target:'_blank', textContent:'Script Home Page'}));
},
save: function() {
GM_config.close();
window.location.reload();
}
});
// I've mananged to do a lot of my script in CSS
var unfuckStyle='#right_column { width: 77% !important; } '+(GM_config.get('profBoxes')?'div[id^="box_app_"]:not(#box_app_2297529396):not(#box_app_2305272732):not(#box_app_2309869772):not(#box_app_2327158227):not(#box_app_2341989679):not(#box_app_2347471856):not(#box_app_2356318349):not(#box_app_2361831622):not(#box_app_2407511955):not(#box_app_2503140832):not(#box_app_2719290516):not(#box_app_2392950137):not(#box_app_2550392059), ':'')+'.gifts_received, .wall_contextual_extra, .nextstep, .app_icon_row, .invitefriends, #ssponsor, div[class$="_ad"], .divider_bar, .more_section, .fbpage_fan, .ad_capsule, .see_more_arrow, #more_apps_divider_narrow, .platform, .profile_empty_divider, .newstuff, .app_install_story, .emu_sponsor, div[id^="emu_"], .adcolumn, .social_ad, .sponsor, #attachment_buttons_list span[style*="app_"], li[id^="bookmarked_app_"] a[href^="http://apps."], li[id^="bookmarked_app_"] a[href*="gift"], #profile_tab_add, .footer_ad, .UIComposer_More_Container, .UIComposer_Attachment a[style*="gift.gif"], '+(GM_config.get('appTabs')?'li[view="box_3"], li[view^="app_"], li[view="app_2347471856"], li[view="app_2392950137"], ':'')+'.approve_friend, .app_story, .UIComposer_Attachment a[style*="/app_"], .UIRoundedImage_CornersSprite, #home_sponsor, .hp_connect_box, .UIUpcoming_Info small, .house_sponsor, #home_sponsor_nile, .UIStandardFrame_SidebarAds, div[style*="white"], '+(GM_config.get('suggest') ? '#pagelet_netego, ':'')+'#unfucked, #ego'+(GM_config.get('recentHide') && false ? ', .UIRecentActivity_Stream' : '')+' { display: none !important; }\n' +
(GM_config.get('columns') != "Three" ? '.UITitledBox_Content { padding: 3px !important; }\n'+
'#contentArea { width: 90% !important; }\n' +
'#rightCol { '+ (GM_config.get('columns') == "Two" || !GM_config.get('noStuff') ? 'display: none !important; width: 0% !important': 'float: left !important; margin-left: 3% !important; width: 40% !important') +' }\n' +
'#headNavOut { width: '+(GM_config.get('columns') == "Two" ? '77.5%' : '55%' )+' !important; float: right !important; }\n'+
'.fbx #globalContainer { width:auto; margin:auto 1.5%; }\n' +
'#leftCol { width: 20.8% !important; border-right: none !important;}\n' +
(GM_config.get('columns') == "One" ? '#contentCol { margin-left: 0% !important; } ' :'#headNavOut, #contentCol { margin-left:21% !important; }\n') +
'.uiSideNav, .uiSideNav li { width: 100% !important; }\n' +
'#contentCurve, #footerContainer { width:auto !important; margin:auto !important; margin-left:5% !important; border: none !important; }\n' +
'#q { display:block !important;}' +
'#navSearch { width: 40% !important; }':'') +
(GM_config.get('columns') == "One" ? '#leftCol { width: 0% !important; display: none !important; padding: 0% !important }\n' +
'#contentCol, #contentArea, #headNavOut { margin-left 0px !imporatant; padding-left 0px !important; float: left !important; }':'') +
(GM_config.get('homeLink') ? '' : '#pageNav li a[href$="?ref=home"] { display: none !important;}') +
(GM_config.get('wideCom') ? '.UIWashFrame_SidebarAds { display: none !important; }\n' +
'.UIWashFrame_Content { width: 99% !important; }\n' +
'.UIStandardFrame_Content { width: 99% !important; }\n' +
'#wall { width: 80% !important; }\n' +
'.uiUfiAddComment .actorPic { display: none !important; }\n' +
'.notes_side_column { margin:0% !important; padding:0% !important; }' +
'#photocomment { width: 80% !important; }' +
'.album .footer .info, .note_footer { width: 100% !important; }\n' +
'.one_row_add_box textarea.DOMControl_placeholder { width: 90% !important; }\n' +
'.comments_add_box textarea, .comment_box, .uiTextareaAutogrow, .uiList, .ufi_section, .comment_text, .ie6 .commentable_item textarea.DOMControl_placeholder, .no_js .commentable_item .comment_box .comments_add_box textarea { width: 98% !important; }\n' +
'.request_link { padding-left: 5% !important; }': '');
// GM_addStyle if not available
if(typeof GM_addStyle == 'undefined')
GM_addStyle = function(css) {
var head = document.getElementsByTagName('head')[0],
style = document.createElement('style');
if (!head) {return}
style.type = 'text/css';
style.textContent = css;
head.appendChild(style);
}
// Inject a script into the page
function addScript(js) {
var body = document.body, script = document.createElement('script');
if (!body) {return}
script.type = 'text/javascript';
try {script.innerHTML = js}
catch(x) {script.innerText = js}
body.appendChild(script);
}
function $x(x, t, r) {
if (t && t.nodeType)
var h = r, r = t, t = h;
var d = r ? r.ownerDocument || r : r = document, p;
switch (t) {
case 1:
p = 'numberValue';
break;
case 2:
p = 'stringValue';
break;
case 3:
p = 'booleanValue';
break;
case 8: case 9:
p = 'singleNodeValue';
break;
default:
return d.evaluate(x, r, null, t || 6, null);
}
return d.evaluate(x, r, null, t, null)[p];
}
// Optional shortcut functions I like
function $x1(x, r) { return $x(x, 9, r) }
function $xb(x, r) { return $x(x, 3, r) }
// A robust and universal forEach
function forEach(lst, cb) {
if(!lst)
return;
if (lst.snapshotItem)
for (var i = 0, len = lst.snapshotLength; i < len; ++i)
cb(lst.snapshotItem(i), i, lst);
else if (lst.iterateNext) {
var item, next = lst.iterateNext;
while (item = next())
cb(item, lst);
} else if (typeof lst.length !== 'undefined')
for (var i = 0, len = lst.length; i < len; ++i)
cb(lst[i], i, lst);
else if (typeof lst === "object")
for (var i in lst)
cb(lst[i], i, lst);
}
// Insert an element after another
function insertAfter(node, after) { after.parentNode.insertBefore(node, after.nextSibling) }
// A really cool element creation funtion by avg and JoeSimmons, and modified by me
function create() {
switch(arguments.length) {
case 1:
var A = document.createTextNode(arguments[0]);
break;
default:
var A = document.createElement(arguments[0]),
B = arguments[1];
for (var b in B) {
if (b.indexOf("on") == 0)
A.addEventListener(b.substring(2), B[b], false);
else if (",style,accesskey,id,name,src,href,which".indexOf("," +
b.toLowerCase()) != -1)
A.setAttribute(b, B[b]);
else
A[b] = B[b];
}
for(var i = 2, len = arguments.length; i < len; ++i)
A.appendChild(arguments[i]);
}
return A;
}
// Remove an element
function destroy(element) { element.parentNode.removeChild(element); }
// Get element by id
function $(element) { return document.getElementById(element); }
// Get element by class name
function $c(element, root) { return (root||document).getElementsByClassName(element); }
// Destroy elements that are retrieved with xpath
function seekAndDestroy(xpath, root) {
forEach($x(xpath, root), destroy);
}
// Add a new class to an element
function addClass(el,cls) {
if (!el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')))
el.className += " "+cls;
}
// Remove a particular class from an element
function removeClass(el,cls) {
if (el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'))) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
el.className = el.className.replace(reg,' ');
}
}
// Get the actual Facebook url
function realUrl() {
return /^#!\/.*/.test(window.location.hash) ?
'http://'+window.location.host+window.location.hash.split('#!')[1] :
window.location.href;
}
// Same domain
function xhr(url, cb, data) {
var res = new XMLHttpRequest();
res.onreadystatechange = function() { if (res.readyState==4 && res.status==200) cb(res.responseText) };
res.open(data ? 'POST' : 'GET', url, true);
res.setRequestHeader('User-agent', window.navigator.userAgent);
if (data) {
res.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
res.setRequestHeader("Connection", "close");
res.setRequestHeader("Content-length", data.length);
}
res.send(data||null);
}
// Cross domain
function xXhr(url, cb, data) {
GM_xmlhttpRequest({
method: data ? 'POST' : 'GET',
url: url,
headers: {
'User-agent': window.navigator.userAgent,
'Accept': (data) ? 'application/x-www-form-urlencoded' : 'application/atom+xml,application/xml,text/xml',
'Content-type': (data) ? 'application/x-www-form-urlencoded' : null
},
data: (data) ? data : null,
onload: function(res) { if (res.status == 200 && cb) cb(res.responseText); }
});
}
function createDoc(html) {
var dt = document.implementation.createDocumentType("html",
"-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd"),
doc = document.implementation.createDocument('', '', dt),
html = doc.createElement('html');
html.innerHTML = html;
doc.appendChild(html);
return doc;
}
function displayStatus(status, time) {
var nameLink = $c('fbxWelcomeBoxName')[0];
nameLink.setAttribute('style', 'display:inline; font-size: 11.5px;');
destroy($c('fbxWelcomeBoxProfileLink')[0]);
nameLink.parentNode.appendChild(create('div', {id:'UIHome_Status', style: 'padding-bottom: 5px; display:inline;'},
nameLink,
create('span',{innerHTML:' '}),
create('span',{style:'font-weight: normal; font-size: 11.5px;',innerHTML:status}),
create('br',{}),
create('span',{style:'color: #BBBBBB; font-size: 10px;',textContent:time}),
create('span',{innerHTML:' '}),
create('a',{href:'#',style:'font-size: 10px;',textContent:'clear',onclick:function (e) { fbAjax('http://www.facebook.com/ajax/updatestatus.php', 'clear=1&profile_id='+unsafeWindow.Env.user);GM_addStyle('#UIHome_Status { display: none !important; } .fbxWelcomeBoxName { display: block !important; }');e.preventDefault()}})
));
GM_addStyle('#UIHome_Status { display: block !important; }');
}
function getStatus() {
if ($('navAccountName')) {
if (typeof GM_xmlhttpRequest !== 'undefined')
xXhr('http://m.facebook.com/profile.php', function(text) {
if (stat=text.match(/
(.+?)
\(]+>(.+?)<\/abbr>\)<\/small>/i))
displayStatus(stat[1], stat[2]);
});
else
xhr($('navAccountName').href, function(text) {
if ((stat=text.match(/(.+?)<\\\/span>/i))&&(time=text.match(/