Facebook User List Maker

Save and Load Friend Lists for Facebook Lists

当前为 2017-12-02 提交的版本,查看 最新版本

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