🏠 Home 

Greasy Fork is available in English.

S1 User Tagging

给stage1st加上标记用户/屏蔽用户帖子/修改用户帖子颜色/保存用户帖子


安装此脚本?
  1. // ==UserScript==
  2. // @name S1 User Tagging
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description 给stage1st加上标记用户/屏蔽用户帖子/修改用户帖子颜色/保存用户帖子
  6. // @author Hibino
  7. // @include http*://bbs.saraba1st.com/*
  8. // @include http*://www.saraba1st.com/*
  9. // @require https://code.jquery.com/jquery-3.1.1.min.js
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @grant GM_addStyle
  13. // ==/UserScript==
  14. (function() {
  15. 'use strict';
  16. var DATA_FILE = "s1_user_tags";
  17. var POST_URL = "/2b/forum.php?mod=redirect&goto=findpost&pid=";
  18. var HTML_USERNAME =
  19. '<div id="tgut_pid_PID" class="tgut" data-uid="UID" data-pid="PID" >' +
  20. '<div class="t">S1UT</div>' +
  21. '<div class="m">' +
  22. '<div class="tag">标签:<input class="in" type="text" name="tag" value="TAG" /></div>' +
  23. '<div class="colors">' +
  24. '<div class="c c1 f"></div>' +
  25. '<div class="c c2"></div>' +
  26. '<div class="c c3"></div>' +
  27. '<div class="c c4"></div>' +
  28. '<div class="c c5 f"></div>' +
  29. '<div class="c c6"></div>' +
  30. '<div class="c c7"></div>' +
  31. '<div class="c c8"></div>' +
  32. '<div class="c c9 f"></div>' +
  33. '<div class="c c10"></div>' +
  34. '<div class="c c11"></div>' +
  35. '<div class="c c12"></div>' +
  36. '<div class="tgut-clear"></div></div>' +
  37. '<div class="clor">颜色:<input class="in" type="text" name="color" value="COLOR" /></div>' +
  38. '<div class="remv"><label><input type="checkbox" name="remove_post" value="1" REMOVE_POST>隐藏该用户帖子</label></div>' +
  39. '<button class="but but-save-tag" type="button" name="dummy" value="Save" data-pid="PID">保存</button>' +
  40. '<hr>' +
  41. '<button class="but but-save-post" type="button" name="dummy" value="Save Post" data-pid="PID" data-uid="UID">保存帖子</button>' +
  42. '&nbsp;&nbsp;&nbsp;&nbsp;' +
  43. '<button class="but but-view-posts" type="button" name="dummy" value="Save Post" data-pid="PID" data-uid="UID">查看帖子</button>' +
  44. '</div>' +
  45. '</div>';
  46. var HTML_TAG = '<div class="tgut-tag">TAG</div>';
  47. var HTML_MSG = '<div id="tgut_msg" class="tgut-msg"></div>';
  48. var HTML_POPUP =
  49. '<div class="tgut-page-cover" id="tgut_page_cover"></div>' +
  50. '<div class="tgut-popup" id="tgut_popup">' +
  51. '<div class="tt"><div class="f-l" id="tgut_popup_title">&nbsp;</div><div class="f-r cls" id="tgut_popup_close"><a>X</a></div><div class="tgut-clear"></div></div>' +
  52. '<div class="ct" id="tgut_popup_content"></div>' +
  53. '</div>';
  54. var HTML_SETTINGS =
  55. '<div id="tgut_settings" class="tgut-sett">'+
  56. '<div class="b"><button class="but but-clean" type="button" name="dummy" value="Clean">清除数据</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
  57. '<button class="but but-export" type="button" name="dummy" value="Export">导出数据</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
  58. '<button class="but but-import" type="button" name="dummy" value="Import">导入数据</button></div>'+
  59. '<div class="t">导出时请保存下框的所有文本数据。导入时请把文本数据复制到下框然后点击“导入数据”按钮' +
  60. '<br /><textarea id="tgut_data_text" class="txa" name="dummy"></textarea></div>' +
  61. '</div>';
  62. GM_addStyle(
  63. `
  64. .tgut-clear{
  65. clear: both;
  66. }
  67. .tgut-blur{
  68. filter: blur(20px);
  69. }
  70. .tgut{
  71. top: 0;
  72. right: 0;
  73. position: absolute;
  74. font-weight: normal;
  75. }
  76. .tgut:hover{
  77. }
  78. .tgut-msg{
  79. display: none;
  80. position: fixed;
  81. width: 300px;
  82. padding: 5px 10px;
  83. top: 0;
  84. left: 50%;
  85. margin-left: -150px;
  86. color: #ffffff;
  87. text-align: center;
  88. background: #0033cc;
  89. z-index: 300;
  90. }
  91. .tgut .t{
  92. display: block;
  93. padding: 2px 5px;
  94. color: #ffffff;
  95. background: #006cc2;
  96. cursor: pointer;
  97. }
  98. .tgut .m{
  99. display: none;
  100. position: absolute;
  101. width: 145px;
  102. right: 0;
  103. padding: 5px;
  104. color: #444444;
  105. text-align: right;
  106. border: 3px solid #006cc2;
  107. background: #ffffff;
  108. z-index: 100;
  109. }
  110. .tgut:hover .m{
  111. display: block;
  112. }
  113. .tgut .in{
  114. width: 95px;
  115. }
  116. .tgut .but{
  117. color: #ffffff;
  118. border: 0;
  119. background: #006cc2;
  120. }
  121. .tgut .tag{
  122. margin: 0 0 10px;
  123. }
  124. .tgut .colors{
  125. margin: 0 0 10px;
  126. }
  127. .tgut .clor{
  128. margin: 0 0 10px;
  129. }
  130. .tgut .remv{
  131. margin: 0 0 10px;
  132. }
  133. .tgut .colors .c{
  134. float: right;
  135. width: 32px;
  136. height: 32px;
  137. margin: 0;
  138. }
  139. .tgut .colors .f{
  140. margin-right: 0;
  141. }
  142. .tgut .colors .c1{
  143. background: #641e16;
  144. }
  145. .tgut .colors .c2{
  146. background: #4a235a;
  147. }
  148. .tgut .colors .c3{
  149. background: #0b5345;
  150. }
  151. .tgut .colors .c4{
  152. background: #7d6608;
  153. }
  154. .tgut .colors .c5{
  155. background: #424949 ;
  156. }
  157. .tgut .colors .c6{
  158. background: #e74c3c;
  159. }
  160. .tgut .colors .c7{
  161. background: #f7dc6f;
  162. }
  163. .tgut .colors .c8{
  164. background: #85929e;
  165. }
  166. .tgut .colors .c9{
  167. background: #17a589 ;
  168. }
  169. .tgut .colors .c10{
  170. background: #f0b27a;
  171. }
  172. .tgut .colors .c11{
  173. background: #000000;
  174. }
  175. .tgut .colors .c12{
  176. background: #00ff00;
  177. }
  178. .tgut-tag{
  179. position: absolute;
  180. width: 130px;
  181. margin: 8px 0;
  182. color: #ffffff;
  183. text-align: center;
  184. line-height: 24px;
  185. border: 0;
  186. background: #006cc2;
  187. z-index: 50;
  188. }
  189. .tgut-page-cover{
  190. display: none;
  191. position:absolute;
  192. top: 0;
  193. left: 0;
  194. -moz-opacity: 0.6;
  195. opacity: 0.6;
  196. background-color: #000000;
  197. z-index: 200;
  198. }
  199. .tgut-popup{
  200. position: absolute;
  201. display: none;
  202. left: 50%;
  203. top: 10%;
  204. width: 60%;
  205. background: #ffffff;
  206. border: 5px solid #006cc2;
  207. z-index: 250;
  208. }
  209. .tgut-popup .f-l{
  210. float: left;
  211. }
  212. .tgut-popup .f-r{
  213. float: right;
  214. }
  215. .tgut-popup .tt{
  216. padding: 0 10px;
  217. line-height: 28px;
  218. color: #ffffff;
  219. background: #006cc2;
  220. }
  221. .tgut-popup .cls{
  222. }
  223. .tgut-popup .cls a{
  224. display: block;
  225. width: 24px;
  226. float: right;
  227. font-size: 120%;
  228. color: #fff;
  229. line-height: 24px;
  230. cursor: pointer;
  231. text-align: center;
  232. text-decoration: none;
  233. }
  234. .tgut-popup .cls a:hover{
  235. color: #0e5685;
  236. background: #fff;
  237. }
  238. .tgut-popup .ct{
  239. clear: both;
  240. __padding: 5px;
  241. text-align: left;
  242. }
  243. .tgut-posts{
  244. padding: 10px;
  245. }
  246. .tgut-posts .post{
  247. clear: both;
  248. margin: 10px 0 20px 0;
  249. padding: 10px;
  250. background: #f0f0f0;
  251. border-bottom: 2px solid #006cc2;
  252. overflow: hidden;
  253. }
  254. .tgut-posts .pid{
  255. float: right;
  256. margin: 0 20px 0 0;
  257. font-weight: bold;
  258. text-decoration: underline;
  259. }
  260. .tgut-posts .time{
  261. float: left;
  262. font-weight: bold;
  263. }
  264. .tgut-posts .del{
  265. float: right;
  266. }
  267. .tgut-posts .del button{
  268. color: #ffffff;
  269. border: 0;
  270. background: #006cc2;
  271. }
  272. .tgut-posts .ct{
  273. clear: both;
  274. margin: 10px 0;
  275. }
  276. .tgut-but{
  277. display: inline-block;
  278. margin: 4px 20px;
  279. padding: 0 10px;
  280. color: #ffffff;
  281. line-height: 25px;
  282. background: #006cc2;
  283. cursor: pointer;
  284. }
  285. .tgut-sett{
  286. padding: 10px;
  287. }
  288. .tgut-sett .but{
  289. color: #ffffff;
  290. border: 0;
  291. background: #006cc2;
  292. }
  293. .tgut-sett .b{
  294. text-align: right;
  295. }
  296. .tgut-sett .t{
  297. margin: 20px 0;
  298. }
  299. .tgut-sett .t .txa{
  300. width: 99%;
  301. height: 200px;
  302. }
  303. `
  304. );
  305. $( 'body' ).append( HTML_MSG );
  306. $( 'body' ).append( HTML_POPUP );
  307. function test( v ){
  308. return ( v && v !== 0 && v != "0" );
  309. }
  310. function trim( txt ){
  311. return ( txt ? txt.replace( /^\s+|\s+$/g, "" ) : "" );
  312. }
  313. function html( s ){
  314. if( typeof s == 'string' ){
  315. return s.replace(/&/g, "&amp;")
  316. .replace(/</g, "&lt;")
  317. .replace(/>/g, "&gt;")
  318. .replace(/"/g, "&quot;")
  319. .replace(/'/g, "&#039;");
  320. }
  321. return '';
  322. }
  323. function count_obj( o, true_only ){
  324. var c = 0;
  325. for( var i in o ){
  326. true_only ? ( test( o[i] ) && c++ ) : c++;
  327. }
  328. return c;
  329. }
  330. function tl( o ){
  331. console.log( o );
  332. }
  333. var tg = {
  334. is_logged_in: 0,
  335. data_init: {
  336. version: 2,
  337. users: {},
  338. posts: {},
  339. },
  340. user_init: {
  341. uid: 0,
  342. name: '',
  343. tag: '',
  344. color: '',
  345. remove_post: 0,
  346. parent_uid: 0,
  347. related_uids: {},
  348. quotes: {}
  349. },
  350. data: {},
  351. msg: function( m ){
  352. $( '#tgut_msg' ).html( m ).stop( true, true ).show( 1, function(){ $( '#tgut_msg' ).animate( {"null":1}, 1000 ).fadeOut( 200 ); } );
  353. },
  354. load_data: function(){
  355. var data = tg.data_init;
  356. var tmp = GM_getValue( DATA_FILE, "" );
  357. try{
  358. data = JSON.parse( tmp );
  359. }catch( e ){
  360. }
  361. if( test( data.version ) ){
  362. tg.data = data;
  363. }
  364. },
  365. save_data: function(){
  366. GM_setValue( DATA_FILE, JSON.stringify( tg.data ) );
  367. },
  368. clean_data: function(){
  369. tg.data = tg.data_init;
  370. tg.save_data();
  371. },
  372. update_data: function(){
  373. if( tg.data.version < 2 ){
  374. tg.data.posts = {};
  375. tg.data.version = 2;
  376. tg.save_data();
  377. }
  378. },
  379. init: function(){
  380. // check if logged in
  381. var l = $( '#um' );
  382. if( l.length > 0 ){
  383. tg.is_logged_in = 1;
  384. // read in stored settings
  385. tg.load_data();
  386. tg.update_data();
  387. post.init();
  388. sett.init();
  389. }else{
  390. // do nothing...
  391. }
  392. pop.init();
  393. }
  394. };
  395. var pop = {
  396. cover: function( on ){
  397. var c = $( '#tgut_page_cover' );
  398. var o = $( 'body' );
  399. if( on ){
  400. c.css( "width", o.width() ).css( "height", o.height() ).show();
  401. o.find( '.wrap:first' ).addClass( "tgut-blur" );
  402. }else{
  403. o.find( '.wrap:first' ).removeClass( "tgut-blur" );
  404. c.hide();
  405. }
  406. },
  407. show: function( t, c ){
  408. var o = $( '#tgut_popup' );
  409. var top = $(document).scrollTop() + ( o.height() > 500 ? 1 : 100 );
  410. $( '#tgut_popup_content' ).html( c );
  411. $( '#tgut_popup_title' ).html( ( t ) );
  412. o.css( "margin-left", - o.width() / 2 ).css( "top", top ).show();
  413. pop.cover( 1 );
  414. },
  415. close: function(){
  416. $( '#tgut_popup' ).hide();
  417. pop.cover();
  418. },
  419. init: function(){
  420. $( '#tgut_popup_close' ).click( pop.close );
  421. }
  422. };
  423. var post = {
  424. process_posts: function(){
  425. $( "#postlist" ).children( 'div' ).each(
  426. function(){
  427. var o = $( this );
  428. if( o.prop( 'id' ).indexOf( 'post_' ) == 0 ){
  429. var user = o.find( ".authi:first" ).css( "position", "relative" );
  430. var popup = o.find( ".userinfopanel" );
  431. o.find( '.pls' ).css( 'overflow', 'visible' );
  432. o.find( '.tgut' ).remove();
  433. user.parent().css( 'overflow', 'visible' )
  434. var name = user.find( "a" ).html();
  435. var uid = post.get_uid( user );
  436. var pid = o.find( "table" ).first().prop( "id" ).replace( "pid", "" );
  437. //tl( username + ":::" + uid + ":::" + pid );
  438. var tag = test( tg.data.users[uid] ) ? tg.data.users[uid] : tg.user_init;
  439. var h = HTML_USERNAME;
  440. h = h.replace( /PID/g, pid )
  441. .replace( /UID/g, uid )
  442. .replace( /TAG/g, html( tag.tag ) )
  443. .replace( /COLOR/g, html( tag.color ) )
  444. .replace( /REMOVE_POST/g, ( test( tag.remove_post ) ? 'checked' : '' ) );
  445. var j = new $( h );
  446. j.find( ".but-save-tag" ).click( post.save );
  447. j.find( ".but-save-post" ).click( post.save_post );
  448. j.find( ".but-view-posts" ).click( post.view_posts );
  449. j.find( ".c" ).click( post.color_click );
  450. user.append( j );
  451. if( tag.uid == uid ){
  452. user.parent().find( '.tgut-tag' ).remove();
  453. if( test( tag.tag ) ){
  454. user.after( HTML_TAG.replace( /TAG/g, html( tag.tag ) ) );
  455. }
  456. user.closest( 'table' ).find( 'td' ).css( 'color', '' );
  457. if( test( tag.color ) ){
  458. user.closest( 'table' ).find( 'td' ).css( 'color', tag.color );
  459. }
  460. var s = o.find( 'favatar:first' );
  461. if( test( tag.remove_post ) ){
  462. //s.children("div:gt(0), p, dl, ul").css( 'display', 'none' );
  463. o.find( '.pct' ).css( 'display', 'none' ).after( '<div class="tgut-mesg">用户帖子和签名被屏蔽</div>' );
  464. o.find( '.sign' ).css( 'display', 'none' );
  465. }else{
  466. //s.children("div:gt(0), p, dl, ul").css( 'display', 'block' );
  467. o.find( '.pct' ).css( 'display', 'block' );
  468. o.find( '.sign' ).css( 'display', 'none' );
  469. o.find( '.tgut-mesg' ).remove();
  470. }
  471. }
  472. }
  473. }
  474. );
  475. },
  476. get_uid: function( d ){
  477. var h = d.find( 'a' ).prop( 'href' );
  478. var s = h.substring( h.lastIndexOf( "-" ) + 1, h.lastIndexOf( '.html' ) );
  479. return trim( s );
  480. },
  481. get_name: function( pid ){
  482. var name = $( '#pid' + pid ).find( 'cite:first' ).find( "a" ).html();
  483. return trim( name );
  484. },
  485. color_click: function( e ){
  486. var o = $( this );
  487. o.closest( ".tgut" ).find( "[name='color']" ).val( o.css( "background-color" ) );
  488. },
  489. save: function( e ){
  490. var o = $( this ).closest( ".tgut" );
  491. var uid = o.data( "uid" );
  492. var pid = o.data( "pid" );
  493. var tag = o.find( "[name='tag']" ).val();
  494. var color = o.find( "[name='color']" ).val();
  495. var remove_post = o.find( "[name='remove_post']" ).is( ':checked' );
  496. if( !test( uid ) ){
  497. return;
  498. }
  499. if( !test( tg.data.users[uid] ) ){
  500. tg.data.users[uid] = tg.user_init;
  501. }
  502. tg.data.users[uid].uid = uid;
  503. tg.data.users[uid].tag = tag;
  504. tg.data.users[uid].name = post.get_name( pid );
  505. tg.data.users[uid].color = color;
  506. tg.data.users[uid].remove_post = remove_post ? 1 : 0;
  507. tg.save_data();
  508. tg.msg( "已保存用户标签" );
  509. post.process_posts();
  510. },
  511. save_post: function( e ){
  512. var o = $( this );
  513. var pid = o.data( 'pid' );
  514. var uid = o.data( 'uid' );
  515. var content = trim( $( '#postmessage_' + pid ).html() );
  516. var time_str = trim( $( '#authorposton' + pid ).text() ); // well well well....
  517. if( !test( tg.data.posts[uid] ) ){
  518. tg.data.posts[uid] = {};
  519. }
  520. tg.data.posts[uid][pid] = {
  521. 'uid': uid,
  522. 'pid': pid,
  523. 'name': post.get_name( pid ),
  524. 'time': time_str,
  525. 'post': content
  526. };
  527. tg.save_data();
  528. tg.msg( "帖子保存了" );
  529. },
  530. del_post: function( e ){
  531. var o = $( this );
  532. var pid = o.data( 'pid' );
  533. var uid = o.data( 'uid' );
  534. if( test( tg.data.posts[uid] ) && test( tg.data.posts[uid][pid] ) ){
  535. delete( tg.data.posts[uid][pid] );
  536. tg.save_data();
  537. tg.msg( "帖子删除了" );
  538. }
  539. $( '#tgut_post_' + pid ).remove();
  540. if( !count_obj( tg.data.posts[uid] ) ){
  541. pop.close();
  542. }
  543. },
  544. view_posts: function( e ){
  545. var o = $( this );
  546. var pid = o.data( 'pid' );
  547. var uid = o.data( 'uid' );
  548. if( !test( tg.data.posts[uid] ) || !count_obj( tg.data.posts[uid] ) ){
  549. tg.msg( '没有针对该用户保存的帖子' );
  550. return;
  551. }
  552. var name = '';
  553. var h = '<div class="tgut-posts">';
  554. for( var i in tg.data.posts[uid] ){
  555. var p = tg.data.posts[uid][i];
  556. name = p.name;
  557. h += '<div class="post" id="tgut_post_' +p.pid+ '"><div class="time">' +p.time+ '</div>' +
  558. '<div class="del"><button class="but" name="dummy" value="Del" data-pid="' +p.pid+ '" data-uid="' +p.uid+ '">删除</button></div>' +
  559. '<div class="pid"><a href="' +POST_URL+p.pid+ '" target="_blank">Post ID: ' +p.pid+ '</a></div>' +
  560. '<div class="ct">' +p.post+ '</div></div>';
  561. }
  562. h += '</div>';
  563. var j = new $( h );
  564. j.find( '.but' ).click( post.del_post );
  565. pop.show( name, j );
  566. },
  567. init: function(){
  568. post.process_posts();
  569. }
  570. };
  571. var sett = {
  572. clean: function(){
  573. if( confirm( "确定删除所有以保存的用户标签以及帖子吗?" ) ){
  574. tg.clean_data();
  575. tg.save_data();
  576. tg.init();
  577. tg.msg( "数据已清除" );
  578. }
  579. },
  580. export: function(){
  581. var str = JSON.stringify( tg.data );
  582. $( '#tgut_data_text' ).val( str );
  583. tg.msg( "数据已显示在输入框中" );
  584. },
  585. import: function(){
  586. var data = {};
  587. var str = trim( $( '#tgut_data_text' ).val() );
  588. try{
  589. data = JSON.parse( str );
  590. }catch( e ){
  591. tg.msg( "数据不是有效的JSON字串" );
  592. return;
  593. }
  594. if( test( data.version ) ){
  595. tg.data = data;
  596. tg.update_data();
  597. tg.save_data();
  598. tg.msg( "成功导入数据" );
  599. tg.init();
  600. }else{
  601. tg.msg( "无法识别数据版本" );
  602. }
  603. },
  604. show: function(){
  605. var j = new $( HTML_SETTINGS );
  606. j.find( '.but-clean' ).click( sett.clean );
  607. j.find( '.but-export' ).click( sett.export );
  608. j.find( '.but-import' ).click( sett.import );
  609. pop.show( 'S1UT设置', j );
  610. },
  611. init: function(){
  612. // find the user bar beside the log
  613. var o = $( '#nv' ).find( 'ul' );
  614. if( !o.find( '.tgut-but' ).length ){
  615. var j = new $( '<div class="tgut-but">S1UT</div>' );
  616. j.click( sett.show );
  617. o.parent().append( j );
  618. }
  619. }
  620. };
  621. tg.init();
  622. })();