EhTagBuilder

Build EhTagTranslater from Wiki.

Versão de: 20/05/2016. Veja: a última versão.

  1. // ==UserScript==
  2. // @name EhTagBuilder
  3. // @name:zh-CN E绅士标签构建者
  4. // @namespace http://www.mapaler.com/
  5. // @description Build EhTagTranslater from Wiki.
  6. // @description:zh-CN 从Wiki获取EhTagTranslater数据库,将E绅士TAG翻译为中文
  7. // @include *://github.com/Mapaler/EhTagTranslator*
  8. // @icon http://exhentai.org/favicon.ico
  9. // @version 2.0.2
  10. // @grant none
  11. // @copyright 2016+, Mapaler <mapaler@163.com>
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. var wiki_URL="https://github.com/Mapaler/EhTagTranslator/wiki"; //GitHub wiki 的地址
  16. var rows_title="rows"; //行名的地址
  17. var buttonInserPlace = document.getElementsByClassName("pagehead-actions")[0]; //按钮插入位置
  18. var windowInserPlace = document.getElementsByClassName("reponav")[0]; //窗口插入位置
  19. var scriptName = typeof(GM_info)!="undefined" ? (GM_info.script.localizedName ? GM_info.script.localizedName : GM_info.script.name) : "EhTagBuilder"; //本程序的名称
  20. var scriptVersion = typeof(GM_info)!="undefined" ? GM_info.script.version : "本地Debug版"; //本程序的版本
  21. var downOverCheckHook; //检测下载是否完成的循环函数
  22. var rowsCount = 0; //行名总数
  23. var rowsCurrent = 0; //当前下载行名
  24.  
  25.  
  26. //访GM_xmlhttpRequest函数v1.0
  27. if(typeof(GM_xmlhttpRequest) == "undefined")
  28. {
  29. var GM_xmlhttpRequest = function(GM_param){
  30. var xhr = new XMLHttpRequest(); //创建XMLHttpRequest对象
  31. if(GM_param.responseType) xhr.responseType = GM_param.responseType;
  32. xhr.onreadystatechange = function() //设置回调函数
  33. {
  34. if (xhr.readyState == 4 && xhr.status == 200)
  35. GM_param.onload(xhr);
  36. }
  37. for (var header in GM_param.headers){
  38. xhr.setRequestHeader(header, GM_param.headers[header]);
  39. }
  40. xhr.open(GM_param.method, GM_param.url, true);
  41. xhr.send(GM_param.data ? GM_param.data : null);
  42. }
  43. }
  44. //仿GM_getValue函数v1.0
  45. if(typeof(GM_getValue) == "undefined")
  46. {
  47. var GM_getValue = function(name, type){
  48. var value = localStorage.getItem(name);
  49. if (value == undefined) return value;
  50. if ((/^(?:true|false)$/i.test(value) && type == undefined) || type == "boolean")
  51. {
  52. if (/^true$/i.test(value))
  53. return true;
  54. else if (/^false$/i.test(value))
  55. return false;
  56. else
  57. return Boolean(value);
  58. }
  59. else if((/^\-?[\d\.]+$/i.test(value) && type == undefined) || type == "number")
  60. return Number(value);
  61. else
  62. return value;
  63. }
  64. }
  65. //仿GM_setValue函数v1.0
  66. if(typeof(GM_setValue) == "undefined")
  67. {
  68. var GM_setValue = function(name, value){
  69. localStorage.setItem(name, value);
  70. }
  71. }
  72. //仿GM_deleteValue函数v1.0
  73. if(typeof(GM_deleteValue) == "undefined")
  74. {
  75. var GM_deleteValue = function(name){
  76. localStorage.removeItem(name);
  77. }
  78. }
  79. //仿GM_listValues函数v1.0
  80. if(typeof(GM_listValues) == "undefined")
  81. {
  82. var GM_listValues = function(){
  83. var keys = [];
  84. for (var ki = 0; ki < localStorage.length; ki++)
  85. {
  86. keys.push(localStorage.key(ki));
  87. }
  88. return keys;
  89. }
  90. }
  91.  
  92.  
  93.  
  94.  
  95. var ds = [];
  96. var rowObj = function(){
  97. var obj = {
  98. name:"",
  99. cname:"",
  100. info:"",
  101. tags:[],
  102. addTagFromName: function(rowObj)
  103. {
  104. if (rowObj == undefined) rowObj = this;
  105. GM_xmlhttpRequest({
  106. method: "GET",
  107. url: wiki_URL + (rowObj.name.length?"/"+rowObj.name:""),
  108. onload: function(response) {
  109. var page_get_w = document.getElementById("ETB_page-get");
  110. if (page_get_w)
  111. {
  112. var statetxt = page_get_w.getElementsByClassName("page-get-" + rowObj.name)[0];
  113. statetxt.classList.add("page-load");
  114. statetxt.innerHTML = "获取成功";
  115. }
  116. dealTags(response.responseText,rowObj.tags);
  117. }
  118. });
  119. },
  120. }
  121. return obj;
  122. }
  123. var tagObj = function(){
  124. var obj = {
  125. type:0,
  126. name:"",
  127. cname:"",
  128. info:"",
  129. }
  130. return obj;
  131. }
  132.  
  133.  
  134. //处理行的页面
  135. function dealRows(response, dataset)
  136. {
  137. var parser = new DOMParser();
  138. PageDOM = parser.parseFromString(response, "text/html");
  139. var page_get_w = document.getElementById("ETB_page-get");
  140. if (page_get_w)
  141. {
  142. var statetxt = page_get_w.getElementsByClassName("page-get-rows")[0];
  143. statetxt.classList.add("page-load");
  144. statetxt.innerHTML = "获取成功";
  145. }
  146. var wiki_body = PageDOM.getElementById("wiki-body");
  147. var table = wiki_body.getElementsByTagName("table")[0].tBodies[0];
  148. rowsCount = table.rows.length;
  149. for(var ri=0;ri<table.rows.length;ri++)
  150. {
  151. var trow = table.rows[ri];
  152. var row = new rowObj;
  153. row.name = trow.cells[0].textContent;
  154. row.cname = trow.cells[1].textContent;
  155. row.info = trow.cells[2];
  156. row.addTagFromName();
  157. dataset.push(row);
  158. if (page_get_w)
  159. {
  160. page_get_w.getElementsByClassName("select-menu-list")[0].appendChild(
  161. buildMenuItem((function()
  162. {
  163. var div = document.createElement("div");
  164. var span1 = document.createElement("span");
  165. span1.className = "page-title";
  166. span1.innerHTML = row.cname ;
  167. div.appendChild(span1);
  168. var span2 = document.createElement("span");
  169. span2.className = "page-get-" + row.name;
  170. span2.innerHTML = "等待";
  171. div.appendChild(span2);
  172. return div;
  173. })()
  174. )
  175. );
  176. }
  177. }
  178. }
  179.  
  180. //获取介绍是图片还是文字
  181. function getInfoString(dom, creatImage)
  182. {
  183. if (creatImage == undefined) creatImage = true;
  184. var info = [];
  185. if (dom.childNodes != undefined)
  186. {
  187. for (var ci = 0; ci < dom.childNodes.length; ci++)
  188. {
  189. var node = dom.childNodes[ci];
  190. info = info.concat(getDomInfoString(node, creatImage))
  191. }
  192. }
  193. function getDomInfoString(node,creatImage)
  194. {
  195. var info = [];
  196. switch (node.nodeName) {
  197. case "BR":
  198. info.push(
  199. "\""
  200. ,"\\A"
  201. ,"\""
  202. );
  203. break;
  204. case "IMG":
  205. if (creatImage)
  206. {
  207. info.push(
  208. "url(\""
  209. ,node.getAttribute("data-canonical-src")
  210. ,"\")"
  211. );
  212. }
  213. break;
  214. case "#text":
  215. default:
  216. if ((ci==0 || ci==(dom.childNodes.length-1)) && node.textContent == "\n")
  217. break;
  218. info.push(
  219. "\""
  220. ,specialCharToCss(node.textContent)
  221. ,"\""
  222. );
  223. break;
  224. }
  225. return info;
  226. }
  227. return info.join("");
  228. }
  229.  
  230. //生成按钮
  231. function specialCharToCss(str)
  232. {
  233. var strn = str;
  234. strn = strn.replace("\\","\\\\");
  235. strn = strn.replace("\"","\\\"");
  236. strn = strn.replace("\r","");
  237. strn = strn.replace("\n","\\A");
  238. return strn;
  239. }
  240.  
  241. //处理Tag页面
  242. function dealTags(response, dataset)
  243. {
  244. var parser = new DOMParser();
  245. PageDOM = parser.parseFromString(response, "text/html");
  246. var wiki_body = PageDOM.getElementById("wiki-body");
  247. var table = wiki_body.getElementsByTagName("table")[0].tBodies[0];
  248. for(var ri=0;ri<table.rows.length;ri++)
  249. {
  250. var trow = table.rows[ri];
  251. var tag = new tagObj;
  252. if (trow.cells.length > 2)
  253. {//没有足够单元格的跳过
  254. tag.name = trow.cells[0].textContent;
  255. tag.cname = trow.cells[1];
  256. tag.info = trow.cells[2];
  257. tag.type = tag.name.replace(/\s/ig,"").length < 1 ? 1 : 0;
  258. dataset.push(tag);
  259. }
  260. }
  261. rowsCurrent++;
  262. }
  263.  
  264. //点击开始任务按钮
  265. function startProgram(dataset){
  266. var downOver = startProgramCheck(dataset);
  267. if (downOverCheckHook == undefined || !downOver)
  268. {
  269. GM_xmlhttpRequest({
  270. method: "GET",
  271. url: wiki_URL + (rows_title.length?"/"+rows_title:""),
  272. onload: function(response) {
  273. dealRows(response.responseText,dataset);
  274. }
  275. });
  276. downOverCheckHook = setInterval(function () { startProgramCheck(dataset) }, 200);
  277. }
  278. if (!downOver)
  279. {
  280. var page_get_w = document.getElementById("ETB_page-get");
  281. if (!page_get_w)
  282. {
  283. windowInserPlace.appendChild(buildMenuModal("window", "ETB_page-get", "数据获取进度", null, [
  284. buildMenuList([
  285. buildMenuItem((function()
  286. {
  287. var div = document.createElement("div");
  288. var span1 = document.createElement("span");
  289. span1.className = "page-title";
  290. span1.innerHTML = "列表页面";
  291. div.appendChild(span1);
  292. var span2 = document.createElement("span");
  293. span2.className = "page-get-rows";
  294. span2.innerHTML = "等待";
  295. div.appendChild(span2);
  296. return div;
  297. })()
  298. )
  299. ])
  300. ],
  301. [
  302. ".ETB_page-get .page-title" + "{\r\n" + [
  303. 'font-weight: bold',
  304. 'margin-right: 15px',
  305. ].join(';\r\n') + "\r\n}",
  306. ".ETB_page-get .page-load" + "{\r\n" + [
  307. 'color: #0A0',
  308. ].join(';\r\n') + "\r\n}",
  309. ].join('\r\n')
  310. ));
  311. }
  312. else
  313. {
  314. page_get_w.style.display = "block";
  315. }
  316. }
  317. }
  318. //检测下载完成情况
  319. function startProgramCheck(dataset)
  320. {
  321. if (rowsCount > 0 && rowsCurrent >= rowsCount)
  322. {
  323. console.debug("获取完成");
  324. clearInterval(downOverCheckHook);
  325. var css = buildCSS(dataset
  326. ,GM_getValue("ETB_create-info","boolean")
  327. ,GM_getValue("ETB_create-info-image","boolean")
  328. ,GM_getValue("ETB_create-cname-image","boolean")
  329. );
  330. var downBlob = new Blob([css], {'type': 'text\/css'});
  331. var downurl = window.URL.createObjectURL(downBlob);
  332. var css_output_w = document.getElementById("ETB_css-output");
  333. if (!css_output_w)
  334. {
  335. windowInserPlace.appendChild(buildMenuModal("window", "ETB_css-output", "用户样式版EhTagTranslator", null,
  336. [
  337. buildMenuList([
  338. buildMenuItem("CSS文本",
  339. (function()
  340. {
  341. var textarea = document.createElement("textarea");
  342. textarea.id = "ETB_css-textarea";
  343. textarea.name = textarea.id;
  344. textarea.className = "txta " + textarea.id;
  345. textarea.value = css;
  346. textarea.wrap = "off";
  347. textarea.setAttribute("readonly",true);
  348. return textarea;
  349. })()
  350. ,buildSVG("css")),
  351. buildMenuItem("直接下载CSS文件",null,buildSVG("download"),downurl,1)
  352. ])
  353. ],
  354. [
  355. ".ETB_css-output .txta" + "{\r\n" + [
  356. 'resize: vertical',
  357. 'width:100%',
  358. 'height:300px',
  359. ].join(';\r\n') + "\r\n}",
  360. ].join('\r\n')
  361. ));
  362. }
  363. else
  364. {
  365. css_output_w.style.display = "block";
  366. css_output_w.getElementsByClassName("ETB_css-textarea")[0].value = css;
  367. css_output_w.getElementsByTagName("a")[0].href = downurl;
  368. }
  369. var page_get_w = document.getElementById("ETB_page-get");
  370. if (page_get_w)
  371. {
  372. page_get_w.parentNode.removeChild(page_get_w);
  373. }
  374. return true;
  375. }
  376. else
  377. {
  378. console.debug("获取%d/%d",rowsCurrent, rowsCount);
  379. return false;
  380. }
  381. }
  382.  
  383. //开始构建CSS
  384. function buildCSS(dataset, createInfo, createInfoImage, createCnameImage)
  385. {
  386. if (createInfo == undefined) createInfo = true;
  387. if (createInfoImage == undefined) createInfoImage = true;
  388. if (createCnameImage == undefined) createCnameImage = true;
  389. var date = new Date();
  390. var cssAry = [];
  391. //样式信息说明
  392. cssAry.push(
  393. "/* EhTagTranslator 用户样式版,由 " + scriptName + " v" + scriptVersion + " 构建"
  394. ," * 构建时间为"
  395. ," * " + date.toString()
  396. ," */"
  397. )
  398. //样式命名区间与应用范围
  399. cssAry.push(
  400. //▼CSS内容部分
  401. "@namespace url(http://www.w3.org/1999/xhtml);"
  402. ,""
  403. ,"@-moz-document"
  404. ," url-prefix('http://exhentai.org/g/'), "
  405. ," url-prefix('http://g.e-hentai.org/g/')"
  406. ,"{"
  407. //▲CSS内容部分
  408. );
  409.  
  410. //链接通用样式部分
  411. cssAry.push(GM_getValue("ETB_global-style"));
  412. for (var ri = 0; ri < dataset.length; ri++)
  413. {
  414. var row = dataset[ri];
  415. cssAry.push( //添加行名的注释
  416. "/* " + row.name
  417. ," * " + row.cname
  418. ," */"
  419. );
  420. for (var ti = 0; ti < row.tags.length; ti++)
  421. {
  422. var tag = row.tags[ti];
  423. if (tag.type == 0)
  424. {
  425. cssAry.push(""
  426. //▼CSS内容部分
  427. ," a[id=\"ta_" + (row.name=="misc"?"":row.name + ":") + tag.name.replace(/ /ig,"_") + "\"]{"
  428. ," font-size:0px;"
  429. ," }"
  430. ," a[id=\"ta_" + (row.name=="misc"?"":row.name + ":") + tag.name.replace(/ /ig,"_") + "\"]::before{"
  431. ," content:" + getInfoString(tag.cname, createCnameImage) + ";"
  432. ," }"
  433. //▲CSS内容部分
  434. );
  435. if (createInfo)
  436. {
  437. var sinfo = getInfoString(tag.info, createInfoImage);
  438. if (sinfo.replace(/\s/ig,"").length > 0)
  439. {
  440. cssAry.push(""
  441. //▼CSS内容部分
  442. ," a[id=\"ta_" + (row.name=="misc"?"":row.name + ":") + tag.name.replace(/ /ig,"_") + "\"]::after{"
  443. ," content:" + sinfo + ";"
  444. ," }"
  445. //▲CSS内容部分
  446. );
  447. }
  448. }
  449. }
  450. else
  451. { //将注释写成CSS注释
  452. cssAry.push(
  453. "/* " + tag.cname
  454. ," * " + tag.info
  455. ," */"
  456. );
  457. }
  458. }
  459. }
  460. cssAry.push(
  461. //▼CSS内容部分
  462. "}"
  463. //▲CSS内容部分
  464. )
  465. var css = cssAry.join("\r\n");
  466. return css;
  467. }
  468.  
  469.  
  470. //生成按钮
  471. function buildButton(title, icon, modal)
  472. {
  473. var li = document.createElement("li");
  474. var select_menu = document.createElement("div");
  475. select_menu.className = "select-menu js-menu-container js-select-menu";
  476. li.appendChild(select_menu);
  477. var button = document.createElement("button");
  478. button.className = "btn btn-sm select-menu-button js-menu-target css-truncate";
  479. select_menu.appendChild(button);
  480. var span = document.createElement("span");
  481. span.className = "js-select-button";
  482. if (icon != undefined)
  483. span.appendChild(icon);
  484. span.innerHTML += title;
  485. button.appendChild(span);
  486. select_menu.appendChild(modal);
  487. return li;
  488. }
  489.  
  490. //生成菜单窗口
  491. function buildMenuModal(mode, id, stitle, filters, lists, sstyle)
  492. {
  493. var modal_holder = document.createElement("div");
  494. modal_holder.className = "select-menu-modal-holder js-menu-content js-navigation-container js-active-navigation-container";
  495. if (id != undefined)
  496. {
  497. modal_holder.id = id;
  498. modal_holder.classList.add(id);
  499. }
  500. if (sstyle != undefined)
  501. {
  502. var style = document.createElement("style");
  503. style.innerHTML = sstyle;
  504. modal_holder.appendChild(style);
  505. }
  506.  
  507. var modal = document.createElement("div");
  508. modal.className = "select-menu-modal subscription-menu-modal js-menu-content";
  509. modal_holder.appendChild(modal);
  510. var header = document.createElement("div");
  511. header.className = "select-menu-header js-navigation-enable";
  512. modal.appendChild(header);
  513. var CloseSvg = buildSVG("Close");
  514. header.appendChild(CloseSvg);
  515.  
  516. switch (mode) {
  517. case "window":
  518. modal_holder.style.display = "block";
  519. CloseSvg.onclick = function(){
  520. modal_holder.style.display = "none";
  521. }
  522. break;
  523.  
  524. case "menu":
  525. default:
  526. break;
  527. }
  528. var title = document.createElement("span");
  529. title.className = "select-menu-title";
  530. title.innerHTML = stitle;
  531. header.appendChild(title);
  532.  
  533. if (lists != undefined)
  534. {
  535. for(var li = 0; li < lists.length; li++)
  536. {
  537. var list = lists[li];
  538. if (list)
  539. modal.appendChild(list);
  540. }
  541. }
  542. return modal_holder;
  543. }
  544.  
  545. //构建一个菜单列表框架
  546. function buildMenuList(items)
  547. {
  548. var list = document.createElement("div");
  549. list.className = "select-menu-list js-navigation-container";
  550. if (items != undefined)
  551. {
  552. for(var ii = 0; ii < items.length; ii++)
  553. {
  554. var item = items[ii];
  555. if (item)
  556. list.appendChild(item);
  557. }
  558. }
  559. return list;
  560. }
  561.  
  562. //构建一个菜单列表项
  563. function buildMenuItem(heading, description, icon, callback, type)
  564. {
  565. if (heading == undefined) heading = "未设定";
  566. var item = document.createElement("div");
  567. if (type == 3)
  568. {
  569. var item = document.createElement("label");
  570. item.setAttribute('for', callback);
  571. }
  572. else if (typeof(callback) == "string")
  573. {
  574. var item = document.createElement("a");
  575. item.target = "_blank";
  576. item.href = callback;
  577. }
  578. else
  579. {
  580. if (callback) item.onclick = callback;
  581. }
  582. item.className = "select-menu-item";
  583. switch (type) {
  584. case 0:
  585. item.classList.add("js-navigation-item");
  586. break;
  587. case 1:
  588. item.classList.add("select-menu-action");
  589. break;
  590. default:
  591. break;
  592. }
  593. if (icon != undefined) item.appendChild(icon);
  594. var item_text = document.createElement("div");
  595. item_text.className = "select-menu-item-text";
  596. item.appendChild(item_text);
  597. if (description != undefined)
  598. {
  599. var item_heading = document.createElement("span");
  600. item_heading.className = "select-menu-item-heading";
  601. if (typeof(heading)=="string")
  602. item_heading.innerHTML = heading;
  603. else
  604. item_heading.appendChild(heading);
  605. var item_description = document.createElement("span");
  606. item_description.className = "description";
  607. if (typeof(description)=="string")
  608. item_description.innerHTML = description;
  609. else
  610. item_description.appendChild(description);
  611. item_text.appendChild(item_heading);
  612. item_text.appendChild(item_description);
  613. }
  614. else
  615. {
  616. if (typeof(heading)=="string")
  617. item_text.innerHTML = heading;
  618. else
  619. item_text.appendChild(heading);
  620. }
  621. return item;
  622. }
  623. //生成svg
  624. function buildSVG(mode,check)
  625. {
  626. if (check == undefined) check = false;
  627. var CloseSvgDiv = document.createElement("div");
  628. var innerHTML = "";
  629. switch (mode) {
  630. case "Close":
  631. innerHTML = '<svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75-1.48-1.48 3.75-3.75L0.77 4.25l1.48-1.48 3.75 3.75 3.75-3.75 1.48 1.48-3.75 3.75z"/></svg>';
  632. break;
  633.  
  634. case "Settings":
  635. innerHTML = '<svg width="14" viewBox="0 0 14 16" version="1.1" height="16" class="octicon octicon-question select-menu-item-icon" aria-hidden="true"><path d="M14 8.77V7.17l-1.94-0.64-0.45-1.09 0.88-1.84-1.13-1.13-1.81 0.91-1.09-0.45-0.69-1.92H6.17l-0.63 1.94-1.11 0.45-1.84-0.88-1.13 1.13 0.91 1.81-0.45 1.09L0 7.23v1.59l1.94 0.64 0.45 1.09-0.88 1.84 1.13 1.13 1.81-0.91 1.09 0.45 0.69 1.92h1.59l0.63-1.94 1.11-0.45 1.84 0.88 1.13-1.13-0.92-1.81 0.47-1.09 1.92-0.69zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"/></svg>';
  636. break;
  637.  
  638. case "check":
  639. innerHTML = '<svg width="12" viewBox="0 0 12 16" version="1.1" height="16" class="octicon octicon-check select-menu-item-icon" aria-hidden="true"><path d="M12 5L4 13 0 9l1.5-1.5 2.5 2.5 6.5-6.5 1.5 1.5z"/></svg>';
  640. break;
  641.  
  642. case "question":
  643. innerHTML = '<svg width="14" viewBox="0 0 14 16" version="1.1" height="16" class="octicon octicon-question select-menu-item-icon" aria-hidden="true"><path d="M6 10h2v2H6V10z m4-3.5c0 2.14-2 2.5-2 2.5H6c0-0.55 0.45-1 1-1h0.5c0.28 0 0.5-0.22 0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28 0-0.5 0.22-0.5 0.5v0.5H4c0-1.5 1.5-3 3-3s3 1 3 2.5zM7 2.3c3.14 0 5.7 2.56 5.7 5.7S10.14 13.7 7 13.7 1.3 11.14 1.3 8s2.56-5.7 5.7-5.7m0-1.3C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7S10.86 1 7 1z"/></svg>';
  644. break;
  645.  
  646. case "download":
  647. innerHTML = '<svg width="16" viewBox="0 0 16 16" version="1.1" height="16" class="octicon octicon-desktop-download select-menu-item-icon" aria-hidden="true"><path d="M4 6h3V0h2v6h3L8 10 4 6z m11-4H11v1h4v8H1V3h4v-1H1c-0.55 0-1 0.45-1 1v9c0 0.55 0.45 1 1 1h5.34c-0.25 0.61-0.86 1.39-2.34 2h8c-1.48-0.61-2.09-1.39-2.34-2h5.34c0.55 0 1-0.45 1-1V3c0-0.55-0.45-1-1-1z"/></svg>';
  648. break;
  649.  
  650. case "book":
  651. innerHTML = '<svg width="16" viewBox="0 0 16 16" version="1.1" height="16" class="octicon octicon-book select-menu-item-icon" aria-hidden="true"><path d="M2 5h4v1H2v-1z m0 3h4v-1H2v1z m0 2h4v-1H2v1z m11-5H9v1h4v-1z m0 2H9v1h4v-1z m0 2H9v1h4v-1z m2-6v9c0 0.55-0.45 1-1 1H8.5l-1 1-1-1H1c-0.55 0-1-0.45-1-1V3c0-0.55 0.45-1 1-1h5.5l1 1 1-1h5.5c0.55 0 1 0.45 1 1z m-8 0.5l-0.5-0.5H1v9h6V3.5z m7-0.5H8.5l-0.5 0.5v8.5h6V3z"/></svg>';
  652. break;
  653.  
  654. case "css":
  655. innerHTML = '<img width="16" height="16" class="octicon octicon-question select-menu-item-icon" aria-hidden="true" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADCUlEQVR42l3RYWjUdRzH8ffv97//7fTaOL2c6+66rNi52Q3Uyors5sYokh50I+iBGVFtoqGI+SQIKoiKkGCxedbOFqGWIJqFSiRoNKOU3DVpixZZc9PVJnO33f2v2/1/3x5s3arPw++DFx8+XyUiVFTYsiToQwGgUMpC40Epi3zeQf81y2JLg9aIVqA0f07nKBSLygMQXbGUziNPoBRo5aHSDuMp1XD1skPPB4cpnf+RrbURVtwaxgouQy+9mcffPwCAB8CyLKqX1IACZWw+O9xP/3e9xGrjrF3TzEztOvb29cGFQbY94GP18lvQSi0AGpubvGFKsy7vvPk5T7bu4OVdzWit+SciwtjYGK/v3M5qKZ/nAeWh0hvlwMcneLhpEy0tLWSzWbq7uxkaGiIQCJBMJqmrq8OyLED+Cyhl4/dGOfPlJfZ27QTg3De9nDr9IZFQDd9+MsDAFyepuDNGpTMDYsqIByA7NU3Pe58yMnyNXC4HQNOGZkZGdpDpu0hVZIZVqkSDVWBZOIhBl0toACef48LZk4QCXg4dOogxBp/PR9vzbXR1pTj2VS/JPZ0cmzHcEAGvF+ZHRESovyMsv57ukJ9O7ZGGWFTS6bSUSiX5f0ZHR+WppofkSufbEo9GRETmGogRZnN5/rg2wZpYlFTnLhKJOC9sa2ffvhTj4+MAhEIhIivrsW27XGAOEEMp5/BSx1Hyvhpui8LB1M+8+FwP35/bzdObN2OMAWB0appnUvu5Ojm1MKIYwRSKuAbS6TSZTIaO/R8xOXGJQrGKtvZ2lFI4jsPwxA3u3rSdH959YwEAMMYFBNd1SSQSNDY24rouSim01jiOwyuvvkZs/SPc0/woR9Md/wYEZVlseew+khtbWHv/elbdFae6ejnGGAYGB/n6/EXWtT7LhoYGqjym/MY5QGksv58H743Tf+U6ppghvnKW4eEsx4//Qtaqp3X3Wyxa5KXSI/i0IPOCEhEW+7xye7gagMlsDm0rgkE/CmHiep6i68UfCKKVoJVCI/z+22UKjqP+BndsSOE7UsTgAAAAAElFTkSuQmCC"/>';
  656. break;
  657.  
  658. case "js":
  659. innerHTML = '<img width="16" height="16" class="octicon octicon-question select-menu-item-icon" aria-hidden="true" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAALHRFWHRDcmVhdGlvbiBUaW1lAFN1biAzMCBNYXIgMjAwOCAxNzoyMjo0NyAtMDUwMNSe+EoAAAAHdElNRQfYBAYRMSwLM2/oAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGPC/xhBQAAAtBJREFUeNpdU11IU3EU/93tTje1vJujzS1xZVNnhdeMStG8ha/VDYKUICYk9RLYW1FBIERv0atFTSgqCllPvRiaDyp9qFPLsTQ12nB96Fzuy3117nVL24HD/3DO+f3u/57z+zNWqxWJRAKpVEr2ZDIpe9Yu2fy1dAhzyxCW1sBPhQy7sjW/3w82GAwi1whUTkcXufgrDMvsMhBLyKVbub0swzD/JS5WL93NgCEBvRn+YjVg1UHQ/PDbIwnw7qhxVSbIAY/TwXMlWrgXV8AqgAodwKk36vMBCAQWsmDJmJtHcQoM7NI9bHV7RdHeBnVBISZGPsL56AnEjnPgG+oRDYfgdDzDzPgnZ1pCpuHoHsIrNqXSOHbX2LhvU2OQwYXbAEUe+OYWcDtMsFRZqTlJeZbq7XBP3BDL9x/A188zAhDRskarjdOXlkIRq6CmIgLnw/H+HbDOwt4iwDH6Vp6gvemwTG6prICO+sNxcHgzBgVUGoRWAzCWmemHVESgQu/IPK70vACUGvQOeyjuo1qeXJP64rEoJJxkikmXe0EKOD1Ni6GpMSwGXw8isBgggoLNWKGkmpL6SmRgFqc0qCIBZeineLazHWyeRv6KRVcKsakJfE0lLJweYmM9+KoymkUceoMWz3sew/P9Txet2cUe2gknp9VArVHj3sN+HG+shf1EszwLJCOwn6Q4uY7paQ8Ghidx+XwjVKkoXGFTL+Db0EHg9wqtKQyxdR+6b/ch4V2BdXsR9LTbVdrZbDAEhZnDteun5XVuNcZkMqGz0jfANxwUxI62zLAkl7gV8sKRJh2n4uQx0sZT0siHwfse0zGfz/dPiV2UdNJNLEdam1FdR+8nLZWYDEES7nEXRvuHsOCZW8hKXb6B2WyWgwtWb7F/DVdJtmfyWezJfTQkhdlAFC8NRbjz4ItZlrLX690kyBolLXQYydVb0rR4LFHvQk4v/gIj/RRmaCXZ1wAAAABJRU5ErkJggg=="/>';
  660. break;
  661.  
  662. case "eh":
  663. innerHTML = '<img width="16" height="16" class="octicon" aria-hidden="true" src="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wARBmb/EQZm/xEGZv8RBmb/EQZm/////wD///8A////ABEGZv8RBmb/////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv8RBmb/EQZm/xEGZv////8A////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/////AP///wD///8A////AP///wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/////AP///wARBmb/EQZm/////wD///8A////AP///wD///8A////ABEGZv8RBmb/////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv////8A////AP///wD///8A////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/EQZm/xEGZv////8AEQZm/xEGZv////8AEQZm/xEGZv8RBmb/EQZm/xEGZv8RBmb/////AP///wARBmb/EQZm/xEGZv8RBmb/////ABEGZv8RBmb/////ABEGZv8RBmb/EQZm/xEGZv8RBmb/EQZm/////wD///8AEQZm/xEGZv////8A////AP///wD///8A////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/////AP///wD///8A////AP///wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/////AP///wARBmb/EQZm/////wD///8A////AP///wD///8A////ABEGZv8RBmb/////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv8RBmb/EQZm/xEGZv////8A////AP///wARBmb/EQZm/////wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/EQZm/xEGZv8RBmb/////AP///wD///8AEQZm/xEGZv////8A////ABEGZv8RBmb/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AACDmQAAg5kAAJ+ZAACfmQAAn5kAAISBAACEgQAAn5kAAJ+ZAACfmQAAg5kAAIOZAAD//wAA//8AAA=="/>';
  664. break;
  665. default:
  666. innerHTML = '<svg width="12" viewBox="0 0 12 16" version="1.1" height="16" class="octicon octicon-check select-menu-item-icon" aria-hidden="true"></svg>';
  667. break;
  668. }
  669. CloseSvgDiv.innerHTML = innerHTML;
  670. var CloseSvg = CloseSvgDiv.firstChild;
  671. if(check)
  672. CloseSvg.classList.add("octicon-check");
  673. else
  674. CloseSvg.classList.remove("octicon-check");
  675. return CloseSvg;
  676. }
  677. //打开设置窗口
  678. function startOption()
  679. {
  680. var option_modal_w = document.getElementById("ETB_option");
  681. if (!option_modal_w)
  682. {
  683. windowInserPlace.appendChild(
  684. buildMenuModal("window", "ETB_option", scriptName + " 设置", null, [
  685. buildMenuList([
  686. buildMenuItem("生成简介","生成光标移动到Tag上时出现的简介。",
  687. (function(){
  688. var chk1 = document.createElement("input");
  689. chk1.type = "checkbox";
  690. chk1.id = "ETB_create-info";
  691. chk1.name = "ETB_create-info";
  692. chk1.className = "octicon octicon-question select-menu-item-icon ETB_create-info";
  693. return chk1;
  694. })()
  695. ,"ETB_create-info",3),
  696. buildMenuItem("生成简介图片","生成简介中的图片。",
  697. (function(){
  698. var chk2 = document.createElement("input");
  699. chk2.type = "checkbox";
  700. chk2.id = "ETB_create-info-image";
  701. chk2.name = "ETB_create-info-image";
  702. chk2.className = "octicon octicon-question select-menu-item-icon ETB_create-info-image";
  703. return chk2;
  704. })()
  705. ,"ETB_create-info-image",3),
  706. buildMenuItem("生成中文名图片","生成中文名中的图片,一般为名称前的小图标。",
  707. (function(){
  708. var chk2 = document.createElement("input");
  709. chk2.type = "checkbox";
  710. chk2.id = "ETB_create-cname-image";
  711. chk2.name = "ETB_create-cname-image";
  712. chk2.className = "octicon octicon-question select-menu-item-icon ETB_create-cname-image";
  713. return chk2;
  714. })()
  715. ,"ETB_create-cname-image",3),
  716. buildMenuItem("Tag通用样式",
  717. (function(){
  718. var div = document.createElement("div");
  719. var span1 = document.createElement("span");
  720. span1.innerHTML = "Tag统一应用的样式,可修改为自己喜爱的样式。不会自己写CSS的用户可每次更新本脚本后重置一下,应用最新的通用样式。";
  721. div.appendChild(span1);
  722. var textarea = document.createElement("textarea");
  723. textarea.id = "ETB_global-style";
  724. textarea.name = "ETB_global-style";
  725. textarea.className = "txta ETB_global-style";
  726. textarea.value = GM_getValue("ETB_global-style")?GM_getValue("ETB_global-style"):"";
  727. textarea.wrap = "off";
  728. div.appendChild(textarea);
  729. return div;
  730. })()
  731. ,null,"ETB_global-style",3),
  732. ]),
  733. buildMenuList([
  734. buildMenuItem(
  735. (function(){
  736. var div = document.createElement("div");
  737. var btn1 = document.createElement("button");
  738. btn1.innerHTML = "重置";
  739. btn1.id = "ETB_reset-option";
  740. btn1.name = "ETB_reset-option";
  741. btn1.className = "btn btn-sm btn-danger ETB_reset-option";
  742. btn1.onclick = function(){
  743. resetOption();
  744. }
  745. div.appendChild(btn1);
  746. /*
  747. var btn2 = document.createElement("button");
  748. btn2.innerHTML = "取消";
  749. btn2.className = "btn btn-sm";
  750. div.appendChild(btn2);
  751. */
  752. var btn3 = document.createElement("button");
  753. btn3.innerHTML = "保存";
  754. btn3.id = "ETB_save-option";
  755. btn3.name = "ETB_save-option";
  756. btn3.className = "btn btn-sm btn-primary ETB_save-option";
  757. btn3.onclick = function(){
  758. saveOption();
  759. }
  760. div.appendChild(btn3);
  761. return div;
  762. })()
  763. ,null,null,null,1),
  764. ]),
  765. ],
  766. [
  767. ".ETB_option .select-menu-item-text" + "{\r\n" + [
  768. 'font-weight: normal',
  769. ].join(';\r\n') + "\r\n}",
  770. ".ETB_option .txta" + "{\r\n" + [
  771. 'resize: vertical',
  772. 'width: 100%',
  773. 'height: 150px',
  774. ].join(';\r\n') + "\r\n}",
  775. ".ETB_option .ETB_save-option" + "{\r\n" + [
  776. 'float: right',
  777. ].join(';\r\n') + "\r\n}",
  778. ].join('\r\n')
  779. )
  780. );
  781. }
  782. else
  783. {
  784. option_modal_w.style.display = "block";
  785. }
  786. }
  787. //重置设置
  788. function resetOption(part)
  789. {
  790. function partReset(name,value,ispart)
  791. {
  792. if (!ispart || ispart && GM_getValue(name) == undefined)
  793. GM_setValue(name, value);
  794. }
  795. var cssAry = [];
  796. cssAry.push(
  797. //▼CSS内容部分
  798. " #taglist a::before{"
  799. ," font-size:12px;"
  800. ," }"
  801. ," #taglist a::after{"
  802. ," color:#fff;"
  803. ," font-size:12pt;"
  804. ," background: #666;"
  805. ," border: 1px solid #fff;"
  806. ," border-radius:5px;"
  807. ," float:left;"
  808. ," position:fixed;"
  809. ," z-index:999;"
  810. ," padding:2px;"
  811. ," box-shadow: 3px 3px 5px #888;"
  812. ," min-width:150px;"
  813. ," max-width:260px;"
  814. ," white-space:pre-wrap;"
  815. ," opacity: 0;"
  816. ," transition: opacity 0.2s;"
  817. ," transform: translate(30px,25px);"
  818. ," top:0px;"
  819. ," pointer-events:none;"
  820. ," }"
  821. ," #taglist a:hover::after,#taglist a:focus::after{"
  822. ," opacity: 1;"
  823. ," transition: opacity 0.5s;"
  824. ," }"
  825. //▲CSS内容部分
  826. );
  827. partReset("ETB_global-style",cssAry.join("\r\n"),part);
  828. partReset("ETB_create-info","true",part);
  829. partReset("ETB_create-info-image","true",part);
  830. partReset("ETB_create-cname-image","true",part);
  831. reloadOption();
  832. }
  833. //访问设置用递归函数
  834. function visitChildNodes(dom, callback)
  835. {
  836. callback(dom);
  837. for (var ci = 0; ci < dom.childNodes.length; ci++)
  838. {
  839. visitChildNodes(dom.childNodes[ci], callback);
  840. }
  841. }
  842. //保存设置
  843. function saveOption()
  844. {
  845. var option_modal_w = document.getElementById("ETB_option");
  846. if (option_modal_w)
  847. {
  848. visitChildNodes(option_modal_w,setValue);
  849. }
  850. function setValue(dom)
  851. {
  852. if (dom.name && dom.value != undefined)
  853. {
  854. if (dom.type == "checkbox")
  855. GM_setValue(dom.name, dom.checked);
  856. else
  857. GM_setValue(dom.name, dom.value);
  858. }
  859. }
  860. option_modal_w.style.display = "none";
  861. }
  862. //重新加载设置窗口
  863. function reloadOption()
  864. {
  865. var option_modal_w = document.getElementById("ETB_option");
  866. if (option_modal_w)
  867. {
  868. visitChildNodes(option_modal_w, getValue);
  869. }
  870. function getValue(dom)
  871. {
  872. if (dom.name && dom.value != undefined)
  873. {
  874. var value = GM_getValue(dom.name);
  875. if (value != undefined)
  876. {
  877. if (dom.type != undefined && dom.type == "checkbox")
  878. dom.checked = value;
  879. else
  880. dom.value = value;
  881. }
  882. }
  883. }
  884. }
  885.  
  886.  
  887. resetOption(true); //重置设置
  888.  
  889. var menu_modal = buildMenuModal("menu", null, "请选择任务 v" + scriptVersion, null, [
  890. buildMenuList([
  891. buildMenuItem("生成CSS","生成用户样式版EhTagTranslator,请使用Stylish扩展安装。手机火狐也可使用。",buildSVG("css"),function(){
  892. startProgram(ds);
  893. }
  894. ,0),
  895. /*buildMenuItem("生成JSON","生成用户脚本版EhTagTranslator数据库,功能暂未开发。",buildSVG("js"),function(){
  896. alert("设想中功能,暂未开发,仅占位");
  897. }
  898. ,0)*/
  899. ]),
  900. buildMenuList([
  901. buildMenuItem("设置选项",null,buildSVG("Settings"),function(){startOption();reloadOption();},1),
  902. buildMenuItem("查看使用帮助",null,buildSVG("question"),"https://github.com/Mapaler/EhTagTranslator/blob/master/README.md",1),
  903. buildMenuItem("贡献翻译",null,buildSVG("book"),"https://github.com/Mapaler/EhTagTranslator/wiki",1),
  904. ])
  905. ]);
  906. buttonInserPlace.insertBefore(buildButton(" " + scriptName + " ", buildSVG("eh"), menu_modal),buttonInserPlace.getElementsByTagName("li")[0]);
  907. })();