Facebook User List Maker

Save and Load Friend Lists for Facebook Lists

目前为 2017-12-07 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Facebook User List Maker
  3. // @namespace facebookuserlistmaker
  4. // @version 1.3.3
  5. // @author Tophness
  6. // @match http://www.facebook.com/*
  7. // @match https://www.facebook.com/*
  8. // @description Save and Load Friend Lists for Facebook Lists
  9. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_deleteValue
  13. // @grant GM_listValues
  14. // @run-at document-idle
  15. // ==/UserScript==
  16.  
  17. var friendsSelector = 'div[id$="_friends"]';
  18. var friendsSelector2 = 'div[class="uiScrollableAreaContent"]';
  19. var storySelector = 'div[id^="friends_"]';
  20. var storySelector2 = 'div[data-testid="friend_list_item"]';
  21. var storySelector3 = 'a[data-hovercard]';
  22. var users = [];
  23. var friendsel;
  24. var mutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  25.  
  26. function includes(k) {
  27. for(var i=0; i < this.length; i++){
  28. if( this[i].name === k || ( this[i].name !== this[i] && k !== k ) ){
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34.  
  35. function block(story) {
  36. if (!story) {
  37. return;
  38. }
  39. if (story.getElementsByTagName('a').length) {
  40. var links = story.getElementsByTagName('a');
  41. for (var i = 0; i < links.length; i++) {
  42. if(links[i].outerHTML.indexOf('data-hovercard') != -1){
  43. var uname = links[i].innerText;
  44. var uid = links[i].getAttribute('data-hovercard');
  45. uid = uid.substring(uid.indexOf('id=') + 3);
  46. if(uid.indexOf('&') == -1){
  47. uid = uid.substring(0, uid.indexOf('"'));
  48. }
  49. else{
  50. uid = uid.substring(0, uid.indexOf('&'));
  51. }
  52. if(uname != ""){
  53. var newuser = {};
  54. newuser.name = uname;
  55. newuser.id = uid;
  56. if(!users.includes(newuser.name)){
  57. users.push(newuser);
  58. }
  59. }
  60. }
  61. }
  62. }
  63. }
  64.  
  65. function block2(link){
  66. if(link.outerHTML.indexOf('data-hovercard') != -1){
  67. var uname = link.innerText;
  68. var uid = link.getAttribute('uid');
  69. if(uname != ""){
  70. var newuser = {};
  71. newuser.name = uname;
  72. if(uid){
  73. newuser.id = uid;
  74. }
  75. else{
  76. uid = link.getAttribute('data-hovercard');
  77. uid = uid.substring(uid.indexOf('id=') + 3);
  78. if(uid.indexOf('&') == -1){
  79. uid = uid.substring(0, uid.indexOf('"'));
  80. }
  81. else{
  82. uid = uid.substring(0, uid.indexOf('&'));
  83. }
  84. newuser.id = uid;
  85. }
  86. if(!users.includes(newuser.name)){
  87. users.push(newuser);
  88. }
  89. }
  90. }
  91. }
  92.  
  93. function process() {
  94. if(document.forms.save.dosave.value == "true" && document.forms.save.listname.value != ""){
  95. var stories = document.querySelector(friendsSelector);
  96. if (!stories) {
  97. return;
  98. }
  99. var story = stories.querySelectorAll(storySelector);
  100. if (!story.length) {
  101. story = stories.querySelectorAll(storySelector2);
  102. if (!story.length) {
  103. return;
  104. }
  105. }
  106. for (var i2 = 0; i2 < story.length; i2++) {
  107. block(story[i2]);
  108. }
  109. GM_setValue(document.forms.save.listname.value, JSON.stringify(users));
  110. }
  111. }
  112.  
  113. function processpage() {
  114. if(document.forms.save.dosave.value == "true" && document.forms.save.listname.value != ""){
  115. var stories = friendssel;
  116. if (!stories || stories == 'div[class="uiScrollableAreaContent"]'){
  117. return;
  118. }
  119. var story = stories.querySelectorAll(storySelector3);
  120. if (!story.length) {
  121. return;
  122. }
  123. for (var i2 = 0; i2 < story.length; i2++) {
  124. block2(story[i2]);
  125. }
  126. GM_setValue(document.forms.save.listname.value, JSON.stringify(users));
  127. }
  128. }
  129.  
  130. function waitForEl(selector, callback, timer=100){
  131. var poller1 = setInterval(function(){
  132. $jObject = jQuery(selector);
  133. if($jObject.length < 1){
  134. return;
  135. }
  136. clearInterval(poller1);
  137. callback($jObject);
  138. },timer);
  139. }
  140.  
  141. function uToken(username, id){
  142. var newdiv = document.createElement('span');
  143. newdiv.className = "removable uiToken";
  144. var newdiv2 = document.createElement('span');
  145. newdiv2.className = "uiTokenText";
  146. newdiv2.innerHTML = username;
  147. var newdiv3 = document.createElement('input');
  148. newdiv3.name="members[]";
  149. newdiv3.autocomplete="off";
  150. newdiv3.type="hidden";
  151. newdiv3.value = id;
  152. var newdiv4 = document.createElement('input');
  153. newdiv4.value=username;
  154. newdiv4.name="text_members[]";
  155. newdiv4.autocomplete="off";
  156. newdiv4.type="hidden";
  157. var newdiv5 = document.createElement('a');
  158. newdiv5.href="#";
  159. newdiv5.aria_label="Remove " + username;
  160. newdiv5.className="remove uiCloseButton uiCloseButtonSmall";
  161. newdiv.appendChild(newdiv4);
  162. newdiv.appendChild(newdiv3);
  163. newdiv.appendChild(newdiv2);
  164. document.getElementById('fbFriendListTokenizer').getElementsByClassName('tokenarea')[0].appendChild(newdiv);
  165. }
  166.  
  167. function listpaste(){
  168. if(document.getElementById('createListMembers')){
  169. if(document.getElementById('createListname') && document.forms.load.listnames.value){
  170. document.getElementById('createListname').value = document.forms.load.listnames.value;
  171. }
  172. if(document.getElementById('fbFriendListTokenizer').getElementsByClassName('tokenarea')[0]){
  173. document.getElementById('fbFriendListTokenizer').getElementsByClassName('tokenarea')[0].className = "tokenarea";
  174. }
  175. for (var i = 0; i < users.length; i++) {
  176. uToken(users[i].name, users[i].id);
  177. }
  178. }
  179. else{
  180. setTimeout(listpaste, 1000);
  181. }
  182. }
  183.  
  184. function observebody(){
  185. if(document.forms.save.dosave.value == "true"){
  186. var listname = document.forms.save.listname.value.toLowerCase().replace(/[^a-zA-Z0-9]+/g, "");
  187. users = JSON.parse(GM_getValue(listname, "[]"));
  188. if(!users){
  189. console.warn("error");
  190. }
  191. users.includes = includes;
  192. if(location.href.indexOf('/community') != -1 || location.href.indexOf('/events') != -1){
  193. processpage();
  194. }
  195. else{
  196. process();
  197. }
  198. }
  199. else{
  200. setTimeout(observebody, 1000);
  201. }
  202. }
  203.  
  204. function loadbegin(){
  205. if(document.forms.load.doload.value == "true"){
  206. users = JSON.parse(GM_getValue(document.forms.load.listnames.value, "[]"));
  207. if(!users){
  208. console.warn("error");
  209. }
  210. users.includes = includes;
  211. if(contentarea.getElementsByClassName('uiHeaderActions')[0].childNodes[0]){
  212. contentarea.getElementsByClassName('uiHeaderActions')[0].childNodes[0].addEventListener('click', listpaste, false);
  213. contentarea.getElementsByClassName('uiHeaderActions')[0].childNodes[0].click();
  214. }
  215. }
  216. else if(document.forms.load.dodelete.value == "true"){
  217. var select = document.forms.load.listnames;
  218. GM_deleteValue(select.value);
  219. dvalue = select.selectedIndex;
  220. select.removeChild(select[dvalue]);
  221. }
  222. else{
  223. setTimeout(loadbegin, 1000);
  224. }
  225. }
  226.  
  227. function loadfindpage(el){
  228. var savebut = document.createElement('div');
  229. savebut.innerHTML = '<form name="save"><input type=button onclick="document.forms.save.dosave.value=true;" value="Save List"><input type=text name=listname><input type=hidden name=dosave value="false"></form>';
  230. el.insertAdjacentElement('afterbegin', savebut);
  231. var observer = new mutationObserver(processpage);
  232. observer.observe(document.querySelector('body'), {
  233. 'childList': true,
  234. 'subtree': true
  235. });
  236. observebody();
  237. }
  238.  
  239. function findpage(){
  240. var divs = document.querySelectorAll(friendsSelector2);
  241. var found = false;
  242. for (var i = 0; i < divs.length; ++i) {
  243. if(divs[i].querySelectorAll(storySelector3).length){
  244. friendssel = divs[i];
  245. found = true;
  246. }
  247. }
  248. if(found){
  249. loadfindpage(friendssel);
  250. }
  251. else{
  252. setTimeout(findpage, 1000);
  253. }
  254. }
  255.  
  256. if(location.href.indexOf('bookmarks/lists') != -1){
  257. var contentarea = document.getElementById('contentArea');
  258. waitForEl(contentarea, function() {
  259. var loadbut = document.createElement('div');
  260. loadbut.innerHTML = '<form name="load"><input type=button onclick="document.forms.load.doload.value=true;" value="Load List"><input type=hidden name=doload value="false"><input type=hidden name=dodelete value="false"><input type=button onclick="document.forms.load.dodelete.value=true;" value="Delete List"></form>';
  261. var x = document.createElement("select");
  262. x.name="listnames";
  263. var alllists = GM_listValues();
  264. for (var i = 0; i < alllists.length; i++) {
  265. var option = document.createElement("option");
  266. option.text = alllists[i];
  267. x.add(option);
  268. }
  269. contentarea.insertAdjacentElement('afterbegin', loadbut);
  270. document.forms.load.appendChild(x);
  271. loadbegin();
  272. });
  273. }
  274. else if(location.href.indexOf('/friends') != -1){
  275. waitForEl(document.querySelector(friendsSelector), function() {
  276. var savebut = document.createElement('div');
  277. savebut.innerHTML = '<form name="save"><input type=button onclick="document.forms.save.dosave.value=true;" value="Save List"><input type=text name=listname><input type=hidden name=dosave value="false"></form>';
  278. document.querySelector(friendsSelector).insertAdjacentElement('afterbegin', savebut);
  279. var observer = new mutationObserver(process);
  280. observer.observe(document.querySelector('body'), {
  281. 'childList': true,
  282. 'subtree': true
  283. });
  284. observebody();
  285. },500);
  286. }
  287. else{
  288. findpage();
  289. }