Gelbooru Endless Scroll

Adds endless scroll function to Gelbooru

Od 09.05.2017.. Pogledajte najnovija verzija.

// ==UserScript==
// @id             gelbooru-endless-scroll
// @name           Gelbooru Endless Scroll
// @version        1.6.3
// @namespace      intermission
// @author         intermission
// @license        WTFPL; http://www.wtfpl.net/about/
// @description    Adds endless scroll function to Gelbooru
// @include        http://gelbooru.com/index.php?*
// @include        https://gelbooru.com/index.php?*
// @include        http://rule34.xxx/index.php?*
// @include        https://rule34.xxx/index.php?*
// @include        http://*.booru.org/index.php?*
// @include        https://*.booru.org/index.php?*
// @include        http://e621.net/post/index/*
// @include        https://e621.net/post/index/*
// @include        http://rule34.paheal.net/post/list/*
// @include        https://rule34.paheal.net/post/list/*
// @run-at         document-end
// @grant          none
// ==/UserScript==

/* This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://www.wtfpl.net/ for more details. */

(function(){
  "use strict";
  var d = document, _on = false, url,
  v = ".thumb",
  vis = function() {
    var rect = target().getBoundingClientRect();
    return rect.x === 0 && rect.y === 0 ? false : (
      rect.top + rect.height >= 0 &&
      ( document.documentElement.clientHeight - rect.bottom ) + rect.height >= 0
    );
  }, total,
  page = function(doc) {
    var images, pageNo = d.createElement("paheal.net" == host ? "div" : "span"), frag = d.createDocumentFragment(), container,
    fn = (e) => {
      e.target.onload = null;
      (e = e.target.parentNode.parentNode).style.overflow = "";
      if (!e.getAttribute("style")) e.removeAttribute("style");
    }, base = a => a.match(r2);
    images = [...doc.querySelectorAll(v)];
    if (images.length === 0)
      throw Error("API error");
    pageNo.innerHTML = '<span style="height:' + ("paheal.net" == host ? "180px" : "inherit") + ';display:flex;flex-direction:column;">Page ' + url.index + '~<span style="margin:auto 0 30px">out of ' + total + "</span></span>";
    pageNo.className = "thumb";
    if ("paheal.net" == host)
      pageNo.setAttribute("style", "transform: translateY(-180px); margin-bottom: -180px");
    frag.appendChild(pageNo);
    for (let a of images) {
      let img = a.querySelector("img");
      if (d.querySelector("img[src*='" + base(img.src) + "']")) continue;
      a.style.overflow = "hidden";
      img.onload = fn;
      frag.appendChild(a);
    };
    container = d.querySelector(v).parentNode;
    if (container.lastElementChild.matches("span")) container.appendChild(frag);
    else container.insertBefore(frag, container.querySelector(".thumb:last-of-type + *"));
    if (paginator.go) paginator();
    if (list.length > 0) {
      events();
      process();
    } return;
  }, req = _ => fetch(url.href).then(
    x => x.text().then(
      text => page((new DOMParser()).parseFromString(text, "text/html"))
    )
  ).catch(err => {
    if (typeof err != "undefined") {
      console.error("Something unexpected happened\n", err);
      setTimeout(() => req(), 5000);
    }
  }), process = function() {
    if (vis()) {
      events();
      url = list.shift();
      return req();
    }
  }, events = function() {
    var name = (_on = !_on) ? "addEventListener" : "removeEventListener";
    window[name]("scroll", process);
    window[name]("resize", process);
    window[name]("visibilitychange", process);
  }, list = [], r = /(pid=|index\/)([0-9]+)|(list\/(?:[^\/]+\/)?)([0-9]+)$/, r2 = /[a-f0-9]{32}/, paginator = function() {
    var el = target(), rect1 = d.querySelector(".thumb:last-of-type"),
      el2 = d.querySelector(".sidebar"), rect2;
    if (el.classList.contains("pagination")) el = el.parentNode;
    rect1 = rect1.offsetTop + rect1.offsetHeight;
    rect2 = el2.offsetTop + el2.offsetHeight - 9;
    if (rect2 >= rect1) {
      el.style.position = "absolute";
      el.style.top = rect1 + "px";
      el.style.left = "calc(50vw + " + (el2.getBoundingClientRect().width / 2) + "px)";
      el.style.transform = "translateX(-50%)";
    } else {
      el.style.position = "";
      el.style.top = "";
      el.style.left = "";
      el.style.transform = "";
      paginator.go = false;
    }
  }, host = location.hostname.match(/[^\.]+\.[^\.]+$/)[0];
  const target = () => (d.querySelector("div.pagination") || d.querySelector("div#paginator") || d.querySelector("section#paginator"));
  if (target() && /\/post\/|page=post/.test(location.href)) {
    let pid = location.href.match(r),
    p = ((pid && pid[1] == "index/") ? target().lastElementChild.previousElementSibling : target().lastElementChild).href,
    n = d.querySelectorAll(v).length,
    start_index, end_index, increment, index = 1;
    if (host == "paheal.net") {
      let ayy = target().children[0].children;
      p = ayy[[...ayy].indexOf([...ayy].find(el => !!~el.textContent.indexOf("Random"))) + 2].href;
    }
    if (!p) return;
    switch(host) {
    case "gelbooru.com": case "rule34.xxx":
      start_index = pid ? pid[2] / n : 0;
      increment = n;
      end_index = p.match(r)[2] / n;
      paginator.go = true;
      break;
    case "booru.org":
      start_index = pid ? pid[2] / n : 0;
      increment = n;
      end_index = p.match(r)[2] / n;
      break;
    case "e621.net":
      start_index = pid ? +pid[2] : 2;
      increment = 1;
      index = 0;
      end_index = +p.match(r)[2];
      break;
    case "paheal.net":
      start_index = pid ? +pid[4] : 1;
      increment = 1;
      index = 0;
      end_index = +p.match(r)[4];
      break;
    }
    while(start_index < end_index)
      list.push({
        href: p.replace(r, (host == "paheal.net" ? "$3" : "$1") + (++start_index * increment)),
        index: start_index + index
      });
    total = end_index + index;
  }
  if (paginator.go) paginator();
  d.addEventListener("gelbooru-slide", _ => {
    if (list.length > 0)
      events();
  }, false);
  d.addEventListener("gelbooru-slide-next", _ => {
    if (list.length > 0)
      events();
  }, false);
  events();
  if (vis()) process();
}());