// ==UserScript==
// @name Facebook APR (application post remover)
// @description remove old posts from FB applications (games, quizes, etc ...)
// @author Sigi_cz
// @version 2.13
// @homepage http://userscripts.org/scripts/show/92953
// @licence http://creativecommons.org/licenses/by-nc-nd/3.0/
// @include http://userscripts.org/scripts/source/92953.meta.js*
// @include http://www.facebook.com/*
// ==/UserScript==
// some code parts are inspired or borroved from many great scripts (why reinvent wheel?)
// thanks to:
// "FFixer" http://userscripts.org/scripts/show/8861
// "FB MafiaWars Addon" http://userscripts.org/scripts/show/90615
// "Facebook Recent Activity" http://userscripts.org/scripts/show/68225
// "google.com"
// "stackoverflow.com"
/*jslint browser: true, devel: true, evil: true*/
/*global unsafeWindow:true, window:false, self:false, chrome:false, localStorage:true, XPathResult:false,
GM_addStyle:true, GM_log:true, GM_getValue:true, GM_setValue:true, GM_deleteValue:true */
(function () {
//------------------------------------------------
// custom settings
//------------------------------------------------
var cfg_defaults = {
appIDs: [], // ID's of applications to remove
all_apps: false, // remove all application posts
time_limit: 12, // remove posts older then X hours
autorun: false, // start automatically (works only in Opera)
only_user_posts: false, // false: remove all app. post; true: remove only your app. posts
continue_proc: true, // search last known post and continue processing (disabled if hide_posts = true)
hide_posts: false, // don't remove posts, only hide
xhr_delay: 300, // XMLHttpRequest delay X in ms (you don't want to remove all posts at once)
updateInterval: 6, // hours
language: 'auto',
isDebug: false // debug mode
};
var appsArr = [['10979261223','Mafia Wars'],
['234860566661','Treasure Isle'],
['46755028429','Castle Age'],
['102452128776','FarmVille'],
['130402594779','Kingdoms of Camelot']];
cfg_defaults.appIDs = appsArr;
var cfg = cfg_defaults;
//------------------------------------------------
// script informations
//------------------------------------------------
var APRinf = {
name: 'Facebook Application Post Remover',
name_med: 'FB Application Post Remover',
name_short: 'FB APR',
id: '92953',
ver: '2.13',
url: 'http://userscripts.org/scripts/show/92953',
meta: 'http://userscripts.org/scripts/source/92953.meta.js'
};
//------------------------------------------------
// unsafeWindow
//------------------------------------------------
if (typeof unsafeWindow === 'undefined') { unsafeWindow = window; }
// don't run in frames, except updater
if (!unsafeWindow.location.href.match(APRinf.meta)) {
if (self !== window.top) { return; }
}
// detect Chromium browser - finally working code
var getDOMWindow = function () {
var elt = document.createElement('div');
elt.setAttribute('onclick', 'return window;');
return elt.onclick();
};
if (typeof chrome !== 'undefined' && chrome.extension) {
unsafeWindow = getDOMWindow();
}
//------------------------------------------------
// text strings
//------------------------------------------------
var text_strings = {
languages : ['cs', 'nl', 'en', 'es'],
// English by Sigi_cz - default
en : {
'_language' : 'English',
'cfg-language' : 'language: ',
'cfg-config' : 'Configuration',
'cfg-author' : 'author',
'cfg-author_email' : '%1send e-mail to author%2',
'cfg-licence' : 'is licensed under a',
'cfg-appIDs' : 'appID\'s to remove:',
'cfg-appIDs-hlp' : 'each row contains one appID, optional text behind ID is comment',
'cfg-all_apps' : 'all applications',
'cfg-all_apps-hlp' : 'remove posts from all applications',
'cfg-time_limit' : '(hours) time limit',
'cfg-time_limit-hlp' : 'remove posts older then X hours',
'cfg-continue_proc' : 'continue processing',
'cfg-continue_proc-hlp' : 'search last known post and continue processing',
'cfg-autorun' : 'start automatically',
'cfg-autorun-hlp' : 'processing starts when page is loaded',
'cfg-only_user_posts' : 'only own posts',
'cfg-only_user_posts-hlp' : 'check only your app. posts or also from friends',
'cfg-hide_posts' : 'hide posts',
'cfg-hide_posts-hlp' : 'don\'t remove posts, only hide',
'cfg-xhr_delay' : '(ms) delay for removing',
'cfg-xhr_delay-hlp' : 'you don\'t want to remove all posts at once',
'cfg-isDebug' : 'debug mode',
'gui-runbtn' : 'APR',
'gui-runbtn-hlp' : 'start posts processing',
'gui-cfgbtn' : 'Configure APR',
'gui-cfgbtn-hlp' : 'show APR configuration window',
'gui-close' : 'Close',
'gui-save' : 'Save',
'gui-add' : 'Add',
'gui-remove' : 'Remove',
'inf-error' : 'error - see console for details.',
'inf-search' : 'searching last known old post %1 - page %2.',
'inf-process' : 'processing visible posts.',
'inf-xremoved' : '%1 posts total, %2 old removed.',
'inf-xhidden' : '%1 posts total, %2 old hidden.',
'str-update_long' : ' UPDATE FOUND%1%1 %2%1 installed version: %3%1 actual version: %4%1 update URL: %5%1%1 Do you want to update now?%1%1',
'str-addremove' : 'add/remove application',
'str-unknown' : 'unknown page',
'str-unknown_long' : 'I don\'t know this page. Should I do something here?%1Contact me with suggestions: ',
'str-old_profile' : 'old profile',
'str-old_profile_long' : 'Old profile page layout is unsupported by APR.%1(I can\'t debug new features on it anymore.)%1%1Please switch to %2new profile layout%3.',
'str-APRhome' : 'homepage',
'str-APRhome_long' : 'Home sweet home :)',
'_language_end' : 'English'
},
// Czech by Sigi_cz
cs : {
'_language' : 'Česky (Czech)',
'cfg-language' : 'jazyk: ',
'cfg-config' : 'Nastavení',
'cfg-author' : 'autor',
'cfg-author_email' : '%1poslat e-mail autorovi%2',
'cfg-licence' : 'je licencován pod',
'cfg-appIDs' : 'ID aplikací k odstranění:',
'cfg-appIDs-hlp' : 'každý řádek obsahuje jedno ID, text za ID je komentář',
'cfg-all_apps' : 'všechny aplikace',
'cfg-all_apps-hlp' : 'odstranit příspěvky ze všech aplikací',
'cfg-time_limit' : '(hodin) časový limit',
'cfg-time_limit-hlp' : 'odstranit příspěvky starší než X hodin',
'cfg-continue_proc' : 'pokračovat ve zpracování',
'cfg-continue_proc-hlp' : 'vyhledat poslední nezpracovaný příspěvek a pokračovat ve zpracování',
'cfg-autorun' : 'automatické spouštění',
'cfg-autorun-hlp' : 'zpracování se spustí ihned po načtení stránky',
'cfg-only_user_posts' : 'pouze vlastní příspěvky',
'cfg-only_user_posts-hlp' : 'kontrolovat pouze vlastní příspěvky, nebo i od přátel',
'cfg-hide_posts' : 'skrývat příspěvky',
'cfg-hide_posts-hlp' : 'příspěvky nemazat ale pouze skrývat',
'cfg-xhr_delay' : '(ms) prodleva pro mazání',
'cfg-xhr_delay-hlp' : 'nechceme odstraňovat všechny příspěvky najednou',
'cfg-isDebug' : 'režim ladění',
'gui-runbtn' : 'APR',
'gui-runbtn-hlp' : 'spustit zpracování příspěvků',
'gui-cfgbtn' : 'Nastavit APR',
'gui-cfgbtn-hlp' : 'zobrazit konfigurační okno APR',
'gui-close' : 'Zavřít',
'gui-save' : 'Uložit',
'gui-add' : 'Přidat',
'gui-remove' : 'Odebrat',
'inf-error' : 'chyba - více informací v chybové konzoli.',
'inf-search' : 'hledám poslední známý nezpracovaný příspěvek.',
'inf-process' : 'zpracovávám zobrazené příspěvky.',
'inf-xremoved' : '%1 příspěvků celkem, %2 starých odstraněno.',
'inf-xhidden' : '%1 příspěvků celkem, %2 starých skryto.',
'str-update_long' : ' NALEZENA AKTUALIZACE%1%1 %2%1 nainstalovaná verze: %3%1 aktuální verze: %4%1 adresa aktualizace: %5%1%1 Přejete si provést aktualizaci?%1%1',
'str-addremove' : 'přidat/odebrat aplikaci',
'str-unknown' : 'neznámá stránka',
'str-unknown_long' : 'Tady to neznám. Měl bych tu něco dělat?%1Kontaktujte mě s nápady: ',
'str-old_profile' : 'starý profil',
'str-old_profile_long' : 'APR nepodporuje starý layout profilu%1(Už na něm nemůžu testovat nové věci.)%1%1Prosím přejděte na %2nový layout%3.',
'str-APRhome' : 'homepage',
'str-APRhome_long' : 'Domov sladký domov :)',
'_language_end' : 'Česky (Czech)'
},
// Dutch translation by Stievydude
nl : {
'_language' : 'Nederlands (Dutch)',
'cfg-language' : 'taal: ',
'cfg-config' : 'Configuratie',
'cfg-author' : 'auteur',
'cfg-author_email' : '%1verstuur een e-mail naar de auteur%2',
'cfg-licence' : 'is gelicentieerd onder een',
'cfg-appIDs' : 'te verwijderen toepassingID\'s:',
'cfg-appIDs-hlp' : 'elke rij bevat één toepassingID, optionele tekst achter het ID is commentaar',
'cfg-all_apps' : 'alle toepassingen',
'cfg-all_apps-hlp' : 'verwijder posts van alle toepassingen',
'cfg-time_limit' : '(uren) tijdslimiet',
'cfg-time_limit-hlp' : 'verwijder posts ouder dan X uren',
'cfg-continue_proc' : 'verdergaan met verwerken',
'cfg-continue_proc-hlp' : 'zoek laatst gekende post en ga verder met verwerken',
'cfg-autorun' : 'start automatisch',
'cfg-autorun-hlp' : 'verwerken start wanneer de pagina is geladen',
'cfg-only_user_posts' : 'alleen eigen posts',
'cfg-only_user_posts-hlp' : 'controleer alleen eigen toepassingposts of ook van vrienden',
'cfg-hide_posts' : 'verberg posts',
'cfg-hide_posts-hlp' : 'verwijder geen posts, alleen verbergen',
'cfg-xhr_delay' : '(ms) vertraging voor verwijderen ',
'cfg-xhr_delay-hlp' : 'Je wil niet alle posts ineens verwijderen',
'cfg-isDebug' : 'debug modus',
'gui-runbtn' : 'APR',
'gui-runbtn-hlp' : 'start met verwerken posts',
'gui-cfgbtn' : 'Configureer APR',
'gui-cfgbtn-hlp' : 'toon APR configuratievenster',
'gui-close' : 'Sluit',
'gui-save' : 'Bewaar',
'gui-add' : 'Voeg toe',
'gui-remove' : 'Verwijder',
'inf-error' : 'fout - zie console voor details.',
'inf-search' : 'bezig met laatst bekende post te zoeken %1 - pagina %2.',
'inf-process' : 'zichtbare posts verwerken.',
'inf-xremoved' : 'totaal aantal posts: %1, %2 oude verwijderd.',
'inf-xhidden' : 'totaal aantal posts: %1, %2 oude verborgen.',
'str-update_long' : ' NIEUWE VERSIE GEVONDEN%1%1 %2%1 geïnstalleerde versie: %3%1 huidige versie: %4%1 update URL: %5%1%1 Nu updaten?%1%1',
'str-addremove' : 'toepassing toevoegen/verwijderen',
'str-unknown' : 'onbekende pagina',
'str-unknown_long' : 'Ik ken deze pagina niet. Zou ik hier iets moeten doen? %1Contacteer me met suggesties: ',
'str-old_profile' : 'oud profiel',
'str-old_profile_long' : 'Oude profielpagina. De layout wordt niet ondersteund door APR.%1(Ik kan de nieuwe functies op deze pagina niet meer debuggen.)%1%1Stap a.u.b over naar het %2nieuw profiel%3.',
'str-APRhome' : 'startpagina',
'str-APRhome_long' : 'Zoals het klokje thuis tikt, tikt het nergens :)',
'_language_end' : 'Nederlands (Dutch)'
},
// Spanish translation by Néstor
es : {
'_language' : 'Español (Spanish)',
'cfg-language' : 'idioma: ',
'cfg-config' : 'Configuración',
'cfg-author' : 'autor',
'cfg-author_email' : '%1enviar e-mail al autor%2',
'cfg-licence' : 'está bajo una licencia de',
'cfg-appIDs' : 'appID\'s a borrar:',
'cfg-appIDs-hlp' : 'cada linea contiene un appID, texto opcional detrás del ID es comentario',
'cfg-all_apps' : 'Todas las aplicaciones',
'cfg-all_apps-hlp' : 'borrar posts de todas aplicaciones',
'cfg-time_limit' : '(horas) tiempo límite',
'cfg-time_limit-hlp' : 'borrar posts más viejos que x horas',
'cfg-continue_proc' : 'continua procesando',
'cfg-continue_proc-hlp' : 'buscar último post y continuar procesando',
'cfg-autorun' : 'comenzar automáticamente',
'cfg-autorun-hlp' : 'proceso comienza cuando la página está cargada',
'cfg-only_user_posts' : 'solo posts propios',
'cfg-only_user_posts-hlp' : 'revisar sólo los posts de tus propias apps o tambien de amigos',
'cfg-hide_posts' : 'ocultar posts',
'cfg-hide_posts-hlp' : 'no borrar posts, sólo esconderlos',
'cfg-xhr_delay' : '(ms) demora para el borrado',
'cfg-xhr_delay-hlp' : 'no querrás borrar todos los posts al mismo tiempo',
'cfg-isDebug' : 'debug mode',
'gui-runbtn' : 'APR',
'gui-runbtn-hlp' : 'Comenzar a procesar posts',
'gui-cfgbtn' : 'Configurar APR',
'gui-cfgbtn-hlp' : 'Mostrar configuración APR',
'gui-close' : 'Cerrar',
'gui-save' : 'Guardar',
'gui-add' : 'Agregar',
'gui-remove' : 'Borrar',
'inf-error' : 'error - mira la consola para detalles.',
'inf-search' : 'buscando último post viejo conocido %1 - página %2.',
'inf-process' : 'procesando posts visibles.',
'inf-xremoved' : '%1 posts total, %2 viejos borrados.',
'inf-xhidden' : '%1 posts total, %2 viejos ocultados.',
'str-update_long' : ' ACTUALIZACIÓN ENCONTRADA%1%1 %2%1 versión instalada: %3%1 versión actual: %4%1 URL de actualiación: %5%1%1 ¿Quieres actualizar ahora?%1%1',
'str-addremove' : 'agregar/quitar aplicación',
'str-unknown' : 'página desconocida',
'str-unknown_long' : 'No conozco esta página. ¿Debería hacer algo aquí?%1Contáctame con sugerencias: ',
'str-old_profile' : 'viejo perfil',
'str-old_profile_long' : 'El viejo diseño de página de perfil no es soportado por APR.%1(Ya no se puede depurar nuevas características en este.)%1%1Por favor cambie al %2nuevo diseño de perfil%3.',
'str-APRhome' : 'homepage',
'str-APRhome_long' : 'Hogar dulce hogar :)',
'_language_end' : 'Español (Spanish)'
}
};
//------------------------------------------------
// some helpfull functions
//------------------------------------------------
function doClick(elm) { var e = document.createEvent('MouseEvents'); e.initEvent('click', true, true, window, 0); elm.dispatchEvent(e); }
function destroy(elm) { if (elm && elm.parentNode) { elm.parentNode.removeChild(elm); } }
function testClass(elm, cls) { if (typeof cls === 'string') { cls = new RegExp('(^|\\s)' + cls + '(\\s|$)'); } return (elm.className && cls.test(elm.className)); }
function insertBefore(elm, ref) { if (ref && ref.parentNode) { ref.parentNode.insertBefore(elm, ref); } }
// select elements by 'tagname' '#ID' '.class' './xpath' '//xpath'
function $(q, root, single) {
if (root && typeof root === 'string') {
root = $(root, null, true);
if (!root) { return null; }
}
root = root || document;
if (q[0]==='#') { return root.getElementById(q.substr(1)); }
else if (q[0]==='/' || (q[0]==='.' && q[1]==='/')) {
if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}
else if (q[0]==='.') { return root.getElementsByClassName(q.substr(1)); }
return root.getElementsByTagName(q);
}
// add event listeners
function on(type, elm, func) {
if (type instanceof Array) { var ii=type.length; while (ii--) { on(type[ii], elm, func); } return; }
if (elm instanceof Array) { var jj=elm.length; while (jj--) { on(type, elm[jj], func); } return; }
(typeof elm === 'string' ? $(elm) : elm).addEventListener(type, func, false);
}
// GM_addStyle emulation
function addStyle(css) {
if (typeof GM_addStyle !== 'undefined') { return GM_addStyle(css); }
else {
var ishead = document.getElementsByTagName('head')[0];
var document_element = (!ishead ? document.documentElement : null);
var link_stylesheet = document.createElement('link');
link_stylesheet.rel = 'stylesheet';
link_stylesheet.type = 'text/css';
link_stylesheet.href = 'data:text/css,' + encodeURIComponent(css);
if (ishead) { ishead.appendChild(link_stylesheet); }
else { document_element.insertBefore(link_stylesheet, document_element.firstChild); }
}
}
// check if string is part of array
function contains(arr, str, identical) {
var ii = arr.length;
while (ii--) {
if (!identical) { if (arr[ii].indexOf(str) >= 0) { return ii; } }
else { if (arr[ii] === str) { return ii; } }
}
return ii;
}
// send XMLHttpRequest
function xhr(url, callback_fn, data) {
var res = new XMLHttpRequest();
res.onreadystatechange = function () { if (typeof callback_fn === 'function' && res.readyState === 4 && res.status === 200) { callback_fn(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);
}
// delay script processing
function delay(millis) {
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while (curDate-date < millis);
}
// write debug info to console
function debugMsg(msg, force) {
if (!force && !cfg.isDebug) { return false; }
if (force === 0) { return false; }
msg = APRinf.name_short + ': ' + msg;
if (typeof GM_log !== 'undefined') { GM_log(msg); return true; }
if (typeof opera !== 'undefined' && opera.postError) { opera.postError(msg); return true; }
if (typeof console !== 'undefined' && console.log) { console.log(msg); return true; }
alert(msg);
return false;
}
//------------------------------------------------
// Data storage
//------------------------------------------------
// implement JSON functions if they're not already defined - modified from
// http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/
if (!this.JSON) { this.JSON = {}; }
if (typeof JSON.parse !== 'function') {
JSON.stringify = function (obj) {
var t = typeof (obj);
if (t !== 'object' || obj === null) {
if (t === 'string') { obj = '"' + obj.replace('"','\\"') + '"'; }
return String(obj);
} else {
var n, v, json = [], arr = (obj && obj.constructor === Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t !== 'function') {
if (t === 'string') { v = '"' + v.replace('"','\\"') + '"'; }
if ( t === 'object' && v !== null) { v = JSON.stringify(v); }
json.push((arr ? '' : '"' + n + '":') + String(v));
}
}
return (arr ? '[' : '{') + String(json) + (arr ? ']' : '}');
}
};
}
if (typeof JSON.parse !== 'function') {
JSON.parse = function (str) {
if (str === '') { str = '""'; }
eval('var p=' + str + ';');
return p;
};
}
// prepare data storage functions
function storageInit() {
debugMsg('initialize data storage');
// detect available storage type
var storage = 'none';
try {
if (typeof GM_getValue === 'function' && typeof GM_setValue === 'function') {
// test if greasemonkey's functions work.
var GM_testkey = 'GM_testkey',
GM_testvalue = 'GM_testvalue-' + (new Date() *1);
GM_setValue(GM_testkey, GM_testvalue);
if (GM_getValue(GM_testkey, false) === GM_testvalue) { storage = 'greasemonkey'; }
GM_deleteValue(GM_testkey);
}
} catch(x) { debugMsg('storageInit error: '+x,1); }
if (storage === 'none' && typeof localStorage === 'object') { storage = 'localstorage'; }
debugMsg('storage type=' + storage);
// some shitty browser detected
if (storage === 'none') {
setTimeout(function () {
alert('Sorry but your browser sux ...\n' +
'No permanent storage detected - initiating temporary storage.\n' +
'All changes will be lost after page refresh!');
}, 0);
localStorage = (function () {
var instance = {},
tmp_array = [];
instance.setItem = function (name, value){
tmp_array[name] = value;
};
instance.getItem = function (name) {
return tmp_array[name] || null;
};
instance.removeItem = function (name) {
tmp_array[name] = null;
};
return instance;
})();
storage = 'fakestorage';
}
// fake GM_ functions
if (storage === 'localstorage' || storage === 'fakestorage') {
GM_setValue = function (name, value) {
localStorage.setItem(name, value);
};
GM_getValue = function (name, defaultValue) {
return localStorage.getItem(name) || defaultValue;
};
GM_deleteValue = function (name) {
localStorage.removeItem(name);
};
}
return storage;
}
// function to handle configuration data
var config = (function () {
var prefix = 'FB_APR-' + 123456 + '-', //to do - user id
instance = {};
instance.set = function (key, value){
//setTimeout(function () { GM_setValue(prefix + key, value); }, 0);
GM_setValue(prefix + key, value);
};
instance.get = function (key, defaultValue) {
return GM_getValue(prefix + key) || defaultValue;
};
instance.remove = function (key) {
GM_deleteValue(prefix + key);
};
instance.save = function (key, value){
GM_setValue(prefix + key, JSON.stringify(value));
};
instance.load = function (key, defaultValue) {
return JSON.parse(GM_getValue(prefix + key) || defaultValue);
};
instance.init = function (key, defaultValue) {
var cfginit;
cfginit = instance.load(key, '"none"');
if (cfginit === 'none') {
instance.save(key, defaultValue);
cfginit = instance.load(key, '"none"');
}
return cfginit;
};
return instance;
})();
// Opera Greasemonkey support
function operaGM() {
setTimeout(function () {
var msgNoOperaGM = config.get('msgNoOperaGM', 1 ) *1;
if ( msgNoOperaGM === 1) {
config.set('msgNoOperaGM', 0 +'');
var GMemu_url = 'http://userscripts.org/scripts/show/88932';
if (confirm('Opera have no built in Greasemonkey suport.\n' +
'Please install Greasemonkey Emulation script.\n' +
'URL: ' + GMemu_url + '\n\n' +
'Do you want to install now?')) {
unsafeWindow.open(GMemu_url, '_blank');
}
}
}, 1000);
}
//------------------------------------------------
// APR "GUI"
//------------------------------------------------
var apr_language = 'en';
// set current language
function aprGuiLanguage() {
debugMsg('GUI select language');
// try read document locale or default to english
var loc = document.body.className.match(/locale_([^ ]+)/i) || ['','en'];
if (cfg.language === 'auto') {
apr_language = loc[1].toLowerCase();
if (!text_strings[apr_language]) {
apr_language = apr_language.split('_')[0];
if (!text_strings[apr_language]) { apr_language = 'en'; }
}
} else { apr_language = cfg.language; }
}
// Get a string in the current language, default to english or return empty.
// Replace %x with text from repl array
function str(key, repl) {
var out_string, lng = apr_language;
if (!text_strings[lng][key]) { lng = 'en'; }
if (text_strings[lng][key]) { out_string = text_strings[lng][key]; }
else { out_string = ''; }
if (repl) {
if (typeof repl === 'number') { repl = repl + ''; }
if (typeof repl === 'string') { repl = repl.split('#&@'); }
if (repl instanceof Array) { var rgx, ii = repl.length; while (ii--) { rgx = new RegExp('%' + (ii + 1),'g'); out_string = out_string.replace(rgx, repl[ii]); } }
}
return out_string;
}
// show info in apr_info div
function aprInfo(text) {
debugMsg('info: "'+text+'"',1);
try {
var result = $('#apr_info');
result.firstChild.innerHTML = 'APR: ' + text;
result.style.height = 'auto';
result.style.overflow = 'visible';
result.style.visibility = 'visible';
} catch(x) { debugMsg('aprInfo error: '+x,1); }
}
// hide apr_info div
function aprInfoHide() {
debugMsg('GUI hide info div');
try {
var result = $('#apr_info');
result.style.height = '0px';
result.style.overflow = 'hidden';
result.style.visibility = 'hidden';
} catch(x) { debugMsg('aprInfo error: '+x,1); }
}
// create div for APR informations
function aprCreateInfoDiv(elm) {
debugMsg('GUI create info div');
if ($('#apr_info')) { return; }
try {
addStyle([
'#apr_info { height:0px; padding:0 5px; display:block; border:1px dotted grey; overflow:hidden; visibility:hidden; }',
'#apr_info:hover #apr_info_close { color:red; }',
''].join(''));
var newAPRinfo = document.createElement('div');
newAPRinfo.id = 'apr_info';
newAPRinfo.innerHTML = [
'<span style="float:left;">APR: information area.</span>',
'<span id="apr_info_close" style="float:right;" title="' + str('gui-close') + '"> [x]</span>',
'<div style="clear:both;"></div>',
''].join('');
insertBefore(newAPRinfo,$(elm).firstChild);
on('click', '#apr_info', aprInfoHide);
} catch(x) { debugMsg('aprCreateInfoDiv error: '+x,1); }
}
// create button on right side of top menu
function aprCreateRunButton() {
debugMsg('GUI create run button');
if ($('#apr_runbtn')) { return; }
try {
var newAPRbutton = document.createElement('li');
newAPRbutton.id = 'apr_runbtn';
newAPRbutton.innerHTML = '<a onclick="javascript:return(void);" title="' + str('gui-runbtn-hlp') + '">' + str('gui-runbtn') + '</a>';
$('#pageNav').appendChild(newAPRbutton);
on('click', '#apr_runbtn', function () { aprProcess(); });
} catch(x) { debugMsg('aprCreateRunButton error: '+x,1); }
}
// create menu item inside FB account menu
function aprCreateConfigButton() {
debugMsg('GUI create configuration button');
if ($('#apr_cfgbtn')) { return; }
try {
var newAPRconfig = document.createElement('li');
newAPRconfig.id = 'apr_cfgbtn';
newAPRconfig.innerHTML = '<a onclick="javascript:return(void);" title=\'' + str('gui-cfgbtn-hlp') + '\'>' + str('gui-cfgbtn') + '</a>';
insertBefore(newAPRconfig, $('//li[@id="navAccount"]/ul', null, true).childNodes[2]);
on('click', '#apr_cfgbtn', aprShowConfig);
} catch(x) { debugMsg('aprCreateConfigButton error: '+x,1); }
}
var apr_popup_level = 0;
// create popup
function aprCreatePopup() {
debugMsg('GUI create popup');
try {
if (apr_popup_level === 0) {
addStyle([
'.apr_popupanchor { display:none; top:0; right:0; bottom:0; left:0; }',
'.apr_popupshadow { display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:black; opacity:0.3; }',
'.apr_popup { position:relative; margin:auto; padding:10px; border:3px double #666666; background:#f6f6f6; }',
'.apr_fll { float:left; }',
'.apr_flr { float:right; }',
'.apr_3t { position:relative; top:3px; }',
''].join(''));
}
var newAPRpopupanchor = document.createElement('div');
newAPRpopupanchor.id = 'apr_popupanchor' + apr_popup_level;
newAPRpopupanchor.className = 'apr_popupanchor';
document.body.appendChild(newAPRpopupanchor);
var newAPRpopupshadow = document.createElement('div');
newAPRpopupshadow.id = 'apr_popupshadow' + apr_popup_level;
newAPRpopupshadow.className = 'apr_popupshadow';
document.body.appendChild(newAPRpopupshadow);
} catch(x) { debugMsg('aprCreatePopup error: '+x,1); }
}
// hide popup created with aprShowPopup
function aprHidePopup() {
debugMsg('GUI hide popup');
try {
$('#apr_popupanchor' + apr_popup_level).style.display = 'none';
$('#apr_popupshadow' + apr_popup_level).style.display = 'none';
apr_popup_level--;
if (apr_popup_level > 0) { $('#apr_popupshadow' + apr_popup_level).style.display = 'block'; }
} catch(x) { debugMsg('aprHidePopup error: '+x,1); }
}
// show popup div with a shadow background
function aprShowPopup(id, width, top, fixedPosition, title, body, footer_l, footer_r, autoclose_delay) {
debugMsg('GUI show popup');
try {
apr_popup_level++;
aprCreatePopup();
var anch = $('#apr_popupanchor' + apr_popup_level),
shdw = $('#apr_popupshadow' + apr_popup_level),
close_btn_id = '#apr_popup_msg_close' + apr_popup_level;
if (typeof id !== 'string') { id = 'apr_popup-' + apr_popup_level; }
if (typeof width !== 'string') { width = '400px'; }
if (typeof top !== 'string') { top = '200px'; }
if (typeof fixedPosition !== 'boolean') { fixedPosition = true; }
if (typeof title !== 'string') { title = ''; }
if (typeof body !== 'string') { body = ''; }
if (typeof footer_l !== 'string') { footer_l = ''; }
if (typeof footer_r !== 'string') { footer_r = ''; }
anch.innerHTML = [
'<div id="' + id + '" class="apr_popup" style="width:' + width + '; top:' + top + ';">',
// "title"
'<span style="font-size:14px;"><b>FB Application Post Remover</b></span> - ' + title + '<br /><hr />',
// "body"
'<div>',
body,
'</div>',
// "footer"
'<div style="clear:both;"></div><hr />',
'<div>',
'<span class="apr_fll apr_3t">',
footer_l,
'</span>',
'<span class="apr_flr">',
footer_r,
'<input type="button" id="' + close_btn_id + '" value="' + str('gui-close') + '" />',
'</span>',
'</div>',
'<div style="clear:both;"></div>',
'</div>'].join('');
shdw.style.zIndex = (1000 + (apr_popup_level * 2)) + '';
anch.style.zIndex = (1001 + (apr_popup_level * 2)) + '';
shdw.style.display = 'block';
anch.style.display = 'block';
$('#apr_popupshadow' + (apr_popup_level - 1)).style.display = 'none';
anch.style.position = fixedPosition ? 'fixed' : 'absolute';
if (!fixedPosition) { window.scroll(0,0); }
doClick(anch); // click on popup to get rid of FB menu
on('click', '#' + close_btn_id, aprHidePopup);
if (typeof autoclose_delay === 'number') {
var aprmsgtimeout = setTimeout(aprHidePopup, autoclose_delay);
on('click', '#' + close_btn_id, function () { clearTimeout(aprmsgtimeout); });
}
} catch(x) { debugMsg('aprShowPopup error: '+x,1); }
}
// messagebox based on aprShowPopup
function aprShowMessage(title, body, buttons, autoclose_delay) {
debugMsg('GUI show message');
aprShowPopup(null, null, null, true, title, body, null, buttons, autoclose_delay);
}
//------------------------------------------------
// Configuration
//------------------------------------------------
// show config window
function aprShowConfig() {
debugMsg('show configuration window');
var apr_option = 'apr_cfg_o_',
cfgID = 'apr_popup-config';
cfg = config.load('cfg', cfg_defaults);
addStyle([
'.apr_in-row { overflow:hidden; clear:both; }',
'.apr_in-row label{ margin-left:4px; position:relative; top:3px; }',
'.apr_in-row_cb { float:left; width:36px; border:1px solid #f6f6f6; }',
'.apr_in-row_ni { float:left; width:32px; margin-right:2px; border:1px solid grey; }',
'#apr_cfg_leftcol { float:left; width:290px; }',
'#apr_cfg_rightcol { float:right; width:290px; }',
''].join(''));
// create checkbox
function inChb(opt) {
return ['<div title="' + str('cfg-' + opt + '-hlp') + '" class="apr_in-row">',
'<div class="apr_in-row_cb"><input type="checkbox" id="' + apr_option + opt + '" class="apr_flr" /></div>',
'<label for="' + apr_option + opt + '">' + str('cfg-' + opt) + '</label>',
'</div>'].join('');
}
// create inputbox
function inVal(opt) {
return ['<div title="' + str('cfg-' + opt + '-hlp') + '" class="apr_in-row">',
'<input type="text" id="' + apr_option + opt + '" class="apr_in-row_ni" />',
'<label for="' + apr_option + opt + '">' + str('cfg-' + opt) + '</label>',
'</div>'].join('');
}
// create language selector
function selLang(opt) {
var opts = '', ii, lngl = text_strings.languages.length;
for (ii = 0; ii < lngl; ii++) {
opts = opts + '<option value="' + text_strings.languages[ii] + '">' + text_strings[text_strings.languages[ii]]._language + '</option>';
}
return ['<div title="' + str('cfg-' + opt + '-hlp') + '" class="apr_in-row">',
str('cfg-' + opt),
'<select id="' + apr_option + opt + '">',
'<option value="auto">Automatic</option>',
opts,
'</select>',
'</div>'].join('');
}
// show config window
aprShowPopup(cfgID, '600px', '100px', true, str('cfg-config'),
// body
['<div id="apr_cfg_leftcol">',
selLang('language'),
'<br />',
inVal('time_limit'),
inChb('continue_proc'),
inChb('autorun'),
inChb('only_user_posts'),
inChb('hide_posts'),
'<br /><br />',
inChb('isDebug'),
inVal('xhr_delay'),
'</div>',
'<div id="apr_cfg_rightcol">',
inChb('all_apps'),
'<span title="' + str('cfg-appIDs-hlp') + '">' + str('cfg-appIDs') + '</span><br />',
'<textarea id="' + apr_option + 'appIDs" style="width:97%; height:150px;"></textarea>',
'</div>',
''].join(''),
// about
['<a href="http://userscripts.org/scripts/show/92953" target="_blank" title="FaceBook Application Post Remover">FB APR</a>',
' v' + APRinf.ver + ' (' + str('cfg-author') + ' ',
str('cfg-author_email', ['<a href="mailto:sigi_cz@centrum.cz" title="','">Sigi_cz</a>']) + ') ',
str('cfg-licence') + ' ',
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License">',
'<span class="apr_3t"><img alt="cc-by-nc-nd-3.0" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-nd/3.0/80x15.png" /></span></a>',
''].join(''),
'<input type="button" id="apr_cfg_save" value="' + str('gui-save') + '" /> '
);
// set/get config values
function setgetInputs(mode) {
var elm, opt,
opts = $('//*[@id="' + cfgID + '"]//input[starts-with(@id,"' + apr_option + '")]'),
ii = opts.snapshotLength;
while (ii--) {
elm = opts.snapshotItem(ii);
opt = elm.id.replace(apr_option,'');
if (mode === 'set') {
if (elm.type === 'checkbox') { elm.checked = cfg[opt]; }
if (elm.type === 'text') { elm.value = cfg[opt]; }
}
if (mode === 'get') {
if (elm.type === 'checkbox') { cfg[opt] = elm.checked; }
if (elm.type === 'text') { cfg[opt] = elm.value; }
}
}
}
// set/get appIDs from textarea
function setgetAppIDs(mode) {
var ii, val, opt = 'appIDs',
elm = $('//*[@id="' + cfgID + '"]//*[@id="' + apr_option + opt + '"]').snapshotItem(0);
function sortByName(a, b) {
var x = ('str' + a[1]).toLowerCase(), y = ('str' + b[1]).toLowerCase();
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
if (mode === 'set') {
//duplicate array, sort by name and join
val = cfg[opt].slice().sort(sortByName); ii = val.length;
while (ii--) { val[ii] = val[ii].join(' '); }
elm.value = val.join('\n');
}
if (mode === 'get') {
//remove empty lines and split into array ...
val = elm.value.replace(/[\r\n][\s]+[\r\n]/g,'\n').replace(/^[\r\n]+|[\r\n]+$/g,'').split(/[\r\n]+/); ii = val.length;
//... trim whitespaces from each element and split (2D array)
while (ii--) { val[ii] = val[ii].replace(/^\s+|\s+$/g, '').split(/\s+(.+)/,2); }
cfg[opt] = val;
}
}
// set/get selected language option
function setgetLanguage(mode) {
var opt = 'language',
elm = $('//*[@id="' + cfgID + '"]//*[@id="' + apr_option + opt + '"]').snapshotItem(0);
if (mode === 'set') { elm.value = cfg[opt]; }
if (mode === 'get') { cfg[opt] = elm.value; }
}
function saveCfg() {
setgetInputs('get');
setgetAppIDs('get');
setgetLanguage('get');
aprGuiLanguage();
config.save('cfg', cfg);
aprHidePopup();
aprShowConfig();
}
setgetInputs('set');
setgetAppIDs('set');
setgetLanguage('set');
on('click', '#apr_cfg_save', saveCfg);
}
//------------------------------------------------
// Updater
//------------------------------------------------
// check for script update
function updaterStart(scriptInfo, metadata) {
debugMsg('updater - check update',1);
try {
var metaID = metadata.match(/@uso:script\s*(.+)/)[1],
metaVer = metadata.match(/@version\s*(.+)/)[1];
debugMsg('' +
'scriptInfo.id=' + scriptInfo.id + '\n' +
'metaID=' + metaID + '\n' +
'scriptInfo.ver=' + scriptInfo.ver + '\n' +
'metaVer=' + metaVer + '\n' +
'');
if (metaID === scriptInfo.id && metaVer !== scriptInfo.ver) {
setTimeout(function () {
if (confirm(str('str-update_long', ['\n', scriptInfo.name, scriptInfo.ver, metaVer, scriptInfo.url]))) {
unsafeWindow.open(scriptInfo.url, '_blank');
}
}, 0);
}
} catch(x) { debugMsg('updaterStart error: '+x,1); return; }
}
// add iframe and load metadata
function updaterFrame(updateSrc) {
debugMsg('updater - create iFrame');
if ($('#apr_updater')) { return; }
try {
var newAPRupdater = document.createElement('iframe');
newAPRupdater.id = 'apr_updater';
newAPRupdater.setAttribute('style', 'display: none;');
//newAPRupdater.setAttribute('style', 'display: block; width:500px; height:300px; border:1px solid red;');
newAPRupdater.src = updateSrc;
$('body')[0].appendChild(newAPRupdater);
} catch(x) { debugMsg('updaterFrame error: '+x,1); }
}
// initialize
function updaterInit() {
debugMsg('updater - initialize');
setTimeout(function () {
var now = new Date().getTime();
var updateInterval = cfg.updateInterval * 60 * 60 * 1000;
var lastUpdateCheck = config.get('lastUpdateCheck', 0)*1;
debugMsg('' +
'now.toLocaleString()=' + now.toLocaleString() + '\n' +
'lastUpdateCheck.toLocaleString()=' + lastUpdateCheck.toLocaleString() + '\n' +
'updateInterval=' + updateInterval + '\n' +
'',0);
if (now > (lastUpdateCheck + updateInterval)) {
updaterFrame(APRinf.meta + '?' + now);
config.set('lastUpdateCheck', now+'');
}
}, 3000);
}
//------------------------------------------------
// Process
//------------------------------------------------
// process posts on profile page
function processProfilePage() {
debugMsg('process profile page',1);
// FB profile page elements
var elmStream = '#profile_minifeed',
elmTime = './/@data-date',
elmClBtn = '.uiCloseButton',
elmPosts = './/*[@class="uiStreamSource"]',
elmMore = '.uiMorePagerPrimary',
elmMoreAn = '.uiMorePager';
cfg = config.load('cfg', cfg_defaults);
aprCreateInfoDiv(elmStream);
// test access to unsafeWindow.Env
if (typeof unsafeWindow.Env.user === 'undefined') {
aprInfo(str('inf-error'));
debugMsg('no access to unsafeWindow.Env.user',1);
return;
}
//------------------------------------------------
// functions - search last known post
//------------------------------------------------
function postsClickOlder(rpt) {
debugMsg('click "Older Posts"');
var clicked = false;
var a = $(elmMore)[0];
try {
if (a) {
try {
if (a.onclick) {
a.onclick();
clicked = true;
}
} catch(xx) { }
if (!clicked) {
doClick(a);
}
}
} catch(x) {
debugMsg('clickOlderPosts error: '+x,1);
if (rpt) { return; } // return on repeated error
setTimeout(function (){ postsClickOlder(true); },1000);
}
}
function postsLoadOlder(callback_func) {
debugMsg('load older posts',1);
var ii=0;
function ni() {
ii++;
debugMsg('' +
'xx=' + ii + '\n' +
'profile_pager=' + $(elmMoreAn)[0].className + '\n' +
'',0);
if (!testClass($(elmMoreAn)[0],'async_saving')) {
debugMsg('load older posts - finished');
$(elmStream).removeEventListener('DOMNodeInserted', ni, false);
callback_func();
}
}
$(elmStream).addEventListener('DOMNodeInserted', ni, false);
postsClickOlder();
}
//------------------------------------------------
// functions - process visible posts
//------------------------------------------------
// get "post" date
function postDate(post) {
if (typeof post === 'string') {
debugMsg('get \'' + post + '\' post date');
var elms = $(elmPosts, $(elmStream));
if (post === 'first') { post = elms.snapshotItem(0); }
if (post === 'last') { post = elms.snapshotItem(elms.snapshotLength - 1); }
}
return Date.parse($(elmTime, post).snapshotItem(0).textContent);
}
//unsafeWindow.Env, cfg(appIDs, all_apps, only_user_posts)
function postsGet() {
debugMsg('get posts',1);
var user2check = cfg.only_user_posts ? 'contains(@data-ft,\'"actrs":"' + unsafeWindow.Env.user + '"\') and ' : '',
apps2check = '', ii;
if (!cfg.all_apps) { ii = cfg.appIDs.length; while (ii--) { apps2check = apps2check + 'contains(@data-ft,\'"app_id":' + cfg.appIDs[ii][0] + '}\') or '; } }
else { apps2check = 'contains(@data-ft,\'"app_id":\')'; }
apps2check = ('(' + apps2check + ')').replace(' or )', ')');
debugMsg('' +
'appIDs=' + cfg.appIDs + '\n' +
'user2check=' + user2check + '\n' +
'apps2check=' + apps2check + '\n' +
'');
// select matching elements
var elms = $('.//*[' + user2check + apps2check + ']', $(elmStream));
debugMsg('' +
'elms.snapshotLength=' + elms.snapshotLength + '\n' +
//'elms.snapshotItem(0).innerHTML=' + elms.snapshotItem(0).innerHTML + '\n' +
'');
return elms;
}
//cfg(time_limit)
function postsFirstOld(elms) {
debugMsg('find first old post',1);
var ii, tDiff,
elms_cnt = elms.snapshotLength,
old = elms_cnt, // first old post
tStory = new Date(), // story time
tNow = new Date(); // current time
tNow.getTime();
// find first expired item
for (ii=0; ii<elms_cnt; ii++) {
tStory.setTime(postDate(elms.snapshotItem(ii)));
tDiff = Math.floor((tNow-tStory)/1000/60/60); // difference in full hours
debugMsg('' +
'ii=' + ii + '\n' +
'time_limit=' + cfg.time_limit + '\n' +
'tStory.toLocaleString()=' + tStory.toLocaleString() + '\n' +
'tNow.toLocaleString()=' + tNow.toLocaleString() + '\n' +
'tDiff=' + tDiff + '\n' +
'',0);
if (tDiff >= cfg.time_limit) {
old = ii;
break;
}
}
debugMsg('' +
'first old=' + old + '\n' +
'');
return old;
}
//save last known post date
function postsSaveLastKnown(post) {
var lkp = postDate(post);
debugMsg('' +
'postsSaveLastKnown ' + new Date(lkp).toLocaleString() + '\n' +
'');
config.set('lastKnownPost', lkp+'');
}
//unsafeWindow.Env, cfg(xhr_delay, hide_posts)
function postsRemove(elms, from) {
debugMsg('remove posts',1);
var ii, story_type, story_key, clbtn,
elms_cnt = elms.snapshotLength,
xhr_userID = unsafeWindow.Env.user || 0,
xhr_pfID = unsafeWindow.Env.post_form_id || 0,
xhr_fbdtsg = unsafeWindow.Env.fb_dtsg || 0;
// check xhr variables
if (xhr_userID===0 || xhr_pfID===0 || xhr_fbdtsg===0) {
aprInfo(str('inf-error'));
debugMsg('' +
'XHR - no access to unsafeWindow.Env\n' +
'xhr_userID=' + xhr_userID + '\n' +
'xhr_pfID=' + xhr_pfID + '\n' +
'xhr_fbdtsg=' + xhr_fbdtsg + '\n' +
'',1);
return;
}
debugMsg('' +
'elms_cnt=' + elms_cnt + '\n' +
'from=' + from + '\n' +
'xhr_userID=' + xhr_userID + '\n' +
'xhr_pfID=' + xhr_pfID + '\n' +
'xhr_fbdtsg=' + xhr_fbdtsg + '\n' +
'xhr_delay=' + cfg.xhr_delay + '\n' +
'');
// remove all expired (from last)
for (ii=elms_cnt-1; ii>=from; ii--) {
clbtn = $(elmClBtn, elms.snapshotItem(ii))[0];
story_type = clbtn.getAttribute('ajaxify').match(/story_type=(\d+)/i)[1];
story_key = clbtn.getAttribute('ajaxify').match(/story_key=(\d+)/i)[1];
debugMsg('' +
'ii=' + ii + '\n' +
'story_type=' + story_type + '\n' +
'story_key=' + story_key + '\n' +
'',0);
if (!cfg.hide_posts && cfg.xhr_delay > 0) {
delay(cfg.xhr_delay); // don't send all requests at once ...
xhr('http://www.facebook.com/ajax/minifeed.php?__a=1', '',
'profile_fbid=' + xhr_userID +
'&ministory_key=' + story_key +
'&story_type=' + story_type +
'&post_form_id=' + xhr_pfID +
'&post_form_id_source=AsyncRequest' +
'&fb_dtsg=' + xhr_fbdtsg
);
postsSaveLastKnown(elms.snapshotItem(ii-1) || elms.snapshotItem(ii));
}
destroy(elms.snapshotItem(ii));
}
// save last post date
if ((!cfg.hide_posts && cfg.xhr_delay > 0) && (elms_cnt === from)) {
postsSaveLastKnown(elms_cnt === 0 ? 'first' : elms.snapshotItem(elms_cnt-1));
}
aprInfo(str(((!cfg.hide_posts && cfg.xhr_delay > 0) ? 'inf-xremoved' : 'inf-xhidden'), [elms_cnt, (elms_cnt - from)]));
}
// select all visible app posts, find first expired and remove old
function postsProcessVisible() {
aprInfo(str('inf-process'));
var posts, firstOld;
posts = postsGet();
firstOld = postsFirstOld(posts);
postsRemove(posts, firstOld);
}
//------------------------------------------------
// processing start
//------------------------------------------------
if (cfg.continue_proc && !cfg.hide_posts) {
var ii = 1, last_visible_post = 0,
last_known_post = config.get('lastKnownPost', new Date())*1,
last_known_post_str = new Date(last_known_post).toLocaleString();
function gogo() {
last_visible_post = postDate('last');
aprInfo(str('inf-search', [last_known_post_str, ii++]));
debugMsg('' +
'last_known_post_str=' + last_known_post_str + '\n' +
'last_visible_post=' + last_visible_post + '\n' +
'last_visible_post=' + new Date(last_visible_post).toLocaleString() + '\n' +
'');
if (last_known_post < last_visible_post) {
debugMsg('last known post not found - load next page');
postsLoadOlder(gogo);
} else {
debugMsg('last known post found');
postsProcessVisible();
}
}
gogo();
} else {
debugMsg('continue processing disabled');
postsProcessVisible();
}
// processing finished
}
// add/remove appIDs on application pages
function processApplicationPage() {
debugMsg('process application page',1);
var app_name = $('//*[@id="profile_name"]').snapshotItem(0).innerHTML,
app_link = $('//*[contains(@id,"left_column")]//a[contains(@href,"/ajax/report.php")]'),
app_ID = app_link.snapshotItem(0).getAttribute('href').match(/cid=(\d+)/i)[1],
elm_action_btn, itm, is_added;
cfg = config.load('cfg', cfg_defaults);
aprShowMessage(str('str-addremove'),
'<span style="font-size:12px;"><b>' + app_ID + ' ' + app_name + '</b></span>',
'<input type="button" id="apr_app_action" value="action" /> ');
elm_action_btn = $('#apr_app_action');
function checkApp() {
itm = contains(cfg.appIDs, app_ID);
is_added = itm >= 0 ? true : false;
elm_action_btn.value = is_added ? str('gui-remove') : str('gui-add');
}
function addremoveApp() {
if (!is_added) { cfg.appIDs.push([app_ID,app_name]); }
else { cfg.appIDs.splice(itm,1); }
config.save('cfg', cfg);
checkApp();
}
checkApp();
on('click', '#apr_app_action', addremoveApp);
}
// identify current page and start
function aprProcess(autorun) {
debugMsg('determine current page');
var user_profile_new = $('//a[contains(@class,\'edit_profilepicture\')]').snapshotLength;
if (user_profile_new) {
debugMsg('current page is user profile (new)');
processProfilePage();
return;
}
// stop if autorun missed profile page
if (autorun) { return; }
var app_page = $('//*[contains(@id,"left_column")]//a[contains(@href,"/ajax/report.php") or contains(@href,"/apps/block.php?")]').snapshotLength;
if (app_page >= 2) {
debugMsg('current page is application page');
processApplicationPage();
return;
}
var apr_homepage = $('//*[contains(@id,"profile_name") and contains(text(),"FB Application Post Remover")]').snapshotLength;
if (apr_homepage) {
debugMsg('current page is FB APR homepage');
aprShowMessage(str('str-APRhome'), str('str-APRhome_long'));
return;
}
var user_profile_old = $('//div[contains(@class,\'can_edit\')]', $('#left_column')).snapshotLength;
if (user_profile_old) {
debugMsg('current page is user profile (old)');
aprShowMessage(str('str-old_profile'), str('str-old_profile_long', ['<br />', '<a href="/about/profile/">', '</a>']));
return;
}
debugMsg('current page is unknown');
aprShowMessage(str('str-unknown'), [str('str-unknown_long', '<br />'),
str('cfg-author_email', ['<a href="mailto:sigi_cz@centrum.cz" title="','">Sigi_cz</a>']),
''].join(''), '', 10000);
return;
}
//------------------------------------------------
// start script
//------------------------------------------------
function aprStart() {
debugMsg('start - DOMContentLoaded\n'+
'unsafeWindow.location.href= '+unsafeWindow.location.href,1);
// metadata found, check for script update and quit
if (unsafeWindow.location.href.match(APRinf.meta)) {
updaterStart(APRinf,document.getElementsByTagName('body')[0].innerHTML);
return;
}
var storage = storageInit();
// ask for Opera Greasemonkey support
if (storage !== 'greasemonkey' && typeof opera !== 'undefined') { operaGM(); }
cfg = config.init('cfg', cfg_defaults);
aprGuiLanguage();
aprCreatePopup();
updaterInit();
aprCreateRunButton();
aprCreateConfigButton();
if (cfg.autorun === true) {
debugMsg('autorun enabled');
aprProcess(true);
}
}
document.addEventListener('DOMContentLoaded', aprStart(), false);
}());
Mozilla add on,User script,Grease Monkey Script, greasemonkey userscripts, updater userscripts mafia wars userscripts mafia wars autoplayer userscripts mafia wars wall userscripts scripts userscripts travian greasemonkey greasemonkey download greasemonkey facebook greasemonkey tutorial greasemonkey youtube greasemonkey travian greasemonkey chrome greasemonkey mafia wars greasemonkey mafia wars autoplayer
Friday, February 4, 2011
Facebook APR (application post remover)
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment