Advertisement
usamimi2323

userscript - nHentai 日本語タイトルJD2登録用リンク置換スクリプト

Nov 28th, 2024 (edited)
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 8.49 KB | Source Code | 0 0
  1. // ==UserScript==
  2. // @name        nhentai
  3. // @namespace   newsox
  4. // @include     https://nhentai.*/g/*
  5. // @version     1
  6. // @grant       none
  7. // ==/UserScript==
  8.  
  9. (function(){
  10. //
  11. // Search on the local EveryThing
  12. //
  13.     const search_prefix='es:';
  14.  
  15. //
  16. // Search on the remote EveryThing HTTP server
  17. //
  18. //  const search_prefix='http://user:password@192.168.1.8/?search=';
  19.    
  20.     const jdp="jdp";
  21.     const jdl="jdl";
  22.     const subfolder="subfolder=ON";
  23.    
  24.     const D=document;
  25.     const E=(a,b=D)=>b.getElementById(a);
  26.     const K=Object.keys;
  27.     const S=(a,b=D)=>b.querySelector(a);
  28.     const A=(a,b=D)=>b.querySelectorAll(a);
  29.     const zeroPadding=(s,l)=>((s.length<l?'0'.repeat(l-s.length):'')+s);
  30.     const stripTag = s=>s.replace(/<[^>]*>/g,'');
  31.     const normalizeTitle=function(s)
  32.     {
  33.         const NT1 = {
  34.             "!":"!","\"":"”","#":"#","$":"$","%":"%","&":"&","'":"’","~":"~","|":"|",
  35.             "*":"*",":":":","<":"<",">":">","?":"?","/":"/","\\":"¥","`":"‘",",":",",
  36.             " ":" ","〜":"~","♡":"","♥":"",
  37.             "―":"-","─":"-","━":"-",
  38.             '卷':'巻','學':'学','黑':'黒','關':'関','繪':'絵','會':'会','亞':'亜','髙':'高',
  39.             '說':'説','说':'説'     //繁体字、簡体字の"説"
  40.         };
  41.  
  42.         const NT2={
  43.             "&times;":"×","&amp;":"&","&nbsp;":" ","%u2019;":"’"
  44.         };
  45.         if (!s) return s;
  46.         const pat1 = new RegExp("["+K(NT1).join('')+"]","g");
  47.         const pat2 = new RegExp("("+K(NT2).join('|')+")","g");
  48.         return( s
  49.     //          .replace(/\u309B/g,"\u3099")
  50.     //          .replace(/\u309C/g,"\u309A")
  51.                 .normalize('NFKC')
  52.                 .replace(pat1,m=>(m in NT1?NT1[m]:m))
  53.                 .replace(pat2,m=>(m in NT2?NT2[m]:m))
  54.                 .replace(/([\]\)])([^\s\.\)\]])/g, '$1 $2')
  55.                 .replace(/([^ ])([\[\(])/g, '$1 $2')
  56.                 .replace(/  +/g," ")
  57.                 .replace(/\.\.+/g,m=>("."))
  58.             );
  59.     }
  60.  
  61.     const execCopy = async (t)=>
  62.     {
  63.         if (!t) return;
  64.         navigator.clipboard.writeText(t).then(()=>{});
  65.     }
  66.     const execShare = async (text,title='')=>
  67.     {
  68.         if (!text) return;
  69.         let data = {text:text,title:title};
  70.         try{
  71.             await navigator.share(data);
  72.         }
  73.         catch(e)
  74.         {
  75.         }
  76.     }
  77.    
  78.    
  79.     //IN: String HTML タイトル要素   
  80.     const setTagsToTitle=function(e)
  81.     {
  82.         var tag_html  = '';
  83.         var tags = [];
  84.        
  85.         // 括弧、英数字、通常
  86.         // [ 以外は末尾の数字除外
  87.         // 数字単体除外
  88.         const b=S('span.before',e);
  89.         const p=S('span.pretty',e);
  90.         const a=S('span.after' ,e);
  91.        
  92.         var tail = '';
  93.        
  94.         if (b)
  95.         {
  96.             const e1 = /[,、×&,、/]/;
  97.             tag_html += b.innerHTML.replace(/\[([^<>]+?) *(?:\(([^<>]+?)\) *)?\]|\(([^<>]+?)\)/g, (m,m1,m2,m3)=>{
  98.                 if (m1)
  99.                 {
  100.                     let tmp = '';
  101.                     tags.push( ...(m1.trim().split(e1)) );
  102.                     tmp += '[' + m1.trim().split(e1).map(x=>setTagHTML(x)).join('×');
  103.                     if (m2)
  104.                     {
  105.                         tags.push( ...(m2.trim().split(e1)) );
  106.                         tmp += ' ('+m2.trim().split(e1).map(x=>setTagHTML(x)).join('×')+')';
  107.                     }
  108.                     tmp+=']';
  109.                     return tmp;
  110.                    
  111.                 }
  112.                 else if (m3)
  113.                 {
  114.                     tags.push( m3.trim() );
  115.                     tail = '('+setTagHTML(stripBrace(m3.trim()))+')';
  116.                     return '';
  117.                 }
  118.                 else
  119.                 {
  120.                     return m;
  121.                 }
  122.             });
  123.            
  124.         }
  125.  
  126.         if (p)
  127.         {
  128.             tag_html += p.innerHTML.replace(/ *[-+] |(.+?)|-([^- ]+?(?:[^-]*?[^- ]+)*)-|([a-zA-Z\d\-=!?'&#$@\/,\.+;:~^|*%]+(?: +[^-+ ][a-zA-Z\d\-=!?'&#$@\/,\.+;:~^|*%]*)*|[^ (?:~.+?)(?:\-.+?\-)]+)/g,
  129.                 (m,m1,m2,m3)=>{
  130.                 if (m1)
  131.                 {
  132.                     let x = '';
  133.                     const r = m1.match(/^(.+?)( *\d+)$/);
  134.                     if (r) m1=r[1],x=r[2];
  135.                     tags.push( m1.trim() );
  136.                     return m[0]+setTagHTML(m1)+x+m[0];
  137.                 }
  138.                 else if (m2)
  139.                 {
  140.                     tags.push( m2.trim() );
  141.                     return m[0]+setTagHTML(m2)+m[0];
  142.                 }
  143.                 else if (m3)
  144.                 {
  145.                     tags.push( m3.trim() );
  146.                     return setTagHTML(m3);
  147.                 }
  148.                 else
  149.                 {
  150.                     return m;
  151.                 }
  152.             });
  153.         }
  154.         if (a)
  155.         {
  156.             tag_html += a.innerHTML.replace(/\[([^<>]+?)\]|\(([^<>]+?)\)|【([^<>]+?)】|~([^<>]+?)~|-([^ <>]+?[^-<>]*[^ <>]+?)-|([a-zA-Z\d\-=!?'&#$@\/,\.+;:~^|*%]+(?: +[a-zA-Z\d\-=!?'&#$@\/,\.+;:~^|*%]+)*|[^ <>]+)/g,
  157.                 (m,m1,m2,m3,m4,m5,m6)=>{
  158.                 if (m1)
  159.                 {
  160.                     tags.push( m1.trim() );
  161.                     return '['+setTagHTML(m1)+']';
  162.                 }
  163.                 else if (m2)
  164.                 {
  165.                     tags.push( m2.trim() );
  166.                     return '('+setTagHTML(m2)+')';
  167.                 }
  168.                 else if (m3)
  169.                 {
  170.                     tags.push( m3.trim() );
  171.                     return '【'+setTagHTML(m3)+'】';
  172.                 }
  173.                 else if (m4)
  174.                 {
  175.                     tags.push( m4.trim() );
  176.                     return m[0]+setTagHTML(m4)+m[0];
  177.                 }
  178.                 else if (m5)
  179.                 {
  180.                     tags.push( m5.trim() );
  181.                     return m[0]+setTagHTML(m5)+m[0];
  182.                 }
  183.                 else if (m6)
  184.                 {
  185.                     tags.push( m6.trim() );
  186.                     return setTagHTML(m6);
  187.                 }
  188.                 else
  189.                 {
  190.                     return m;
  191.                 }
  192.             });
  193.         }
  194.         tag_html = tag_html.trim() + tail;
  195.        
  196.         return {html:tag_html, tag:tags};
  197.     }
  198.     function stripBrace(str)
  199.     {
  200.         return str.trim().replace(/^\(|\)$/g, '');
  201.     }
  202.     function setTagHTML(str)
  203.     {
  204.         return `<a class="tag" href="${search_prefix+str.replace(/[!?!?。。..、、,,っッ]+$/,'')}"><span class=name>${str}</span></a>`;
  205.     }
  206.    
  207.     const getURLs = (sep='\r\n')=>
  208.     {
  209.         const elem_tags = E("tags");
  210.         const elem_thumb_container = E('thumbnail-container');
  211.         if (elem_tags === null || elem_thumb_container === null)
  212.             return '';
  213.        
  214.         // 情報テキスト取得
  215.         let tmp = elem_tags.textContent;
  216.         // ページ数からファイル名の桁数取得
  217.         var digit = 4 <= (tmp.match(/Pages:\s+(\d+)/))[1].length ? 4 : 3;
  218.         // カテゴリ取得 Categories: doujinshi/manga/?
  219.         let categories = (tmp.match(/Categories:\s+([a-z]+)/i))[1];
  220.         // タイトル取得、日本語名がなければ英語名
  221.         tmp=S("h2.title");
  222.         if (tmp===null) tmp=S("h1.title");
  223.         var t = stripTag(tmp.textContent.trim());
  224.        
  225.         // カテゴリ名を付与、先頭の配布イベント名は後方へやっておく
  226.         //if (t.indexOf("(同人")==-1)
  227.         if (!/^\(同人/.test(t))
  228.         {
  229.             // 先頭の括弧"(*****) ~~~~"を後方へ送る
  230.             var limit = t.length;
  231.             while (0 < limit)
  232.             {
  233.                 if (tmp=t.match(/^(\([^\)\[]+\))\s*(.+?)(\s*\[[^\]\[]+\])*$/))
  234.                 {
  235.                     t=tmp[2]+" "+tmp[1];
  236.                     if (tmp[3]) t+=" "+tmp[3].trim();
  237.                     limit -= tmp[1].length;
  238.                 }
  239.                 else
  240.                     break;
  241.             }
  242.             // 同人誌の場合のみ
  243.             if (categories=="doujinshi") t = "(同人誌) "+t;
  244.         }
  245.  
  246. //      console.log('t='+t);
  247.        
  248.         var buf="";
  249.         const r=/^https:\/\/t(\d+)(\.[^\/]+\/galleries\/)(\d+)\/(\d+)t(\.[^\/\.]+)(?:\.[^\/]+)?$/;  // 拡張子重複対応
  250.         A("img.lazyload",elem_thumb_container).forEach((g)=>
  251.         {
  252.             let w = g.getAttribute("data-src");
  253.             if (w)
  254.                 buf+=w.replace(r,
  255.                     (ma,m1,m2,m3,m4,m5)=>("https://i"+m1+m2+m3+"/"+m4+m5
  256.                     +"#"+jdp+"="+encodeURIComponent(normalizeTitle(t))+"&"+jdl+"="+zeroPadding(m4,digit)+(subfolder?('&'+subfolder):'')))
  257.                     +sep;
  258.         });
  259.         return buf;
  260.     }
  261.    
  262.     // already modified...
  263.     if (E('copyURLs')) return;
  264.    
  265.     //
  266.     // Tags for EveryThing
  267.     //
  268.     [S("h1.title"), S("h2.title")].forEach((h,i)=>
  269.     {
  270.         const h_num = i+1;
  271.         if (!h) return;
  272.         h.style.display='inline';
  273.         const o = setTagsToTitle(h);
  274.         h.innerHTML = o['html'];
  275.         h.insertAdjacentHTML('afterend', `<a class="btn btn-primary tooltip" id="copy_title_${h_num}" style="text-align: center"><i class="fa fa-copy"></i><div class="top">Copy the title</div></a><br>`);
  276.         E(`copy_title_${h_num}`).addEventListener('click',()=>{execCopy(S(`h${h_num}.title`).textContent.trim().replace(/  +/g,' '))});
  277.     });
  278.    
  279.    
  280.     //
  281.     // Edit buttons
  282.     //
  283.     const disable_share = (navigator.canShare)?'':' btn-disabled';
  284.    
  285.     const bt_html = `<a class="btn btn-primary tooltip" id="copyURLs">
  286.     <i class="fa fa-copy"></i> Copy<div class="top">Copy all images URLs.<i></i></div>
  287.     </a>
  288.     <a class="btn btn-primary tooltip${disable_share}" id="shareURLs">
  289.     <i class="fa fa-share"></i> Share<div class="top">Share all images URLs.<i></i></div>
  290.     </a>`;
  291.     const e = S('div#info >div.buttons');
  292.     if (!e) return;
  293.     e.insertAdjacentHTML("afterbegin", bt_html);
  294.    
  295.     // Favorite, Downloadボタン修正
  296.     A('a',e).forEach(a=>
  297.     {
  298.         a.style.minWidth='60px';
  299.         if (a.textContent.indexOf('Favorite')!=-1)
  300.         {
  301.             const x = S('span',a);
  302.             x.innerHTML = x.innerHTML.replace('Favorite','');
  303.         }
  304.         else if (a.textContent.indexOf('Download')!=-1)
  305.         {
  306.             a.innerHTML = a.innerHTML.replace('Download','DL');
  307.         }
  308.     });
  309.    
  310.     // クリックイベント設定
  311.     E('copyURLs').addEventListener('click',()=>{execCopy(getURLs())});
  312.     if (navigator.canShare && navigator.canShare('dummy'))
  313.         E('shareURLs').addEventListener('click',()=>{execShare(getURLs())});
  314.     else
  315.         E('shareURLs').classList.add('btn-disabled')
  316. })();
  317.  
  318.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement