4d4y tools

屏蔽用户、名单同步;标识新帖;好孩子也看的见;

目前为 2022-07-01 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 4d4y tools
  3. // @namespace 4d4y-tools-by-2200
  4. // @description 屏蔽用户、名单同步;标识新帖;好孩子也看的见;
  5. // @include http*://*.4d4y.com/forum/*
  6. // @grant GM_addStyle
  7. // @license MIT
  8. // @version 5.2.4
  9. // ==/UserScript==
  10. // Version 5.2.4-by-johntomato
  11. // 适配新域名 4d4y.com
  12. // Version 5.2.3-by-Achilles
  13. // 修改介绍和Changelog
  14. // Version 5.2.2-by-Achilles
  15. // 添加license
  16. // Version 5.2.1-by-Achilles
  17. // 修复了https失效的问题
  18. // 兼容TamperMonkey
  19. // Version 5.2
  20. // 修正各种chrome不兼容的函数
  21. // 因SAE挂掉,去除了同步功能
  22. // Version 5.1 TODO
  23. // 宽窄可选
  24. // opera支持
  25. // 投票icon
  26. // 枫叶版chrome兼容
  27. // 点击显示图片
  28. // 屏蔽用户hover改为帖子触发
  29. // 预取几页可选
  30. // 高亮自己的贴
  31. // Version 5.0
  32. // Date 2011-12-18
  33. // 增加同步功能
  34. // Version 4.0
  35. // Date 2011-12-06
  36. // 论坛改版
  37. // Version 3.0
  38. // Date 2011-7-13
  39. // 增加自动更新
  40. // Version 2.2
  41. // Date 2011-7-13
  42. // 修正zhuyi增加【只讨论2.0】板块后预读页面错误
  43. // 高亮功能修改为可选,颜色自定义
  44. // 屏蔽用户功能修改为分版面可选
  45. // Version 2.1
  46. // Date 2011-4-3
  47. // 修正Chrome错误
  48. // 脚本仅针对D版有效
  49. // Version 2.0
  50. // Date 2010-2-9
  51.  
  52. // @require http://userscript-updater-generator.appspot.com/?id=106358
  53. // Chrome浏览器不支GM_GetValue/GM_SetValue/GM_addStyle/GM_xmlhttpRequest
  54. try{
  55. if (!this.GM_getValue || this.GM_getValue.toString().indexOf("not supported")>-1) {
  56. this.GM_getValue=function (key,def) {
  57. return localStorage[key] || def;
  58. };
  59. this.GM_setValue=function (key,value) {
  60. return localStorage[key]=value;
  61. };
  62. }
  63. if (!this.GM_addStyle || this.GM_addStyle.toString().indexOf("not supported")>-1){
  64. this.GM_addStyle = function(css) {
  65. var head = document.getElementsByTagName('head')[0], style = document.createElement('style');
  66. if (!head) {return}
  67. style.type = 'text/css';
  68. try {style.innerHTML = css} catch(x) {style.innerText = css}
  69. head.appendChild(style);
  70. }
  71. }
  72. if ( !this.GM_xmlhttpRequest || this.GM_xmlhttpRequest.toString().indexOf("not supported")>-1 ) {
  73. this.GM_xmlhttpRequest =
  74. function (details) {
  75. var xmlhttp = new XMLHttpRequest();
  76. xmlhttp.onreadystatechange = function() {
  77. var responseState = {
  78. responseXML:(xmlhttp.readyState==4 ? xmlhttp.responseXML : ''),
  79. responseText:(xmlhttp.readyState==4 ? xmlhttp.responseText : ''),
  80. readyState:xmlhttp.readyState,
  81. responseHeaders:(xmlhttp.readyState==4 ? xmlhttp.getAllResponseHeaders() : ''),
  82. status:(xmlhttp.readyState==4 ? xmlhttp.status : 0),
  83. statusText:(xmlhttp.readyState==4 ? xmlhttp.statusText : '')
  84. }
  85. if (details["onreadystatechange"]) {
  86. details["onreadystatechange"](responseState);
  87. }
  88. if (xmlhttp.readyState==4) {
  89. if (details["onload"] && xmlhttp.status>=200 && xmlhttp.status<300) {
  90. details["onload"](responseState);
  91. }
  92. if (details["onerror"] && (xmlhttp.status<200 || xmlhttp.status>=300)) {
  93. details["onerror"](responseState);
  94. }
  95. }
  96. }
  97. try {
  98. //cannot do cross domain
  99. xmlhttp.open(details.method, details.url);
  100. } catch(e) {
  101. if( details["onerror"] ) {
  102. //simulate a real error
  103. details["onerror"]({responseXML:'',responseText:'',readyState:4,responseHeaders:'',status:403,statusText:'Forbidden'});
  104. }
  105. return;
  106. }
  107. if (details.headers) {
  108. for (var prop in details.headers) {
  109. xmlhttp.setRequestHeader(prop, details.headers[prop]);
  110. }
  111. }
  112. xmlhttp.send((typeof(details.data)!='undefined')?details.data:null);
  113. }
  114. }
  115. }
  116. catch(e){}
  117.  
  118. var _pc = 1; // 当前页面的page值
  119. var _fid; // 当前版面fid
  120. var _uid; // 当前登录用户uid
  121. var _tid= 0; // 当前帖子的tid
  122. var _pxt; // 当前页面上“最后回复时间”的最大值
  123. var _pmt; // 当前页面上“最后回复时间”的最小值
  124. var _lvt; // 上次访问时间,页面关闭时,_pxt 存储为 _lvt
  125. var _today; // 与发帖日期比较,超过30天的发帖人单元格显示灰色
  126. var _first_time_use;
  127. var _max_read_pages = 5; // 不能读取更多啦,太多了容易死机
  128. var _hightlight_en; // 启用高亮功能
  129. var _hightlight_color; // 高亮颜色自定义
  130. var _blacklist_en_hpd; // 启用D版的黑名单功能
  131. var _blacklist_en_other; // 启用其他版的黑名单功能
  132. var _simple_style; // 启用精简风格
  133. var _hover_style; // 启用悬停风格
  134. var _reply_avatar; // 回复位置是否显示自己的头像
  135. var _font_size; // 论坛字体大小
  136. var blacklistArray; // 黑名单
  137. var blacklistLen; // 黑名单长度
  138. var blacklistStr;
  139. var serverBlacklist; // 同步冲突时服务器端的列表
  140. var serverListStr;
  141. var serverVersion;
  142. var newBlacklist // 同步冲突时的新列表
  143. var _syn_pending; // 正在同步
  144. var _syn_lastversion;
  145. var _syn_modified;
  146. var _att_max_width; // 帖子附件图片最大宽度
  147.  
  148. var grave_image; // 坟贴背景图片
  149. // var _old_post_bgcolor = "#E1E1E1";
  150. var _old_post_bgcolor = "#e9e9e9";
  151. var _today_post_color = "#FF0000";
  152. var now = new Date();
  153. var year = now.getYear()+1900;
  154. var month = now.getMonth()+1;
  155. var day = now.getDate();
  156. var hour = now.getHours();
  157. var min = now.getMinutes();
  158. var _bFORUMDISPLAY = location.href.indexOf('4d4y.com/forum/forumdisplay.php?');
  159. var _bVIEWTHREAD = location.href.indexOf('4d4y.com/forum/viewthread.php?');
  160.  
  161. // 工具函数
  162. var JSON;
  163. if (!JSON) {JSON = {};}
  164. (function () {
  165. 'use strict';
  166. function f(n) {return n < 10 ? '0' + n : n;}
  167.  
  168. if (typeof Date.prototype.toJSON !== 'function') {
  169.  
  170. Date.prototype.toJSON = function (key) {
  171.  
  172. return isFinite(this.valueOf()) ?
  173. this.getUTCFullYear() + '-' +
  174. f(this.getUTCMonth() + 1) + '-' +
  175. f(this.getUTCDate()) + 'T' +
  176. f(this.getUTCHours()) + ':' +
  177. f(this.getUTCMinutes()) + ':' +
  178. f(this.getUTCSeconds()) + 'Z' : null;
  179. };
  180.  
  181. String.prototype.toJSON =
  182. Number.prototype.toJSON =
  183. Boolean.prototype.toJSON = function (key) {
  184. return this.valueOf();
  185. };
  186. }
  187.  
  188. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  189. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  190. gap,
  191. indent,
  192. meta = { // table of character substitutions
  193. '\b': '\\b',
  194. '\t': '\\t',
  195. '\n': '\\n',
  196. '\f': '\\f',
  197. '\r': '\\r',
  198. '"' : '\\"',
  199. '\\': '\\\\'
  200. },
  201. rep;
  202.  
  203.  
  204. function quote(string) {
  205.  
  206. // If the string contains no control characters, no quote characters, and no
  207. // backslash characters, then we can safely slap some quotes around it.
  208. // Otherwise we must also replace the offending characters with safe escape
  209. // sequences.
  210.  
  211. escapable.lastIndex = 0;
  212. return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  213. var c = meta[a];
  214. return typeof c === 'string' ? c :
  215. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  216. }) + '"' : '"' + string + '"';
  217. }
  218.  
  219.  
  220. function str(key, holder) {
  221.  
  222. // Produce a string from holder[key].
  223.  
  224. var i, // The loop counter.
  225. k, // The member key.
  226. v, // The member value.
  227. length,
  228. mind = gap,
  229. partial,
  230. value = holder[key];
  231.  
  232. // If the value has a toJSON method, call it to obtain a replacement value.
  233.  
  234. if (value && typeof value === 'object' &&
  235. typeof value.toJSON === 'function') {
  236. value = value.toJSON(key);
  237. }
  238.  
  239. // If we were called with a replacer function, then call the replacer to
  240. // obtain a replacement value.
  241.  
  242. if (typeof rep === 'function') {
  243. value = rep.call(holder, key, value);
  244. }
  245.  
  246. // What happens next depends on the value's type.
  247.  
  248. switch (typeof value) {
  249. case 'string':
  250. return quote(value);
  251.  
  252. case 'number':
  253.  
  254. // JSON numbers must be finite. Encode non-finite numbers as null.
  255.  
  256. return isFinite(value) ? String(value) : 'null';
  257.  
  258. case 'boolean':
  259. case 'null':
  260.  
  261. // If the value is a boolean or null, convert it to a string. Note:
  262. // typeof null does not produce 'null'. The case is included here in
  263. // the remote chance that this gets fixed someday.
  264.  
  265. return String(value);
  266.  
  267. // If the type is 'object', we might be dealing with an object or an array or
  268. // null.
  269.  
  270. case 'object':
  271.  
  272. // Due to a specification blunder in ECMAScript, typeof null is 'object',
  273. // so watch out for that case.
  274.  
  275. if (!value) {
  276. return 'null';
  277. }
  278.  
  279. // Make an array to hold the partial results of stringifying this object value.
  280.  
  281. gap += indent;
  282. partial = [];
  283.  
  284. // Is the value an array?
  285.  
  286. if (Object.prototype.toString.apply(value) === '[object Array]') {
  287.  
  288. // The value is an array. Stringify every element. Use null as a placeholder
  289. // for non-JSON values.
  290.  
  291. length = value.length;
  292. for (i = 0; i < length; i += 1) {
  293. partial[i] = str(i, value) || 'null';
  294. }
  295.  
  296. // Join all of the elements together, separated with commas, and wrap them in
  297. // brackets.
  298.  
  299. v = partial.length === 0 ? '[]' : gap ?
  300. '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
  301. '[' + partial.join(',') + ']';
  302. gap = mind;
  303. return v;
  304. }
  305.  
  306. // If the replacer is an array, use it to select the members to be stringified.
  307.  
  308. if (rep && typeof rep === 'object') {
  309. length = rep.length;
  310. for (i = 0; i < length; i += 1) {
  311. k = rep[i];
  312. if (typeof k === 'string') {
  313. v = str(k, value);
  314. if (v) {
  315. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  316. }
  317. }
  318. }
  319. } else {
  320.  
  321. // Otherwise, iterate through all of the keys in the object.
  322.  
  323. for (k in value) {
  324. if (Object.prototype.hasOwnProperty.call(value, k)) {
  325. v = str(k, value);
  326. if (v) {
  327. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  328. }
  329. }
  330. }
  331. }
  332.  
  333. // Join all of the member texts together, separated with commas,
  334. // and wrap them in braces.
  335.  
  336. v = partial.length === 0 ? '{}' : gap ?
  337. '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
  338. '{' + partial.join(',') + '}';
  339. gap = mind;
  340. return v;
  341. }
  342. }
  343.  
  344. // If the JSON object does not yet have a stringify method, give it one.
  345.  
  346. if (typeof JSON.stringify !== 'function') {
  347. JSON.stringify = function (value, replacer, space) {
  348.  
  349. // The stringify method takes a value and an optional replacer, and an optional
  350. // space parameter, and returns a JSON text. The replacer can be a function
  351. // that can replace values, or an array of strings that will select the keys.
  352. // A default replacer method can be provided. Use of the space parameter can
  353. // produce text that is more easily readable.
  354.  
  355. var i;
  356. gap = '';
  357. indent = '';
  358.  
  359. // If the space parameter is a number, make an indent string containing that
  360. // many spaces.
  361.  
  362. if (typeof space === 'number') {
  363. for (i = 0; i < space; i += 1) {
  364. indent += ' ';
  365. }
  366.  
  367. // If the space parameter is a string, it will be used as the indent string.
  368.  
  369. } else if (typeof space === 'string') {
  370. indent = space;
  371. }
  372.  
  373. // If there is a replacer, it must be a function or an array.
  374. // Otherwise, throw an error.
  375.  
  376. rep = replacer;
  377. if (replacer && typeof replacer !== 'function' &&
  378. (typeof replacer !== 'object' ||
  379. typeof replacer.length !== 'number')) {
  380. throw new Error('JSON.stringify');
  381. }
  382.  
  383. // Make a fake root object containing our value under the key of ''.
  384. // Return the result of stringifying the value.
  385.  
  386. return str('', {'': value});
  387. };
  388. }
  389.  
  390.  
  391. // If the JSON object does not yet have a parse method, give it one.
  392.  
  393. if (typeof JSON.parse !== 'function') {
  394. JSON.parse = function (text, reviver) {
  395.  
  396. // The parse method takes a text and an optional reviver function, and returns
  397. // a JavaScript value if the text is a valid JSON text.
  398.  
  399. var j;
  400.  
  401. function walk(holder, key) {
  402.  
  403. // The walk method is used to recursively walk the resulting structure so
  404. // that modifications can be made.
  405.  
  406. var k, v, value = holder[key];
  407. if (value && typeof value === 'object') {
  408. for (k in value) {
  409. if (Object.prototype.hasOwnProperty.call(value, k)) {
  410. v = walk(value, k);
  411. if (v !== undefined) {
  412. value[k] = v;
  413. } else {
  414. delete value[k];
  415. }
  416. }
  417. }
  418. }
  419. return reviver.call(holder, key, value);
  420. }
  421.  
  422.  
  423. // Parsing happens in four stages. In the first stage, we replace certain
  424. // Unicode characters with escape sequences. JavaScript handles many characters
  425. // incorrectly, either silently deleting them, or treating them as line endings.
  426.  
  427. text = String(text);
  428. cx.lastIndex = 0;
  429. if (cx.test(text)) {
  430. text = text.replace(cx, function (a) {
  431. return '\\u' +
  432. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  433. });
  434. }
  435.  
  436. // In the second stage, we run the text against regular expressions that look
  437. // for non-JSON patterns. We are especially concerned with '()' and 'new'
  438. // because they can cause invocation, and '=' because it can cause mutation.
  439. // But just to be safe, we want to reject all unexpected forms.
  440.  
  441. // We split the second stage into 4 regexp operations in order to work around
  442. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  443. // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  444. // replace all simple value tokens with ']' characters. Third, we delete all
  445. // open brackets that follow a colon or comma or that begin the text. Finally,
  446. // we look to see that the remaining characters are only whitespace or ']' or
  447. // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
  448.  
  449. if (/^[\],:{}\s]*$/
  450. .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  451. .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
  452. .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  453.  
  454. // In the third stage we use the eval function to compile the text into a
  455. // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  456. // in JavaScript: it can begin a block or an object literal. We wrap the text
  457. // in parens to eliminate the ambiguity.
  458.  
  459. j = eval('(' + text + ')');
  460.  
  461. // In the optional fourth stage, we recursively walk the new structure, passing
  462. // each name/value pair to a reviver function for possible transformation.
  463.  
  464. return typeof reviver === 'function' ?
  465. walk({'': j}, '') : j;
  466. }
  467.  
  468. // If the text is not JSON parseable, then a SyntaxError is thrown.
  469.  
  470. throw new SyntaxError('JSON.parse');
  471. };
  472. }
  473.  
  474. // Augment the basic prototypes if they have not already been augmented.
  475. // These forms are obsolete. It is recommended that JSON.stringify and
  476. // JSON.parse be used instead.
  477.  
  478. if (!Object.prototype.toJSONString) {
  479. Object.prototype.toJSONString = function (filter) {
  480. return JSON.stringify(this, filter);
  481. };
  482. Object.prototype.parseJSON = function (filter) {
  483. return JSON.parse(this, filter);
  484. };
  485. }
  486. }());
  487. function $(select){
  488. var name = select.substring(1);
  489. switch(select.charAt(0)){
  490. case '#':
  491. return document.getElementById(name);
  492. case '.':
  493. return document.getElementsByClassName(name);
  494. case '/':
  495. return document.getElementsByTagName(name);
  496. default:
  497. return document.getElementsByName(select);
  498. }
  499. };
  500. function getNowTimeStamp(){ // 当前时刻 yyyy-m-d h:m:s
  501. var nowtime = new Date();
  502. var timestamp =(nowtime.getYear()+1900)+'-'+(nowtime.getMonth()+1)+'-'+nowtime.getDate()+' '+checkTime(nowtime.getHours())+':'+checkTime(nowtime.getMinutes())+':'+checkTime(nowtime.getSeconds());
  503. return timestamp;
  504. }
  505. function timeDiff(date1,date2){// 比较日期大小,年,月,日,小时,分钟
  506. var re=/^(\d{4})\S(\d{1,2})\S(\d{1,2})\s(\d{1,2})\S(\d{1,2})$/;
  507. var dt1,dt2;
  508. if (re.test(date1)) dt1=new Date(RegExp.$1,RegExp.$2-1,RegExp.$3,RegExp.$4,RegExp.$5);
  509. if (re.test(date2)) dt2=new Date(RegExp.$1,RegExp.$2-1,RegExp.$3,RegExp.$4,RegExp.$5);
  510. else dt2=new Date();
  511. return dt1>=dt2;
  512. }
  513. function dateDiff(date1,date2){// 比较日期大小,年月日
  514. var re=/^(\d{4})\S(\d{1,2})\S(\d{1,2})$/;
  515. var dt1,dt2;
  516. if (re.test(date1)) dt1=new Date(RegExp.$1,RegExp.$2-1,RegExp.$3);
  517. if (re.test(date2)) dt2=new Date(RegExp.$1,RegExp.$2-1,RegExp.$3);
  518. return Math.floor((dt2-dt1)/(1000*60*60*24))
  519. }
  520. function checkTime(i){ // 一位数的时间前加0
  521. if (i<10)
  522. {i="0" + i}
  523. return i
  524. }
  525. function getKeys(e){ // keycode 转换
  526. var codetable={'96':'Numpad 0','97':'Numpad 1','98':'Numpad 2','99':'Numpad 3','100':'Numpad 4','101':'Numpad 5','102':'Numpad 6','103':'Numpad 7','104':'Numpad 8','105':'Numpad 9','106':'Numpad *','107':'Numpad +','108':'Numpad Enter','109':'Numpad -','110':'Numpad .','111':'Numpad /','112':'F1','113':'F2','114':'F3','115':'F4','116':'F5','117':'F6','118':'F7','119':'F8','120':'F9','121':'F10','122':'F11','123':'F12','8':'BackSpace','9':'Tab','12':'Clear','13':'Enter','16':'Shift','17':'Ctrl','18':'Alt','20':'Cape Lock','27':'Esc','32':'Spacebar','33':'Page Up','34':'Page Down','35':'End','36':'Home','37':'←','38':'↑','39':'→','40':'↓','45':'Insert','46':'Delete','144':'Num Lock','186':';:','187':'=+','188':',<','189':'-_','190':'.>','191':'/?','192':'`~','219':'[{','220':'\|','221':']}','222':'"'};
  527. var Keys = '';
  528. e.shiftKey && (e.keyCode != 16) && (Keys += 'shift+');
  529. e.ctrlKey && (e.keyCode != 17) && (Keys += 'ctrl+');
  530. e.altKey && (e.keyCode != 18) && (Keys += 'alt+');
  531. return Keys + (codetable[e.keyCode] || String.fromCharCode(e.keyCode) || '');
  532. };
  533. function addHotKey(codes,func){// 监视并执行快捷键对应的函数
  534. document.addEventListener('keydown', function(e){
  535. if ((e.target.tagName != 'INPUT') && (e.target.tagName != 'TEXTAREA') && getKeys(e) == codes){
  536. func();
  537. e.preventDefault();
  538. e.stopPropagation();
  539. }
  540. }, false);
  541. };
  542. // 触发函数
  543. function onToggleBlackList(e){// 黑名单[名字]触发
  544. var v = e.target.value;
  545. var bShow = e.target.checked;
  546. if(_bVIEWTHREAD>0){
  547. var s = document.evaluate("//div[@class='postinfo']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  548. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  549. var t = s.snapshotItem(i);
  550. var a = t.getElementsByTagName('a')[0];
  551. if( a != undefined){
  552. var u = a.href.substring(a.href.indexOf('uid')+4);
  553. if((u+'='+a.text) == v)t.parentNode.parentNode.parentNode.parentNode.style.display = bShow?'none':'';
  554. }
  555. }
  556. }
  557. if(_bFORUMDISPLAY>0){
  558. var s = document.evaluate("//td[@class='f_author']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  559. for (var i = s.snapshotLength - 1; i >= 0; i--) { // 屏蔽BLACK_LIST的发帖
  560. var t = s.snapshotItem(i);
  561. var a = t.getElementsByTagName('a')[0];
  562. if( a != undefined){
  563. var n = a.text;
  564. var u = a.href.substring(a.href.indexOf('uid')+4);
  565. if((u+'='+a.text) == v)t.parentNode.style.display = bShow?'none':'';
  566. }
  567. }
  568. }
  569. };
  570. function onBlockUser(e){ // [屏蔽] 按钮触发
  571. var a = e.target.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('postinfo')[0].getElementsByTagName('a')[0];
  572. var nm= a.text;
  573. var id= a.href.substring(a.href.indexOf('uid')+4);
  574. if(blacklistStr.indexOf(id+'='+nm)<0){//检查有没有重复的
  575. blacklistArray.push(id+'='+nm);
  576. blacklistStr = blacklistArray.toString();
  577. GM_setValue('HiPDA_Discovery_BLACK_LIST',blacklistArray.join());
  578. blacklistLen=blacklistArray.length;
  579. }
  580. _syn_modified = true;
  581. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  582. // 重新激活同步按钮
  583. document.getElementById('s_syn').className="enable";
  584. document.getElementById('s_syn').innerHTML="₪ 同步";
  585. document.getElementById('s_syn').style.background='#eef9eb';
  586. document.getElementById('s_syn').style.color='#000';
  587. refreshConfigDiv();
  588. processBlackList();
  589. };
  590. function onWindowResize(){ // 调整body宽度
  591. // alert('resize');
  592. if(_simple_style){
  593. if(window.innerWidth>1600)
  594. GM_addStyle("body {width:65%;}");
  595. else if(window.innerWidth>1400)
  596. GM_addStyle("body {width:75%;}");
  597. else if(window.innerWidth>1200)
  598. GM_addStyle("body {width:85%;}");
  599. else
  600. GM_addStyle("body {width:980px;}");
  601. }
  602. }
  603. function onAttachImageLoaded(){ // 附件图片加载完成后修改宽度
  604. var newimg = new Image();
  605. newimg.src =this.src;
  606. if(newimg.width<=_att_max_width ){
  607. this.width=newimg.width;
  608. //去除zoom
  609. this.removeAttribute('onclick');
  610. this.className="nozoom";
  611. }
  612. else
  613. this.width=_att_max_width;
  614. }
  615. function onLoadNewPage(req){ // 后台读取页面完毕
  616. try {
  617. if (req.status == 200) {
  618. var newPageHTML = req.responseText.substring(req.responseText.indexOf('<table summary="forum_'),req.responseText.indexOf('</form>'));
  619. var newPageThread= newPageHTML.substring(newPageHTML.indexOf('<tbody id="normalthread_'),newPageHTML.indexOf('</table>'));
  620. var threadList = document.getElementsByName("moderate")[0].getElementsByClassName("datatable")[0];
  621. // 增加预取了页面的提示
  622. // var newpagetip="<tbody><tr><td class='folder'></td><td><center>---------- 第"+_pc+"页 ----------</center></td><th class='subject'>&nbsp</th><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr></tbody>";
  623. var newpagetip="<tbody><tr><td colspan=5><center>---------- 第"+_pc+"页 ----------</center></td></tr></tbody>";
  624. threadList.innerHTML = threadList.innerHTML + newpagetip + newPageThread;
  625. // 去除预取页面对应的选择导航按钮
  626. var pagenav=document.evaluate("//div[@class='pages']//a",
  627. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  628. for(var btncnt=pagenav.snapshotLength-1;btncnt>=0;btncnt--){
  629. var btn=pagenav.snapshotItem(btncnt);
  630. if(btn.text == _pc)btn.parentNode.removeChild(btn);
  631. }
  632. }
  633. } catch (e) {}
  634. refreshMinTime();
  635. _max_read_pages--;
  636. if( _max_read_pages && (timeDiff(_pmt,_lvt))){
  637. _pc++;
  638. GM_xmlhttpRequest({
  639. method: 'GET',
  640. url: 'http://'+document.domain+'/forum/forumdisplay.php?fid='+_fid+'&page='+_pc,
  641. onload: onLoadNewPage,
  642. overrideMimeType: "text/html; charset=gbk"
  643. });
  644. }
  645. processHighlightColor();
  646. processBlackList();
  647. }
  648. function onSynReply(req){ // 同步时,服务器返回结果
  649. document.getElementById('s_syn').className="disabled";
  650. // try {
  651. _syn_pending=false;
  652. if (req.status == 200) { // 200 OK
  653. var response=JSON.parse(req.responseText);
  654. // alert(response.list); // 输出中文,不乱码
  655. // response.result
  656. // .version
  657. // .list
  658. var nowtimestamp=getNowTimeStamp();
  659. switch(response.result){
  660. case "0": // 无更新
  661. document.getElementById('s_syn').style.background='#88ff88';
  662. document.getElementById('s_syn').innerHTML="√ 无更新";
  663. GM_setValue('HiPDA_Discovery_SYN_LASTTIME',nowtimestamp);
  664. break;
  665. case "1": // OK,本地覆盖了服务器,返回新的版本号
  666. _syn_lastversion = response.version;
  667. _syn_modified = false;
  668. GM_setValue("HiPDA_Discovery_SYN_LASTVERSION",_syn_lastversion);
  669. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  670. document.getElementById('s_syn').style.background='#88ff88';
  671. document.getElementById('s_syn').innerHTML="√ 已同步";
  672. GM_setValue('HiPDA_Discovery_SYN_LASTTIME',nowtimestamp);
  673. break;
  674. case "2": // 服务器有更高版本覆盖本地列表
  675. var newblacklistArray = new Array();
  676. if( response.list )
  677. newblacklistArray = response.list.split(",");
  678. GM_setValue("HiPDA_Discovery_BLACK_LIST",newblacklistArray.join());
  679. _syn_lastversion = response.version;
  680. GM_setValue("HiPDA_Discovery_SYN_LASTVERSION",_syn_lastversion);
  681. _syn_modified = false;
  682. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  683. document.getElementById('s_syn').style.background='#88ff88';
  684. document.getElementById('s_syn').innerHTML="√ 已更新";
  685. GM_setValue('HiPDA_Discovery_SYN_LASTTIME',nowtimestamp);
  686. break;
  687. case "3": // 冲突 TODO
  688. serverBlacklist = new Array();
  689. if( response.list )
  690. serverBlacklist = response.list.split(",");
  691. serverListStr = serverBlacklist.join();
  692. document.getElementById('s_syn').addEventListener('click', processConflict, false);
  693. serverVersion = response.version;
  694. _syn_pending = true;
  695. processConflict();
  696. document.getElementById('s_syn').style.background='#f00';
  697. document.getElementById('s_syn').style.color='#fff';
  698. document.getElementById('s_syn').innerHTML="! 有冲突";
  699. document.getElementById('s_syn').title="版本有冲突";
  700. break;
  701. case "4": // 参数错误
  702. document.getElementById('s_syn').style.background='#f00';
  703. document.getElementById('s_syn').style.color='#fff';
  704. document.getElementById('s_syn').innerHTML="X 参数错误";
  705. document.getElementById('s_syn').title=response.list;
  706. break;
  707. case "5": // 频繁刷新
  708. document.getElementById('s_syn').style.background='#f00';
  709. document.getElementById('s_syn').style.color='#fff';
  710. document.getElementById('s_syn').innerHTML="服务器忙";
  711. document.getElementById('s_syn').title="限定10s一次";
  712. break;
  713. case "500": // 服务器错误
  714. document.getElementById('s_syn').style.background='#f00';
  715. document.getElementById('s_syn').style.color='#fff';
  716. document.getElementById('s_syn').innerHTML="服务器错误";
  717. break;
  718. default:
  719. document.getElementById('s_syn').innerHTML="! 未知错误";
  720. }
  721. refreshConfigDiv();
  722. }
  723. else { // 500,404,443,...
  724. document.getElementById('s_syn').style.background='#f00';
  725. document.getElementById('s_syn').style.color='#fff';
  726. document.getElementById('s_syn').innerHTML="X 网络错误";
  727. }
  728. // }
  729. // catch (e) {
  730. // document.getElementById('s_syn').style.background='#f00';
  731. // document.getElementById('s_syn').style.color='#fff';
  732. // document.getElementById('s_syn').innerHTML="! 格式错误";
  733. // }
  734. }
  735. function onSynChooseBtn(choose){ // 同步冲突界面选择按钮
  736. var nowtimestamp=getNowTimeStamp();
  737. switch (choose){
  738. case 0: // 使用 新列表
  739. // 把配置界面显示出来,等待服务器回应
  740. document.getElementById('hp_cfg_div').style.display = "";
  741. document.getElementById('s_syn').style.background='#999';
  742. document.getElementById('s_syn').innerHTML="同步中...";
  743. // _syn_pending=false;
  744. // 获取新列表
  745. var r = document.getElementsByClassName('hpdtool_syn_chk_new');
  746. for (var i = r.length-1; i >= 0; i--)
  747. if(r[i].checked)
  748. newBlacklist.push(r[i].value);
  749. // 存储新列表,服务器的版本号,标志已修改
  750. GM_setValue("HiPDA_Discovery_BLACK_LIST",newBlacklist.join());
  751. _syn_lastversion = serverVersion;
  752. GM_setValue("HiPDA_Discovery_SYN_LASTVERSION",_syn_lastversion);
  753. _syn_modified = true;
  754. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  755. GM_setValue('HiPDA_Discovery_SYN_LASTTIME',nowtimestamp);
  756. document.getElementById('s_syn').removeEventListener('click', processConflict, false);
  757. // 向服务器发起请求
  758. var data={
  759. "uid":_uid,
  760. "lastversion":_syn_lastversion,
  761. "modified":_syn_modified,
  762. "action":"update",
  763. "blacklist":newBlacklist
  764. };
  765. GM_xmlhttpRequest({
  766. method: 'GET',
  767. url: 'http://hipdatool.sinaapp.com/sync.php?data='+JSON.stringify(data),
  768. onload: onSynReply,
  769. overrideMimeType: "text/html; charset=gbk"
  770. });
  771. break;
  772. case 1: // 使用 服务器
  773. GM_setValue("HiPDA_Discovery_BLACK_LIST",serverBlacklist.join());
  774. _syn_lastversion = serverVersion;
  775. GM_setValue("HiPDA_Discovery_SYN_LASTVERSION",_syn_lastversion);
  776. _syn_modified = false;
  777. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  778. document.getElementById('s_syn').style.background='#88ff88';
  779. document.getElementById('s_syn').innerHTML="√ 已更新";
  780. GM_setValue('HiPDA_Discovery_SYN_LASTTIME',nowtimestamp);
  781. refreshConfigDiv();
  782. document.getElementById('hp_cfg_div').style.display = "";
  783. document.getElementById('s_syn').removeEventListener('click', processConflict, false);
  784. _syn_pending=false;
  785. break;
  786. case 2: // 使用 本地
  787. // 把配置界面显示出来,等待服务器回应
  788. document.getElementById('hp_cfg_div').style.display = "";
  789. document.getElementById('s_syn').style.background='#999';
  790. document.getElementById('s_syn').innerHTML="同步中...";
  791. // _syn_pending=false;
  792. // 向服务器发起请求
  793. var data={
  794. "uid":_uid,
  795. "lastversion":_syn_lastversion,
  796. "modified":_syn_modified,
  797. "action":"update",
  798. "blacklist":blacklistArray
  799. };
  800. GM_xmlhttpRequest({
  801. method: 'GET',
  802. url: 'http://hipdatool.sinaapp.com/sync.php?data='+JSON.stringify(data),
  803. onload: onSynReply,
  804. overrideMimeType: "text/html; charset=gbk"
  805. });
  806. document.getElementById('s_syn').removeEventListener('click', processConflict, false);
  807. break;
  808. default:
  809. _syn_pending=false;
  810. }
  811. document.getElementById('hpdtool_syn_list').innerHTML="";
  812. document.getElementById('hpdtool_syn_div').style.display = 'none';
  813. }
  814. function onClickSynBtn(){ // 点击同步按钮
  815. if(_syn_pending)return;
  816. if(_uid == 0) return;
  817. if(document.getElementById('s_syn').className=="disabled")return;
  818. _syn_pending=true;
  819. document.getElementById('s_syn').style.background='#999';
  820. document.getElementById('s_syn').innerHTML="同步中...";
  821. var data={
  822. "uid":_uid,
  823. "lastversion":_syn_lastversion,
  824. "modified":_syn_modified,
  825. "action":"sync",
  826. "blacklist":blacklistArray
  827. };
  828. GM_xmlhttpRequest({
  829. method: 'GET',
  830. url: 'http://hipdatool.sinaapp.com/sync.php?data='+JSON.stringify(data),
  831. onload: onSynReply,
  832. overrideMimeType: "text/html; charset=gbk"
  833. });
  834. }
  835. function onPageUnload(){ // 关闭页面时保存参数
  836. _lvt = year + "-" + month + "-" + day + " " + hour + ":" + min;
  837. if((_pc == 1)&&(timeDiff(_lvt,_pxt)))
  838. GM_setValue("HiPDA_Discovery_LAST_VISIT_TIME"+_fid,_lvt);
  839. }
  840. function onSaveConfig(save){ // [保存]、[取消]按钮触发,保存hpd-tool参数以及黑名单编辑结果
  841. if(save){
  842. var r = document.getElementsByClassName('bl_chk');
  843. blacklistArray = new Array();
  844. for (var i = r.length-1; i >= 0; i--)
  845. if(r[i].checked)
  846. blacklistArray.push(r[i].value);
  847. GM_setValue('HiPDA_Discovery_BLACK_LIST',blacklistArray.join());
  848. if(blacklistLen != blacklistArray.length){ // 列表长度变化,表示列表进行了修改
  849. _syn_modified = true;
  850. GM_setValue("HiPDA_Discovery_SYN_MODIFIED",_syn_modified);
  851. // 重新激活同步按钮
  852. document.getElementById('s_syn').className="enable";
  853. document.getElementById('s_syn').innerHTML="₪ 同步";
  854. document.getElementById('s_syn').style.background='#eef9eb';
  855. document.getElementById('s_syn').style.color='#000';
  856. }
  857. blacklistLen=blacklistArray.length;
  858. blacklistStr=blacklistArray.toString();
  859. var temp = document.getElementById('_chk_hightlight_color').value;
  860. if(RegExp("#[A-F,a-f,0-9]{6}").test(temp)){
  861. var t = temp.indexOf("#");
  862. _hightlight_color = temp.substr(t,7);
  863. }/*else alert('wrong color');
  864. alert(_hightlight_color);*/
  865. GM_setValue("HiPDA_Discovery_HIGHLIGHT_COLOR",_hightlight_color);
  866.  
  867. var rd=document.getElementsByName('_radio_font_size');
  868. for(var i=0;i<rd.length;i++)
  869. if(rd[i].checked)_font_size = rd[i].value;
  870. GM_setValue("HiPDA_Discovery_FONT_SIZE",_font_size);
  871. // _hightlight_en = document.getElementById('_chk_hightlight_en').checked;
  872. // _blacklist_en_hpd = document.getElementById('_chk_blacklist_en_hpd').checked;
  873. // _blacklist_en_other = document.getElementById('_chk_blacklist_en_other').checked;
  874. // _simple_style = document.getElementById('_chk_simple_style').checked;
  875. // _hover_style = document.getElementById('_chk_hover_style').checked;
  876. // _reply_avatar = document.getElementById('_chk_reply_avatar').checked;
  877. _hightlight_en = document.getElementById('_chk_hightlight_en').checked;
  878. _blacklist_en_hpd = document.getElementById('_chk_blacklist_en_hpd').checked;
  879. _blacklist_en_other = document.getElementById('_chk_blacklist_en_other').checked;
  880. _simple_style = document.getElementById('_chk_simple_style').checked;
  881. _hover_style = document.getElementById('_chk_hover_style').checked;
  882. _reply_avatar = document.getElementById('_chk_reply_avatar').checked;
  883. GM_setValue("HiPDA_Discovery_HIGHLIGHT_ENABLE",_hightlight_en);
  884. GM_setValue("HiPDA_Discovery_BLACKLIST_ENABLE_HPD",_blacklist_en_hpd);
  885. GM_setValue("HiPDA_Discovery_BLACKLIST_ENABLE_OTHER",_blacklist_en_other);
  886. GM_setValue("HiPDA_Discovery_SIMPLE_STYLE",_simple_style);
  887. GM_setValue("HiPDA_Discovery_HOVER_STYLE",_hover_style);
  888. GM_setValue("HiPDA_Discovery_REPLY_AVATAR",_reply_avatar);
  889. }
  890. document.getElementById('hp_cfg_div').style.display = (document.getElementById('hp_cfg_div').style.display == 'none')?'':'none';
  891. changeFontSize(true);
  892. processBlackList();
  893. };
  894. // 论坛信息
  895. function readPageURL(){ // 取得当前的tid和page值
  896. var offset = window.location.search.indexOf("page=");
  897. if(offset>0){
  898. var t = window.location.search.substr(offset);
  899. if(t.indexOf("&") >0){
  900. _pc = t.slice(5,t.indexOf("&"));
  901. }else{
  902. _pc = t.slice(5);
  903. }
  904. }else{
  905. _pc = 1;
  906. }
  907. offset = window.location.search.indexOf("tid=");
  908. if(offset>0){
  909. var t = window.location.search.substr(offset);
  910. if(t.indexOf("&") >0){
  911. _tid = t.slice(4,t.indexOf("&"));
  912. }else{
  913. _tid = t.slice(4);
  914. }
  915. }
  916. }
  917. function refreshMinTime(){ // 取得当前页面的 _pmt —— 包含预读取的后续页面内容
  918. var snapResults3 = document.evaluate("//td [@class='lastpost']",
  919. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  920. for (var i = snapResults3.snapshotLength - 1; i >= 0; i--){
  921. var e = snapResults3.snapshotItem(i);
  922. //如果是置顶帖子,就不要取时间值
  923. var checkTop = e.parentNode.getElementsByClassName('folder');
  924. if(checkTop[0] != undefined){
  925. if(checkTop[0].innerHTML.indexOf('images/default/pin')<0 && checkTop[0].innerHTML.indexOf('images/default/folder_lock')<0 ){
  926. var _rt = e.getElementsByTagName('a')[1].text;
  927. if(timeDiff(_pmt,_rt))
  928. _pmt = _rt;
  929. }
  930. //else alert(e.getElementsByTagName('a')[1].text);
  931. }
  932. }
  933. }
  934. // 论坛界面修改
  935. function changeURL(){ // 把cnc页面上的连接都换成cnc.4d4y.com
  936. var url = document.evaluate("//a",
  937. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  938. for(var i = url.snapshotLength-1;i>=0;i--){
  939. var a=url.snapshotItem(i);
  940. a.href=a.href.replace(/www.4d4y.com/,document.domain);
  941. };
  942. }
  943. function changeFontSize(save){
  944. var sz=_font_size;
  945. if(save == false){ // 即时预览,未保存字体大小
  946. var rd=document.getElementsByName('_radio_font_size');
  947. for(var i=0;i<rd.length;i++){
  948. if(rd[i].checked == true)
  949. sz=rd[i].value;
  950. }
  951. }
  952. var fnt=".t_msgfont,.t_msgfont td,td,th,.subject,.lastpost,.author,.nums,#newspecialtmp,#newspecial,#postreplay,.signatures,#umenu,#nav,.pages_btns,.threadtype{font-size: "+sz+"px;}";
  953. GM_addStyle(fnt);
  954. fnt = ".postauthor dt {width:"+4*sz+"px} .mainbox td.postauthor{width:180px} .forumcontrol .modaction{width:150px;}";
  955. GM_addStyle(fnt);
  956. }
  957. function changeStyle(){ // 改变页面风格
  958. // 好孩子看不见
  959. GM_addStyle(".goodboysglasses {color:red;font-size:16;border:1px solid #ff0000;padding:15px 15px 15px 52px;width:75%;margin:20px 30px}");
  960. GM_addStyle(".goodboysglasses {background:url(data:img/png;base64,\
  961. iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\
  962. bWFnZVJlYWR5ccllPAAAAqJJREFUeNrsV09rE0EUf7s7k91tTENBQ6FYegoUJRX8AiJegt5UUKkJ\
  963. JLd8A+9+gV5yS0KuirdC9SO0Fy8WwUuzh0hbYou20fyd9b1hdpumZbPohlzy4JHNZOb9fvN7895s\
  964. NNd1YZamw4xtTmBOQEPn9Xr9AKthRdM0yOfzJo71poQXQ6wuVZ4Q4kOhUHhBCiwQ+IOHjyCdXoda\
  965. rdalidMAp9iEQVi6rj/FMZsImMSI6Qasrt6GzMY9IJYRk5A7p9iEQViq/5j+GbBsE/b2duF7swmU\
  966. CrR4hATiFJNiEwZheWeQ+QRME05OfkCxWMzi1+Oo9c/lcvfxI1WpVHYIyzNJgOTgOKh2fqAItCPE\
  967. b6u4bcIgLO8K8BWIMcN7PFUepfWU8zGsCwJkg8EAqtXq0TTrnjBGzSfQ6XRhc/O1l4apGUlPWJcI\
  968. EGir1UJ9BOgT8AWm7s9AgIs9zCNLQV1dB82yQNONYAJiCEa/76/1FUhiaSy+/YwJmsCg58Lpmwwc\
  969. /TyDr/tf5ND6nbuweCsF+0tJmKQfHb3Mr/OrKTBNfIzbcCMWfD2ccwE2kt39+InaNpUsNa6dxy9f\
  970. QSLE5SII1LauEmCM4em0wGTBIXpCAOcMhsOhV7LymcYS6nKZpAAbrwLKoU4EuIkeTCDmCjl3pGSl\
  971. cdU6wxDgCvNyGWJQZliSgBbEfijk3HGjPSVCVoJx/fsAg9zGEnQGHGWOXev0G80Zax8XCjx7LlUI\
  972. dJzDx/sANodDp9FY3squwVZ28g5wrlwz0lwOHcdZXnv/LpQCDcfx15PaScMw0uVyeZtzngoToN/v\
  973. H5dKpSd4+L5JSf9jvabUu4m+otIYppLO0JvoLTX2z+u1kRQuUDsIeY6ol/6mzUS0foYvpfO/ZnMC\
  974. sybwV4ABAEMXBDR9AlSHAAAAAElFTkSuQmCC) no-repeat 10px 5px");
  975. if(_simple_style){ // 启用了精简风格
  976. onWindowResize();
  977. GM_addStyle("\
  978. body {margin:0 auto;background:#f0f0f0;}\
  979. .postact {line-height:20px}\
  980. .postact a,body, td, input, textarea, select, button,.posterinfo em {color:#222222 !important;}\
  981. .postauthor em a {color:#222222}\
  982. .postactions {border-top:0px}\
  983. .postinfo {border-bottom:0px}\
  984. .authorinfo em {margin:0px}\
  985. .posterinfo {color:#ffffff}\
  986. .posterinfo:hover {color:#222222}\
  987. .posterinfo:hover a {color:#222222}\
  988. .posterinfo .pagecontrol {display:none}\
  989. .posterinfo:hover .pagecontrol {display:block}\
  990. .authorinfo a {color:#ffffff}\
  991. .authorinfo:hover a {color:#222222}\
  992. #header .wrap {padding:0}\
  993. #umenu a {margin:0 2px}\
  994. #umenu {position:static;float:right}\
  995. .threadad td.postauthor,.adcontent {background: #f0f0f0;}\
  996. .signatures {font-size: 13px;color:#222222;max-height:100px !important;}\
  997. #moderate .colplural,#moderate .icon,.datatable .icon,#forumheader {display:none}\
  998. #nav {color:#000000;text-indent:0px;background:none;margin-bottom:8px;}\
  999. #nav a,#footlink,#footlink a,#rightinfo,#rightinfo a{color:#000000}\
  1000. .datatable .subject{padding:2px 5px;}\
  1001. td,.subject{font:13px/1.4em;}\
  1002. ");
  1003. }
  1004. changeFontSize();
  1005. if(!_hover_style){ // 用户 注册、积分、发帖数 等显示在头像下方
  1006. var s = document.evaluate("//td[@class='postauthor']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1007. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1008. var userdata=s.snapshotItem(i).getElementsByTagName('dl')[0];
  1009. if(userdata != undefined){
  1010. userdata.style.margin="0px 10px 0px 20px";
  1011. // 去掉了一些项目
  1012. userdata.removeChild(userdata.lastChild);
  1013. userdata.removeChild(userdata.lastChild);
  1014. var regtime1=userdata.lastChild;
  1015. userdata.removeChild(userdata.lastChild);
  1016. var regtime2=userdata.lastChild;
  1017. userdata.removeChild(userdata.lastChild);
  1018. userdata.removeChild(userdata.lastChild);
  1019. userdata.removeChild(userdata.lastChild);
  1020. userdata.appendChild(regtime2);
  1021. userdata.appendChild(regtime1);
  1022. s.snapshotItem(i).appendChild(userdata);
  1023. // 去除头像悬停菜单
  1024. var avatar=s.snapshotItem(i).getElementsByClassName('avatar')[0];
  1025. avatar.removeAttribute('onmouseover');
  1026. }
  1027. }
  1028. GM_addStyle(".postauthor dt,.postauthor dd {color:#222222;height:1.2em;line-height:1.2em;}");
  1029. }
  1030. if(!_reply_avatar && _bVIEWTHREAD>0 && document.getElementById('fastpostform') )document.getElementById('fastpostform').getElementsByClassName('avatar')[0].innerHTML="";
  1031. // 【发表回复】、【发表新帖】
  1032. if(document.getElementById('post_reply')) document.getElementById('post_reply').getElementsByTagName('a')[0].innerHTML="发表回复";
  1033. if(document.getElementById('newspecial')) document.getElementById('newspecial').innerHTML="发表新帖";
  1034. if(document.getElementById('newspecialtmp')) document.getElementById('newspecialtmp').innerHTML="发表新帖";
  1035. GM_addStyle("#post_reply,.forumcontrol #newspecial,.pages_btns #newspecial,.forumcontrol #newspecialtmp,.pages_btns #newspecialtmp{border:1px solid #003B54;line-height:22px;padding:2px 8px 2px 8px;float:left;margin:2px 5px 3px 5px}");
  1036.  
  1037. // 顶部菜单
  1038. if(document.getElementById('menu')){
  1039. document.getElementById('menu').style.display='none';
  1040. if(_uid>0){
  1041. document.getElementById('umenu').appendChild(document.createTextNode(" | "));
  1042. var menuitem=document.createElement('a');
  1043. menuitem.innerHTML="搜索";
  1044. menuitem.href='http://'+document.domain+'/forum/search.php';
  1045. document.getElementById('umenu').appendChild(menuitem);
  1046. document.getElementById('umenu').appendChild(document.createTextNode(" | "));
  1047. menuitem=document.createElement('a');
  1048. menuitem.innerHTML="我的主题";
  1049. menuitem.target="_blank";
  1050. menuitem.href='http://'+document.domain+'/forum/my.php?item=threads';
  1051. document.getElementById('umenu').appendChild(menuitem);
  1052. document.getElementById('umenu').appendChild(document.createTextNode(" "));
  1053. menuitem=document.createElement('a');
  1054. menuitem.innerHTML="我的回复";
  1055. menuitem.target="_blank";
  1056. menuitem.href='http://'+document.domain+'/forum/my.php?item=posts';
  1057. document.getElementById('umenu').appendChild(menuitem);
  1058. document.getElementById('umenu').appendChild(document.createTextNode(" "));
  1059. menuitem=document.createElement('a');
  1060. menuitem.innerHTML="我的收藏";
  1061. menuitem.target="_blank";
  1062. menuitem.href='http://'+document.domain+'/forum/my.php?item=favorites&type=thread';
  1063. document.getElementById('umenu').appendChild(menuitem);
  1064. }
  1065. }
  1066. // 下一页
  1067. // var nextpageurl=document.getElementsByClassName('pages')[1].getElementsByClassName('next')[0];
  1068. // if(nextpageurl != undefined){
  1069. // GM_addStyle(".thread-follow-page{border:1px solid #f00;height:31px;line-height:31px;align:center} .thread-follow-page a:hover{text-decoration:none}.thread-follow-page a{background-color:#DFD0BD;display:block;width:100%;height:31px;}");
  1070. // var nextpagebtn=document.createElement('div');
  1071. // nextpagebtn.className="thread-follow-page";
  1072. // nextpagebtn.innerHTML="<a href='"+nextpageurl.href+"'>点击显示下一页</a>"
  1073. // var pagenav=document.getElementsByClassName('forumcontrol')[1];
  1074. // if(pagenav != undefined){
  1075. // document.getElementsByTagName('body')[0].appendChild(nextpagebtn);
  1076. // document.getElementById('wrap').insertBefore(nextpagebtn,pagenav);
  1077. // }
  1078. // }
  1079. }
  1080. function appendControl(){ // 添加[屏蔽]按钮
  1081. var s = document.evaluate("//div[@class='authorinfo']",
  1082. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1083. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1084. var t = s.snapshotItem(i);
  1085. var a1=document.createElement('a');
  1086. a1.innerHTML = '屏蔽';
  1087. a1.href = '###';
  1088. a1.addEventListener('click', onBlockUser,false);
  1089. t.appendChild(document.createTextNode(" | "));
  1090. t.appendChild(a1);
  1091. }
  1092. };
  1093. function addConfigDiv(){ // 添加Alt+O的界面
  1094. // 处理冲突界面
  1095. GM_addStyle('\
  1096. #hpdtool_syn_div { position:fixed;width:303px;bottom:20px;right:20px;font-size:13px;z-index:999;text-align:left;background-color:#9287AE;padding:15px;border:2px solid #bfbfbf;-moz-border-radius:5px;opacity:0.95;}\
  1097. #hpdtool_syn_div hr {color: #bfbfbf;border: 1px solid;margin: 8px 0;}\
  1098. #hpdtool_syn_div,#hpdtool_syn_div td,.hpdtool_syn_srv,.hpdtool_syn_lcl {color:#ffffff !important;}\
  1099. #hpdtool_syn_list {margin-left:5px;max-height:600px;overflow:auto;}\
  1100. #hpdtool_syn_div a {padding:2px 5px;-moz-border-radius: 4px;background: #eef9eb;width: 50px;border: 1px solid #aaa;}\
  1101. #hpdtool_syn_div a:hover {border: 1px solid #aaa;background: #fff;color: #000;}\
  1102. #hpdtool_syn_div .hpdtool_syn_new {width:45px;text-align:center;border-right:1px solid #fff;}\
  1103. #hpdtool_syn_div .hpdtool_syn_srv {width:78px;max-width:78px;text-align:center;border-right:1px solid #fff;padding:2px 5px;}\
  1104. #hpdtool_syn_div .hpdtool_syn_lcl {width:78px;max-width:78px;text-align:center;padding:2px 5px;}\
  1105. ');
  1106. var hpdtool_syn = document.createElement("div");
  1107. hpdtool_syn.id = "hpdtool_syn_div";
  1108. hpdtool_syn.style.display = "none";
  1109. hpdtool_syn.innerHTML = "<div class='locker'><center><font face='Impact' size=3>同步冲突处理</font></center><hr>\
  1110. 本地与服务器黑名单差异部分,<b>相同部分已省略</b>。请点选对应的列表进行同步。\
  1111. <div id='hpdtool_syn_list'></div><br />\
  1112. <a href='javascript:void(0)' id='hpdtool_use_new' >新列表</a>\
  1113. <a href='javascript:void(0)' id='hpdtool_use_server' >服务器列表</a>\
  1114. &nbsp;&nbsp;<a href='javascript:void(0)' id='hpdtool_use_local' >本地列表</a>\
  1115. &nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:void(0)' id='hpdtool_use_nothing' >保持不变</a></div>";
  1116. document.getElementsByTagName('body')[0].appendChild(hpdtool_syn);
  1117. document.getElementById('hpdtool_use_new').addEventListener('click', function(){onSynChooseBtn(0);}, false);
  1118. document.getElementById('hpdtool_use_server').addEventListener('click', function(){onSynChooseBtn(1);}, false);
  1119. document.getElementById('hpdtool_use_local').addEventListener('click', function(){onSynChooseBtn(2);}, false);
  1120. document.getElementById('hpdtool_use_nothing').addEventListener('click', function(){onSynChooseBtn(3);}, false);
  1121. // Alt+O 控制界面
  1122. GM_addStyle('\
  1123. #hp_cfg_div {position:fixed;align:center;width: 303px;padding: 15px;bottom:20px;right:20px;z-index:99;color:#fff;background:#9287AE;border:2px solid #bfbfbf;-moz-border-radius:5px;opacity:0.95;text-align:left;font-size:14px !important;}\
  1124. #hp_cfg_div input {height: 12px}\
  1125. #s_syn {display: none}\
  1126. #hp_cfg_div hr {color: #bfbfbf;border: 1px solid;margin: 8px 0;}\
  1127. #hp_cfg_div a {-moz-border-radius: 4px;background: #eef9eb;width: 50px;border: 1px solid #aaa;}\
  1128. #hp_cfg_div a:hover {border: 1px solid #aaa;background: #fff;color: #000;}\
  1129. #s_ok,#s_cl,#s_syn {padding:2px 5px;}\
  1130. #blacklist {margin-left:5px;max-height:600px;overflow:auto;}\
  1131. #_chk_hightlight_color {margin-left:4px;}\
  1132. ');
  1133. var hp_cfg = document.createElement("div");
  1134. hp_cfg.id = "hp_cfg_div";
  1135. hp_cfg.style.display = "none";
  1136. hp_cfg.innerHTML = '<center><font face="Impact" size=3 title="来自D版带着爱">4d4y &hearts; tool</font> <sub>version 5.2</sub></center><hr />\
  1137. 字体大小:\
  1138. <input type="radio" id="_font_size_13px" name="_radio_font_size" value="13" /><font size=2>小</font>\
  1139. <input type="radio" id="_font_size_14px" name="_radio_font_size" value="14" /><font size=3>中</font>\
  1140. <input type="radio" id="_font_size_16px" name="_radio_font_size" value="16" /><font size=4.5>大</font>\
  1141. <br />\
  1142. 界面风格:\
  1143. <cite title="精简界面风格" ><input type="checkbox" id="_chk_simple_style" />简版</cite>\
  1144. <cite title="用户信息显示在悬浮菜单,不选则显示在头像下方" ><input type="checkbox" id="_chk_hover_style" />头像菜单</cite>\
  1145. <cite title="回帖时显示自己头像" ><input type="checkbox" id="_chk_reply_avatar" />回帖头像</cite>\
  1146. <br />\
  1147. 新帖高亮:\
  1148. <input id="_chk_hightlight_en" type="checkbox" />启用\
  1149. <input id="_chk_hightlight_color" type="text" style="width:65px;height:18px;" title="HTML颜色代码,&#13;输入无效代码将使用原来的设置" value="未定义"/><br />\
  1150. 屏蔽用户:\
  1151. <input id="_chk_blacklist_en_hpd" type="checkbox" />D版\
  1152. <input id="_chk_blacklist_en_other" type="checkbox" />其他\
  1153. <br />\
  1154. <div id="blacklist"></div><br /><br />\
  1155. <div align="center">\
  1156. <a href="javascript:void(0)" id="s_ok" >√ 确定</a>\
  1157. &nbsp;\
  1158. <a href="javascript:void(0)" id="s_cl" >X 取消</a>\
  1159. &nbsp;&nbsp;&nbsp;&nbsp;\
  1160. <a href="javascript:void(0)" id="s_syn" >₪ 同步</a>\
  1161. <br />\
  1162. </div>\
  1163. ';
  1164. document.getElementsByTagName('body')[0].appendChild(hp_cfg);
  1165. if(_uid == 0){
  1166. document.getElementById('s_syn').innerHTML="未登录";
  1167. document.getElementById('s_syn').href="http://"+document.domain+"/forum/logging.php?action=login";
  1168. }
  1169. document.getElementById('s_ok').addEventListener('click', function(){onSaveConfig(true);}, false);
  1170. document.getElementById('s_cl').addEventListener('click', function(){onSaveConfig(false);}, false);
  1171. document.getElementById('s_syn').addEventListener('click', function(){onClickSynBtn(false);}, false);
  1172. document.getElementById('_font_size_13px').addEventListener('click', function(){changeFontSize(false);}, false);
  1173. document.getElementById('_font_size_14px').addEventListener('click', function(){changeFontSize(false);}, false);
  1174. document.getElementById('_font_size_16px').addEventListener('click', function(){changeFontSize(false);}, false);
  1175. addHotKey('alt+O',function(){if(_syn_pending)return;refreshConfigDiv();onSaveConfig(false); });
  1176. addHotKey('Esc',function(){if(_syn_pending)return;else document.getElementById('hp_cfg_div').style.display = 'none'});
  1177. }
  1178. function readConfig(){
  1179. grave_image="url(data:img/png;base64,\
  1180. iVBORw0KGgoAAAANSUhEUgAAAJYAAACECAYAAAEFGOLkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\
  1181. bWFnZVJlYWR5ccllPAAAA1xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp\
  1182. bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6\
  1183. eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz\
  1184. NDM0MiwgMjAxMC8wMS8xMC0xODowNjo0MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo\
  1185. dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw\
  1186. dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEu\
  1187. MC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVz\
  1188. b3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1N\
  1189. Ok9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMTIxRTYyMzYxMjZFMTExOTA1MkM0NDMxNTJG\
  1190. QzY0QSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyNUI0ODYyNDI2NjgxMUUxOEFEMkMyMzg3\
  1191. QkVENjI2OCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyNUI0ODYyMzI2NjgxMUUxOEFEMkMy\
  1192. Mzg3QkVENjI2OCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1Ij4gPHhtcE1N\
  1193. OkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDEyMUU2MjM2MTI2RTExMTkw\
  1194. NTJDNDQzMTUyRkM2NEEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDEyMUU2MjM2MTI2RTEx\
  1195. MTkwNTJDNDQzMTUyRkM2NEEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94Onht\
  1196. cG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5AxfV3AAAPxElEQVR42mL8//8/A7UAEwMVAQuMsfX8\
  1197. IRCF7ExGZIXehnbEG4ZmEJgPNIDx27dvYA6UxmoZFxcXdm/euX4LoZqRqRyfZQTDTEVTDc7ecu5A\
  1198. B4o3hE1RaHQDkQ2bjCUYfpISAYzISQMYCR+AFD+6Ikd1E7xmwMKMEVc6Axr8n2qGwQCWWMRpGFUT\
  1199. 7aAz7P+Auew/WekMFzh06BA+Qxnt7OxI9uZ2LGKrkTkAAcQ4uAtHaMG4HogDoOJ5yBmfmIIR7k2g\
  1200. YTpA9mU0OQ6gIT9hhSOWmMVZOF4+svsAmHHh5FmYmh/AwpGBnMKxzMbVAcwwMDdGqP7/D0UjUqGI\
  1201. 15s40xGw+GEkudQAVR7YVO6/eaaZrKQBMhBqaB6ScA3VstNo4UiT8ow2JS2xheM5IGWIReoOsGBU\
  1202. JdVlRljEvgCxKrIAQABRtXCkScMRqYxEB2JA/IoYw4gtQ0l2GJGp6hjQAdZoOReDjcVMRnyGwnI3\
  1203. rnQBdxRS2Y0CXjx9ZgVquIHKc7QyHd0cZMyAhU9evkSuBwqi0+BsWKUDbDhvo6BdQtCB6G1jkho8\
  1204. QCAArGs+YnMUrBL78/Y0nA9j46t2cYYYrvoJB/gArLdysIUUyBHIDsHiKLyBgBFi6DkLuSNAADwB\
  1205. hp4MOYUpthCjuBxDyonkGsRIVFQOFjDqsKHosP+07GL+p7bjWKjRdsI3aoTD0YyEQoxqzR5go41s\
  1206. g4CNOoxCHSCABmV7jGk0N1Kp1SoLxI8HQ4sV5JBH+OoxWgOMhE6o5YDeBMLTdEbP+kQ3o5lIbcqQ\
  1207. 0NxBL2DJbz7vWLcZ0aH79BlFDtbWh7XpCbTrye0mYxvwVge34Wsyi8GOANHgruv1Www8fLwMHeUN\
  1208. DHM2L6PIUkJqsHoV5LCEvHSGBZNmMXgE+aLI5VQXM0hIS1HiINISOgnpBQRMgIn+LK5xO+ROBY4O\
  1209. Bs5OBnpIzSLBUWdICSVCw3k4ow/o83RSghkYsmLEqMMRSsSnKRK7Yi+JdQgpDmMipoDEB4D9Q6o3\
  1210. M5gIlNx5A+EwottTwPSjAqRmArETFumfwM4qO7l9QvTcN9CdVaKKhNFG3mB11P/RkBp1FC2bLIN6\
  1211. wGOwRN9/WozAjLAeMrmVOp6+3X8CdR5WfRQ7ClSRHjp0CGToKhKiEqZuPhAnwRY/UDv6QFMooWTo\
  1212. S4R6hurRBwJeUHoeEBswYJ/1RAbnQV1JIA7DJgkQQIN2EnO0+hsNrJEDWPD0rbAJd0H7WsY4tIHW\
  1213. OZYyYF8DSTSg5kAqvVMWaCnXD2g1UYonoEAA1DmdxIAYVlw/IlIWFJwhEDiEQAA00AKBqWUDgQ43\
  1214. XjEym3Ukj7ijzzITm7JmUhhQyGA9MFvPpFK7l5TZR2rMVBJuOiCP1ILWo4DGsGHrUu5cv8kwYeks\
  1215. 8Ng2aAAexAeNeYOGknNqihnWLFjGAFrreOfaLQYVLTUwDV37mOdj5IBSnn39+oWenQNGWqUsMAAF\
  1216. Bmh2ArSwR0JGkuHIngMMLdN74fJgcWAgvXjyHBxQEDEThjXzl0MmCcoakJfhT9py7gCoghCEtkRD\
  1217. 6ZkyKDULX2CB52hAHoZN3+xYu4WBh5eXoSAaMugtIS0JnjEBpZo5m5fBZ1NA2wpAAfvi6TOwHA8f\
  1218. D7K5e4H4PbSVvJocj+EbridiKP8/LbIhTfrGUPAYWODLESjM/xMKDPSRe3xyxGZJSrKhKo0CSxYY\
  1219. GQvoOYBB6wIe3jgEsi9D21vUBlcc1U10BzCwGKlawENb1CAPgdazPqayY3VA0z9AHD/YUxXRKQuL\
  1220. XACNWucfgSmNn57+JyVlkRVYWNSC1q2AFgrXUMED34H4Bah/CQy4viERWPQCWGrD/4M1ZY0O0VB5\
  1221. 1GEUjAbWaGDRtK84mrJGA2tkBNb/wWznaMoiIcCYRniqIsl+ptGAIt4dTKMBRTxgGQRuYGQgb1qL\
  1222. orWq5OhnGSSRBvbEmTNncMmDJm5BExygqSDQgL4EA2Rk4jYQ22ppaeHtAAPNXQ3VizPwTUxMCDty\
  1223. MK2iOXToEGhpUOIAWO1lZ2e3fag1HZIYKFwnQQYApbrtRCX/0fVZxAOAAOydv2sUQRTHZyFlNNqE\
  1224. NFrIBQu1ULcSAtEqhgRyJPirOhSuS2otBMFUlmJjpRYSy/wDmkpBiD9AG0EsoqixNNfKOt/Zmc1m\
  1225. szv7a2Zvd/MehL3L/v7sm7ezN9/3lmDRsyHBIlgEi2CRxfbgE/SkcZY54T6r1VVPWsSzoCndZru6\
  1226. qS22V42H7wsHvRleYL4IF2rl8RRPw7A+HvJOH0RY0IK+Zr4SOatBi/pJQm53zArZMvM1DEUNkCd5\
  1227. HPqatEB0+D6jUjlsuoo7ua3o8D2846GBC/LKwkVOUi3nVTMba4ZQxPwxsA+o/PqGIZletjSshZRg\
  1228. nsceS1lSWVBVrpcZ1p5aCI9WfSk3SqmETX1X88MGLXzE+uHiNClFakyfsBFgI5p4JUwkBuzsCDCQ\
  1229. eAMMJNvQwkMfD9k2ZNyAM/g7EPOELp5PYSikg2VHDx9Cs747TM+w5Vmn1AdVKh/JATOL8wIMTl6V\
  1230. MkLRnqXeDaGR7634oUllYgDY7Qf3BGzY2NEja3xyIu6iVADKswUrCOyqTCqSBz6+3R1QUKVUAQKJ\
  1231. A4ASNsCEpwEcPA1e+PzlepfP+ia7I9jYu4qdw0qGxRv1ATk6YQ+DF6HJIZtiqXddgEDz/P3jZwBp\
  1232. ZnFOwMQ6KhVFlo1SHVts1G1K8ws6cXE/K8s715YK1PAQnLwK5KopYh5gIeUETQ75Oip/59r0vICp\
  1233. vDJUY2t17tx0ELs0iU7aDIu4DApNuat9512kU5oEy+aVDVJRND321LydJFhJ80zA0t27n1mCdUy+\
  1234. 6KDcbTyS0JSnVpmNTmnP4n5LJxzkrZtmIh6m9QptDXh2NN7lDQFeeVg8tqxY3PdyG3/POmNp333u\
  1235. XeeLeFCSF+nmVQKLe9dnPula2v/mxpfNs23yLCbLDMxaOoYNDmysNbAkMChNjls4BoDC+xLGKz53\
  1236. zxosCey7rLu5buHgtzmwF63wrAi0rgz8pjuuV+sMS/e4kyc58zKf3GdmKoz8439PL550b1Vx/qae\
  1237. DQuPDvP1L0kvwVBY5keblHct1hNWlaZ56V3tYJEwxHaAJ1hkBItgESyCRbAIFhnBIljmjIpgkGcR\
  1238. LILV2rhFsBrqWV7d902e1UDP8ppwDFReJcexUDOkrgPBGrqNNOQ4HUOxzklZ16m7Zzmag0ybVxR4\
  1239. 3HadJnmWoykJpcpBwfCCNJSDmpT/G7iuO5G0It8mlsUr5fDmt9k4QFnKQdUCVsxwOcpC4eSnmF8r\
  1240. K81GNZCZ3NadmOb3RG7/im7Ivs4x6z1Lf62eKVN1uqCCyaSAqdvdcBj60qmm3g3RNDp5TqCkfWD7\
  1241. y9s1BtbNmKDekcF8ouS2UQHgl7w5DCL7ynYHomJj2e2/AO2dO2gUQRzGJ8GgRTSkUINolaj4CPgI\
  1242. CCpBwcZHQBQVbAQRrUx3amEhaBOChcFGELXS+MJARATxQcRUURtBRIuAgiKBoFiY6pxvMxPGzd5l\
  1243. d28fM3vfB8Pd7c3e3u789j+P3f2GB4ti15AiWBTBoiiCRREsqp4VabwhgnOpX5vVuMF6lVaohOdW\
  1244. YQ80pV5/qnGBDyqN2nCQbHZNLQRYEQQj02MinP+dzlPN3+6XmH7GGA9o32Wx1VdVCHtO7dxYEsmZ\
  1245. KkItCtRB9fuDIplHiylLwUK19kQVdpaWMnjsGtcI4US8m8VYrKrwpEp5Rg4Ndq9sB8UyrQrj4BzD\
  1246. 5Xku1TphV2YKe40+qYiF6HTNoupoQHYsnisTCRtVFrU7Y5cT+h1rq8KSSMbuPGkBKsC11UKY0t6G\
  1247. 82B1iNomG8hCb3KOXHkUtnWARQVLj0fNElyTYUENaUNz2E6f6Dk6k0cv1/lhImxKuzTPJWxH+4Rj\
  1248. Hb8zvdQVmBwHOc7HdKB3pXCtASzSbTOysAaCen96GgGABBdqmMHDqhuO1fisvdBh8W3mf3Drjti+\
  1249. a4fnTA3o8D0svwHOtMN+s+dsDV91fAeA9O+1LV8mmhcu/D+crl1lOlxjaqlt+zbtqDrFVBXn67Qa\
  1250. 4ZmVrUuN90VBC1HogAMgAQTYn2ur8y8fP3nvAZ32gkf+DVumb5+GBTpmJEAeyPOPl3DAO14vA0RI\
  1251. kJdXQQWjfg+mgz3edjRUgPTqpcsrRl+MYED1kOpoPFPVuJ7Z4KxMuwrc488V+qjDDah/jvkXApqO\
  1252. Nau9QgZMSBCqNRS2uUwLkQmC/z689wEM8gPQc30XZuV9+nDYe4/ZHCDABPhQ1WK7Ohp6IEoglWf/\
  1253. usfvXrXJqHUqYF/6Chqpgv5n5kMVUSNW4LU7FKwfNECC6kwDZbbBAAei2uCrYQ+AH9++z1R/AAyw\
  1254. mO0oQIN814dvewBr2PCb3lwr8j2A1HOw+HRRwrVf1LcyPxGitrGEqlZOBjXe9XQpYQRoEKl0dRdF\
  1255. etajKCeEjFrbEmpjRS4k//wQYTzX46yTRpsrbhsrDlgYJ8Jod4tjZ23/3o3dZ/wLI46q1wxVGEgq\
  1256. TVSSB1xZjryjOjwgkpnmMEuV5IlRy/VMPnWSMlgQJgk95eD+DsQcPM0UqhSnJynbDpae7aPLwciF\
  1257. yz5HBGUnWAqutzItFdM34NmsKd/nQQlXKY/oEzYaxV3PlqgVp/GuofJ/h1tYMMQ+36ETC52QAztX\
  1258. d03VWdsqdCM+69tmgqIX7lHHs/B7HDrA+K9/X34aO8/Ky9KIFZAXwxKYBnOJQ8ejX6YhGcFG66A3\
  1259. GCpqZTmOFQosYx3cEYGR75JD1SQuXJckYHcJlqVg+dbHLTcADRPVOdEzy2GKMoJVq+TvYfR+q4Jt\
  1260. v5h9qzMe+8p7hB//4bdMvRKyRwTLAbCqbAc9zEWqfXZava7MoSrFnYmLJVBNjFjRZKVpq+phag3N\
  1261. UbVCCxR0LQrIFvV5vvouSH+N9tRvlferWn9KwvRW8DJONr3CImqOi9BFPjipRiyaglCpiGBRBIsi\
  1262. WBTBoiiCRREsynKVCRbFiEVRBIsiWJRb7SyCRRGsIvWair6fBItKBS6CRbEqZDXozj4TLELl3/cy\
  1263. wSJU1h4HgkWoUjkeBMuBWR5chItgUewVUu5oHg9B4mpgG45gmSCUEwapWr5yTnBH2XYDwUqhMMbG\
  1264. xlLfVmtra7m9vT2xH5X/uaEWYLq6kjNAIVjxdMN43ybTRpmaVQqtycnJWQA3NjaKzs5O0dRU3S5i\
  1265. YmJCjI+PV4pGf4z02VgG/ZCpN/WztN4fsa+kkZERDVCzAqejgLsJyF7LdB+puzs5oxdGrMqCP2nR\
  1266. 55tGtD2kEgBLjCwON1TWF5ne18m+3jSqSkaslGW2Q+4Z73XV2OboyfLd1wY7zuGG/HQ4RqPeBFH4\
  1267. GvaV3lfTH9+r8DXUTR3P+4Cx8U6lon91nfaudVT0FwAAAABJRU5ErkJggg==) no-repeat 90% 95%";
  1268.  
  1269. _hightlight_en = GM_getValue('HiPDA_Discovery_HIGHLIGHT_ENABLE');
  1270. if(_hightlight_en == undefined)_hightlight_en = false;
  1271. if(_hightlight_en == "false" || !_hightlight_en) _hightlight_en = false;
  1272. else _hightlight_en = true;
  1273. _blacklist_en_hpd = GM_getValue('HiPDA_Discovery_BLACKLIST_ENABLE_HPD');
  1274. if(_blacklist_en_hpd == undefined)_blacklist_en_hpd = true;
  1275. if(_blacklist_en_hpd == "false" || !_blacklist_en_hpd) _blacklist_en_hpd = false;
  1276. else _blacklist_en_hpd = true;
  1277. _blacklist_en_other = GM_getValue('HiPDA_Discovery_BLACKLIST_ENABLE_OTHER');
  1278. if(_blacklist_en_other == undefined)_blacklist_en_other = true;
  1279. if(_blacklist_en_other == "false" || !_blacklist_en_other) _blacklist_en_other = false;
  1280. else _blacklist_en_other = true;
  1281. _simple_style = GM_getValue('HiPDA_Discovery_SIMPLE_STYLE');
  1282. if(_simple_style == undefined)_simple_style = true;
  1283. if(_simple_style == "false" || !_simple_style) _simple_style = false;
  1284. else _simple_style = true;
  1285. _hover_style = GM_getValue('HiPDA_Discovery_HOVER_STYLE');
  1286. if(_hover_style == undefined)_hover_style = false;
  1287. if(_hover_style == "false" || !_hover_style) _hover_style = false;
  1288. else _hover_style = true;
  1289. _reply_avatar = GM_getValue('HiPDA_Discovery_REPLY_AVATAR');
  1290. if(_reply_avatar == undefined)_reply_avatar = false;
  1291. if(_reply_avatar == "false" || !_reply_avatar ) _reply_avatar = false;
  1292. else _reply_avatar = true;
  1293. _syn_modified = GM_getValue('HiPDA_Discovery_SYN_MODIFIED');
  1294. if(_syn_modified == undefined)_syn_modified = false;
  1295. if(_syn_modified == "false" || !_syn_modified) _syn_modified = false;
  1296. else _syn_modified = true;
  1297. _hightlight_color = GM_getValue('HiPDA_Discovery_HIGHLIGHT_COLOR');
  1298. if(_hightlight_color == undefined)_hightlight_color = "#F0E68C";
  1299. _font_size = GM_getValue('HiPDA_Discovery_FONT_SIZE');
  1300. if(_font_size == undefined)_font_size = '13';
  1301. _syn_lastversion = GM_getValue('HiPDA_Discovery_SYN_LASTVERSION');
  1302. if(_syn_lastversion == undefined)_syn_lastversion = 0;
  1303. var b = GM_getValue('HiPDA_Discovery_BLACK_LIST');
  1304. if(b == undefined)b='';
  1305. blacklistArray = '';
  1306. if(b.length)blacklistArray = b.split(",");
  1307. else blacklistArray = new Array();
  1308. blacklistLen=blacklistArray.length;
  1309. blacklistStr=blacklistArray.toString();
  1310.  
  1311. try{ // 取得当前登录用户 uid
  1312. var c = document.getElementById('umenu').getElementsByTagName('cite')[0].getElementsByTagName('a')[0].href;
  1313. _uid = c.substr(c.indexOf("uid=")+4);
  1314. if(c.indexOf("&")>0)
  1315. _uid = c.substr(0,c.indexOf("&"));
  1316. }catch (e) {_uid = 0;}
  1317.  
  1318. _today = year + "-" + month + "-" + day;
  1319. _pxt = "1900-1-1 01:01";
  1320. _pmt = year + "-" + month + "-" + day + " " + hour + ":" + min;
  1321. var offset = window.location.search.indexOf("page=");
  1322. if(offset>0){
  1323. var t = window.location.search.substr(offset);
  1324. if(t.indexOf("&") >0) _pc = t.slice(5,t.indexOf("&"));
  1325. else _pc = t.slice(5);
  1326. }
  1327. else _pc = 1;
  1328. offset = window.location.search.indexOf("fid=");
  1329. if(offset>0){
  1330. var t = window.location.search.substr(offset);
  1331. if(t.indexOf("&") >0)_fid = t.slice(4,t.indexOf("&"));
  1332. else _fid = t.slice(4);
  1333. }
  1334. else _fid = 2; // 默认D版好了
  1335. _lvt = GM_getValue("HiPDA_Discovery_LAST_VISIT_TIME"+_fid);
  1336. if(_lvt == undefined){
  1337. _lvt = year + "-" + month + "-" + day + " " + hour + ":" + min;
  1338. _first_time_use = true;
  1339. GM_setValue("HiPDA_Discovery_LAST_VISIT_TIME"+_fid,_lvt);
  1340. }
  1341. else _first_time_use = false;
  1342. }
  1343. function refreshConfigDiv(){ // 刷新编辑黑名单的界面
  1344. readConfig();
  1345. document.getElementById('_chk_hightlight_color').value=_hightlight_color;
  1346. document.getElementById('_chk_hightlight_en').checked=( !_hightlight_en || _hightlight_en=="false")?0:1;
  1347. document.getElementById('_chk_blacklist_en_hpd').checked=( !_blacklist_en_hpd || _blacklist_en_hpd=="false")?0:1;
  1348. document.getElementById('_chk_blacklist_en_other').checked=( !_blacklist_en_other || _blacklist_en_other=="false")?0:1;
  1349. document.getElementById('_chk_simple_style').checked=( !_simple_style || _simple_style=="false")?0:1;
  1350. document.getElementById('_chk_hover_style').checked=( !_hover_style || _hover_style=="false")?0:1;
  1351. document.getElementById('_chk_reply_avatar').checked=( !_reply_avatar || _reply_avatar=="false")?0:1;
  1352. // 被点击过以后就不必更新此按钮,直到刷新页面
  1353. if(document.getElementById('s_syn').className != "disabled") {
  1354. if(_uid == 0){
  1355. document.getElementById('s_syn').innerHTML="未登录";
  1356. document.getElementById('s_syn').href="http://"+document.domain+"/forum/logging.php?action=login";
  1357. }
  1358. else {
  1359. document.getElementById('s_syn').innerHTML="₪ 同步";
  1360. document.getElementById('s_syn').style.background='#eef9eb';
  1361. document.getElementById('s_syn').style.color='#000';
  1362. }
  1363. }
  1364. document.getElementById('s_syn').title="上次同步时间:"+GM_getValue('HiPDA_Discovery_SYN_LASTTIME');
  1365. var rd=document.getElementsByName('_radio_font_size');
  1366. for(var i=0;i<rd.length;i++){
  1367. if(rd[i].value == _font_size)
  1368. rd[i].checked="true";
  1369. }
  1370. if(blacklistLen){
  1371. document.getElementById('blacklist').innerHTML='';
  1372. for(var i=0;i<blacklistLen;i++){
  1373. var t = blacklistArray[i];
  1374. var lst=document.createElement('input');
  1375. lst.className = 'bl_chk';
  1376. lst.value = t;
  1377. lst.type = 'checkbox';
  1378. lst.checked = true;
  1379. lst.addEventListener('click', onToggleBlackList,false);
  1380. var dv=document.createElement('div');
  1381. dv.appendChild(lst);
  1382. dv.appendChild(document.createTextNode(t.substr(t.indexOf('=')+1)));
  1383. document.getElementById('blacklist').appendChild(dv);
  1384. }
  1385. }else document.getElementById('blacklist').innerHTML = '您还没有屏蔽任何用户';
  1386. }
  1387. // 功能实现
  1388. function mouseOverPost(event){
  1389. this.style.background="";
  1390. this.removeAttribute('onmouseover');
  1391. }
  1392. function processBlackList(){ // 屏蔽黑名单
  1393. if( (_fid == 2)&&!_blacklist_en_hpd )return; // 当前浏览D版且未启用黑名单功能
  1394. else if(!_blacklist_en_other)return; // 浏览其他版块
  1395. if(_bVIEWTHREAD>0){ // 帖子
  1396. var s = document.evaluate("//div[@class='postinfo']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1397. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1398. var t = s.snapshotItem(i);
  1399. var a = t.getElementsByTagName('a')[0];
  1400. if( a != undefined){
  1401. var u = a.href.substring(a.href.indexOf('uid')+4);
  1402. t.parentNode.parentNode.parentNode.parentNode.style.display=(blacklistStr.indexOf(u+'='+a.text)>=0)?'none':'';
  1403. }
  1404. }
  1405. // 屏蔽 被引用 的黑名单用户发言
  1406. s = document.evaluate("//div[@class='quote']//blockquote//font//font[@color='#999999']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1407. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1408. var t = s.snapshotItem(i);
  1409. var n=t.innerHTML.substring(0,t.innerHTML.indexOf('发表于')-1);
  1410. if(blacklistStr.indexOf(('='+n+','))>=0)t.parentNode.parentNode.parentNode.style.display = 'none';
  1411. }
  1412. }
  1413. if(_bFORUMDISPLAY>0){ // 论坛列表
  1414. // 屏蔽BLACK_LIST的发帖
  1415. var s = document.evaluate("//td[@class='author']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1416. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1417. var t = s.snapshotItem(i);
  1418. var a = t.getElementsByTagName('a')[0];
  1419. if( a != undefined){
  1420. var n = a.text;
  1421. var u = a.href.substring(a.href.indexOf('uid')+4);
  1422. if(blacklistStr.indexOf(u+'='+n)>=0)t.parentNode.parentNode.style.display='none';
  1423. else t.parentNode.parentNode.style.display='';
  1424. }
  1425. }
  1426. // 隐藏BLACK_LIST在最后回复位置的显示
  1427. s = document.evaluate("//td[@class='lastpost']",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1428. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1429. var t = s.snapshotItem(i);
  1430. var a = t.getElementsByTagName('a')[1];
  1431. if((a != undefined)&&(blacklistStr.indexOf(('='+a.text))>=0))a.innerHTML='anonymous';
  1432. }
  1433. }
  1434. };
  1435. function processShowHiddenText(){ // 好孩子看得见
  1436. var s = document.evaluate("//font[\
  1437. translate(@color,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz')='white' \
  1438. or translate(@color,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz')='#ffffff'\
  1439. or translate(@color,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz')='#wheat'\
  1440. or translate(@color,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz')='#lemonchiffon']",
  1441. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1442. for (var i = s.snapshotLength - 1; i >= 0; i--) {
  1443. var t=s.snapshotItem(i).innerHTML;
  1444. t=t.replace(/white/i,"red");
  1445. t=t.replace(/#ffffff/i,"red");
  1446. t=t.replace(/wheat/i,"red");
  1447. t=t.replace(/lemonchiffon/i,"red");
  1448. //t=s.snapshotItem(i).innerHTML='<fieldset class="goodboysglasses"><legend>好孩子看不见</legend>'+t+'</fieldset>';
  1449. t=s.snapshotItem(i).innerHTML='<div class="goodboysglasses" title="好孩子看不见">'+t+'</div>';
  1450. }
  1451. };
  1452. function processHighlightColor(){ // 对帖子进行高亮
  1453. if( !_hightlight_en ){ // 如果不启用高亮就把这次页面打开的时刻写进去
  1454. if( 1 == _pc )
  1455. GM_setValue("HiPDA_Discovery_LAST_VISIT_TIME"+_fid,year + "-" + month + "-" + day + " " + hour + ":" + min)
  1456. return;
  1457. }
  1458. if(_bFORUMDISPLAY>0){
  1459. // 遍历页面中的帖子列表,将所有“最后回复时间”大于 _lvt 的帖子背景色换成 _hightlight_color
  1460. // 这里没有排除置顶帖子
  1461. var f = document.evaluate("//td[@class='lastpost']",
  1462. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1463. for (var i = f.snapshotLength - 1; i >= 0; i--){
  1464. var e = f.snapshotItem(i);
  1465. var a = e.getElementsByTagName('a')[1];
  1466. if( a != undefined){
  1467. var _rt = a.text;
  1468. if (timeDiff(_rt,_lvt)){
  1469. e.parentNode.style.background=_hightlight_color;
  1470. e.parentNode.addEventListener('mouseover',mouseOverPost,false);
  1471. }
  1472. if(timeDiff(_rt,_pxt))_pxt = _rt;
  1473. if(timeDiff(_pxt,_lvt)) GM_setValue("HiPDA_Discovery_LAST_VISIT_TIME"+_fid,_pxt);
  1474. }
  1475. }
  1476. // 将发帖日期超过30天的帖子里发帖人单元格背景换成 _old_post_bgcolor :灰色
  1477. // 将当天发布的帖子里发帖日期颜色变成 _today_post_color :红色
  1478. var snapResults = document.evaluate("//td [@class='author']",
  1479. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1480. for (var i = snapResults.snapshotLength - 1; i >= 0; i--) {
  1481. var e = snapResults.snapshotItem(i).getElementsByTagName('em')[0];
  1482. if(e != undefined){
  1483. var dd = dateDiff(e.innerHTML,_today);
  1484. if (dd >= 30) {
  1485. if (e.parentNode.parentNode.innerHTML.indexOf("images/default/pin")==-1 && e.parentNode.parentNode.innerHTML.indexOf('images/default/folder_lock')==-1 ){
  1486. e.parentNode.parentNode.style.background=_old_post_bgcolor;
  1487. e.parentNode.parentNode.removeEventListener('mouseover',mouseOverPost,false);
  1488. }
  1489. }
  1490. if (dd == 0) {
  1491. if (e.parentNode.parentNode.innerHTML.indexOf("images/default/pin")==-1 && e.parentNode.parentNode.innerHTML.indexOf('images/default/folder_lock')==-1 )
  1492. e.style.color=_today_post_color;
  1493. }
  1494. }
  1495. }
  1496. }
  1497. if(_bVIEWTHREAD>0){
  1498. var pst=document.evaluate("//div[@class='postinfo']//strong//a//em",
  1499. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1500. for (var i = pst.snapshotLength - 1; i >= 0; i--){
  1501. if(pst.snapshotItem(i).innerHTML == 1){ // 1st floor
  1502. var t1=pst.snapshotItem(i).parentNode.parentNode.parentNode.getElementsByClassName('authorinfo')[0].getElementsByTagName('em')[0];
  1503. if(t1 != undefined){
  1504. var postdate=t1.innerHTML;
  1505. postdate = postdate.substr(4,postdate.indexOf(':')-7);
  1506. if(dateDiff(postdate,_today) >=30)
  1507. t1.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('defaultpost')[0].style.background=grave_image;
  1508. }
  1509. }
  1510. }
  1511. }
  1512. }
  1513. function processImageZoom(){ // 调整附件图片大小
  1514. var imglist=document.evaluate("//img[substring(@id,1,5)='aimg_']",
  1515. document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1516. for (var i = imglist.snapshotLength - 1; i >= 0; i--)
  1517. imglist.snapshotItem(i).addEventListener('load',onAttachImageLoaded,false);
  1518. }
  1519. function processConflict(){
  1520. document.getElementById('hp_cfg_div').style.display = 'none';
  1521. // 显示【勾选界面】,【服务器列表】,【本地列表】的差异换面和对应选项
  1522. // 如果以服务器为准,则存储response的version和list即可
  1523. // 如果以本地为准、或以新列表为准(先存储新列表),则请求action=update,等待返回结果【跳到 case 1:】
  1524. newBlacklist = new Array();
  1525. var listhtml="<table><tbody>";
  1526. var i;
  1527. for ( i in serverBlacklist ){
  1528. var item = serverBlacklist[i];
  1529. if(/\d+=.+/.test(item)){
  1530. if(blacklistStr.indexOf(item)>=0){ // 服务、本地名单都有
  1531. newBlacklist.push(item);
  1532. }
  1533. else{ // 服务器有,本地没有
  1534. var n = item.substr(item.indexOf('=')+1);
  1535. listhtml = listhtml +"<tr><td class='hpdtool_syn_new'><input class='hpdtool_syn_chk_new' type='checkbox' value='"+item+"'></td><td class='hpdtool_syn_srv' nowrap='nowrap'>"+n+"</td><td class='hpdtool_syn_lcl'>&nbsp;</td></tr>";
  1536. }
  1537. }
  1538. }
  1539. for ( i in blacklistArray ){
  1540. var item = blacklistArray[i];
  1541. if( /\d+=.+/.test(item) && serverListStr.indexOf( item )<0 ){ // 本地有,服务器没有
  1542. var n = item.substr(item.indexOf('=')+1);
  1543. listhtml = listhtml +"<tr><td class='hpdtool_syn_new'><input class='hpdtool_syn_chk_new' type='checkbox' value='"+item+"'></td><td class='hpdtool_syn_srv'>&nbsp;</td><td class='hpdtool_syn_lcl' nowrap='nowrap'>"+n+"</td></tr>";
  1544. }
  1545. }
  1546. listhtml = listhtml + "</tbody></table>";
  1547. document.getElementById('hpdtool_syn_list').innerHTML = listhtml;
  1548. document.getElementById('hpdtool_syn_div').style.display="";
  1549. }
  1550. readConfig();
  1551. changeStyle();
  1552. changeURL();
  1553. if(_bFORUMDISPLAY>0 || _bVIEWTHREAD>0){
  1554. addConfigDiv();
  1555. window.addEventListener('resize',onWindowResize,false);
  1556. }
  1557. if(_bFORUMDISPLAY>0){
  1558. window.addEventListener('unload',onPageUnload,false);
  1559. refreshMinTime(); // 一开始就刷新一次_pmt,否则直接就取下一页了
  1560. if(!_first_time_use && _hightlight_en){ //第一次用就不往后续读取了
  1561. if(timeDiff(_pmt,_lvt)){
  1562. _pc++;
  1563. GM_xmlhttpRequest({
  1564. method: 'GET',
  1565. url: 'http://'+document.domain+'/forum/forumdisplay.php?fid='+_fid+'&page='+_pc,
  1566. onload: onLoadNewPage,
  1567. overrideMimeType: "text/html; charset=gbk"
  1568. });
  1569. }
  1570. }
  1571. processHighlightColor();
  1572. processBlackList();
  1573. }
  1574. if(_bVIEWTHREAD>0){
  1575. appendControl();
  1576. processBlackList();
  1577. processHighlightColor();
  1578. processShowHiddenText();
  1579. _att_max_width=document.getElementsByClassName('t_msgfontfix')[0].clientWidth; // 最宽这么宽
  1580. if(_att_max_width<10)_att_max_width=600;
  1581. processImageZoom();
  1582. }