Advertisement
usamimi2323

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

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