Reddit Plus

Additional little features for Reddit.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Reddit Plus
// @namespace   reddit
// @description Additional little features for Reddit.
// @include     https://www.reddit.com*
// @version     1.2
// @copyright   2015 Armando Lüscher
// @author      Armando Lüscher
// @oujs:author noplanman
// @grant       GM_addStyle
// @require     https://code.jquery.com/jquery-1.11.3.min.js
// @homepageURL https://github.com/noplanman/Reddit-Plus
// @supportURL  https://github.com/noplanman/Reddit-Plus/issues
// ==/UserScript==

var RedditPlus = {};

/**
 * The MutationObserver to detect page changes.
 */
RedditPlus.Observer = {

  // The mutation observer object.
  observer : null,

  // The elements that we are observing.
  queryToObserve : '#siteTable',

  /**
   * Start observing for DOM changes.
   */
  init : function() {

    // Check if we can use the MutationObserver.
    if ('MutationObserver' in window) {
      var toObserve = document.querySelector(RedditPlus.Observer.queryToObserve);
      if (toObserve) {
        RedditPlus.Observer.observer = new MutationObserver(function() {
          RedditPlus.addCommentToggles();
        });

        // Observe child changes.
        RedditPlus.Observer.observer.observe(toObserve, {
          childList: true
        });
      }
    }
  }
};

/**
 * Fetch the comments and fill them into the appropriate div.
 * @param  {jQuery} $div DIV of the comment area.
 * @param  {string} url  URL of the entry to load the comments from.
 */
RedditPlus.loadComments = function($div, url) {
  // Let the user know that it's loading the comments.
  $div.html('loading...');

  // Get the comments page and extract the info we need.
  $.get(url, function(response) {
    // Get rid of all images first, no need to load those.
    var $post = $(response.replace(/<img[^>]*>/g, ''));

    // Also fetch the text telling us how many comments there are.
    var numOfCommentsText = $post.find('.flat-list .first .comments').html();
    $div.prevAll('.flat-list').find('.first .comments').html(numOfCommentsText);

    // Find the comments area.
    var $commentArea = $('.commentarea', $post);

    // Remove the title and comment filter menu.
    $commentArea.find('.panestack-title, .menuarea').remove();

    // Hide the input field to add a comment and add a button to show it.
    var $commentForm = $('.usertext.cloneable', $commentArea).hide();
    var $textArea = $('textarea', $commentForm);

    // Add a button at the top to add a new comment.
    $('<a/>', {
      class : 'rp-button',
      html  : '<button>add new comment</button><button style="display:none;">cancel</button>',
      click : function() {
        // Switch the "Add new comment" and "Cancel" buttons.
        $('button', this).toggle();

        // Show or Hide the comment form.
        $commentForm.toggle();

        // Set the focus on the comment input field.
        $textArea.focus();
      }
    }).prependTo($commentArea);

    $('button.save', $commentArea).click(function() { $textArea.focus(); });

    // Add a link at the bottom to close the comments.
    $('<a/>', {
      class : 'rp-link',
      html  : '<span>close comments [-]</span>',
      click : function() {
        // Scroll the window to the correct position.
        $(window).scrollTop($(window).scrollTop() - $div.height());

        // Hide the comments.
        RedditPlus.toggleComments($div, url);
      }
    }).appendTo($commentArea);


    // Add a button at the top to reload the comments.
    $('<a/>', {
      class : 'rp-button',
      html  : '<button>reload comments</button>',
      click : function() {
        // Reload all the comments.
        RedditPlus.loadComments($div, url);
      }
    }).prependTo($commentArea);

    // Add the freshly loaded comments to the DIV.
    $div.html($commentArea);
  });
};

/**
 * Toggle the comments area below the link.
 *
 * @param  {jQuery} $div DIV of the comment area.
 * @param  {string} url  URL of the entry to load the comments from.
 */
RedditPlus.toggleComments = function($div, url) {
  // Show / Hide the comments area div.
  $div.toggle();

  // Switch the "[+]" and "[-]" buttons.
  $div.closest('.entry').find('.rp-comments-toggle span').toggle();

  // If we aren't loading / haven't loaded the comments yet, do this now.
  if (!$div.attr('data-loading')) {
    $div.attr('data-loading', true);
    RedditPlus.loadComments($div, url);
  }
};

/**
 * Add the toggles next to the comment links.
 */
RedditPlus.addCommentToggles = function() {
  // Don't execute on comment pages.
  if ($('body.comments-page').length > 0) {
    return;
  }

  // Add toggles next to the comment links that haven't been handled yet.
  $('.comments').not('.rp-comments-toggle-added').each(function() {
    var $commentsLink = $(this);

    // Remember the url of the post page, cause that's where we load the comments from.
    var url = this.href;

    // The div that will contain the loaded comments.
    var $div = $('<div/>', {
      class : 'rp-comments-div',
      html  : 'loading...'
    })
    .hide()
    .appendTo($commentsLink.closest('.entry'));

    // Link to expand / reduce the comments.
    $('<a/>', {
      class : 'rp-comments-toggle',
      style : 'cursor: pointer;',
      html  : '<span title="show comments">[+]</span><span title="close comments" style="display:none">[-]</span>',
      click : function() {
        // Show or Hide the comments.
        RedditPlus.toggleComments($div, url);
      }
    }).insertAfter($commentsLink);

    // Add a class to remember which ones have already been added.
    $commentsLink.addClass('rp-comments-toggle-added');
  });
};

/**
 * Start the party.
 */
RedditPlus.init = function() {
  // Add the global CSS rules.
  GM_addStyle(
    '.rp-comments-div .rp-button { display: inline-block; margin: 4px; }' +
    '.rp-comments-div .rp-link { cursor: pointer; }'
  );

  // Start the observer.
  RedditPlus.Observer.init();

  // Initial load.
  RedditPlus.addCommentToggles();
};

// source: https://muffinresearch.co.uk/does-settimeout-solve-the-domcontentloaded-problem/
if (/(?!.*?compatible|.*?webkit)^mozilla|opera/i.test(navigator.userAgent)) { // Feeling dirty yet?
  document.addEventListener('DOMContentLoaded', RedditPlus.init, false);
} else {
  window.setTimeout(RedditPlus.init, 0);
}