OpenAnySelectedURL

Open all unique URLs found in the selected text using Ctrl + Escape.

目前為 2025-05-07 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        OpenAnySelectedURL
// @version     25.5.7
// @description Open all unique URLs found in the selected text using Ctrl + Escape.
// @author      8TM (https://github.com/8tm/Tampermonkey-OpenAnySelectedURL)
// @license     CC-BY-NC-4.0
// @icon        https://raw.githubusercontent.com/8tm/Tampermonkey-OpenAnySelectedURL/4cf59b8545017d6358ffb7e02a933e3d2929f346/icon.png
// @match       *://*/*
// @compatible  firefox
// @grant       GM_openInTab
// @namespace   https://greasyfork.org/users/1386567
// ==/UserScript==

(() => {
  'use strict';

  // Simple regex for detecting URLs (used only in normalizeUrl)
  const urlPattern = /^(https?:\/\/[\S]+)|(www\.[^\s]+)/i;

  // Check if URL is valid
  function isValidUrl(string) {
    try {
      new URL(string);
      return true;
    } catch (_) {
      return false;
    }
  }

  // Normalizes and auto-completes the protocol if missing (www → http://www)
  function normalizeUrl(str) {
    let url = str.trim();
    if (!/^https?:\/\//i.test(url)) {
      if (/^www\./i.test(url)) {
        url = 'http://' + url;
      } else {
        return null;
      }
    }
    return url;
  }

  // Common function for handling the current selection
  function handleOpen() {
    const sel = window.getSelection().toString().trim();
    if (!sel) return;

    // Locate all URLs in the text, excluding surrounding parentheses, quotes or angle brackets
    const matches = sel.match(/(https?:\/\/[^\s\(\)'\"<>]+|www\.[^\s\(\)'\"<>]+)/ig);
    if (!matches) return;

    // Normalize, filter out invalid and dedupe
    const urls = Array.from(new Set(
      matches
        .map(raw => {
          // 1) remove all BBCode tags [/<tagname>]
          const cleaned = raw.replace(/(\[\/[^\]]+\])+$/gi, '');
          // 2) normalize
          const normalized = normalizeUrl(cleaned);
          if (!normalized) return null;
          // 3) Czeck if it's real URL
          if (!isValidUrl(normalized)) {
            alert(`Invalid URL: ${normalized}`);
            return null;
          }
          return normalized;
        })
        .filter(u => u)
    ));

    // Open each URL in the background
    urls.forEach(u => {
      GM_openInTab(u, true);
    });
  }

  // Keyboard shortcut: Ctrl + Escape
  document.addEventListener('keydown', e => {
    if (e.ctrlKey && e.key === 'Escape') {
      e.preventDefault();
      handleOpen();
    }
  });

})();