PTH User tagging

Tag, ignore, highlight, and change avatars for users on PTH

目前为 2017-01-08 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name PTH User tagging
  3. // @version 0.7
  4. // @description Tag, ignore, highlight, and change avatars for users on PTH
  5. // @author Chameleon
  6. // @include http*://passtheheadphones.me/*
  7. // @grant none
  8. // @namespace https://greasyfork.org/users/87476
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. window.setTimeout(checkHeight.bind(undefined, document.body.clientHeight), 800);
  15.  
  16. if(window.location.href.indexOf('user.php?id=') != -1)
  17. {
  18. var username=document.getElementsByTagName('h2')[0].getElementsByTagName('a')[0].textContent;
  19. var a=document.createElement('a');
  20. a.innerHTML = '[User tags]';
  21. a.href='javascript:void(0);';
  22. a.addEventListener('click', openTags.bind(undefined, username, undefined), false);
  23. document.getElementsByClassName('linkbox')[0].appendChild(a);
  24. }
  25.  
  26. var posts=document.getElementsByClassName('forum_post');
  27. for(var i=0; i<posts.length; i++)
  28. {
  29. var p=posts[i];
  30. if(p.getAttribute('class').indexOf('preview_wrap') != -1)
  31. continue;
  32. var links=p.getElementsByTagName('td')[0].firstElementChild;
  33. var username=p.getElementsByTagName('strong')[0].getElementsByTagName('a')[0].textContent;
  34.  
  35. var a=document.createElement('a');
  36. a.href='javascript:void(0);';
  37. a.innerHTML='Tag';
  38. a.setAttribute('class', 'brackets');
  39. a.addEventListener('click', openTags.bind(undefined, username, p), false);
  40. links.appendChild(document.createTextNode(' - '));
  41. links.appendChild(a);
  42.  
  43. var img=p.getElementsByTagName('img')[0];
  44. if(img)
  45. {
  46. img.setAttribute('originalAvatar', img.src);
  47. }
  48. }
  49. /*
  50. var avatars=document.getElementsByClassName('avatar');
  51. for(var i=0; i<avatars.length; i++)
  52. {
  53. var avatar=avatars[i];
  54. addTagLinks(avatar);
  55. var img=avatar.getElementsByTagName('img')[0];
  56. if(img)
  57. {
  58. img.setAttribute('originalAvatar', img.src);
  59. }
  60. }*/
  61.  
  62. addTags();
  63. })();
  64.  
  65.  
  66. function checkHeight(height)
  67. {
  68. if(height != document.body.clientHeight)
  69. {
  70. pageResized();
  71. }
  72.  
  73. window.setTimeout(checkHeight.bind(undefined, document.body.clientHeight), 800);
  74. }
  75. /*
  76. function addTagLinks(avatar)
  77. {
  78. var tags=getTags();
  79.  
  80. var postTable=avatar.parentNode;
  81. while(postTable.tagName != 'TABLE')
  82. postTable=postTable.parentNode;
  83. if(postTable.getAttribute('id') == 'preview_wrap_0')
  84. return;
  85. var username=postTable.getElementsByTagName('strong')[0].textContent;
  86.  
  87. var id=postTable.getAttribute('id').split('post')[1];
  88.  
  89. var a=document.createElement('a');
  90. a.setAttribute('class', 'tagLink');
  91. a.setAttribute('postId', id);
  92. var place = avatar.getBoundingClientRect();
  93. var style='position: absolute; z-index: 50000000; top: '+(place.top+window.scrollY)+'px; left: '+(place.left+window.scrollX)+'px; width: '+avatar.clientWidth+'px;';
  94. style+='text-align: center; color: blue; background: rgba(200,200,200,0.8); border-radius: 0px 0px 10px 10px;';
  95. a.setAttribute('style', style);
  96.  
  97. a.innerHTML = 'Show user tags';
  98. a.href='javascript:void(0);';
  99. a.addEventListener('click', openTags.bind(undefined, username, postTable), false);
  100. document.body.appendChild(a);
  101. a.style.display='none';
  102.  
  103. avatar.addEventListener('mouseover', mouseOver.bind(undefined, a), false);
  104. avatar.addEventListener('mouseout', mouseOut.bind(undefined, avatar, a), false);
  105. }
  106. */
  107. function pageResized()
  108. {
  109. /*var tagLinks=document.getElementsByClassName('tagLink');
  110. for(var i=0; i<tagLinks.length; i++)
  111. {
  112. var t=tagLinks[i];
  113. var id=t.getAttribute('postId');
  114. var postTable=document.getElementById('post'+id);
  115. var avatar=postTable.getElementsByClassName('avatar')[0];
  116.  
  117. var place = avatar.getBoundingClientRect();
  118. var style='position: absolute; z-index: 50000000; top: '+(place.top+window.scrollY)+'px; left: '+(place.left+window.scrollX)+'px; width: '+avatar.clientWidth+'px;';
  119. style+='text-align: center; color: blue; background: rgba(200,200,200,0.8); border-radius: 0px 0px 10px 10px;';
  120. t.setAttribute('style', style);
  121. t.style.display='none';
  122. }*/
  123.  
  124. resetTags();
  125. addTags();
  126. }
  127.  
  128. function resetTags()
  129. {
  130. var ignoredQuotes=document.getElementsByClassName('toggleQuote');
  131. for(var i=0; i<ignoredQuotes.length; i++)
  132. {
  133. var ig=ignoredQuotes[i];
  134. ig.nextElementSibling.style.display='';
  135. ig.parentNode.removeChild(ig);
  136. }
  137.  
  138. var posts=document.getElementsByClassName('forum_post');
  139. for(var i=0; i<posts.length-1; i++)
  140. {
  141. var p=posts[i];
  142. var avatar=p.getElementsByClassName('avatar')[0];
  143.  
  144. var postTable=p;
  145.  
  146. if(postTable.getAttribute('id') == 'preview_wrap_0')
  147. continue;
  148. var u=postTable.getElementsByTagName('strong')[0].getElementsByTagName('a')[0];
  149. var username=u.textContent;
  150.  
  151.  
  152. var c=postTable.getElementsByClassName('user_title');
  153. if(c.length > 0)
  154. {
  155. var orig=c[0].getAttribute('original');
  156. if(orig)
  157. c[0].innerHTML=orig;
  158. }
  159.  
  160. if(avatar)
  161. {
  162. var img=avatar.getElementsByTagName('img')[0];
  163. if(img)
  164. {
  165. var orig=img.getAttribute('originalAvatar');
  166. if(orig)
  167. img.src=img.getAttribute('originalAvatar');
  168. }
  169. }
  170. u.setAttribute('style', '');
  171. postTable.setAttribute('style', '');
  172. postTable.getElementsByTagName('tr')[1].style.display='';
  173. var id=postTable.getAttribute('id').split('post')[1];
  174. var tag=document.getElementById('tag'+id);
  175. if(tag)
  176. tag.parentNode.removeChild(tag);
  177. }
  178. var hardIgnores=document.getElementsByClassName('hardIgnoreLink');
  179. for(var i=0; i<hardIgnores.length; i++)
  180. {
  181. var h=hardIgnores[i];
  182. h.parentNode.removeChild(h);
  183. }
  184. }
  185.  
  186. function addTags()
  187. {
  188. var quotes=document.getElementsByTagName('blockquote');
  189. for(var i=0; i<quotes.length; i++)
  190. {
  191. var q=quotes[i];
  192. var username = q.previousElementSibling;
  193. if(username)
  194. {
  195. username=username.textContent.split(' ')[0];
  196. var user=getUser(username)[0];
  197. if(user.softIgnore || user.hardIgnore)
  198. {
  199. var a=document.createElement('a');
  200. a.href='javascript:void(0);';
  201. a.textContent='<Ignored>';
  202. a.addEventListener('click', toggleQuote.bind(undefined, a, q), false);
  203. a.setAttribute('class', 'toggleQuote');
  204. q.parentNode.insertBefore(a, q);
  205. if(q.getAttribute('unIgnored')=="true")
  206. {
  207. a.textContent='Ignore';
  208. }
  209. else
  210. q.style.display='none';
  211. }
  212. }
  213. }
  214.  
  215. var posts=document.getElementsByClassName('forum_post');
  216. for(var i=0; i<posts.length-1; i++)
  217. {
  218. var p=posts[i];
  219. var avatar=p.getElementsByClassName('avatar')[0];
  220.  
  221. var postTable=p;
  222.  
  223. if(postTable.getAttribute('id') == 'preview_wrap_0')
  224. continue;
  225. var u=postTable.getElementsByTagName('strong')[0].getElementsByTagName('a')[0];
  226. var username=u.textContent;
  227.  
  228. var user=getUser(username)[0];
  229. if(user.replacementAvatar && avatar)
  230. {
  231. avatar.getElementsByTagName('img')[0].src=user.replacementAvatar;
  232. }
  233. if(user.usernameColour)
  234. {
  235. var style=u.getAttribute('style');
  236. if(!style)
  237. style='';
  238. u.setAttribute('style', style+' color: '+user.usernameColour+';');
  239. }
  240. if(user.postHighlight)
  241. {
  242. var style=postTable.getAttribute('style');
  243. postTable.setAttribute('style', 'box-shadow: '+user.postHighlight+' 0 0 5px 1px !important;');
  244. }
  245. if(user.customTitle)
  246. {
  247. var c=postTable.getElementsByClassName('user_title');
  248. if(c.length > 0)
  249. c=c[0];
  250. else
  251. {
  252. c=document.createElement('span');
  253. c.setAttribute('class', 'user_title');
  254. var before=postTable.getElementsByClassName('time')[0];
  255. before.parentNode.insertBefore(c, before);
  256. }
  257. if(!c.getAttribute('original'))
  258. c.setAttribute('original', c.innerHTML);
  259.  
  260. c.innerHTML='('+user.customTitle+')';
  261. }
  262. if(user.tag && user.showTag)
  263. {
  264. var div=document.createElement('div');
  265. var id=postTable.getAttribute('id').split('post')[1];
  266. div.setAttribute('id', 'tag'+id);
  267. div.innerHTML = user.tag.replace(/\n/g,'<br />')+' ';
  268. if(!user.showTagInHeader)
  269. {
  270. var before=document.getElementById('bar'+id).firstElementChild;
  271. before.parentNode.insertBefore(div, before);
  272. div.setAttribute('style', 'display: inline-block; margin-right: 5px;');
  273. div.setAttribute('class', 'r10');
  274. }
  275. else
  276. {
  277. var first;
  278. if(!avatar)
  279. {
  280. avatar=postTable;
  281. first=avatar;
  282. }
  283. else
  284. first=avatar.firstElementChild;
  285. var place = postTable.getBoundingClientRect();
  286. var width=300;
  287. var left=place.left+window.scrollX-width-20;
  288. if(left<0)
  289. left=0;
  290. var style='position: absolute; z-index: 1001; top: '+(place.top+window.scrollY)+'px; left: '+left+'px; max-width: '+width+'px; text-align: center; color: white; background: rgba(20,20,20,0.7); border-radius: 20px 0px 0px 20px;';
  291. style+='font-size: large; box-shadow: inset '+(user.postHighlight ? user.postHighlight : 'black')+' 0 0 20px 0; padding: 10px;';
  292. div.setAttribute('style', style);
  293. document.body.appendChild(div);
  294. var avatarHeight=first.clientHeight;
  295. var top=place.top+window.scrollY+((avatarHeight-div.clientHeight)/2);
  296. div.style.top=top+'px';
  297. if(div.clientWidth < width)
  298. {
  299. left=place.left+window.scrollX-div.clientWidth;
  300. if(left<0)
  301. left=0;
  302. div.style.left=left+'px';
  303. }
  304. }
  305. }
  306. if(user.softIgnore)
  307. {
  308. postTable.getElementsByTagName('tr')[1].style.display='none';
  309. }
  310. if(user.hardIgnore)
  311. {
  312. var a=document.createElement('a');
  313. var hr=document.createElement('hr');
  314. hr.setAttribute('title', username);
  315. a.appendChild(hr);
  316. a.setAttribute('class', 'hardIgnoreLink');
  317. a.href=postTable.getElementsByTagName('strong')[0].getElementsByTagName('a')[0].href;
  318. postTable.parentNode.insertBefore(a, postTable);
  319. postTable.style.display='none';
  320. }
  321. }
  322. }
  323.  
  324. function toggleQuote(a, q)
  325. {
  326. if(a.innerHTML.indexOf('Ignored') != -1)
  327. {
  328. a.textContent = 'Ignore';
  329. q.style.display='';
  330. q.setAttribute('unIgnored', "true");
  331. }
  332. else
  333. {
  334. a.textContent = '<Ignored>';
  335. q.style.display='none';
  336. q.setAttribute('unIgnored', "false");
  337. }
  338. }
  339.  
  340. function openTags(username, postTable)
  341. {
  342. var div=document.getElementById('chameleonTagsDiv');
  343. if(!div)
  344. {
  345. div=document.createElement('div');
  346. div.setAttribute('id', 'chameleonTagsDiv');
  347. document.body.appendChild(div);
  348. div.setAttribute('style', 'position: fixed; top: 20px; margin: auto; left: 0; right: 0; text-align: center; background: rgba(0,0,0,0.7); color: white; width: 80%; z-index: 1000;');
  349. }
  350. div.innerHTML = '<h2>'+username+'\'s Tags<br />';
  351.  
  352. var user=getUser(username)[0];
  353.  
  354. var input=document.createElement('input');
  355. div.appendChild(input);
  356. input.placeholder='Replacement avatar URL';
  357. input.value = user.replacementAvatar ? user.replacementAvatar : '';
  358. input.addEventListener('change', changeTags.bind(undefined, div, username, postTable, input), false);
  359.  
  360. div.appendChild(document.createElement('br'));
  361.  
  362. var input=document.createElement('input');
  363. div.appendChild(input);
  364. input.placeholder='Replacement custom title';
  365. input.value = user.customTitle ? user.customTitle : '';
  366. input.addEventListener('change', changeTags.bind(undefined, div, username, postTable, input), false);
  367.  
  368. div.appendChild(document.createElement('br'));
  369.  
  370. var input=document.createElement('input');
  371. div.appendChild(input);
  372. input.placeholder='Post highlight colour';
  373. input.value = user.postHighlight ? user.postHighlight : '';
  374. input.addEventListener('change', changeTags.bind(undefined, div, username, postTable, input), false);
  375.  
  376. div.appendChild(document.createElement('br'));
  377.  
  378. var input=document.createElement('input');
  379. div.appendChild(input);
  380. input.placeholder='Username colour';
  381. input.value = user.usernameColour ? user.usernameColour : '';
  382. input.addEventListener('change', changeTags.bind(undefined, div, username, postTable, input), false);
  383.  
  384. div.appendChild(document.createElement('br'));
  385.  
  386. var input=document.createElement('textarea');
  387. input.setAttribute('id', 'tagTextarea');
  388. div.appendChild(input);
  389. input.setAttribute('style', 'text-align: center; border: none;');
  390. input.placeholder='Tag';
  391. input.value = user.tag ? user.tag : '';
  392. resize('tagTextarea');
  393. input.addEventListener('keyup', resize.bind(undefined, 'tagTextarea'), false);
  394. input.addEventListener('change', changeTags.bind(undefined, div, username, postTable, input), false);
  395.  
  396. div.appendChild(document.createElement('br'));
  397.  
  398. var a=document.createElement('a');
  399. div.appendChild(a);
  400. a.innerHTML = 'Show tag: '+(user.showTag ? 'On' : 'Off');
  401. a.href='javascript:void(0);';
  402. a.addEventListener('click', changeTags.bind(undefined, div, username, postTable, a), false);
  403.  
  404. div.appendChild(document.createElement('br'));
  405.  
  406. var a=document.createElement('a');
  407. div.appendChild(a);
  408. a.innerHTML = 'Show tag left of avatar: '+(user.showTagInHeader ? 'On' : 'Off');
  409. a.href='javascript:void(0);';
  410. a.addEventListener('click', changeTags.bind(undefined, div, username, postTable, a), false);
  411.  
  412. div.appendChild(document.createElement('br'));
  413.  
  414. var a=document.createElement('a');
  415. div.appendChild(a);
  416. a.innerHTML = 'Soft ignore: '+(user.softIgnore ? 'On' : 'Off');
  417. a.href='javascript:void(0);';
  418. a.addEventListener('click', changeTags.bind(undefined, div, username, postTable, a), false);
  419.  
  420. div.appendChild(document.createElement('br'));
  421.  
  422. var a=document.createElement('a');
  423. div.appendChild(a);
  424. a.innerHTML = 'Hard ignore: '+(user.hardIgnore ? 'On' : 'Off');
  425. a.href='javascript:void(0);';
  426. a.addEventListener('click', changeTags.bind(undefined, div, username, postTable, a), false);
  427.  
  428. div.appendChild(document.createElement('br'));
  429.  
  430. var a=document.createElement('a');
  431. div.appendChild(a);
  432. a.innerHTML = 'Save';
  433. a.href='javascript:void(0);';
  434. a.addEventListener('click', saveAndClose.bind(undefined, div, username, postTable), false);
  435. }
  436.  
  437. function changeTags(div, username, table, a)
  438. {
  439. var user=getUser(username);
  440. var index=user[1];
  441. user=user[0];
  442.  
  443. var inputs=div.getElementsByTagName('input');
  444. user.replacementAvatar = inputs[0].value;
  445. user.customTitle = inputs[1].value;
  446. user.postHighlight = inputs[2].value;
  447. user.usernameColour = inputs[3].value;
  448.  
  449. var textareas=div.getElementsByTagName('textarea');
  450. user.tag=textareas[0].value;
  451.  
  452. var as=div.getElementsByTagName('a');
  453. if(as[0] == a)
  454. {
  455. if(a.innerHTML.indexOf('On') != -1)
  456. user.showTag=false;
  457. else
  458. user.showTag=true;
  459. }
  460. if(as[1] == a)
  461. {
  462. if(a.innerHTML.indexOf('On') != -1)
  463. user.showTagInHeader=false;
  464. else
  465. user.showTagInHeader=true;
  466. }
  467. if(as[2] == a)
  468. {
  469. if(a.innerHTML.indexOf('On') != -1)
  470. user.softIgnore=false;
  471. else
  472. user.softIgnore=true;
  473. }
  474. if(as[3] == a)
  475. {
  476. if(a.innerHTML.indexOf('On') != -1)
  477. user.hardIgnore=false;
  478. else
  479. user.hardIgnore=true;
  480. }
  481.  
  482. var tags=getTags();
  483. if(index != -1)
  484. tags[index]=user;
  485. else
  486. {
  487. user.username=username;
  488. tags.push(user);
  489. }
  490. window.localStorage.userTags = JSON.stringify(tags);
  491.  
  492. openTags(username, table);
  493. }
  494.  
  495. function saveAndClose(div, username, table)
  496. {
  497. resetTags();
  498. addTags();
  499. div.parentNode.removeChild(div);
  500. }
  501.  
  502. /*
  503. function mouseOver(a)
  504. {
  505. a.style.display = 'initial';
  506. }
  507.  
  508. function mouseOut(avatar, a, event)
  509. {
  510. if(event.relatedTarget == avatar || event.relatedTarget == a)
  511. return;
  512. a.style.display = 'none';
  513. }*/
  514.  
  515. function getUser(username)
  516. {
  517. var tags=getTags();
  518. for(var i=0; i<tags.length; i++)
  519. {
  520. var t=tags[i];
  521. if(t.username === username)
  522. return [t, i];
  523. }
  524. return [{}, -1];
  525. }
  526.  
  527. function getTags()
  528. {
  529. var tags = window.localStorage.userTags;
  530. if(!tags)
  531. {
  532. tags = [];
  533. }
  534. else
  535. tags = JSON.parse(tags);
  536. return tags;
  537. }