Text to URL

Конвертирует текст в виде ссылок в реальные ссылки, на которые можно кликнуть.

当前为 2018-05-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Text to URL
  3. // @namespace https://github.com/T1mL3arn
  4. // @author T1mL3arn
  5. // @description:ru Конвертирует текст в виде ссылок в реальные ссылки, на которые можно кликнуть.
  6. // @description:en Converts url-like text into clickable url.
  7. // @match *://*/*
  8. // @version 1.0.1
  9. // @run-at document-end
  10. // @license GPLv3
  11. // @supportURL https://gf.qytechs.cn/en/scripts/367955-text-to-url/feedback
  12. // @homepageURL https://gf.qytechs.cn/en/scripts/367955-text-to-url
  13. // @description Конвертирует текст в виде ссылок в реальные ссылки, на которые можно кликнуть.
  14. // ==/UserScript==
  15.  
  16. let linkEreg = /(https|http|ftp|file):\/\/.+?(?=\s|$)/gi;
  17. let linkEregLocal = /(https|http|ftp|file):\/\/.+?(?=\s|$)/i;
  18. let obsOptions = { childList: true, subtree: true };
  19. let wrappedCount = 0;
  20.  
  21. function printWrappedCount() {
  22. if (wrappedCount > 0) {
  23. console.info(`[ ${GM_info.script.name} ] wrapped links count: ${wrappedCount}`);
  24. }
  25. }
  26.  
  27. let obs = new MutationObserver((changes, obs) => {
  28. wrappedCount = 0;
  29. obs.disconnect();
  30. changes.forEach((change) => change.addedNodes.forEach((node) => fixLinks(node)) );
  31. obs.observe(document.body, obsOptions);
  32. printWrappedCount();
  33. });
  34.  
  35. function fixLinks(node) {
  36. if (node.tagName != 'A') {
  37. // this is a text node
  38. if (node.nodeType === 3) {
  39. let content = node.textContent;
  40. if (content && content != '') {
  41. if (linkEregLocal.test(content)) {
  42. wrapTextNode(node);
  43. }
  44. }
  45. } else if (node.childNodes && node.childNodes.length > 0) {
  46. node.childNodes.forEach(fixLinks);
  47. }
  48. }
  49. }
  50.  
  51. function wrapTextNode(node) {
  52. let match;
  53. let sibling = node;
  54. let content = node.textContent;
  55. linkEreg.lastIndex = 0;
  56. while ((match = linkEreg.exec(content)) != null) {
  57. let fullMatch = match[0];
  58. let anchor = document.createElement('a');
  59.  
  60. let range = document.createRange();
  61. range.setStart(sibling, linkEreg.lastIndex - match[0].length);
  62. range.setEnd(sibling, linkEreg.lastIndex);
  63. range.surroundContents(anchor);
  64.  
  65. wrappedCount++;
  66.  
  67. anchor.href = fullMatch;
  68. anchor.textContent = fullMatch;
  69. anchor.target = '_blank';
  70. anchor.title = 'open link in a new tab';
  71. linkEreg.lastIndex = 0;
  72. sibling = getNextTextSibling(anchor);
  73. if (sibling == null)
  74. break;
  75. else
  76. content = sibling.textContent;
  77. }
  78. }
  79.  
  80. function getNextTextSibling(node) {
  81. let next = node.nextSibling;
  82. while (next != null) {
  83. if (next.nodeType == 3)
  84. return next;
  85. else
  86. next = node.nextSibling;
  87. }
  88. return null;
  89. }
  90.  
  91. fixLinks(document.body);
  92. printWrappedCount();
  93. obs.observe(document.body, obsOptions);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址