Reddit Plus

Additional little features for Reddit.

目前為 2015-09-06 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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);
}