Kiwi Farms Hightlighted Post Keyboard Shortcuts

Allows you to move between highlighted posts with the A and D keys.

As of 2025-07-27. See the latest version.

// ==UserScript==
// @name         Kiwi Farms Hightlighted Post Keyboard Shortcuts
// @namespace    http://kiwifarms.st
// @version      2025-07-27
// @description  Allows you to move between highlighted posts with the A and D keys.
// @author       Enzo
// @match        https://kiwifarms.st/threads/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kiwifarms.st
// @grant        none
// @license      CC0
// ==/UserScript==

let SelectedPost;
function FindPost(ID) {
    return document.querySelector(`article[data-content="${ID}"]`);
}

function GetPostFromHash() {
    let Hash = window.location.hash;
    if (!Hash) {
        return;
    }

    const ID = Hash.substring(1);
    return FindPost(ID);
}

function ClickHightlightAnchor(Anchor)
{
    let NewPost;
    let Href = Anchor.getAttribute('href');
    if (Href) {
        if (Href.startsWith('#')) {
            // If just a hash, make it the selected post.
            const ID = Href.substring(1);
            NewPost = FindPost(ID);
            //window.location.hash = Href; // Update page hash as well.
        } else {
            //window.location = Anchor.href;
        }
        Anchor.click();
    }

    return NewPost;
}

function ClickPostHighlight(PostElement, Direction) {
    let QueryString = 'a.hb-react-highlight';
    if (Direction < 0) { QueryString += 'Prev'; }
    else if (Direction > 0) { QueryString += 'Next'; }
    else { return; }

    const Anchor = PostElement.querySelector(QueryString);
    if (!Anchor) {
        console.error(`Unable to locate ${Direction < 0 ? "previous": "next"} highlight anchor.`, PostElement);
        return;
    }

    return ClickHightlightAnchor(Anchor);
}

function DoMove(Dir) {
    if (SelectedPost) {
        const NewPost = ClickPostHighlight(SelectedPost, Dir);
        if (NewPost) {
            console.log('New Selected Post from existing;', SelectedPost, '->', NewPost);
            SelectedPost = NewPost;
            return;
        }
    }

    // No current selected post. Fall back to the core highlight buttons.
    const BlockOuter = document.querySelector('div.block-outer-opposite');
    let ClassName = 'i.fa-award';
    if (Dir < 0) {
        ClassName = 'i.fa-backward';
    }
    const IEle = BlockOuter.querySelector(ClassName);
    if (!IEle) {
        console.error(`Unable to locate global ${Dir < 0 ? "previous" : "next"} highlight class;`, ClassName);
        return;
    }

    const ParentAnchor = IEle.closest('a');
    if (!ParentAnchor) {
        console.error(`Unable to locate global ${Dir < 0 ? "previous" : "next"} highlight anchor. Reached;`, ParentAnchor);
        return;
    }

    const NewPost = ClickHightlightAnchor(ParentAnchor);
    if (NewPost) {
        console.log('New Selected Post from global highlight buttons;', NewPost);
        SelectedPost = NewPost;
    }
}

function DoKeyDown(e) {
    let Dir = 0;
    switch (e.code) {
        case 'KeyA'://Back
            Dir = -1;
            break;
        case 'KeyD'://Forward
            Dir = 1;
            break;
        default:
            return;
    }

    DoMove(Dir);
}

(function() {
    'use strict';
    SelectedPost = GetPostFromHash();
    console.log('OnLoad Selected Post', SelectedPost);

    document.addEventListener('keydown', DoKeyDown, false);
})();