Trim Reddit

Trimmer for Reddit

目前为 2022-06-29 提交的版本。查看 最新版本

// ==UserScript==
// @name          Trim Reddit
// @namespace     stgeorge
// @description   Trimmer for Reddit
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @match         *://old.reddit.com/*
// @match         *://www.reddit.com/*
// @grant         GM.xmlHttpRequest
// @grant         GM.getValue
// @grant         GM.setValue
// @grant         GM.deleteValue
// @version       2.11
// @license       MIT
// @run-at        document-end
// ==/UserScript==

(() => {
  let side = null;

  let DONT_MATCH = [
    /\/r\/\w+\/comments\//,
    /\/login/,
    /\/over18/,
  ];

  const OPT_NEW_LINKS = true;

  // 0 => load links in same tab
  // 1 => image links in new tab
  // 2 => all links in new tab.
  const OPT_LINK_LOAD = 2;

  const IMG_LINKS = $([
    'imgur.com',
    'i.imgur.com',
    'preview.redd.it',
    'youtube.com'
  ]);

  function trim() {
    $(`<style>
      .selected .choice {
        color: red !important;
      }
      .choice {
        color: black !important;
      }
      #search {
        text-align: center;
        padding: 5px;
        position: revert !important;
        margin-top: 0 !important;
        width: 80% !important;
        transform:none !important;
      }
      #search input {
        max-width: revert !important;
        min-width: revert !important;
      }
      .tabmenu {
        margin: 10px 0 10px 0;
      }
      .tabmenu li a {
        font-weight: normal !important;
      }
      #body-wrapper {
        display: flex;
        background: white;
        height: calc(100vh - 50px);
      }
      #header {
        height: revert !important;
        position: sticky !important;
        font-size: 0.7rem;
        background: white !important;
        color: black !important;
        border-bottom: solid 1px black !important;
        padding: 0 !important;
      }
      #header * {
        background-color: #fefefe !important;
        color: black !important;
      }
      #newr,#lgn {
        color: red !important;
      }
      #header::after {
        position: revert !important;
      }
      .thing {
        background-color:white !important;
      }
      .link {
        margin-right: revert !important;
      }
      .link * {
        padding: 0px 2px 0px 2px !important;
        margin-right: revert !important;
      }
      .linkflairlabel,.link .rank,.title::before,.thumbnail,.midcol {
        display: none !important;
      }
      .entry {
        margin-left: 5px !important;
      }
      body div.content {
        margin: 5px !important;
      }
      .sitetable {
        border-bottom: 0 !important;
        border-left: 0 !important;
        border-right:solid 1px #eeeeff !important;
        margin-right: revert !important;
      }
      .linklisting.sitetable {
        margin-right: 0 !important;
      }
      .listing-page #siteTable {
        margin-right: 0;
      }
      #siteTable::before {
        padding: 0 !important;
        margin: 5px 0 5px 0 !important;
        content: '' !important;
        height: 0 !important;
        width: 0 important;
        border: none !important;
      }
      .curauthor {
        color: red !important;
        font-weight: bold !important;
      }
      .side {
        margin: 0 !important;
        z-index: 100 !important;
        background: url('') !important;
        background-color: transparent !important;
        box-shadow: revert !important;
        width:100% !important;
        overflow-y:auto !important;
        padding-top: 0 !important;
        border-left: solid 1px black !important;
      }
      .side::before {
        content: revert !important;
        background: revert !important;
      }
      .side:after {
        content: '';
      }
      .side * {
        font-size: 16px !important;
      }
      .side a {
        background-color: revert !important;
      }
      a.title {
        background: url('') !important;
      }
      .side .commentarea {
        margin-right: revert !important;
      }
      .sidemenu {
        padding:2px 2px 5px 5px;
        margin:2px;
        background-color:#eee;
        position:sticky;
        top:0;
        z-index:999;
      }
      .sidemenu-button {
        font-weight:bold;
        cursor:pointer;
      }
      .expando {
        position: revert !important;
      }
      .expando-button {
        display: none !important;
      }
      .md {
        background: white !important;
      }
      div.md>blockquote>p {
        position: inherit !important;
      }
      .md p::before {
        width:0 !important;
      }
      .content:before {
        background-color: revert !important;
        background-image: revert !important;
        height:0px !important;
      }
      .clicked {
        background-color: #f8fefe !important;
        border: solid 1px black !important;
      }
      .ui-resizable-e { 
        cursor: e-resize; 
        width: 2px; 
        right: -1px; 
        top: 0; 
        bottom: 0; 
        background-color: blue !important;
      }
      #popup {
        position: fixed;
        top: 0;
        left:0;
        background:rgba(0,0,0,0.75);
        width:100%;
        height:100%;
        display:none;
      }
      .searchpane,.search-result-group-header {
        display:none !important;
      }
      .search-result-listing {
        margin: revert !important;
      }
      .search-result-group {
        max-width: 100% !important;
        min-width: 100% !important;
        padding-left: 5px !important;
        padding-right: 5px !important;
      }
      .disabled {
        cursor:not-allowed;
      }
      .hide {
        display:none !important;
      }
      .menuarea,a[name="content"] {
        visibility:hidden;
        display:none;
      }
    </style>`).appendTo('head');

    let tabmenu = $('.tabmenu').detach();
    $('.infobar').remove();
    $('.footer-parent').remove();
    $('#sr-header-area').siblings().remove();
    let content = $('.content[role="main"]');

    content.css({
      width:'35%',
      // height: '1000px',
      'overflow-y': 'auto',
      resize:'horizontal',
      margin: '0',
    });

    //
    // We make the right-hand side sidebar (.side) bigger and empty its
    // contents. Then, we make the main pane (.content) thinner and
    // use it show the list of articles. (We mark it as resizable horizontally
    // so that it can be widened.) When an article is clicked on in
    // the .content pane, we show its threaded comments in the .side pane.
    //
    // +----------------------------------------------------+
    // |                      #header                       |
    // +----------------------------------------------------+
    // |                #body-wrapper (new)                 |
    // | +-------------+----------------------------------+ |
    // | |  .content   |             .side                | |
    // | |+-----------+|                                  | |
    // | ||  tabmenu  ||                                  | |
    // | |+-----------+|                                  | |
    // | ||  #search  ||        Post and comments         | |
    // | |+-----------+|                                  | |
    // | || Post list ||                                  | |
    // | ||  ...      ||                                  | |
    // | |+-----------+|                                  | |
    // | +-------------+----------------------------------+ |
    // +----------------------------------------------------+
    //
    let wrapper = $('<div id="body-wrapper"></div>');
    $('#header').after(wrapper);
    wrapper.append(content);
    let search = $('#search').detach();
    content.prepend(search);
    search.find('label').detach();
    let subs = /r\/(\w+)\//i.exec(top.location.href);
    if (subs && subs.length > 1) 
      $('#search').children('input[name="q"]').first().val('subreddit:'+subs[1]+' ');
    content.prepend(tabmenu);
    side = $('.side');
    side.empty();
    wrapper.append(side);

    let curbg = 'white';
    let first = null;
    retargetLinks($('.entry').add('.search-result'));
    $('.entry a').add('.search-result a').add('a.title')
      .each(function(k,v) {
      let t = $(this).closest('.thing');
      if (t.length == 0)
        t = $(this).closest('.search-result');
      let a = $(this);
      a.attr('title', a.text());
      let href = a.attr('href');
      if (href.indexOf('/comments/') != -1) {
        a.on('click', function(e) {
          e.preventDefault();
          e.stopPropagation();
          t.css({'background-color':'#ffeeee'});
          t.addClass('clicked');
          t.siblings().css({'background-color':curbg});
          t.siblings().removeClass('clicked');
          href = href.replace('www.reddit.com', 'old.reddit.com').
            replace('//reddit.com', '//www.reddit.com');
          (async () => {await GM.setValue('lastseen', href)})();
          loadComment(href);
        });
        if (first === null && !t.hasClass('stickied')) {
          first = a;
        }
      }
    });
    (async() => {
      let last_seen = await GM.getValue('lastseen', null);
      GM.deleteValue('lastseen');
      let l = null;
      if (last_seen) {
        l = $('a[href="'+last_seen+'"]');
      }
      let to_show = (l && l.length > 0) ? l : first;
      if (to_show) {
        to_show.click();
      }
    })();
  }

  function retargetLinks(div) {
    if (OPT_LINK_LOAD > 0) {
      div.find('a').each(function(k,v) {
        let anchor = $(this);
        let href = anchor.attr('href');
        if (!href) return true;
        if (OPT_LINK_LOAD == 1) {
          IMG_LINKS.each(function(x,y) {
            if (href.indexOf('/'+y+'/') != -1) {
              anchor.attr('rel','noopener');
              anchor.attr('target','_blank');
              return false;
            }
          });
        } else if ((href.startsWith('http://') || href.startsWith('https://')) &&
          href.indexOf('.reddit.com/') == -1) {
          anchor.attr('rel','noopener');
          anchor.attr('target','_blank');
        }
      });
    }
  }

  function toggleComments(expand) {
    $('.commentarea').find('.comment').each(function(k,v) {
      let cur = $(v);
      let p = cur.parents('.comment');
      if (p.length == 0) {
        let children = cur.find('.comment');
        if (expand) {
          children.removeClass('collapsed').addClass('noncollapsed');
        } else {
          children.addClass('collapsed').removeClass('noncollapsed');
        }
        cur.removeClass('collapsed').addClass('noncollapsed');
      }
    });
  }
  
  function loadComment(u) {
    GM.xmlHttpRequest({
      method: "GET",
      url: u+'?sort=new',
      onload: function(response) {
        side.html($.parseHTML(response.responseText));
        let c = side.find('.content[role="main"]').detach();
        side.empty();
        side.append(`
          <div class="sidemenu">
            <span class="sidemenu-button" title="Expand/collapse lower levels" id="toggleall">[+/-]</span>
            <span style="margin-left:1em" title="Next entry by user" class="hide sidemenu-button" id="fnext">[&#9660;]</span>
            <span class="hide sidemenu-button" title="Previous entry by user" id="fprev">[&#9650;]</span>
            </div>
          </div>
        `);
        side.append(c);
        c.css({margin:'10px'});
        side.find('.infobar').detach();
        let toggle_expand = false;
        $('#toggleall').on('click', function(e) {
          e.preventDefault();
          e.stopPropagation();
          toggleComments(toggle_expand);
          toggle_expand = !toggle_expand;
        });
        retargetLinks(side);
        let all = [];
        let all_index = -1;
        let url = document.URL.replace(/\?.*/, '');
        if (url.indexOf('/user/') != -1) {
          side.find('a[href="'+url+'"]').each(function(k,v) {
            let a = $(this);
            all.push(a);
            a.addClass('curauthor');
          });
          if (all.length > 0) {
            $('.sidemenu-button').removeClass('hide');
            $('#fnext').on('click', function(e) {
              e.preventDefault();
              e.stopPropagation();
              if (++all_index >= all.length)
                all_index = 0;
              scrollTo(side, all[all_index]);
            });
            $('#fprev').on('click', function(e) {
              e.preventDefault();
              e.stopPropagation();
              if (--all_index < 0)
                all_index = all.length - 1;
              scrollTo(side, all[all_index]);
            });
          }
        }
        setTimeout(function() {
          $(document).scrollTop(0);
          side.scrollTop(0);
        }, 500);
      }
    });
  }

  function enable(x, v) {
    if (v) {
      $(x).removeClass('disabled');
    } else {
      $(x).addClass('disabled');
    }
  }
  function scrollTo(p, el) {
    if (!el) return;
    setTimeout(function() {
      p.scrollTop(el.offset().top - p.offset().top + p.scrollTop() - 50);
    }, 500);
  }

  function fixHeader() {
    //
    // If OPT_NEW_LINKS is set, we add a 'new' link to to the header
    // to toggle between old and new reddits and a 'login' link.
    if (OPT_NEW_LINKS) {
      let bars = $('#sr-bar');
      let i = 0;
      bars.find('li').each(function(k,v) {
        if (i++ == 1) {
          let li = $(this);
          bars.prepend(addLink(li, 'newr', 'new',
            top.location.href.replace('old','www'), 'New Reddit'));
          bars.prepend(addLink(li, 'lgn', 'login',
            top.location.href.replace(/\.com\/.*/, '.com/login'), 'Login'));
          return false;
        }
      });
    }
  }

  function addLink(template, new_id, new_text, new_url, new_title) {
    let x = template.clone(true);
    let span = x.find('span').first();
    let a = x.find('a').first();
    a.text(new_text);
    a.attr('id', new_id);
    a.attr('href', new_url);
    a.attr('title', new_title);
    span.before(a);
    return x;
  }

  function addOldButton() {
    //
    // If we're in the 'new' reddit, add an 'Old' button to help
    // us switch to old reddit.
    //
    if (document.URL.indexOf('www.reddit.com') != -1) {
      let x = $('#email-verification-tooltip-id');
      $('#email-verification-tooltip-id').
        before($('<button title="Old Reddit" id="old-button" type="button">Old</button>'));
      let old = $('#old-button');
      old.css({
        margin: '10px',
        border: 'solid 1px #0079d3',
        padding: '8px',
        width: '120px',
        'border-radius': '9999px',
        color: '#0079d3',
        'font-weight': 'bold',
      });
      old.on('click', function() {
        top.location.hostname = 'old.reddit.com';
      });
      return;
    }
  }

  // Main.
  // The setTimeout is there to handle race conditions to run our
  // script after reddit loads all its scripts. Doesn't seem to work
  // always :-(
  // 
  setTimeout(function() {
    addOldButton();
    let do_trim = true;
    $(DONT_MATCH).each(function(k,v) {
      if (document.URL.match(v)) {
        do_trim = false;
        return false;
      }
    });
    if (do_trim) {
      trim();
      fixHeader();
    }
  }, 1000);

})();

QingJ © 2025

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