User:Gary/comment highlighter.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// Generated by CoffeeScript 2.1.1
(function() {
  /*
    COMMENT HIGHLIGHTER
    Description: Highlights recent comments yellow, while your own comments are
    highlighted in blue.

    (Requires [[User:Gary/comments in local time.js]] for now).

    FIXME: Remove dependency on [[User:Gary/comments in local time.js]].
    FIXME: Fix on [[WP:RFA]] nominations (!votes, as in comments wrapped in
      <li>s).
  */
  var CommentHighlighter, runCHScript;

  CommentHighlighter = (function() {
    var now;

    class CommentHighlighter {
      static calculateColorRatio(maxTime, minPercentage, maxPercentage, timestamp) {
        var colorRatio;
        minPercentage = minPercentage / 100;
        maxPercentage = maxPercentage / 100;
        colorRatio = ((maxPercentage - minPercentage) * ((now.valueOf() - timestamp.valueOf()) / maxTime) + minPercentage) * 100;
        if (colorRatio < minPercentage) {
          colorRatio = minPercentage;
        }
        return colorRatio;
      }

      static getCommentParent(node, commentDivsExist) {
        var i, len, newParent, parent, possible, possibleParentNode, possibleParentNodes, possibleParents, possibleResults;
        possibleParentNodes = ['DD', 'DIV', 'LI', 'P'];
        parent = node.parent();
        if (parent.closest('.diff').length) {
          return $();
        } else if (commentDivsExist && $.inArray(parent[0].nodeName, possibleParentNodes) > -1) {
          return parent;
        }
        possibleParents = [];
        possibleResults = {};
        for (i = 0, len = possibleParentNodes.length; i < len; i++) {
          possibleParentNode = possibleParentNodes[i];
          possible = possibleParentNode.toLowerCase();
          possibleResults[possible] = node.parentsUntil(possible);
          possibleParents.push([possibleResults[possible].first().parent(), possibleResults[possible].length]);
        }
        // Get the closest parent node for a comment.
        possibleParents.sort(function(a, b) {
          return a[1] - b[1];
        });
        if (possibleParents[0][1]) {
          parent = possibleParents[0][0];
        }
        if (parent.length && !commentDivsExist && parent.contents().length) {
          newParent = $('<div class="comment"></div>');
          parent.contents().each(function(index, element) {
            node = $(element);
            if (node[0].nodeName === 'DL') {
              return false;
            }
            return newParent.append(node);
          });
          parent.prepend(newParent);
          return newParent;
        } else {
          return parent;
        }
      }

      static highlightComment(timestamp, maxTime) {
        var colorRatio, parent, timestampValue;
        timestampValue = parseInt(timestamp.attr('timestamp'));
        parent = this.getCommentParent(timestamp, false);
        if (!parent.length) {
          return true;
        }
        parent.attr('title', timestamp.text());
        if (now.valueOf() - timestampValue < maxTime) {
          colorRatio = this.calculateColorRatio(maxTime, 50, 100, new Date(timestampValue));
          return parent.css('background-color', 'rgb(100%, 100%, ' + colorRatio + '%)');
        }
      }

      static highlightUsername(link, formattedUsername, secondUsername, usernameBackground) {
        var linkIsGood, parent, secondUsernameCheck, usernameCheck;
        linkIsGood = link && link.attr('href');
        usernameCheck = this.linkLinksToUsername(formattedUsername, link);
        if (secondUsername) {
          secondUsernameCheck = this.linkLinksToUsername(secondUsername, link);
        } else {
          secondUsernameCheck = false;
        }
        if (linkIsGood && (usernameCheck || secondUsernameCheck) && !link.closest('#contentSub').length) {
          parent = this.getCommentParent(link, true);
          if (!parent.length) {
            return true;
          }
          parent.css('background-color', usernameBackground);
          return link.parentsUntil('.mw-content-ltr').last().prevUntil('h2').last().prev().css('background-color', usernameBackground);
        }
      }

      static init() {
        var formattedUsername, maxTime, myUsername, secondUsername, usernameBackground;
        // 24 hours before we don't color a comment anymore
        maxTime = 1000 * 60 * 60 * 24;
        // Highlight messages posted today (REQUIRES [[WP:Comments in Local Time]]
        // SCRIPT)
        $('span.localcomments').each((index, element) => {
          return CommentHighlighter.highlightComment($(element), maxTime);
        });
        // Check to see if any comments contain comments. None of them should. But if
        // they do, then unwrap the parent .comment.
        $('.comment').find('.comment').each(function(index, element) {
          var childComment, parentComment;
          childComment = $(element);
          parentComment = childComment.parent().closest('.comment');
          return parentComment.children().first().unwrap();
        });
        // Highlight discussion sections that I am linked from (i.e. that I
        // participated or was mentioned in). Also highlight the line itself.
        myUsername = window.mw.config.get('wgUserName');
        if (myUsername != null) {
          formattedUsername = 'User:' + myUsername.replace(/\ /g, '_');
          usernameBackground = '#eef';
          if (myUsername === 'Gary') {
            secondUsername = 'User:Gary_King';
          }
          return $('#bodyContent a').each((index, element) => {
            return CommentHighlighter.highlightUsername($(element), formattedUsername, secondUsername, usernameBackground);
          });
        }
      }

      static linkLinksToUsername(username, link) {
        if (link.attr('href') && link.attr('href').indexOf(username) > -1 && link.attr('href').indexOf(username) === (link.attr('href').length - username.length)) {
          return true;
        } else {
          return false;
        }
      }

    };

    now = new Date();

    return CommentHighlighter;

  }).call(this);

  // This script depends on "Comments in Local Time", so it should run after that.
  runCHScript = function() {
    if (window.mw.config.get('wgAction') === 'view' && (typeof isDiscussionPage !== "undefined" && isDiscussionPage !== null) && isDiscussionPage) {
      return setTimeout(function() {
        return CommentHighlighter.init();
      }, 0);
    }
  };

  $(function() {
    return runCHScript();
  });

}).call(this);