Freenode Web IRC 刷屏插件

在 Freenode Web IRC 聊天室中创造瀑布

当前为 2015-10-31 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Freenode Web IRC 刷屏插件
  3. // @namespace xuyiming.open@outlook.com
  4. // @description 在 Freenode Web IRC 聊天室中创造瀑布
  5. // @author 依然独特
  6. // @version 0.6
  7. // @grant none
  8. // @run-at document-end
  9. // @include http://webchat.freenode.net/*
  10. // @match http://webchat.freenode.net/*
  11. // ==/UserScript==
  12.  
  13. ( function() {
  14. var POST_INTERVAL = 250;
  15.  
  16. function main() {
  17. var e = document.querySelector( "div.dynamicpanel.qwebirc-qui.bottomboundpanel.widepanel.input" ),
  18.  
  19. intervalID = setInterval( function() {
  20. if ( e.style.display !== "none" ) {
  21. load();
  22. clearInterval( intervalID );
  23. }
  24. }, 1000 ),
  25.  
  26. post = ( function() {
  27. var queue = [ ],
  28. form = document.querySelector( "form.input" ),
  29. input = form.querySelector( "input.keyboard-input" );
  30.  
  31. function next() {
  32. if ( queue.length > 0 ) {
  33. input.value = queue.shift();
  34. submit( form );
  35. }
  36. }
  37.  
  38. function submit( form ) {
  39. var event = document.createEvent( "HTMLEvents" );
  40. event.initEvent( "submit", true, true );
  41. form.dispatchEvent( event );
  42. }
  43.  
  44. form.addEventListener( "submit", function () {
  45. setTimeout( next, POST_INTERVAL )
  46. }, false );
  47.  
  48. return function( message ) {
  49. queue = queue.concat( message.replace( /\t/g, " " ).split( "\n" ).filter( function( line ) {
  50. // 去掉空行
  51. return !/^\s+$/.test( line );
  52. } ) );
  53. next();
  54. };
  55. } )();
  56.  
  57. function load() {
  58. var textarea = document.createElement( "textarea" ),
  59. position = {
  60. self: { x: 0, y: 0 }, //元素相对基准点的位置
  61. viewport: { x: 0, y: 0 }, //基准点在页面中的位置
  62. cursor: { x: 0, y: 0 }, //光标相对元素的位置
  63. };
  64.  
  65. function onkeydown( event ) {
  66. var value, selectionStart, selectionEnd, beforeSelected, selected, afterSelected;
  67.  
  68. // Tab 添加缩进而不是切换焦点
  69. if ( event.keyCode === 9 ) {
  70. event.preventDefault();
  71.  
  72. value = textarea.value;
  73.  
  74. selectionStart = textarea.selectionStart;
  75. selectionEnd = textarea.selectionEnd;
  76.  
  77. beforeSelected = value.slice( 0, selectionStart );
  78. selected = value.slice( selectionStart, selectionEnd );
  79. afterSelected = value.slice( selectionEnd );
  80.  
  81. selected = selected.split( "\n" ).map( function( line ) {
  82. return "\t" + line;
  83. } ).join( "\n" );
  84.  
  85. textarea.value = beforeSelected + selected + afterSelected;
  86.  
  87. // 如果没有选定内容,则将光标移至制表符后
  88. if ( selectionStart === selectionEnd ) {
  89. textarea.selectionStart = textarea.selectionEnd = selectionEnd + 1;
  90. // 否则,选定制表符和原有选定内容
  91. } else {
  92. textarea.selectionStart = selectionStart;
  93. textarea.selectionEnd = selectionStart + selected.length;
  94. }
  95. // Ctrl + Enter 发送消息
  96. } else if ( event.ctrlKey && event.keyCode === 13 && textarea.value.replace( /\s/g, "" ) ) {
  97. event.preventDefault();
  98. post( textarea.value.trim() );
  99. textarea.value = "";
  100. }
  101. }
  102.  
  103. function onmousedown( event ) {
  104. var x, y, style, rect;
  105.  
  106. // 按住 Ctrl 和鼠标可以移动 <textarea>
  107. if ( event.ctrlKey ) {
  108. event.preventDefault();
  109.  
  110. style = getComputedStyle( textarea );
  111. rect = textarea.offsetParent && textarea.offsetParent.getBoundingClientRect() || { top: 0, left: 0 };
  112.  
  113. /*
  114. switch( style.position ) {
  115. case "absolute":
  116. case "fixed":
  117. position.self.x = textarea.offsetLeft - parseInt( style.marginLeft );
  118. position.self.y = textarea.offsetTop - parseInt( style.marginTop );
  119. break;
  120. case "relative":
  121. x = textarea.offsetLeft,
  122. y = textarea.offsetTop;
  123. textarea.style.top = "0px";
  124. textarea.style.left = "0px";
  125. position.self.x = x - textarea.offsetLeft;
  126. position.self.y = y - textarea.offsetTop;
  127. break;
  128. default:
  129. // static 定位元素无法拖动
  130. return;
  131. }
  132. */
  133.  
  134. /* */
  135. position.self.x = textarea.offsetLeft - parseInt( style.marginLeft );
  136. position.self.y = textarea.offsetTop - parseInt( style.marginTop );
  137. /* */
  138.  
  139. position.viewport.x = rect.left;
  140. position.viewport.y = rect.top;
  141. position.cursor.x = event.pageX - position.viewport.x - position.self.x;
  142. position.cursor.y = event.pageY - position.viewport.y - position.self.y;
  143.  
  144. textarea.style.top = position.self.y + "px";
  145. textarea.style.left = position.self.x + "px";
  146. textarea.style.bottom = "auto";
  147. textarea.style.right = "auto";
  148.  
  149. document.addEventListener( "mousemove", onmousemove, false );
  150. document.addEventListener( "mouseup", onmouseup, false );
  151. }
  152. }
  153.  
  154. function onmousemove( event ) {
  155. event.preventDefault();
  156. textarea.style.top = event.pageY - position.viewport.y - position.cursor.y + "px";
  157. textarea.style.left = event.pageX - position.viewport.x - position.cursor.x + "px";
  158. }
  159.  
  160. function onmouseup( event ) {
  161. event.preventDefault();
  162. position = {
  163. self: { x: 0, y: 0 },
  164. viewport: { x: 0, y: 0 },
  165. cursor: { x: 0, y: 0 },
  166. };
  167. document.removeEventListener( "mousemove", onmousemove, false );
  168. document.removeEventListener( "mouseup", onmouseup, false );
  169. }
  170.  
  171. textarea.style.border = "1px solid rgb( 195, 210, 224 )";
  172. textarea.style.width = "150px";
  173. textarea.style.height = "75px";
  174. textarea.style.top = "45px";
  175. textarea.style.right = "150px";
  176. textarea.style.position = "fixed";
  177.  
  178. textarea.addEventListener( "keydown", onkeydown, false );
  179. textarea.addEventListener( "mousedown", onmousedown, false );
  180.  
  181. document.body.appendChild( textarea );
  182. };
  183. }
  184.  
  185. if ( document.readyState === "complete" ) {
  186. main();
  187. } else {
  188. // 因为需要等待样式表
  189. window.addEventListener( "load", main.bind( this ), false );
  190. }
  191. } )();