FB Wall Manager

Manages Wall Posts for Various FB Games

目前為 2014-12-12 提交的版本,檢視 最新版本

// ==UserScript==
// @name           FB Wall Manager
// @namespace      MerricksdadWallManager
// @description    Manages Wall Posts for Various FB Games
// @include        http*://www.facebook.com/lists/*
// @license        http://creativecommons.org/licenses/by-nc-nd/3.0/us/
// @grant          GM_setValue
// @grant          GM_getValue
// @grant          GM_xmlhttpRequest
// @grant          GM_registerMenuCommand
// @grant          GM_addStyle
// @grant          GM_log
// @grant          GM_openInTab
// @grant          GM_getResourceURL
// @version        4.0.0.3
// @copyright      Charlie Ewing except where noted
// @require https://gf.qytechs.cn/scripts/416-wm-common-library/code/WM%20Common%20Library.user.js
// @require https://gf.qytechs.cn/scripts/417-wm-debug-console/code/WM%20Debug%20Console.user.js
// @require https://gf.qytechs.cn/scripts/418-js-forms-library-b/code/JS%20Forms%20Library%20B.user.js
// @require https://gf.qytechs.cn/scripts/419-wm-config-interface/code/WM%20Config%20Interface.user.js
// @require https://gf.qytechs.cn/scripts/6908-wm-host-object/code/WM%20Host%20Object.js
// @require https://gf.qytechs.cn/scripts/6907-wm-user-console-object/code/WM%20User%20Console%20Object.js
// @require https://gf.qytechs.cn/scripts/6906-wm-sidekick-docking-object/code/WM%20Sidekick%20Docking%20Object.js
// @require https://gf.qytechs.cn/scripts/6905-wm-collector-object/code/WM%20Collector%20Object.js
// @require https://gf.qytechs.cn/scripts/6904-wm-dynamic-grabber-object/code/WM%20Dynamic%20Grabber%20Object.js
// @require https://gf.qytechs.cn/scripts/6899-wm-test-object/code/WM%20Test%20Object.js
// @require https://gf.qytechs.cn/scripts/6898-wm-feed-manager-objects/code/WM%20Feed%20Manager%20Objects.js
// @require https://gf.qytechs.cn/scripts/6897-wm-friend-tracker-objects/code/WM%20Friend%20Tracker%20Objects.js
// @require https://gf.qytechs.cn/scripts/6896-wm-rules-manager-objects/code/WM%20Rules%20Manager%20Objects.js
// @require https://gf.qytechs.cn/scripts/6895-wm-app-object/code/WM%20App%20Object.js
// @require https://gf.qytechs.cn/scripts/6894-wm-post-object/code/WM%20Post%20Object.js
// @resource       IconSheet http://i.imgur.com/sLxzUA6.png
// ==/UserScript==

// Based on script built by Joe Simmons in Farmville Wall Manager


(function() {
//***************************************************************************************************************************************
//***** Preload
//***************************************************************************************************************************************
	//dont run in iframes
	try {
		//this does not mean we are using GM's unsafe window
		var unsafeWindow = unsafeWindow || window.wrappedJSObject || window;
		if (unsafeWindow.frameElement != null) {
			alert("unsafe window");
			return;
		}
	} catch(e) {log("preload: "+e);}

//***************************************************************************************************************************************
//***** Debug Object
//***************************************************************************************************************************************
	if (debug) { //from script WM_Debug_Console.user.js
		debug.init();
		if (debug.initialized) log("Debug Console Initialized");
	}

//***************************************************************************************************************************************
//***** Globals
//***************************************************************************************************************************************

	//returns the current date-time in unix format, not localized
	WM.__defineGetter__("currentTime",function(){try{
		return timeStamp();
	}catch(e){log("WM.currentTime: "+e);}});
	
	//returns the appID of the selected app tab on the collection panel, or 'all' if 'Show All' is selected
	WM.__defineGetter__("currentAppTab",function(){try{
		var tabCtrl=WM.console.collectTabControl;
		if (tabCtrl||null) {
			var tab = tabCtrl._selectedTab;
			if (tab||null) return tab.appFilter;
		}
		return "all";
	}catch(e){log("WM.currentAppTab: "+e);}});

	var sandbox=this;
	

//***************************************************************************************************************************************
//***** new graph functions
//***************************************************************************************************************************************
	
this.Graph={
	posts:{}, //"post_id":1 or null
	userID:null,
	userName:null,
	userAlias:null,
	
	fetchTimeout: 30,
	
	likePost: function(postObj,params){
		//detect state of like link
		var subNode = postObj.likeLink;
		if (subNode) {
			var isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?";
			if (!isLiked) {
				click(subNode);
			} else {
				//already liked
			}
			if (params.callback) params.callback(postObj);
		}
		postObj.pageNode.style.display="block";
	},
	
	unlikePost: function(postObj){
		//detect state of like link
		var subNode = postObj.likeLink;
		if (subNode) {
			var isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?";
			if (isLiked) {
				click(subNode);
			} else {
				//already not liked
			}
			if (params.callback) params.callback(postObj);
		}
		postObj.pageNode.style.display="block";
	},
	
	commentPost: function(postObj,comment){
		debug.print("commenting is disabled in WM version 4 until further notice");
		/*
		var subNode = postObj.commentLink;
		if (subNode) {
			click(subNode);
			setTimeout(function(){typeText(comment);},1000);
			
		}
		*/
	},
	
	getCurrentUser: function(params){
		var node = selectSingleNode("//img[starts-with(@id,'profile_pic_header_')]");		
		this.userID = node.id.split("profile_pic_header_")[1];
		this.userName = node.parentNode.childNodes[1].textContent; //will only get first name
		this.userAlias = node.parentNode.href.split("facebook.com/")[1];
	},
	
	validatePost: function(params){
		var post=params.post;
		var callback=params.callback;
		var isOlder=params.next;

		//log("Graph.validatePost()",{level:1});

		//exclude non-app posts and posts with no action links
		//if (!exists(post.actions||null) || !exists(post.application)) return;

		//exclude posts with less than like and comment and which have no link
		//if (!(post.actions.length>=2) || !exists(post.link)) return;
		
		var postID=post["post_id"]||post["id"];

		//exclude posts already in our repository
		if (exists(Graph.posts[postID])) return;

		//store a reference to this post
		Graph.posts[postID]=1;

		//send the post back to the callback function here
		if (callback) setTimeout(function(){callback(post,isOlder);},0);		
	},
	
	fetchPosts: function(params){		
		//reads post data from the page
		var postNodes = selectNodes("//div[starts-with(@class,'_4-u2 mbm _5jmm _5pat _5v3q') and not(contains(@class,'foundWM'))]");
											       
		//translate post dom to useable data
		var retPosts = {};
		if (postNodes.snapshotLength) {
			//debug.print (postNodes.snapshotLength + " post nodes found");
			
			for (var i=0,node;(node=postNodes.snapshotItem(i));i++) {
				
				var post = {};
				post.pageNode = node.childNodes[0].parentNode;
				
				//post id
				try{
					var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//form//input[contains(@value,'target_fbid')]",{node:node});
					post.post_id = subNode.getAttribute('value').parseJSON()['target_fbid'];
				} catch (e){
					//debug.print("cound not locate postID " + node.id);
					continue;
				}

				/*//post QID
				try{
					post.qid = post.pageNode.getAttribute('data-ft').parseJSON()['qid'];
				} catch (e){
					debug.print("cound not locate post qid " + node.id);
					//continue;
				}*/

				//from
				try{
					var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//span[contains(@class,'fwb fcg')]/a[contains(@data-hovercard,'user.php')]",{node:node});
					post.source_id = subNode.getAttribute('data-hovercard').split('user.php?id=')[1].split("&")[0];
					post.fromName = subNode.textContent;
				} catch (e){
					//debug.print("cound not locate fromID " + node.id);
					continue;
				}

					//exclude posts already in our repository
				if (Graph.posts[post.source_id+"_"+post.post_id]!=1) {

					//appID
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]",{node:node});
						post.app_id = subNode.getAttribute('data-gt').parseJSON()['appid'].toString(); 
						if (!(WM.apps[post.app_id]||null)) continue;
					} catch (e){
						//debug.print("cound not locate appID: " + node.id);
						continue;
					}

					//created time
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//abbr[contains(@class,'timestamp')]",{node:node});
						post.created_time = subNode.getAttribute('data-utime');
					} catch (e){
						//debug.print("cound not locate created time " + node.id);
						continue;
					}
									
					//message
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_5pbx userContent')]",{node:node});
						post.message = subNode.textContent;
					} catch (e){
						//debug.print("cound not locate message " + node.id);
						//continue; //don't break if this does not exist
						post.message="";
					}

					//title
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6m6')]/a",{node:node});
						post.title = subNode.textContent;
					} catch (e){
						//debug.print("cound not locate title " + node.id);
						continue;
					}
									
					//description
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6lz _6mb')]",{node:node});
						post.description = subNode.textContent;
					} catch (e){
						//debug.print("cound not locate description " + node.id);
						continue;
					}
					
					//caption
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6m7')]",{node:node});
						post.caption = subNode.textContent;
					} catch (e){
						//debug.print("cound not locate caption " + node.id);
						continue;
					}
					
					//picture
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'fbStoryAttachmentImage')]/img",{node:node});
						post.picture = subNode.src;
					} catch (e){
						//debug.print("cound not locate picture " + node.id);
						continue;
					}

					//link href
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//form//div[contains(@class,'_5pcp _5vsi')]/div/a",{node:node});
						//put our mouse over it first to force it to update link data
						mouseover(subNode);
						post.linkHref = subNode.href;
						post.linkText = subNode.textContent;
					} catch (e){
						//debug.print("cound not locate link " + node.id);
						continue;
					}

					//like button
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_5pcp _5vsi')]/div/span/a[contains(@data-reactid,'.')]",{node:node});
						post.isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?";
						post.likeLink = subNode;
					} catch (e){
						//debug.print("cound not locate likes " + node.id);
						continue;
					}
					
					//comment section
					try{
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//label[contains(@class,'uiLinkButton comment_link')]/input",{node:node});
						post.commentLink = subNode;
						
						var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_209g _2vxa')]/span/br",{node:node});
						post.commentNode = subNode;
					} catch (e){
						//debug.print("cound not locate comments " + node.id);
						continue;
					}

					
					
					node.className += " foundWM";
					if (post.isLiked) {
						post.pageNode.style.display="block";
					}
					
					//debug.print([post.app_id, post.source_id, post.post_id, post.fromName, post.created_time, post.title, post.caption, post.description, post.picture, post.linkHref, post.linkText, post.isLiked]);


					//store a reference to this post
					Graph.posts[post.source_id+"_"+post.post_id]=1;

					//send the post back to the callback function here
					params.callback(post);
				}				
				
			}
		} else {
			//debug.print ("no post nodes found");
		};
	}
	
};

Graph.getCurrentUser();

	


//***************************************************************************************************************************************
//***** Immediate
//***************************************************************************************************************************************

	log("Script: WM initialized",{level:0});

	// section for reclaiming memory and stopping memory leaks
	this.newIntv=null; //refresh interval
	this.oldIntv=null; //refresh interval
	this.procIntv=null; //process interval
	this.cleanIntv=null; //post removal interval
	this.hbIntv=null; //global heartbeat interval

	this.olderLimit=day; //default 1 day

	//mutation observer
	var observer = new MutationObserver(function(mutations) {
		//mutations.forEach(function(mutation) {
		//console.log(mutation.type);
		
		//only process new nodes if console is ready for them
		if (!WM.console.initialized) return;
		
		//when any page mutation occurs, run our post detector
		Graph.fetchPosts({
			callback:WM.validatePost
		});
	});    
	
	//cleanup function
	var cleanup=function() {try{
		//destroy intervals
		if (newIntv) window.clearInterval(newIntv);
		if (oldIntv) window.clearInterval(oldIntv);
		if (procIntv) window.clearInterval(procIntv);
		if (cleanIntv) window.clearInterval(cleanIntv);
		if (hbIntv) window.clearInterval(hbIntv);
		oldIntv = newIntv = procIntv = cleanIntv = hbIntv = null;

		//close the sidekick tabs
		WM.collector.closeAll();

		//remove this event listener
		window.removeEventListener("beforeunload", cleanup, false);
		window.removeEventListener("message", WM.receiveSidekickMessage, false);
		window.removeEventListener("resize", WM.onWindowResize, false);
		
		observer.disconnect();

		//clean up memory
		WallManager=null;
		Graph=null;
		jsForms=null;
		olderLimit=null;
		opts=null; quickOpts=null;
		
	}catch(e){log("cleanup: "+e);}}

	window.addEventListener("beforeunload", cleanup, false);
	window.addEventListener("resize", WM.onWindowResize, false);

	observer.observe(document.body,{ attributes: true, childList: true, characterData: true });
	
	addGlobalStyle(".foundWM {background-color:green; display:none;}\n","styleDebugTemp");
	
	//start it up
	WM.run();
	
})(); // anonymous function wrapper end

/* recent changes
	4.0.0.0:
		moved many object's code to their own files

	
*/

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址