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