nastoolNameTest

NasTools名称测试划词版

目前为 2023-04-14 提交的版本。查看 最新版本

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