RequirementEasyJump

Turn plain requirement text URLs into clickable links

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name						RequirementEasyJump
// @description					Turn plain requirement text URLs into clickable links
// @description:zh				把需求文字链接转换为可点击链接
// @author						chiyuan666
// @namespace					chiyuan666
// @version						1.0
// @license						AGPL
// @include						*gates.nsn-net.net/*
// @exclude						*pan.baidu.com/*
// @exclude						*renren.com/*
// @exclude						*exhentai.org/*
// @exclude						*music.google.com/*
// @exclude						*play.google.com/music/*
// @exclude						*mail.google.com/*
// @exclude						*docs.google.com/*
// @exclude						*www.google.*
// @exclude						*acid3.acidtests.org/*
// @exclude						*.163.com/*
// @exclude						*.alipay.com/*
// @run-at						document-end
// @grant						unsafeWindow
// @charset						UTF-8
// ==/UserScript==

"use strict";
;
var clearLink, excludedTags, linkFilter, linkMixInit, linkPack, linkify, observePage, observer, setLink, urlPrefixes, xPath;
var url_regexp_CP_Entity_Architecture_and_Algorithms;
var url_regexp_CP_External_Interface_Network;
var url_regexp_CP_External_Interface_RRC;
var url_regexp_CP_System_Level_Dual_Connectivity;
var url_regexp_CP_System_Level_Mobility_Management;
var url_regexp_5G_CP_System_Level_Node_Configuration;
var url_regexp_CP_System_Level_Others;
var url_regexp_Entity_Level;
var url_regexp_L3_Entity_Level_Flows;
var url_regexp_L3_Interfaces;


//url_regexp = /((https?:\/\/|www\.)[\x21-\x7e]+[\w\/=]|\w([\w._-])+@\w[\w\._-]+\.(com|cn|org|net|info|tv|cc|gov|edu)|(\w[\w._-]+\.(com|cn|org|net|info|tv|cc|gov|edu))(\/[\x21-\x7e]*[\w\/])?|ed2k:\/\/[\x21-\x7e]+\|\/|thunder:\/\/[\x21-\x7e]+=)/gi;
url_regexp_CP_Entity_Architecture_and_Algorithms = /(5G_CP_ARC_ALG_\d+)/gi
url_regexp_CP_External_Interface_Network = /(5G_CP_IF_NTW_\d+)/gi
url_regexp_CP_External_Interface_RRC = /(5G_CP_IF_RRC_\d+)/gi
url_regexp_CP_System_Level_Dual_Connectivity = /(5G_CP_DC_\d+)/gi
url_regexp_CP_System_Level_Mobility_Management = /(5G_CP_MM_\d+)/gi
url_regexp_5G_CP_System_Level_Node_Configuration = /(5G_CP_CONF_\d+)/gi
url_regexp_CP_System_Level_Others = /(5G_CP_OTH_\d+)/gi
url_regexp_Entity_Level = /(5G_L3_\d+)/gi
url_regexp_L3_Entity_Level_Flows = /(5G_L3_FLOW_\d+)/gi
url_regexp_L3_Interfaces = /(5G_L3_IF_\d+)/gi



urlPrefixes = ['http://', 'https://', 'ftp://', 'thunder://', 'ed2k://', 'mailto://', 'file://'];

clearLink = function (event) {
  var j, len, link, prefix, ref, ref1, url;
  link = (ref = event.originalTarget) != null ? ref : event.target;
  if (!(link != null && link.localName === "a" && ((ref1 = link.className) != null ? ref1.indexOf("textToLink") : void 0) !== -1)) {
    return;
  }
  url = link.getAttribute("href");
  //console.log url
  for (j = 0, len = urlPrefixes.length; j < len; j++) {
    prefix = urlPrefixes[j];
    if (url.indexOf(prefix) === 0) {
      return;
    }
  }
  if (url.indexOf('@') !== -1) {
    return link.setAttribute("href", "mailto://" + url);
  } else {
    return link.setAttribute("href", "http://" + url);
  }
};

document.addEventListener("mouseover", clearLink);

setLink = function (candidate) {
  var ref, ref1, ref2, span, text;
  if (candidate == null || ((ref = candidate.parentNode) != null ? (ref1 = ref.className) != null ? typeof ref1.indexOf === "function" ? ref1.indexOf("textToLink") : void 0 : void 0 : void 0) !== -1 || candidate.nodeName === "#cdata-section") {
    return;
  }
  if(candidate.textContent.match(url_regexp_CP_Entity_Architecture_and_Algorithms))
  {
      text = candidate.textContent.replace(url_regexp_CP_Entity_Architecture_and_Algorithms, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_CP_External_Interface_Network))
  {
      text = candidate.textContent.replace(url_regexp_CP_External_Interface_Network, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_CP_External_Interface_RRC))
  {
      text = candidate.textContent.replace(url_regexp_CP_External_Interface_RRC, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_CP_System_Level_Dual_Connectivity))
  {
      text = candidate.textContent.replace(url_regexp_CP_System_Level_Dual_Connectivity, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_CP_System_Level_Mobility_Management))
  {
      text = candidate.textContent.replace(url_regexp_CP_System_Level_Mobility_Management, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
   else if(candidate.textContent.match(url_regexp_5G_CP_System_Level_Node_Configuration))
  {
      text = candidate.textContent.replace(url_regexp_5G_CP_System_Level_Node_Configuration, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_CP_System_Level_Others))
  {
      text = candidate.textContent.replace(url_regexp_CP_System_Level_Others, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_Entity_Level))
  {
      text = candidate.textContent.replace(url_regexp_Entity_Level, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else if(candidate.textContent.match(url_regexp_L3_Entity_Level_Flows))
  {
      text = candidate.textContent.replace(url_regexp_L3_Entity_Level_Flows, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }
  else
  {
      text = candidate.textContent.replace(url_regexp_L3_Interfaces, '<a href="https://gates.nsn-net.net/requirement/$1", target="_blank" class="textToLink">$1</a>');
  }

  if (((ref2 = candidate.textContent) != null ? ref2.length : void 0) === text.length) {
    return;
  }
  console.log("hello")
  console.log(candidate.textContent)

  span = document.createElement("span");
  span.innerHTML = text;
  return candidate.parentNode.replaceChild(span, candidate);
};

excludedTags = "a,svg,canvas,applet,input,button,area,pre,embed,frame,frameset,head,iframe,img,option,map,meta,noscript,object,script,style,textarea,code".split(",");

xPath = `//text()[not(ancestor::${excludedTags.join(') and not(ancestor::')})]`;

linkPack = function (result, start) {
  var i, j, k, ref, ref1, ref2, ref3, startTime;
  startTime = Date.now();
  while (start + 10000 < result.snapshotLength) {
    for (i = j = ref = start, ref1 = start + 10000; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) {
      setLink(result.snapshotItem(i));
    }
    start += 10000;
    if (Date.now() - startTime > 2500) {
      return;
    }
  }
  console.log("linkPack")
  console.log("snapshotLength:",result.snapshotLength)
  console.log("start:",start)
  for (i = k = ref2 = start, ref3 = result.snapshotLength; ref2 <= ref3 ? k <= ref3 : k >= ref3; i = ref2 <= ref3 ? ++k : --k) {
      console.log("i:",i)
    setLink(result.snapshotItem(i));
  }
};

linkify = function (node) {
  var result;
  result = document.evaluate(xPath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  return linkPack(result, 0);
};

linkFilter = function (node) {
  var j, len, tag;
  for (j = 0, len = excludedTags.length; j < len; j++) {
    tag = excludedTags[j];
    if (tag === node.parentNode.localName.toLowerCase()) {
      return NodeFilter.FILTER_REJECT;
    }
  }
  return NodeFilter.FILTER_ACCEPT;
};

observePage = function (root) {
  var tW;
  tW = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, { //+ NodeFilter.SHOW_ELEMENT,
    acceptNode: linkFilter
  }, false);
  while (tW.nextNode()) {
    setLink(tW.currentNode);
  }
};

observer = new window.MutationObserver(function (mutations) {
  var Node, j, k, len, len1, mutation, ref;
  for (j = 0, len = mutations.length; j < len; j++) {
    mutation = mutations[j];
    if (mutation.type === "childList") {
      ref = mutation.addedNodes;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        Node = ref[k];
        observePage(Node);
      }
    }
  }
});

linkMixInit = function () {
  if (window !== window.top || window.document.title === "") {
    return;
  }
  //console.time('a')
  linkify(document.body);
  //console.timeEnd('a')
  return observer.observe(document.body, {
    childList: true,
    subtree: true
  });
};

setTimeout(linkMixInit, 3000);