nastoolNameTest

NasTools名称测试划词版

当前为 2023-04-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name nastoolNameTest
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description NasTools名称测试划词版
  6. // @author yubanmeiqin9048
  7. // @match https://*/details.php?id=*
  8. // @match https://*/details_movie.php?id=*
  9. // @match https://*/details_tv.php?id=*
  10. // @match https://*/details_animate.php?id=*
  11. // @match https://bangumi.moe*
  12. // @match https://*.acgnx.se*
  13. // @match https://*.dmhy.org*
  14. // @match https://nyaa.si*
  15. // @grant GM_log
  16. // @grant GM_xmlhttpRequest
  17. // @connect *
  18. // @license MIT
  19. // ==/UserScript==
  20.  
  21.  
  22. (function () {
  23. 'use strict';
  24. //nastool地址
  25. const nastoolUrl = 'http://localhost:3000';
  26. // 结果面板
  27. class TranslateTip {
  28. constructor() {
  29. const div = document.createElement('div');
  30. div.hidden = true;
  31. div.setAttribute('style',
  32. `position:absolute!important;
  33. font-size:13px!important;
  34. overflow:auto!important;
  35. background:#fff!important;
  36. font-family:sans-serif,Arial!important;
  37. font-weight:normal!important;
  38. text-align:left!important;
  39. color:#000!important;
  40. padding:0.5em 1em!important;
  41. line-height:1.5em!important;
  42. border-radius:5px!important;
  43. border:1px solid #ccc!important;
  44. box-shadow:4px 4px 8px #888!important;
  45. max-width:350px!important;
  46. max-height:216px!important;
  47. z-index:2147483647!important;`
  48. );
  49. document.documentElement.appendChild(div);
  50. //点击了内容面板,不再创建图标
  51. div.addEventListener('mouseup', e => e.stopPropagation());
  52. this._tip = div;
  53. }
  54. showText(text) { //显示测试结果
  55. this._tip.innerHTML = text;
  56. this._tip.hidden = !1;
  57. }
  58. hide() {
  59. this._tip.innerHTML = '';
  60. this._tip.hidden = true;
  61. }
  62. pop(ev) {
  63. this._tip.style.top = ev.pageY + 'px';
  64. //面板最大宽度为350px
  65. this._tip.style.left = (ev.pageX + 350 <= document.body.clientWidth ?
  66. ev.pageX : document.body.clientWidth - 350) + 'px';
  67. }
  68. }
  69. const tip = new TranslateTip();
  70.  
  71. class Icon {
  72. constructor() {
  73. const icon = document.createElement('span');
  74. icon.hidden = true;
  75. icon.innerHTML = `<svg style="margin:4px !important;" width="16" height="16" viewBox="0 0 24 24">
  76. <path d="M12 2L22 12L12 22L2 12Z" style="fill:none;stroke:#3e84f4;stroke-width:2;"></path></svg>`;
  77. icon.setAttribute('style',
  78. `width:24px!important;
  79. height:24px!important;
  80. background:#fff!important;
  81. border-radius:50%!important;
  82. box-shadow:4px 4px 8px #888!important;
  83. position:absolute!important;
  84. z-index:2147483647!important;`
  85. );
  86. document.documentElement.appendChild(icon);
  87. //拦截二个鼠标事件,以防止选中的文本消失
  88. icon.addEventListener('mousedown', e => e.preventDefault(), true);
  89. icon.addEventListener('mouseup', ev => ev.preventDefault(), true);
  90. icon.addEventListener('click', ev => {
  91. if (ev.ctrlKey) navigator.clipboard.readText()
  92. .then(text => {
  93. this.queryText(text.trim(), ev);
  94. })
  95. .catch(err => {
  96. console.error('Failed to read contents: ', err);
  97. });
  98. else {
  99. const text = window.getSelection().toString().trim().replace(/\s{2,}/g, ' ');
  100. this.queryText(text, ev);
  101. }
  102. });
  103. this._icon = icon;
  104. }
  105. pop(ev) {
  106. const icon = this._icon;
  107. icon.style.top = ev.pageY + 9 + 'px';
  108. icon.style.left = ev.pageX + -18 + 'px';
  109. icon.hidden = !1;
  110. setTimeout(this.hide.bind(this), 2e3);
  111. }
  112. hide() {
  113. this._icon.hidden = true;
  114. }
  115. queryText(text, ev) {
  116. if (text) {
  117. this._icon.hidden = true;
  118. tip.pop(ev);
  119. nastool(text);
  120. }
  121. }
  122. }
  123. const icon = new Icon();
  124.  
  125. document.addEventListener('mouseup', function (e) {
  126. var text = window.getSelection().toString().trim();
  127. GM_log(text);
  128. if (!text) {
  129. icon.hide();
  130. tip.hide();
  131. }
  132. else icon.pop(e);
  133. });
  134.  
  135. function nastool(text) {
  136. tip.showText(`识别中`);
  137. let name = text.replace(/&/g, "%26");
  138. GM_log(text);
  139. GM_xmlhttpRequest({
  140. url: nastoolUrl + "/do?random=" + Math.random(),
  141. method: "POST",
  142. responseType: 'json',
  143. data: `cmd=name_test&data=%7B%22name%22%3A%22${name}%22%7D`,
  144. headers: {
  145. "user-agent": navigator.userAgent,
  146. "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
  147. },
  148. onload: (res) => {
  149. if (res.status === 200) {
  150. GM_log(res.response.data);
  151. let html = '';
  152. html += res.response.data.type ? `类型:${res.response.data.type}<br>` : '';
  153. html += res.response.data.category ? `分类:${res.response.data.category}<br>` : '';
  154. html += res.response.data.name ? `名称:${res.response.data.name}<br>` : '';
  155. html += res.response.data.title ? `标题:${res.response.data.title}<br>` : '';
  156. html += res.response.data.season_episode ? `季集:${res.response.data.season_episode}<br>` : '';
  157. html += res.response.data.year ? `年份:${res.response.data.year}<br>` : '';
  158. html += res.response.data.team ? `制作:${res.response.data.team}<br>` : '';
  159. html += res.response.data.tmdbid ? 'tmdb:<a href="' + res.response.data.tmdblink + '" target="_blank">' + res.response.data.tmdbid + '</a>' : 'tmdb:未识别';
  160. tip.showText(html);
  161. } else {
  162. GM_log(res);
  163. tip.showText("连接失败");
  164. }
  165. }
  166. });
  167. }
  168. })();