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

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址