Automatic URL Decoder

Декодирует все найденные на странице ссылки, похожие на "%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80", в удобочитаемое "привет мир"

Verzia zo dňa 05.04.2018. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name Automatic URL Decoder
// @namespace https://github.com/T1mL3arn
// @description:ru Декодирует все найденные на странице ссылки, похожие на "%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80", в удобочитаемое "привет мир"
// @description:en It decodes all cyrillic links on current page.
// @match *://*/*
// @version 1.0
// @run-at document-end
// @license GPLv3
// @supportURL https://github.com/T1mL3arn/Automatic-URL-Decoder/issues
// @homepageURL https://github.com/T1mL3arn/Automatic-URL-Decoder
// @description Декодирует все найденные на странице ссылки, похожие на "%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80", в удобочитаемое "привет мир"
// ==/UserScript==

let linkEreg = /(https|http|ftp|file):.+?(?=\s|$)/gi;
let linkEregLocal = /(https|http|ftp|file):.+?(?=\s|$)/i;
let obsOptions = { childList: true, subtree: true };

let underlineStyle = new Map([["border-bottom","2px solid currentColor"], ["margin-bottom", "-2px"]]);
// set one of style from above to enable 
// custom style for fixed links
let changedLinkStyle = null;

let obs = new MutationObserver((changes, obs) => {
  changes.forEach((change) => change.addedNodes.forEach((node) => fixLinks(node)) );
});
obs.observe(document.body, obsOptions);

function fixLinks(node) {
  if (node.nodeType === 3) {
    let content = node.textContent;
    if (content && content != '') {
      if (linkEregLocal.test(content)) {
        if (changedLinkStyle)
          replaceAndStyleLink(node);
        else {
          let decoded = content.replace(linkEreg, decodeURIComponent);
          if(decoded.length!=content.length)
            node.textContent = decoded;
        }
      }
    }
  } else if (node.childNodes && node.childNodes.length > 0) {
    node.childNodes.forEach(fixLinks);
  }
}

function replaceAndStyleLink(node) {
  let match;
  let offset = 0;
  let sibling = node;
  let content = node.textContent;
  obs.disconnect();
  while ((match = linkEreg.exec(content)) != null) {
    let fullMatch = match[0];
    let decoded = decodeURIComponent(fullMatch);
    if (decoded.length != fullMatch.length) {
      let span = document.createElement('span');

      changedLinkStyle.forEach((val, key) => span.style.setProperty(key, val));
      
      let range = document.createRange();
      range.setStart(sibling, linkEreg.lastIndex - match[0].length);
      range.setEnd(sibling, linkEreg.lastIndex);
      range.surroundContents(span);
      
      sibling = getNextTextSibling(span);
      content = sibling.textContent;
      span.textContent = decoded;
      linkEreg.lastIndex = 0;

      if (sibling == null)
        break;
    }
  }
  obs.observe(document.body, obsOptions);
}

function getNextTextSibling(node) {
  let next = node.nextSibling;
  while (next != null) {
    if (next.nodeType == 3)
      return next;
    else
      next = node.nextSibling;
  }
  return null;
}

fixLinks(document.body);