PTH User tagging

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

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