plsDirectJump

This is a script (planned) to remove cushion pages such as 2ch.net and FC2 Wiki from <a href> so that you can jump directly to them.

As of 2024-01-16. See the latest version.

  1. // ==UserScript==
  2. // @name plsDirectJump
  3. // @namespace https://github.com/PC-CNT/UserscriptWorks/
  4. // @version 0.7.8
  5. // @description This is a script (planned) to remove cushion pages such as 2ch.net and FC2 Wiki from <a href> so that you can jump directly to them.
  6. // @description:ja <a href>から2ch.netやFC2 Wikiなどのクッションページを削除して直接飛ぶようにするスクリプト(の予定)です。
  7. // @author PC-CNT
  8. // @license MIT
  9. // @match *://*/*
  10. // @match *://www.youtube.com/watch?v=*
  11. // @match *://steamcommunity.com/*
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15.  
  16. ( () => {
  17. "use strict";
  18.  
  19. function fixPrefix(url) {
  20. if (url.match(/^https?:\/\//)) {
  21. return url;
  22. } else {
  23. return "//" + url;
  24. }
  25. }
  26.  
  27. function isURL(text) {
  28. if (text.match(/^https?:\/\//) && !(text.match(/^[0-9]{1,2}:[0-9]{2}/))) {
  29. return true;
  30. } else {
  31. return false;
  32. }
  33. }
  34.  
  35.  
  36. function youtube() {
  37. //* YouTube(米欄)
  38. //* (https://www.youtube.com/watch?v=1X2TwPb3y10)
  39. //! 以下メモ
  40. //* #comments -> #sections -> #contents:米全体 -> ytd-comment-thread-renderer:米一つずつ
  41. //* -> #comment -> #body -> #main -> #expander -> #content -> #content-text -> spanまたはa
  42. //* class="style-scope ytd-comment-renderer"
  43. //* "yt-confirm-dialog-renderer" 警告のダイアログ (desktop_polymer.jsに書いてあるけど全然わからん)
  44. //* .yt-simple-endpoint このクラスがついてるとダイアログでる
  45. //! ここまでメモ
  46.  
  47. const target = document.getElementById("content")
  48. // const target = document.body;
  49. const config = {childList: true, subtree: true}
  50.  
  51. const observer = new MutationObserver(() => {
  52. const content_text = document.querySelectorAll("#content-text");
  53. if ((content_text) && (content_text.length)) {
  54. content_text.forEach(block => {
  55. block.querySelectorAll("a").forEach(function(value) {
  56. const a_text = value.innerText;
  57. if (isURL(a_text)) {
  58. // console.info("value:", value);
  59. value.classList.remove("yt-simple-endpoint");
  60. value.style.textDecoration = "none";
  61. value.setAttribute("href", a_text);
  62. value.setAttribute("target", "_blank");
  63. value.setAttribute("rel", "noopener noreferrer");
  64. }
  65. });
  66. });
  67. }
  68.  
  69. document.querySelectorAll(`a`).forEach((ra) => {
  70. if (ra.href.match(/https:\/\/www\.youtube\.com\/redirect\?.+/)) {
  71. // https://www.youtube.com/redirect?event=video_description&redir_token=rrrrr&q=https%3A%2F%2Fexample.com%2F&v=RgFaK6ZQifE
  72. ra.href = decodeURIComponent(ra.href.match(/&q=([^&]+)/)[1]);
  73. // console.log(ra.href)
  74. }
  75. })
  76. });
  77. observer.observe(target, config);
  78. }
  79.  
  80. const okwave = () => {
  81. const target = document.querySelector(`body`)
  82. const config = {childList: true, subtree: true}
  83.  
  84. const observer = new MutationObserver(() => {
  85. const al = document.querySelectorAll(`a`);
  86. al.forEach((value) => {
  87. if (value.href.match(/^https:\/\/okwave\.jp\/jump\?url=.+/)) {
  88. // * OKWAVE
  89. // * (https://okwave.jp/jump?url=https%3A%2F%2Fexample.com%2F)
  90. value.setAttribute("href", decodeURIComponent(value.href.replace(/^https:\/\/okwave\.jp\/jump\?url=/, "")));
  91. } else {
  92. observer.disconnect();
  93. }
  94. });
  95. });
  96.  
  97. observer.observe(target, config);
  98. }
  99.  
  100. const futaba = () => {
  101. //* ふたば☆ちゃんねる
  102. //* (https://www.2chan.net/bin/jump.php?https://example.com)
  103. const target = document.querySelector(`html`)
  104. const config = {childList: true, subtree: true}
  105.  
  106. const observer = new MutationObserver(() => {
  107. const al = document.querySelectorAll(`a`);
  108. al.forEach((value) => {
  109. if (value.href.match(/^https?:\/\/.+\.2chan\.net\/bin\/jump\.php\?/)) {
  110. value.setAttribute("href", decodeURIComponent(value.href.replace(/^https?:\/\/.+\.2chan\.net\/bin\/jump\.php\?/, "")));
  111. value.setAttribute("rel", "noopener noreferrer");
  112. }
  113. });
  114. });
  115. observer.observe(target, config);
  116. }
  117.  
  118.  
  119. function others() {
  120. document.querySelectorAll("a").forEach(function(value) {
  121. const url_source_abs = value.href;
  122. const url_source_rel = value.getAttribute("href")
  123. //TODO: hrefの編集
  124. if (url_source_abs) {
  125. if (url_source_abs.match(/^https?:\/\/jump.(2|5)ch\.net\/\?.+/)) {
  126. //* 2ちゃんねる
  127. //* (https://jump.5ch.net/?http://example.com/, jump.2ch.net/?,)
  128. value.setAttribute("href", fixPrefix(url_source_abs.replace(/^https?:\/\/jump.(2|5)ch\.net\/\?/, "")));
  129. }
  130. if (url_source_abs.match(/^https?:\/\/www\.pinktower\.com\/\?.+/)) {
  131. //* PINKちゃんねる
  132. //* (https://www.pinktower.com/?https://example.com/)
  133. value.setAttribute("href", fixPrefix(url_source_abs.replace(/^https?:\/\/www\.pinktower\.com\/\?/, "")));
  134. }
  135. if (location.hostname.match(/^.+\.wiki\.fc2\.com/)) {
  136. //* FC2 Wiki
  137. //* (https://example.wiki.fc2.com/jump/https/example.com%2exapmple)
  138. if (url_source_rel.match(/^\/jump\/https?\/.*/)) {
  139. value.setAttribute("href", decodeURIComponent(url_source_rel.replace(/^\/jump\/(https?)\//, "$1://")));
  140. value.setAttribute("target", "_blank");
  141. value.setAttribute("rel", "noopener noreferrer");
  142. }
  143. }
  144. if (url_source_abs.match(/^https?:\/\/kakaku\.com\/jump\/\?url=.*/)) {
  145. //* 価格.com
  146. //* (https://kakaku.com/jump/?url=https%3A%2F%2Fwww%2Eexample%2Ecom%2F)
  147. value.setAttribute("href", decodeURIComponent(url_source_abs.replace(/^https?:\/\/kakaku\.com\/jump\/\?url=/, "")));
  148. }
  149. if (url_source_abs.match(/^https:\/\/steamcommunity\.com\/linkfilter\/\?url=/)) {
  150. //* Steam
  151. //* (https://steamcommunity.com/linkfilter/?url=https://example.com/)
  152. value.setAttribute("href", decodeURIComponent(url_source_abs.replace(/^https:\/\/steamcommunity\.com\/linkfilter\/\?url=/, "")));
  153. }
  154. if (url_source_abs.match(/^https:\/\/re\.wikiwiki\.jp\//)) {
  155. //* Wikiwiki
  156. //* (https://re.wikiwiki.jp/?http://example.com/)
  157. value.setAttribute("href", decodeURIComponent(url_source_abs.replace(/^https:\/\/re\.wikiwiki\.jp\/\?/, "")));
  158. value.setAttribute("target", "_blank");
  159. value.setAttribute("rel", "noopener noreferrer");
  160. }
  161. if (url_source_abs.match(/^https?:\/\/link\.zhihu\.com\/\?target=.+/)) {
  162. // * 知乎
  163. // * (https://link.zhihu.com/?target=https%3A//example.com/)
  164. value.setAttribute("href", decodeURIComponent(url_source_abs.replace(/^https?:\/\/link\.zhihu\.com\/\?target=/, "")));
  165. value.setAttribute("target", "_blank");
  166. }
  167. }
  168. });
  169. }
  170.  
  171. if (location.host.match(/^www\.youtube\.com/)) {
  172. youtube();
  173. } else if (location.host.match(/^okwave\.jp/)) {
  174. okwave();
  175. } else if (location.host.match(/^.+\.2chan\.net/)) {
  176. futaba();
  177. } else {
  178. others();
  179. }
  180.  
  181. })();