Advertisement
Guest User

5chのアフィロンダチェック ver0.0.2

a guest
May 3rd, 2023
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        5chのアフィロンダチェック
  3. // @namespace   User Scripts
  4. // @match       https://*.5ch.net/**
  5. // @grant       none
  6. // @version     0.0.2
  7. // @author      -
  8. // @description 5chのスレから転載されているサイトを調査するためのスクリプト
  9. // ==/UserScript==
  10. class HTMLGenerator {
  11.   /**
  12.    * ナビゲーションバーの生成
  13.    * @returns
  14.    */
  15.   createNav() {
  16.     const nav = document.createElement('nav')
  17.     nav.style.position = 'fixed'
  18.     nav.style.bottom = '120px'
  19.     nav.style.zIndex = '9999999'
  20.     nav.style.width = '80%'
  21.     return nav
  22.   }
  23.  
  24.   /**
  25.    * 全体用の枠の生成
  26.    * @returns
  27.    */
  28.   createAllObjects() {
  29.     const allObjects = document.createElement('div')
  30.     allObjects.className = 'allAddObjects'
  31.     return allObjects
  32.   }
  33.  
  34.   /**
  35.    * 一発検索用の枠生成
  36.    * @returns
  37.    */
  38.   createAllSearchBox() {
  39.     const allSearchBox = document.createElement('div')
  40.     allSearchBox.className = 'allSearchBox'
  41.     return allSearchBox
  42.   }
  43.  
  44.   /**
  45.    * 個々の検索欄のセットの枠生成
  46.    * @param {*} topの位置
  47.    * @returns
  48.    */
  49.   createSearchInputDiv(top) {
  50.     const searchInput = document.createElement('div')
  51.     searchInput.className = 'search-input'
  52.     searchInput.style.position = 'relative'
  53.     searchInput.style.top = top + 'px' // 位置を調整する
  54.     searchInput.style.width = '100%'
  55.     searchInput.style.left = '0px'
  56.     return searchInput
  57.   }
  58.  
  59.   /**
  60.    * 検索欄をまとめる枠
  61.    * いらないんじゃないかなこれ
  62.    * @returns
  63.    */
  64.   createInputGroup() {
  65.     const inputGroup = document.createElement('div')
  66.     inputGroup.className = 'input-group'
  67.     return inputGroup
  68.   }
  69.  
  70.   /**
  71.    * 個々の検索欄のテキストボックス生成
  72.    * @param {*} id タグのid
  73.    * @param {*} placeholder 予め入れてるテキスト
  74.    * @returns
  75.    */
  76.   createInputTextBox(id, placeholder) {
  77.     const input = document.createElement('input')
  78.     input.id = id
  79.     input.type = 'text'
  80.     input.placeholder = placeholder
  81.     input.className = 'form-control'
  82.     input.resize = 'both'
  83.     return input
  84.   }
  85.  
  86.   /**
  87.    * 検索するボタンの分離
  88.    * @param {*} id ボタンのID
  89.    * @returns
  90.    */
  91.   createInputSearchButton(id) {
  92.     const button = document.createElement('button')
  93.     button.id = id + '検索'
  94.     button.className = 'btn 検索'
  95.     button.type = 'button'
  96.     return button
  97.   }
  98.  
  99.   /**
  100.    * 検索欄用のアイコン用imgタグ生成
  101.    * @returns
  102.    */
  103.   createInputSearchIcon() {
  104.     const img = document.createElement('img')
  105.     img.src = '//penguin.5ch.net/images/magni.png'
  106.     img.className = 'magni'
  107.     return img
  108.   }
  109.  
  110.   /**
  111.    * 個々の検索用のタグ生成
  112.    * @param {*} idの名前
  113.    * @param {*} placeholder のテキスト
  114.    * @param {*} topの位置
  115.    * @returns
  116.    */
  117.   createSearchInput(id, placeholder, top) {
  118.     // 個々の検索用の枠
  119.     const searchInput = this.createSearchInputDiv(top)
  120.     // 個々の検索用のタグまとめる用
  121.     const inputGroup = this.createInputGroup()
  122.     // 検索用のテキストボックス
  123.     const input = this.createInputTextBox(id, placeholder)
  124.     // メガネアイコンと検索まとめる用の枠
  125.     const span = document.createElement('span')
  126.     span.className = 'input-group-btn'
  127.     // 検索用のボタン
  128.     const button = this.createInputSearchButton(id)
  129.     // 検索用のボタンのアイコン
  130.     const img = this.createInputSearchIcon()
  131.     // 生成
  132.     button.appendChild(img)
  133.     span.appendChild(button)
  134.     inputGroup.appendChild(input)
  135.     inputGroup.appendChild(span)
  136.     searchInput.appendChild(inputGroup)
  137.  
  138.     return searchInput
  139.   }
  140.  
  141.   /**
  142.    * 一発検索用の枠生成
  143.    * @returns
  144.    */
  145.   createSearchAllButtonDiv() {
  146.     const searchAllDiv = document.createElement('div')
  147.     searchAllDiv.className = 'megane'
  148.     searchAllDiv.style.position = 'fixed'
  149.     searchAllDiv.style.right = '0px'
  150.     searchAllDiv.style.width = '20%'
  151.     searchAllDiv.style.paddingLeft = '30px'
  152.     return searchAllDiv
  153.   }
  154.  
  155.   /**
  156.    * HTMLを生成する
  157.    * @returns
  158.    */
  159.   generateHTML() {
  160.     // ナビゲーションバーの生成
  161.     const nav = this.createNav()
  162.     // 全体用の枠
  163.     const allObjects = this.createAllObjects()
  164.     // 一発検索用枠
  165.     const allSearchBox = this.createAllSearchBox()
  166.  
  167.     // 個々の検索を生成
  168.     const searchBarTopPosition = 35
  169.     const searchInput1 = this.createSearchInput(
  170.       'スレタイ',
  171.       'スレタイ',
  172.       searchBarTopPosition * 0,
  173.     )
  174.     const searchInput2 = this.createSearchInput(
  175.       '検索するID',
  176.       '検索するIDをクリック',
  177.       searchBarTopPosition,
  178.     )
  179.     const searchInput3 = this.createSearchInput(
  180.       'レス本文',
  181.       'レスをクリック',
  182.       searchBarTopPosition * 2,
  183.     )
  184.     // 全体検索用
  185.     const searchAllDiv = this.createSearchAllButtonDiv()
  186.  
  187.     const megane = document.createTextNode('全部検索')
  188.  
  189.     //  構造に従って生成
  190.     nav.appendChild(allObjects)
  191.     allObjects.appendChild(allSearchBox)
  192.     allObjects.appendChild(searchAllDiv)
  193.     searchAllDiv.appendChild(megane)
  194.  
  195.     allSearchBox.appendChild(searchInput2)
  196.     allSearchBox.appendChild(searchInput1)
  197.     allSearchBox.appendChild(searchInput3)
  198.  
  199.     return nav
  200.   }
  201. }
  202. // HTMLを生成してbodyに追加する
  203. const generator = new HTMLGenerator()
  204. document.body.appendChild(generator.generateHTML())
  205.  
  206. // ボタンにクリックイベントを追加する
  207. const buttons = document.querySelectorAll('.検索')
  208. buttons.forEach((button) => {
  209.   button.addEventListener('click', () => {
  210.     const input = button.parentElement.parentElement.querySelector('input')
  211.     const searchText = input.value
  212.     searchElementText(searchText)
  213.   })
  214. })
  215.  
  216. /**
  217.  * ボタンを押したら直前のテキストボックスのテキストを読み込みその文字列で検索
  218.  * @param {*} 検索する文字列
  219.  */
  220. function searchElementText(str) {
  221.   // 要素のテキストを検索エンジンで検索する関数を定義する
  222.   const searchEngines = [
  223.     'https://www.google.com/search?q=',
  224.     'https://www.bing.com/search?q=',
  225.   ] // 文字列の配列として定義する
  226.   const query = encodeURI(str)
  227.   for (const searchEngine of searchEngines) {
  228.     window.open(searchEngine + query + '_blank')
  229.   }
  230. }
  231.  
  232. // 検索が入ってるやつを全部変更
  233. document.querySelectorAll('.検索').forEach((button) => {
  234.   button.addEventListener('click', () => {
  235.     // 直前のテキストボックスの内容を取得するコード
  236.     const input = button.previousElementSibling.querySelector('input')
  237.     const str = input.value
  238.     searchElementText(str)
  239.   })
  240. })
  241.  
  242. // スレの要素を取得
  243. // xpath 定義
  244. const xpaths = {
  245.   thread_title: '//title',
  246.   first_id: " //div[@id='1']/div/span[@class='uid']",
  247.   first_res: "//div[@id='1']/div/span[@class='escaped']",
  248. }
  249. /**
  250.  * xpathをデータに変換
  251.  * @param {*} 取得するxpathの並列
  252.  * @returns
  253.  */
  254. function getThreadData(xpaths) {
  255.   const threadData = {
  256.     thread_title: getXpathData(xpaths.thread_title),
  257.     first_id: getXpathData(xpaths.first_id),
  258.     first_res: getXpathData(xpaths.first_res),
  259.   }
  260.   return threadData
  261. }
  262.  
  263. /**
  264.  * xpathで取得
  265.  * @param {*} xpath
  266.  * @returns
  267.  */
  268. function getXpathData(xpath) {
  269.   const element = document.evaluate(
  270.     xpath,
  271.     document,
  272.     null,
  273.     XPathResult.FIRST_ORDERED_NODE_TYPE,
  274.     null,
  275.   ).singleNodeValue
  276.   return element
  277. }
  278.  
  279. const threadData = getThreadData(xpaths)
  280.  
  281. /**
  282.  * 検索するデータ(配列)をテキストボックスに入れる
  283.  * @param {*} threadData
  284.  */
  285. function setSearchTextBox(threadData) {
  286.   document.getElementById('スレタイ').value =
  287.     threadData.thread_title.textContent
  288.   document.getElementById('検索するID').value = threadData.first_id.textContent
  289.   document.getElementById('レス本文').value = threadData.first_res.textContent
  290. }
  291.  
  292. setSearchTextBox(threadData)
  293.  
  294. // クリックしたものをテキストボックスに入れ替え
  295. document.addEventListener('click', function (e) {
  296.   // get the clicked element
  297.   const target = e.target
  298.   // get the text of the clicked element
  299.   const text = target.textContent.trim()
  300.  
  301.   // classがuidならIDに代入
  302.   if (target.classList.contains('uid')) {
  303.     document.getElementById('検索するID').value = text
  304.   }
  305.  
  306.   // class がmessageまたはescapedならレスに代入
  307.   if (
  308.     target.classList.contains('message') ||
  309.     target.classList.contains('escaped')
  310.   ) {
  311.     document.getElementById('レス本文').value = text
  312.   }
  313. })
  314.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement