Greasy Fork

AH/QQ/SB/SV direct links to Reader Mode

Append "/reader/" to forum links if they have a wordcount.

当前为 2025-04-23 提交的版本,查看 最新版本

// ==UserScript==
// @name        AH/QQ/SB/SV direct links to Reader Mode
// @description Append "/reader/" to forum links if they have a wordcount.
// @author      C89sd
// @version     1.2
// @match       https://forums.spacebattles.com/forums/*
// @match       https://forums.spacebattles.com/search/*
// @match       https://forums.spacebattles.com/tags/*
// @match       https://forums.sufficientvelocity.com/forums/*
// @match       https://forums.sufficientvelocity.com/search/*
// @match       https://forums.sufficientvelocity.com/tags/*
// @match       https://forum.questionablequesting.com/forums/*
// @match       https://forum.questionablequesting.com/search/*
// @match       https://forum.questionablequesting.com/tags/*
// @match       https://www.alternatehistory.com/forum/forums/*
// @match       https://www.alternatehistory.com/forum/search/*
// @match       https://www.alternatehistory.com/forum/tags/*
// @namespace   https://greasyfork.org/users/1376767
// ==/UserScript==

// note: https://forums.spacebattles.com/account/*
//       https://forums.spacebattles.com/search/*
//  \ cannot be implemented because there's no wordcount to detect if /reader/ is valid or not.

const IS_AH = (window.location.hostname === 'www.alternatehistory.com');

let regex;
if (IS_AH) { regex = /^(https:\/\/[^\/]+\/forum\/threads\/[^\/]+\/)/; }
else       { regex = /^(https:\/\/[^\/]+\/threads\/[^\/]+\/)/; }

const threads = document.querySelectorAll('div.structItem, li.block-row'); // forum, search
for (const thread of threads) {

   // old, view as threads
  var foundCount = false;
  var wordcountOld = thread.querySelector('li>a[data-xf-click="overlay"]')?.textContent?.trim();
  if (wordcountOld && (wordcountOld.startsWith('Words: ') || wordcountOld.startsWith('Word Count: '))) {
    foundCount = true;
  }
  else {
    var wordcountNew = thread.querySelector('dl:has(>dd>a[data-xf-click="overlay"])')?.textContent?.trim();
    if (wordcountNew && wordcountNew.startsWith('Word')) {
      foundCount = true;
    }
    else {
      var wordcountSearch = thread.querySelector('li>a.wordcount');
      if (wordcountSearch) {
        foundCount = true;
      }
    }
  }

  if (foundCount) {
    const title = thread.querySelector('div.structItem-title > a:not(.unreadLink), h3.contentRow-title > a');
    const match = title.href.match(regex);
    if (match) {
      title.href = match[1] + 'reader/';
    }
  }
}