Advertisement
jcunews

DuckDuckGoGoogleYahooJpSearch.user.js

Apr 15th, 2021 (edited)
2,075
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         DuckDuckGo-Google-YahooJp Search
  3. // @namespace    https://greasyfork.org/en/users/85671-jcunews
  4. // @version      1.0.1
  5. // @license      AGPLv3
  6. // @author       jcunews
  7. // @description  Combined web search for DuckDuckGo, Google (.com), and Yahoo Japan (.co.jp). Access the search from the script's GM menu. Search results will be provided in a new tab.
  8. // @match        *://*/*
  9. // @grant        GM_registerMenuCommand
  10. // @grant        GM_xmlhttpRequest
  11. // @connect      html.duckduckgo.com
  12. // @connect      www.google.com
  13. // @connect      search.yahoo.co.jp
  14. // ==/UserScript==
  15.  
  16. (() => {
  17.   let
  18.     qry = "",
  19.     engs = [
  20.       {name: "DuckDuckGo", url: "https://html.duckduckgo.com/html?q=", result: null},
  21.       {name: "Google", url: "https://www.google.com/search?q=", result: null},
  22.       {name: "YahooJp", url: "https://search.yahoo.co.jp/search?p=", result: null}
  23.     ],
  24.     cnt = engs.length;
  25.  
  26.   function chkReq(a) {
  27.     if (cnt > 0) return;
  28.     (a = document.createElement("DIV")).id = "content";
  29.     a.innerHTML = `
  30. <h3>Search results for <i id="q"></i></h3>
  31. <div id="entries">
  32. ${
  33.   ((r, i) => {
  34.     r = "";
  35.     for (i = 0; i < 99; i++) {
  36.       s = engs.map(e => e.result ? (e.result.children[i] ? e.result.children[i].outerHTML : "") : "").join("");
  37.       if (s) {
  38.         r += s
  39.       } else break
  40.     }
  41.     return r
  42.   })()
  43. }
  44. </div>
  45. `;
  46.     a.querySelector("#q").textContent = qry;
  47.     open(URL.createObjectURL(new Blob([`<!doctype html>
  48. <html>
  49. <head>
  50.   <meta charset="utf-8">
  51.   <title>DuckDuckGo-Google-YahooJp Search</title>
  52.   <style>
  53.     #content { margin: 0 auto }
  54.     @media (orientation: landscape) {
  55.       #content { max-width: 56.25vw }
  56.     }
  57.     #entries > * { margin: .5em 0 }
  58.     #entries > *:nth-child(2n) { background-color: #eee }
  59.     h2, h3, p { margin: 0 }
  60.     h2 { font-size: 14pt }
  61.     figure { display: inline-block; margin: 0 .2em 0 0; width: 116px; height: 65px }
  62.     figure img { width: 100%; height: 100%; object-fit: contain; background: #000 }
  63.   </style>
  64. </head>
  65. <body>
  66. ${a.outerHTML}
  67. </body>
  68. </html>`
  69.     ], {type: "text/html"})), "_blank")
  70.   }
  71.   function doerror() {
  72.     cnt--;
  73.     chkReq();
  74.   }
  75.  
  76.   function doload(e, l, s) {
  77.     if (this.status < 400) {
  78.       (e = document.createElement("DIV")).innerHTML = this.responseText.match(/<body(?:\s|\S)+<\/body>/i)[0];
  79.       switch (this.context.name) {
  80.         case "DuckDuckGo":
  81.           e.innerHTML = Array.from(e.querySelectorAll(".result__body")).map(l => {
  82.             l.querySelectorAll("a").forEach(f => {
  83.               f.rel = "noreferrer";
  84.               f.removeAttribute("ping")
  85.             });
  86.             l.querySelectorAll("script,.result__icon").forEach(f => f.remove());
  87.             l.querySelectorAll(".result__snippet").forEach((f, g) => {
  88.               (g = document.createElement("DIV")).innerHTML = f.innerHTML;
  89.               f.replaceWith(g);
  90.             });
  91.             return l.outerHTML
  92.           }).join("");
  93.           break;
  94.         case "Google":
  95.           e.innerHTML = Array.from(e.querySelectorAll(".g>div:not([class])")).map(l => {
  96.             l.querySelectorAll("a").forEach(f => {
  97.               f.rel = "noreferrer";
  98.               f.removeAttribute("ping")
  99.             });
  100.             l.querySelectorAll("br,script,.B6fmyf,.IsZvec~*").forEach(f => f.remove());
  101.             l.querySelectorAll("a").forEach(f => f.removeAttribute("onmousedown"));
  102.             return l.outerHTML
  103.           }).join("");
  104.           break;
  105.         case "YahooJp":
  106.           e.innerHTML = Array.from(e.querySelectorAll("section")).map((l, a) => {
  107.             if (l.querySelector("a") && !l.querySelector('a[href*="//search.yahoo.co.jp"]')) {
  108.               l.querySelectorAll("a").forEach(f => {
  109.                 f.rel = "noreferrer";
  110.                 f.removeAttribute("ping")
  111.               });
  112.               l.querySelectorAll("br,figcaption,script,.sw-Card__titleCiteWrapper--pullDown").forEach(f => f.remove());
  113.               if ((a = l.querySelector(".sw-Card__titleCiteWrapper")) && a.nextElementSibling) a.parentNode.appendChild(a);
  114.               return l.outerHTML
  115.             } else return ""
  116.           }).join("");
  117.           break;
  118.       }
  119.       this.context.result = e;
  120.     }
  121.     cnt--;
  122.     chkReq();
  123.   }
  124.  
  125.   GM_registerMenuCommand("Search", s => {
  126.     if ((s = prompt("Enter search query.", qry)) === null) return;
  127.     qry = encodeURIComponent(s.trim());
  128.     cnt = engs.length;
  129.     engs.forEach((e, i) => {
  130.       e.result = null;
  131.       GM_xmlhttpRequest({
  132.         method: "GET",
  133.         url: e.url + qry,
  134.         onerror: doerror,
  135.         onload: doload,
  136.         context: e
  137.       })
  138.     })
  139.   })
  140. })();
  141.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement