FuckShortenedUrl

Replace shortened URLs with real URLs

当前为 2021-02-21 提交的版本,查看 最新版本

// ==UserScript==
// @name         FuckShortenedUrl
// @namespace    https://greasyfork.org/en/users/173996-wtfjs
// @version      0.17
// @description  Replace shortened URLs with real URLs
// @author       wtfjs
// @match        https://*.douban.com/*
// @match        https://*.zhihu.com/*
// @match        https://*.twitter.com/*
// @match        https://*.youtube.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

;(function __FuckShortenedUrl() {
  "use strict";
  var utils = {
    $: function $(selector, parent) {
      var _parent = parent || document
      return _parent.querySelector(selector)
    },

    $$: function $$(selector, parent) {
      var _parent = parent || document
      return _parent.querySelectorAll(selector)
    },

    forEachRight: function forEachRight(arr, fn, _this) {
      var __this = Object(_this || this)
      for (var i = (arr.length >>> 0) - 1; i >= 0; i -= 1) {
        var it = arr[i]
        var res = fn.call(__this, it, i, arr)
        if (res === false) {
          break;
        }
      }
    },

    concurrent: function concurrent(job) {
      var dispatch = window.requestIdleCallback || window.requestAnimationFrame || window.setTimeout
      dispatch(job)
    },

    isElement: function isElement(any) {
      return typeof any === "object" && any.nodeType === 1 // Node.ELEMENT_NODE
    },

    getSearchParams(urlStr) {
      try {
        return new URL(urlStr).searchParams
      } catch {}
      return null
    }
  }

  var handlers = [
    [
      /zhihu\.com*/,
      function transform($link) {
        var re = /https?:\/\/link\.zhihu\.com/
        if (re.test($link.href)) {
          var searchParams = utils.getSearchParams($link.href)
          if (searchParams && searchParams.get("target")) {
            $link.href = searchParams.get("target")
          }
        }
        return $link
      }
    ],
    [
      /douban\.com*/,
      function transform($link) {
        var re1 = /https?:\/\/douc\.cc/
        var re2 = /https?:\/\/(www.)?douban\.com\/link2/
        if (re1.test($link.href)) {
          $link.textContent = $link.textContent.replace($link.href, $link.title)
          $link.href = $link.title
        } else if (re2.test($link.href)) {
          var searchParams = utils.getSearchParams($link.href)
          if (searchParams && searchParams.get("url")) {
            $link.href = searchParams.get("url")
          }
        }
        return $link
      }
    ],
    [
      /twitter\.com*/,
      function transform($link) {
        var re = /https?:\/\/t\.co/
        if (re.test($link.href)) {
          $link.href = $link.textContent.replace(/((\.\.\.)|(…))$/, '')
        }
        return $link
      }
    ],
    [
      /youtube\.com*/,
      function transform($link) {
        var re = /https?:\/\/(www\.)?youtube\.com\/redirect\?/
        if (re.test($link.href)) {
          var searchParams = utils.getSearchParams($link.href)
          if (searchParams && searchParams.get("q")) {
            $link.href = searchParams.get("q")
          }
        }
        return $link
      }
    ]
  ]

  function transformLinks($links, handler) {
    utils.forEachRight($links, function(it) {
      if (it) {
        utils.concurrent(
          function transform() {
            handler[1](it)
          }
        )
      }
    })
  }

  function createMutationCallback(handlerToUse) {
    return function onDomMutation(mutationList) {
      utils.forEachRight(mutationList, function(mutation) {
        utils.concurrent(function () {
          var target = mutation.target
          if (!target) return

          var $newLinks = []

          if (utils.isElement(target)) {
            utils.forEachRight(utils.$$("a", target), function addNewLink($link) {
              $newLinks.push($link)
            })
          }

          transformLinks($newLinks, handlerToUse)
        })
      })
    }
  }

  function start() {
    var hostname = window.location.hostname

    var handlerToUse = null
    while (handlers.length > 0) {
      var handler = handlers.pop()
      if (handler[0].test(hostname)) {
        handlerToUse = handler
        break;
      }
    }

    if (handlerToUse) {
      transformLinks(utils.$$("a"), handlerToUse)
      var observer = new MutationObserver(createMutationCallback(handlerToUse))
      observer.observe(document.body, {subtree: true, childList: true})
    }
  }

  document.addEventListener("DOMContentLoaded", start)
})()