colorDate

"Set date color according to date 根据网页上日期的新旧程度, 给日期进行着色, 比如说已经是5年前的一个日期会成为红色, 以便提醒阅览者,注意信息可能过于陈旧。"

当前为 2018-04-03 提交的版本,查看 最新版本

// ==UserScript==
// @name     colorDate
// @namespace https://github.com/mika-cn/user-scripts
// @description "Set date color according to date 根据网页上日期的新旧程度, 给日期进行着色, 比如说已经是5年前的一个日期会成为红色, 以便提醒阅览者,注意信息可能过于陈旧。"
// @version  1.0.3
// @grant    none
// ==/UserScript==
// @author   mika
// @code     https://github.com/mika-cn/user-scripts

(function(){


  /*
   * 获取文本节点迭代器
   */
  function getTextNodeIterator(){
    return document.createNodeIterator(
      document.body,
      NodeFilter.SHOW_TEXT, function(node) {
        if(['script', 'style', 'datetext', 'datespan'].indexOf(node.parentNode.nodeName.toLowerCase()) > -1){
          return NodeFilter.FILTER_REJECT;
        }else{
          return NodeFilter.FILTER_ACCEPT;
        }
      }
   );
  }


  /*
   * 根据规则(判断是否是日期),获取满足的节点
   */
  function getMatchNode(){
    var nodes = [];
    var currentNode;
    var nodeIterator = getTextNodeIterator();
    while (currentNode = nodeIterator.nextNode()) {
      var v = currentNode.nodeValue;
      var rule = rules.some(function(rule){
        return !!v.match(rule.regExp)
      });
      if(rule){
        nodes.push(currentNode)
      }
    }
    return nodes;
  }

  /*
   * 时长阀值与色值
   */
  var day  = 24 * 60 * 60 * 1000;
  var year = 365 * day;
  var colors = [
    {color: "#ff0000", threshold: 5 * year},
    {color: "#ff5f00", threshold: 3 * year},
    {color: "#d700ff", threshold: 1 * year},
    {color: "#8700ff", threshold: 183 * day},
    {color: "#00af00", threshold: 7 * day},
    {color: "#00d700", threshold: 1 * day},
  ]

  /*
   * 判断规则
   */
  var rules = [
    {key: "regExp_01", regExp: /\d{4}-[0,1]?\d-[0-3]?\d/g},
    {key: "regExp_02", regExp: /\d{4}\/[0,1]?\d\/[0-3]?\d/g},
  //  {key: "regExp_03", regExp: /(\d{4}-[0,1]?\d)[^-]*/g},
  //  {key: "regExp_04", regExp: /(\d{4}\/[0,1]?\d)[^\/]*/g},
    {key: "regExp_05", regExp: /[0,1]{1}\d-[0-3]{1}\d/g},
    {key: "regExp_06", regExp: /(?:Jan|jan|Feb|feb|Mar|mar|Apr|apr|May|may|Jun|jun|Jul|jul|Aug|aug|Sep|sep|Oct|oct|Nov|nov|Dec|dec) [0-3]?\d[,\s]{1}\s?\d{4}/},

    {key: "regExp_11", regExp: /\d{4}年[0,1]?\d月[0-3]?\d日/g},
    {key: "regExp_13", regExp: /\d{4}年[0,1]?\d月/g},
    {key: "regExp_15", regExp: /[0,1]?\d月[0-3]?\d日/g},
  ]

  /*
   * 根据不同的正则,返回处理函数
   */
  function getReplace(key){

    var group_01 = ["regExp_01", "regExp_02", "regExp_06", "regExp_11"]
    var group_02 = ["regExp_03", "regExp_04", "regExp_13"]
    var group_03 = ["regExp_05", "regExp_15"]

    if(group_01.indexOf(key) > -1){
      return function(match){
        var dateStr = match.replace(/年|月/g, '-').replace("日", '');
        return replace(match, dateStr)
      }
    }

    if(group_02.indexOf(key) > -1){
      return function(match){
        var dateStr = match.replace(/年|\//g, '-').replace("月", '') + "-01";
        return replace(match, dateStr)
      }
    }

    if(group_03.indexOf(key) > -1){
      return function(match){
        var dateStr = (new Date()).getFullYear().toString() + "-" + match.replace(/月/g, '-').replace("日", '');
        return replace(match, dateStr)
      }
    }
  }

  /*
   * 处理函数, 根据时长阀值着色
   */
  function replace(match, dateStr){
    try{
      var result = match;
      var diff = Date.now() - Date.parse(dateStr);
      colors.some(function(item){
        if(diff >= item.threshold){
          result = "<datespan style='color:"+ item.color +";'>" + match +"</datespan>";
          return true
        }
        return false
      })
      return result;
    }catch(e){
      return match;
    }
  }


  // 主函数
  function colorDate(){
    //console.log("color date");
    nodes = getMatchNode();
    nodes.forEach(function(node){
      // replace child node
      var newNode = document.createElement("datetext");
      var html = node.nodeValue;
      rules.forEach(function(rule){
        var match = html.match(rule.regExp);
        if(match){
          html = html.replace(rule.regExp, getReplace(rule.key))
        }
      })
      newNode.innerHTML = html
      node.parentNode.replaceChild(newNode, node)
    })
  }



  /*
   * 创建延迟调用对象
   * 用来防止短时间内被调用多次
   */
  var createDelayCall = function(fn, delay){
    var dc = {};
    dc.action = fn;
    dc.clearTimeout = function(){
      if(dc.timeoutId){
        clearTimeout(dc.timeoutId);
      }
    };
    dc.run = function(){
      dc.clearTimeout();
      dc.timeoutId = setTimeout(function(){
        dc.action();
        dc.clearTimeout();
      }, delay);
    }
    return dc;
  }

  /*
   * 判断变更是否来自脚本
   */
  function isColorDateMotation(mutationRecords){
    return mutationRecords.every(function(record){
      return record.type === "childList" && record.addedNodes.length > 0 && record.addedNodes[0].nodeName.toLowerCase() === "datetext";
    })
  }

  var delayColorDate = createDelayCall(colorDate, 400);

  /*
   * 初始化 mutationObserver
   */
  function initMutationObserver(){
    var config = { };
    var mutated = function(mutationRecords){
      if(isColorDateMotation(mutationRecords)){
        // 本脚本产生的变更,不触发
        // console.log("Ignore motation")
      }else{
        delayColorDate.run();
      }
    }
    var observer = new MutationObserver(mutated);
    observer.observe(document, {
      attributes: false,
      childList: true,
      subtree: true
    });
    //console.log("init mutationObserver");
  }

  // 监听变更,触发着色 (适用于动态网页,如: ajax加载内容后产生变更)
  initMutationObserver();
  // 静态网页加载过程中不会产生变更, 直接调用
  setTimeout(colorDate, 400);
  setTimeout(colorDate, 1000);
  setTimeout(colorDate, 4000);

})();

QingJ © 2025

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