TorViet Shoutbox Enhancer

A small script to tweak the shoutbox

目前为 2015-06-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TorViet Shoutbox Enhancer
  3. // @namespace http://torviet.com/userdetails.php?id=1662
  4. // @version 0.6.2
  5. // @license http://www.wtfpl.net/txt/copying/
  6. // @homepageURL https://github.com/S-a-l-a-d/TorViet-Shoutbox-Enhancer
  7. // @supportURL https://github.com/S-a-l-a-d/TorViet-Shoutbox-Enhancer/issues
  8. // @icon http://torviet.com/pic/salad.png
  9. // @description A small script to tweak the shoutbox
  10. // @author Salad
  11. // @match http://torviet.com/qa.php*
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_deleteValue
  15. // @grant GM_addStyle
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. // First let's get the elements which we will work on.
  20. var boxHead = document.getElementById('boxHead'),
  21. marquee = document.getElementsByClassName('marquee')[0],
  22. sltTheme = document.getElementById('sltTheme'),
  23. clock = document.getElementById('clock'),
  24. inputSection = document.getElementsByClassName('input-section')[0],
  25. idQuestion = document.getElementById('idQuestion'),
  26. navigationPage = document.getElementsByClassName('navigation_page')[0],
  27. emoGroup = document.getElementById('emogroup'),
  28. emoGroupDetail = document.getElementsByClassName('emo-group-detail')[0];
  29.  
  30. // Also create a namespace.
  31. var EMOTICON = (function() {
  32. var emoList = GM_getValue('emoList'),
  33. emoHtml = '';
  34.  
  35. var promptForEmoList = function(action, list) {
  36. var message = 'Chọn bộ emoticon bạn muốn' + ' ' + action + ':\n',
  37. answer;
  38.  
  39. for (var i = 0, len = list.length; i < len; i++) {
  40. message += i + 1 + '. ' + list[i] + '\n';
  41. }
  42. message += 'Điền tên bộ emoticon, ngăn cách bằng dấu phẩy, phân biệt hoa/thường.' + ' ' +
  43. 'Có thể điền emoticon đơn bằng cách điền tên tập tin emoticon đó.\nVí dụ: Voz,707,Rage';
  44.  
  45. do {
  46. answer = prompt(message);
  47. }
  48. while (!answer || answer.trim() === '');
  49.  
  50. return answer.replace(/\s+/g, '').split(',');
  51. };
  52. var initemoList = function() {
  53. emoList = promptForEmoList('sử dụng');
  54. GM_setValue('emoList', emoList);
  55. };
  56. var requestEmoticons = function(groupName) {
  57. var request = new XMLHttpRequest();
  58. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  59. * Using synchronous request here is the simplest implementation to make it work. *
  60. * This process is fast enough so the user will hardly notice the unresponsive moment *
  61. * while the browser is sending the request and receiving the response. *
  62. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  63. request.open('POST', 'qa_smiley_ajax.php', false);
  64. request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  65. request.onreadystatechange = function() {
  66. request.readyState == 4 && request.status == 200 &&
  67. (emoHtml = JSON.parse(request.responseText).str);
  68. };
  69. request.send('group=' + groupName);
  70. };
  71. var makeEmoticonHtml = function(emoName) {
  72. emoHtml = '<div style="height:43px;width:43px;float:left;display:inline-block;margin:1px;">' +
  73. '<a style="margin: 0;" class="btuEmotion" alt="[em' + emoName +
  74. ']"><img style="max-width: 43px; max-height: 43px" src="/pic/smilies/' + emoName +
  75. '.gif" alt=""></a></div>';
  76. };
  77.  
  78. return {
  79. checkemoList: function() {
  80. !emoList && initemoList();
  81. },
  82. add: function() {
  83. var emoGroupRemain = [];
  84. for (var i = 0, options = emoGroup.options, len = options.length; i < len; i++) {
  85. (emoList.indexOf(options[i].text) === -1) &&
  86. emoGroupRemain.push(options[i].text);
  87. }
  88.  
  89. var emoListToAdd = promptForEmoList('thêm', emoGroupRemain);
  90. for (var i = 0, len = emoListToAdd.length; i < len; i++) {
  91. (emoList.indexOf(emoListToAdd[i]) === -1) &&
  92. emoList.push(emoListToAdd[i]);
  93. }
  94.  
  95. GM_setValue('emoList', emoList);
  96. location.href = 'qa.php';
  97. },
  98. remove: function() {
  99. var emoListToRemove = promptForEmoList('xóa', emoList);
  100. for (var i = 0, len = emoListToRemove.length; i < len; i++) {
  101. var index = emoList.indexOf(emoListToRemove[i]);
  102. (index > -1) && emoList.splice(index, 1);
  103. }
  104.  
  105. GM_setValue('emoList', emoList);
  106. location.href = 'qa.php';
  107. },
  108. clear: function() {
  109. GM_deleteValue('emoList');
  110. location.href = 'qa.php';
  111. },
  112. getEmoticons: function(groupName) {
  113. requestEmoticons(groupName);
  114. return emoHtml;
  115. },
  116. generateEmoticons: function(emoName) {
  117. makeEmoticonHtml(emoName);
  118. return emoHtml;
  119. },
  120. addEmosToEmoGroup: function() {
  121. emoGroupDetail.innerHTML = '';
  122. for (var i = 0, len = emoList.length; i < len; i++) {
  123. emoGroupDetail.innerHTML += isNaN(emoList[i]) ?
  124. this.getEmoticons(emoList[i]) :
  125. this.generateEmoticons(emoList[i]);
  126. }
  127. },
  128. addEmoGroupEvent: function() {
  129. // Let's add click events for the newly added emoticons.
  130. for (var i = 0, emos = emoGroupDetail.childNodes, len = emos.length; i < len; i++)
  131. emos[i].addEventListener('click', function(e) {
  132. idQuestion.value += e.target.parentNode.getAttribute('alt');
  133. idQuestion.focus();
  134. });
  135. }
  136. };
  137. })();
  138.  
  139. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  140. * Now remove the unnecessary elements including the box containing new torrents *
  141. * and football news, the warning, the theme drop-down list and the clock. *
  142. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  143. boxHead.parentNode.removeChild(boxHead);
  144. marquee.parentNode.removeChild(marquee);
  145. sltTheme.parentNode.removeChild(sltTheme);
  146. clock.innerHTML = '';
  147.  
  148. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  149. * Here we get the window height of the current window size and the height *
  150. * without the input section and the div holding the navigation. *
  151. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  152. var windowHeight = window.innerHeight,
  153. remainingHeight = inputSection.parentNode.offsetHeight + navigationPage.offsetHeight - 100;
  154.  
  155. // And polish things with our custom CSS.
  156. GM_addStyle(
  157. '.all-wrapper {' +
  158. ' background-image: none !important;' +
  159. ' height : ' + windowHeight + 'px;' +
  160. ' margin : auto;' +
  161. '}' +
  162. '.all-wrapper > :nth-child(2) {' +
  163. ' padding: 0 !important;' +
  164. '}' +
  165. '.navigation_page {' +
  166. ' width: auto;' +
  167. '}' +
  168. '#boxQuestion {' +
  169. ' height: ' + (windowHeight - remainingHeight) + 'px;' +
  170. '}' +
  171. '.q-head {' +
  172. ' border-radius: 0;' +
  173. '}' +
  174. '#clock {' +
  175. ' height : 72px;' +
  176. ' text-align: center;' +
  177. '}' +
  178. '#emo-section, .slimScrollDiv, .emo-group-detail {' +
  179. ' height : ' + (windowHeight - remainingHeight - 72 - 6) + 'px !important;' +
  180. ' padding: 0 !important;' +
  181. '}'
  182. );
  183.  
  184. var toBeAppendedToClock = document.createDocumentFragment(),
  185. someText = document.createElement('span'),
  186. btnAdd = document.createElement('input'),
  187. btnRemove = document.createElement('input'),
  188. btnClear = document.createElement('input');
  189.  
  190. someText.innerHTML = 'For custom emoticon group<br />';
  191.  
  192. btnAdd.type = 'button';
  193. btnAdd.value = 'Add';
  194. btnAdd.addEventListener('click', EMOTICON.add);
  195.  
  196. btnRemove.type = 'button';
  197. btnRemove.value = 'Remove';
  198. btnRemove.addEventListener('click', EMOTICON.remove);
  199.  
  200. btnClear.type = 'button';
  201. btnClear.value = 'Clear';
  202. btnClear.addEventListener('click', EMOTICON.clear);
  203.  
  204. toBeAppendedToClock.appendChild(emoGroup.parentNode);
  205. toBeAppendedToClock.appendChild(someText);
  206. toBeAppendedToClock.appendChild(btnAdd);
  207. toBeAppendedToClock.appendChild(btnRemove);
  208. toBeAppendedToClock.appendChild(btnClear);
  209. clock.appendChild(toBeAppendedToClock);
  210.  
  211. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  212. * Let's see if the user is using Firefox to add the required key mapping event. *
  213. * This method is taken from http://stackoverflow.com/questions/9847580/ *
  214. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  215. var isFirefox = typeof InstallTrigger !== 'undefined';
  216. isFirefox ? document.addEventListener('keypress', keyEvent) :
  217. document.addEventListener('keydown', keyEvent);
  218.  
  219. // Here comes our own functions.
  220. function changeEmoGroup() {
  221. emoGroupDetail.innerHTML = EMOTICON.getEmoticons(emoGroup.value);
  222. EMOTICON.addEmoGroupEvent();
  223. }
  224.  
  225. function keyEvent(e) {
  226. switch (e.keyCode) {
  227. // Down arrow.
  228. case 40:
  229. emoGroup !== document.activeElement &&
  230. emoGroup.selectedIndex !== emoGroup.length - 1 &&
  231. emoGroup.selectedIndex++;
  232. changeEmoGroup();
  233. break;
  234. // Up arrow.
  235. case 38:
  236. emoGroup !== document.activeElement &&
  237. emoGroup.selectedIndex !== 0 &&
  238. emoGroup.selectedIndex--;
  239. changeEmoGroup();
  240. break;
  241. default:
  242. }
  243. }
  244.  
  245. // The following should run at startup.
  246. EMOTICON.checkemoList();
  247. EMOTICON.addEmosToEmoGroup();
  248. !isFirefox && EMOTICON.addEmoGroupEvent();
  249. idQuestion.focus();
  250. })();