futaba auto reloader

赤福Firefox版で自動更新しちゃう(実況モードもあるよ!)

当前为 2015-12-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name futaba auto reloader
  3. // @namespace https://github.com/himuro-majika
  4. // @description 赤福Firefox版で自動更新しちゃう(実況モードもあるよ!)
  5. // @author himuro_majika
  6. // @include http://*.2chan.net/*/res/*
  7. // @include http://board.futakuro.com/*/res/*
  8. // @require http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js
  9. // @version 1.6.1
  10. // @grant none
  11. // @license MIT
  12. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPUExURYv4i2PQYy2aLUe0R////zorx9oAAAAFdFJOU/////8A+7YOUwAAAElJREFUeNqUj1EOwDAIQoHn/c88bX+2fq0kRsAoUXVAfwzCttWsDWzw0kNVWd2tZ5K9gqmMZB8libt4pSg6YlO3RnTzyxePAAMAzqMDgTX8hYYAAAAASUVORK5CYII=
  13. // ==/UserScript==
  14. this.$ = this.jQuery = jQuery.noConflict(true);
  15.  
  16. (function ($) {
  17. /*
  18. * 設定
  19. */
  20. var USE_SOUDANE = true; //そうだねをハイライト表示する
  21. var USE_CLEAR_BUTTON = true; //フォームにクリアボタンを表示する
  22. var USE_TITLE_NAME = true; //新着レス数・スレ消滅状態をタブに表示する
  23. var RELOAD_INTERVAL_NORMAL = 60000; //リロード間隔[ミリ秒](通常時)
  24. var RELOAD_INTERVAL_LIVE = 5000; //リロード間隔[ミリ秒](実況モード時)
  25. var LIVE_SCROLL_INTERVAL = 12; //実況モードスクロール間隔[ミリ秒]
  26. var LIVE_SCROLL_SPEED = 2; //実況モードスクロール幅[px]
  27. var LIVE_TOGGLE_KEY = "76"; //実況モードON・OFF切り替えキーコード(With Alt)
  28. var SHOW_NORMAL_BUTTON = true; //通常モードボタンを表示する
  29.  
  30. var res = 0; //新着レス数
  31. var timerNormal, timerLiveReload, timerLiveScroll;
  32. var url = location.href;
  33. var script_name = "futaba_auto_reloader";
  34.  
  35. if(!isFileNotFound()){
  36. setNormalReload();
  37. }
  38.  
  39. soudane();
  40. makeFormClearButton();
  41. reset_title();
  42. make_live_button();
  43.  
  44. //通常リロード開始
  45. function setNormalReload() {
  46. timerNormal = setInterval(rel, RELOAD_INTERVAL_NORMAL);
  47. console.log(script_name + ": Start auto reloading @" + url);
  48. }
  49. //通常リロード停止
  50. function clearNormalReload() {
  51. clearInterval(timerNormal);
  52. console.log(script_name + ": Stop auto reloading @" + url);
  53. }
  54. /*
  55. * 404チェック
  56. */
  57. function isFileNotFound() {
  58. if(document.title == "404 File Not Found") {
  59. return true;
  60. }
  61. else {
  62. return false;
  63. }
  64. }
  65.  
  66. /*
  67. * ボタン作成
  68. */
  69. function make_live_button() {
  70. var normal_flag = true; //通常モード有効フラグ
  71. //通常モードボタン
  72. var $normalButton = $("<a>", {
  73. id: "GM_FAR_relButton_normal",
  74. class: "GM_FAR_relButton",
  75. text: "[通常]",
  76. css: {
  77. cursor: "pointer",
  78. "background-color": "#ea8",
  79. },
  80. click: function() {
  81. normalMode();
  82. }
  83. });
  84.  
  85. var live_flag = false; //実況モード有効フラグ
  86. //実況モードボタン
  87. var $liveButton = $("<a>", {
  88. id: "GM_FAR_relButton_live",
  89. class: "GM_FAR_relButton",
  90. text: "[実況モード(Alt+" + String.fromCharCode(LIVE_TOGGLE_KEY) + ")]",
  91. css: {
  92. cursor: "pointer",
  93. },
  94. click: function() {
  95. liveMode();
  96. }
  97. });
  98.  
  99. var $input = $("input[value$='信する']");
  100. $input.after($liveButton);
  101. if(SHOW_NORMAL_BUTTON){
  102. $input.after($normalButton);
  103. }
  104.  
  105. //実況モードトグルショートカットキー
  106. window.addEventListener("keydown",function(e) {
  107. if ( e.altKey && e.keyCode == LIVE_TOGGLE_KEY ) {
  108. liveMode();
  109. }
  110. }, false);
  111.  
  112. /*
  113. * 通常モード切り替え
  114. */
  115. function normalMode() {
  116. if(normal_flag) {
  117. clearNormalReload();
  118. $normalButton.css("background" , "none");
  119. normal_flag = false;
  120. } else {
  121. setNormalReload();
  122. $normalButton.css("background-color" , "#ea8");
  123. normal_flag = true;
  124. }
  125.  
  126. }
  127.  
  128. /*
  129. * 実況モード
  130. * 呼出ごとにON/OFFトグル
  131. */
  132. function liveMode() {
  133. if (!live_flag) {
  134. //実況モード時リロード
  135. timerLiveReload = setInterval(rel_scroll, RELOAD_INTERVAL_LIVE);
  136. //自動スクロール
  137. timerLiveScroll = setInterval(live_scroll, LIVE_SCROLL_INTERVAL);
  138. $liveButton.css("backgroundColor", "#ffa5f0");
  139. console.log(script_name + ": Start live mode @" + url);
  140. live_flag = true;
  141. } else {
  142. clearInterval(timerLiveReload);
  143. clearInterval(timerLiveScroll);
  144. $liveButton.css("background", "none");
  145. console.log(script_name + ": Stop live mode @" + url);
  146. live_flag = false;
  147. }
  148.  
  149. //新着スクロール
  150. function rel_scroll() {
  151. $('html, body').animate(
  152. {scrollTop:window.scrollMaxY},"fast"
  153. );
  154. if(isAkahukuNotFound()){
  155. //404時
  156. liveMode();
  157. }
  158. else {
  159. clickrelbutton();
  160. }
  161. }
  162.  
  163. function live_scroll() {
  164. window.scrollBy( 0, LIVE_SCROLL_SPEED );
  165. }
  166. }
  167. }
  168.  
  169.  
  170. /*
  171. * 新着レスをリセット
  172. */
  173. function reset_title() {
  174. //ページ末尾でホイールダウンした時
  175. window.addEventListener("DOMMouseScroll",function scroll(event) {
  176. var window_y = window.scrollY;
  177. var window_ymax = window.scrollMaxY;
  178. if (event.detail > 0 && window_y >= window_ymax) {
  179. reset_titlename();
  180. }
  181. return;
  182. } ,false);
  183. //F5キー押された時
  184. window.addEventListener("keydown",function(e) {
  185. if ( e.keyCode == "116" ) {
  186. reset_titlename();
  187. }
  188. }, false);
  189.  
  190. function reset_titlename() {
  191. res = 0;
  192. var title_char = title_name();
  193. document.title = title_char;
  194. }
  195. }
  196.  
  197. function rel() {
  198. soudane();
  199. setTimeout(changetitle, 1000);
  200. if(isAkahukuNotFound()){
  201. //404時
  202. clearNormalReload();
  203. console.log(script_name + ": Page not found, Stop auto reloading @" + url);
  204. }
  205. else {
  206. clickrelbutton();
  207. }
  208. }
  209. /**
  210. * 赤福の続きを読むボタンをクリック
  211. */
  212. function clickrelbutton() {
  213. var relbutton = document.getElementById("akahuku_reload_button");
  214. if(relbutton){
  215. var e = document.createEvent("MouseEvents");
  216. e.initEvent("click", false, true);
  217. relbutton.dispatchEvent(e);
  218. }
  219. }
  220.  
  221. /*
  222. * そうだねの数に応じてレスを着色
  223. */
  224. function soudane() {
  225. if ( USE_SOUDANE ) {
  226. $("td > .sod").each(function(){
  227. var sodnum = $(this).text().match(/\d+/);
  228. if (sodnum){
  229. var col = "rgb(180, 240," + (Math.round(10 * sodnum + 180)) + ")";
  230. $(this).parent().css("background-color", col);
  231. }
  232. });
  233. }
  234. }
  235.  
  236. /*
  237. * タブタイトルに新着レス数・スレ消滅状態を表示
  238. */
  239. function changetitle() {
  240. if ( USE_TITLE_NAME ) {
  241. var title_char = title_name();
  242. var newres = $("#akahuku_new_reply_header_number").text();
  243. if (isAkahukuNotFound()) {
  244. document.title = "#" + title_char;
  245. } else {
  246. if(newres) {
  247. res += parseInt(newres);
  248. }
  249. if ( res !== 0) {
  250. document.title = "(" + res + ")" + title_char;
  251. }
  252. }
  253. }
  254. }
  255.  
  256. /*
  257. * 赤福のステータスからスレ消滅状態をチェック
  258. */
  259. function isAkahukuNotFound() {
  260. var statustext = $("#akahuku_reload_status").text();
  261. if (statustext.match(/(No Future)|((M|N)ot Found)/)) {
  262. return true;
  263. }
  264. else {
  265. return false;
  266. }
  267. }
  268.  
  269. function title_name() {
  270. var title = document.title;
  271. var title_num = title.match(/^(#|\(\d+\))/);
  272. var title_num_length;
  273. if(!title_num){
  274. title_num_length = 0;
  275. }
  276. else {
  277. title_num_length = title_num[0].length;
  278. }
  279. var act_title_name = title.substr(title_num_length);
  280. return act_title_name;
  281. }
  282.  
  283. function makeFormClearButton() {
  284. if ( USE_CLEAR_BUTTON ) {
  285. var $formClearButton = $("<div>", {
  286. id: "formClearButton",
  287. text: "[クリア]",
  288. css: {
  289. cursor: "pointer",
  290. margin: "0 5px"
  291. },
  292. click: function() {
  293. clearForm();
  294. }
  295. });
  296. var $comeTd = $(".ftdc b:contains('コメント')");
  297. $comeTd.after($formClearButton);
  298. }
  299.  
  300. function clearForm() {
  301. $("#ftxa").val("");
  302. }
  303. }
  304.  
  305. })(jQuery);