TorViet Shoutbox Enhancer

A small script to tweak the shoutbox

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

  1. // ==UserScript==
  2. // @name TorViet Shoutbox Enhancer
  3. // @namespace http://torviet.com/userdetails.php?id=1662
  4. // @version 0.7.4
  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.  
  43. message += 'Điền tên bộ emoticon, ngăn cách bằng dấu phẩy, phân biệt hoa/thường.' + ' ' +
  44. 'Có thể điền emoticon đơn bằng cách điền tên tập tin emoticon đó.\nVí dụ: Voz,707,Rage';
  45.  
  46. do {
  47. answer = prompt(message);
  48. }
  49. while (!answer || answer.trim() === '');
  50.  
  51. return answer.replace(/\s+/g, '').split(',');
  52. };
  53. var initemoList = function() {
  54. var emoListAvailable = [];
  55. for (var i = 0, options = emoGroup.options, len = options.length; i < len; i++) {
  56. emoListAvailable.push(options[i].text);
  57. }
  58.  
  59. emoList = promptForEmoList('sử dụng', emoListAvailable);
  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 emoListAvailable = [];
  90. for (var i = 0, options = emoGroup.options, len = options.length; i < len; i++) {
  91. (emoList.indexOf(options[i].text) === -1) &&
  92. emoListAvailable.push(options[i].text);
  93. }
  94.  
  95. var emoListToAdd = promptForEmoList('thêm', emoListAvailable);
  96. for (var i = 0, len = emoListToAdd.length; i < len; i++) {
  97. (emoList.indexOf(emoListToAdd[i]) === -1) &&
  98. emoList.push(emoListToAdd[i]);
  99. }
  100.  
  101. GM_setValue('emoList', emoList);
  102. location.href = 'qa.php';
  103. },
  104. remove: function() {
  105. var emoListToRemove = promptForEmoList('xóa', emoList);
  106. for (var i = 0, len = emoListToRemove.length; i < len; i++) {
  107. var index = emoList.indexOf(emoListToRemove[i]);
  108. (index > -1) && emoList.splice(index, 1);
  109. }
  110.  
  111. GM_setValue('emoList', emoList);
  112. location.href = 'qa.php';
  113. },
  114. clear: function() {
  115. GM_deleteValue('emoList');
  116. location.href = 'qa.php';
  117. },
  118. getEmoticons: function(groupName) {
  119. var emoHtmlOld = emoHtml;
  120. do {
  121. requestEmoticons(groupName);
  122. }
  123. while (emoHtml === emoHtmlOld);
  124. return emoHtml;
  125. },
  126. generateEmoticons: function(emoName) {
  127. makeEmoticonHtml(emoName);
  128. return emoHtml;
  129. },
  130. addEmosToEmoGroup: function() {
  131. emoGroupDetail.innerHTML = '';
  132. for (var i = 0, len = emoList.length; i < len; i++) {
  133. emoGroupDetail.innerHTML += isNaN(emoList[i]) ?
  134. this.getEmoticons(emoList[i]) :
  135. this.generateEmoticons(emoList[i]);
  136. }
  137. },
  138. addEmoGroupEvent: function() {
  139. // Let's add click events for the newly added emoticons.
  140. for (var i = 0, emos = emoGroupDetail.childNodes, len = emos.length; i < len; i++)
  141. emos[i].firstChild.addEventListener('click', function(e) {
  142. idQuestion.value += e.target.parentNode.getAttribute('alt');
  143. idQuestion.focus();
  144. });
  145. }
  146. };
  147. })();
  148.  
  149. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  150. * Now remove the unnecessary elements including the box containing new torrents *
  151. * and football news, the warning, the theme drop-down list and the clock. *
  152. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  153. boxHead.parentNode.removeChild(boxHead);
  154. marquee.parentNode.removeChild(marquee);
  155. sltTheme.parentNode.removeChild(sltTheme);
  156. clock.innerHTML = '';
  157.  
  158. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  159. * Here we get the window height of the current window size and the height *
  160. * without the input section and the div holding the navigation. *
  161. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  162. var windowHeight = window.innerHeight,
  163. remainingHeight = inputSection.parentNode.offsetHeight + navigationPage.offsetHeight - 100;
  164.  
  165. // And polish things with our custom CSS.
  166. GM_addStyle(
  167. '.all-wrapper {' +
  168. ' background-image: none !important;' +
  169. ' height : ' + windowHeight + 'px;' +
  170. ' margin : auto;' +
  171. '}' +
  172. '.all-wrapper > :nth-child(2) {' +
  173. ' padding: 0 !important;' +
  174. '}' +
  175. '.navigation_page {' +
  176. ' width: auto;' +
  177. '}' +
  178. '#boxQuestion {' +
  179. ' height: ' + (windowHeight - remainingHeight) + 'px;' +
  180. '}' +
  181. '.q-head {' +
  182. ' border-radius: 0;' +
  183. '}' +
  184. '#clock {' +
  185. ' height : 72px;' +
  186. ' text-align: center;' +
  187. '}' +
  188. '#emo-section, .slimScrollDiv, .emo-group-detail {' +
  189. ' height : ' + (windowHeight - remainingHeight - 72 - 6) + 'px !important;' +
  190. ' padding: 0 !important;' +
  191. '}'
  192. );
  193.  
  194. var toBeAppendedToClock = document.createDocumentFragment(),
  195. someText = document.createElement('span'),
  196. btnAdd = document.createElement('input'),
  197. btnRemove = document.createElement('input'),
  198. btnClear = document.createElement('input');
  199.  
  200. someText.innerHTML = 'For custom emoticon group<br />';
  201.  
  202. btnAdd.type = 'button';
  203. btnAdd.value = 'Add';
  204. btnAdd.addEventListener('click', EMOTICON.add);
  205.  
  206. btnRemove.type = 'button';
  207. btnRemove.value = 'Remove';
  208. btnRemove.addEventListener('click', EMOTICON.remove);
  209.  
  210. btnClear.type = 'button';
  211. btnClear.value = 'Clear';
  212. btnClear.addEventListener('click', EMOTICON.clear);
  213.  
  214. toBeAppendedToClock.appendChild(emoGroup.parentNode);
  215. toBeAppendedToClock.appendChild(someText);
  216. toBeAppendedToClock.appendChild(btnAdd);
  217. toBeAppendedToClock.appendChild(btnRemove);
  218. toBeAppendedToClock.appendChild(btnClear);
  219. clock.appendChild(toBeAppendedToClock);
  220.  
  221. // Here comes our own functions.
  222. function changeEmoGroup() {
  223. emoGroupDetail.innerHTML = EMOTICON.getEmoticons(emoGroup.value);
  224. EMOTICON.addEmoGroupEvent();
  225. }
  226.  
  227. function keyEvent(e) {
  228. switch (e.keyCode) {
  229. // Down arrow.
  230. case 40:
  231. emoGroup !== document.activeElement &&
  232. emoGroup.selectedIndex !== emoGroup.length - 1 &&
  233. emoGroup.selectedIndex++;
  234. changeEmoGroup();
  235. break;
  236. // Up arrow.
  237. case 38:
  238. emoGroup !== document.activeElement &&
  239. emoGroup.selectedIndex !== 0 &&
  240. emoGroup.selectedIndex--;
  241. changeEmoGroup();
  242. break;
  243. // Enter.
  244. case 13:
  245. var inputText = idQuestion.value;
  246. inputText = inputText.replace(/(:\^\))|(\/:\))/g, '[em528]');
  247. inputText = inputText.replace(/:\)/g, '[em564]');
  248. inputText = inputText.replace(/:\({2}/g, '[em7]');
  249. inputText = inputText.replace(/:\(/g, '[em561]');
  250. inputText = inputText.replace(/:x/g, '[em535]');
  251. inputText = inputText.replace(/:"\>/g, '[em23]');
  252. inputText = inputText.replace(/:\-?\*/g, '[em570]');
  253. inputText = inputText.replace(/=\(\(/g, '[em572]');
  254. inputText = inputText.replace(/:\-?[oO]/g, '[em222]');
  255. inputText = inputText.replace(/[xX]\-?\(/g, '[em541]');
  256. inputText = inputText.replace(/[bB]\-\)/g, '[em555]');
  257. inputText = inputText.replace(/\>:\)/g, '[em552]');
  258. inputText = inputText.replace(/\(:\|/g, '[em571]');
  259. inputText = inputText.replace(/:\|/g, '[em206]');
  260. inputText = inputText.replace(/:\-&/g, '[em37]');
  261. inputText = inputText.replace(/:\-?\?/g, '[em223]');
  262. inputText = inputText.replace(/=\)\)/g, '[em707]');
  263. inputText = inputText.replace(/:\-?[dD]/g, '[em536]');
  264. inputText = inputText.replace(/;;\)/g, '[em524]');
  265. inputText = inputText.replace(/:\-?\>/g, '[em537]');
  266. inputText = inputText.replace(/:\-[sS]/g, '[em558]');
  267. inputText = inputText.replace(/\[\-\(/g, '[em200]');
  268. inputText = inputText.replace(/=[pP]~/g, '[em566]');
  269. inputText = inputText.replace(/;\)\)/g, '[em18]');
  270. inputText = inputText.replace(/[tT]_[tT]/g, '[em544]');
  271. inputText = inputText.replace(/\-_\-/g, '[em136]');
  272. idQuestion.value = inputText;
  273. break;
  274. default:
  275. }
  276. }
  277.  
  278. // The following should run at startup.
  279. document.addEventListener('keydown', keyEvent);
  280. EMOTICON.checkemoList();
  281. EMOTICON.addEmosToEmoGroup();
  282. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  283. * Let's see if the user is using Firefox. *
  284. * This method is taken from http://stackoverflow.com/questions/9847580/ *
  285. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  286. typeof InstallTrigger === 'undefined' && EMOTICON.addEmoGroupEvent();
  287. idQuestion.focus();
  288. })();