Hacker News Infinite Scroll

Adds infinite scroll to HackerNews

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @description Adds infinite scroll to HackerNews
// @name Hacker News Infinite Scroll
// @namespace Violentmonkey Scripts
// @match https://news.ycombinator.com/
// @version 1.1.0
// @grant none
// ==/UserScript==

const regex = new RegExp(/<center>.*(<table id="hnmain".*)<\/center>/gms);
let moreLinkAnchor = document.querySelector('td.title > a.morelink');
let count = 2;

function getHTML(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', url, true);
        xhr.responseType = 'document';
        xhr.onload = function () {
            var status = xhr.status;
            if (status == 200) {
                resolve(xhr.response.documentElement.innerHTML);
            } else {
                reject(status);
            }
        };
        xhr.send();
    });
}

let tableName = (document.querySelector('table.itemlist') === null) ? "comment-tree" : "itemlist"

const insertAfter = (el, referenceNode) => {
    referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}

const isMoreLink = elm => {
  return [...elm.getElementsByTagName("*")].map(e => e.className).includes('morelink');
}

const parseNextPage = (nextPage, tableType, moreTr) => {
    const page = new DOMParser().parseFromString(nextPage, 'text/html');
    let queryStr = (tableType === 'comment-tree') ? `table.${tableType} tr.athing` : `table.${table.class} tr`
    let newTrs = [...page.querySelectorAll(queryStr)];
    if (tableType === 'comment-tree' && newTrs.length < 259) {
        noMoreLeft = true;
        moreTr.nextElementSibling.style.display = "none";
    }
    let filteredTrs = (tableType === 'itemlist') ? newTrs.filter(e => !isMoreLink(e)) : newTrs
    filteredTrs.forEach(tr => {
        if (tr.className !== "morespace") {
            moreTr.parentNode.insertBefore(tr, moreTr)
        }
    });
}

let noMoreLeft = false;
window.onscroll = async function() {
    if (((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) && (noMoreLeft !== true)) {
        console.log('bottom of page reached');
        let testResponse;
        let parsed;
        if (moreLinkAnchor !== null) {
            //let table;
            let moreLink = /^(.*?p=)/.exec(moreLinkAnchor['href'])[0];
            let nextPage = `${moreLink}${count}`;
            table = document.querySelector('table.itemlist') === null ? {
                class: "comment-tree",
                element: document.querySelector('table.comment-tree')
            } : {
                class: "itemlist",
                element: document.querySelector('table.itemlist')
            };
            let tableRowMore = table.element.querySelector('.morespace');
            let pageRes = await getHTML(nextPage);
            parseNextPage(pageRes, table.class, tableRowMore)
            count++;
        }
    }
};