Gelbooru Endless Scroll

Adds endless scroll function to Gelbooru

04.05.2017 itibariyledir. En son verisyonu görün.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu betiği yüklemek için bir betik yöneticisi eklentisi yüklemeniz gerekecektir.

(Zaten bir betik yöneticim var, hadi yükleyelim!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @id             gelbooru-endless-scroll
// @name           Gelbooru Endless Scroll
// @version        1.6.2
// @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.target.parentNode.style.overflow = "";
    }, 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();
}());