Makes so that the gallery continues loading the next page when you reach its bottom
当前为
// ==UserScript==
// @name Infini-Gallery
// @namespace Violentmonkey Scripts
// @match *://*.furaffinity.net/*
// @grant none
// @version 1.3
// @author Midori Dragon
// @description Makes so that the gallery continues loading the next page when you reach its bottom
// @icon https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png?v2
// @homepageURL https://greasyfork.org/de/scripts/462632-infini-gallery
// @supportURL https://greasyfork.org/de/scripts/462632-infini-gallery/feedback
// @license MIT
// ==/UserScript==
// jshint esversion: 8
//User Options:
let showPageSeperator = JSON.parse(localStorage.getItem("igsetting_01"));
if (showPageSeperator == null)
showPageSeperator = true;
let showDisableButton = JSON.parse(localStorage.getItem("igsetting_02"));
if (showDisableButton == null)
showDisableButton = true;
const matchList = ['net/browse', 'net/gallery', 'net/search', 'net/favorites' ];
const isSettings = window.location.toString().includes('controls/settings');
let exSettings = JSON.parse(localStorage.getItem("igsettings"));
if (exSettings == null)
exSettings = false;
addExSettings();
if (isSettings) {
addExSettingsSidebar();
if (exSettings)
createSettings();
}
if (window.parent !== window)
return;
if (!matchList.some(x => window.location.toString().includes(x)))
return;
console.info('%cRunning: Infini-Gallery', 'color: blue');
const isGallery = window.location.toString().includes('net/gallery');
const isFavorites = window.location.toString().includes('net/favorites');
const isBrowse = window.location.toString().includes('net/browse');
let allowScan = true;
let nextButtons;
let lastNextButton;
let gallery;
let lastLink;
let lastNextPageButton;
let pageCount;
if (!isSettings) {
if (isGallery)
nextButtons = document.querySelectorAll('button[class*="button standard"][type="submit"]');
else if (isFavorites)
nextButtons = document.querySelectorAll('a[class*="button mobile-button right"][href]');
else if (isBrowse)
nextButtons = document.querySelectorAll('a[class*="button standard"][href]');
if (!nextButtons || nextButtons.length == 0)
return;
if (showDisableButton) {
let navPage = document.querySelector('userpage-nav-links').querySelector('ul');
let disableIGButton = document.createElement('button');
disableIGButton.id = "disableIGButton";
disableIGButton.type = "button";
disableIGButton.className = "button standard mobile-fix";
disableIGButton.textContent = "Disable Infini Gallery";
disableIGButton.style.marginTop = "8px";
disableIGButton.style.marginRight = "18px";
disableIGButton.onclick = function() {
allowScan = !allowScan;
if (allowScan) {
disableIGButton.textContent = "Disable Infini Gallery";
scan();
} else
disableIGButton.textContent = "Enable Infini Gallery";
};
navPage.appendChild(disableIGButton);
}
lastNextButton = nextButtons[nextButtons.length - 1];
gallery = document.querySelector('section[id*="gallery"]');
lastLink = window.location.toString();
lastNextPageButton = lastNextButton;
pageCount = 1;
scan();
}
async function scan() {
const interval = setInterval(() => {
if (!allowScan)
clearInterval(interval);
if (isElementOnScreen(lastNextButton)) {
clearInterval(interval);
loadNextPage();
}
}, 100);
}
async function loadNextPage() {
let figures;
if (isGallery)
figures = await getNextPageFiguresGallery();
else if (isFavorites)
figures = await getNextPageFiguresFavorites();
else if (isBrowse)
figures = await getNextPageFiguresGallery();
if (!figures || figures.length == 0) {
lastNextButton.parentNode.removeChild(lastNextButton);
return;
}
pageCount++;
let nextPageDescContainer = document.createElement('div');
nextPageDescContainer.className = 'folder-description';
nextPageDescContainer.style.marginTop = '6px';
nextPageDescContainer.style.marginBottom = '6px';
let nextPageDesc = document.createElement('div');
nextPageDesc.className = 'container-item-top';
let nextPageDescText = document.createElement('h3');
nextPageDescText.textContent = 'Page: ' + pageCount;
nextPageDesc.appendChild(nextPageDescText);
nextPageDescContainer.appendChild(nextPageDesc);
gallery.appendChild(nextPageDescContainer);
for (const figure of figures)
gallery.appendChild(figure);
try { window.updateEmbedded(); } catch {} //Embedded Image Viewer Integration
try { window.updateFastFavoriter(); } catch {} //Fast Favoriter 2 Integration
await scan();
}
async function getNextPageFiguresGallery() {
const nextLink = await incrementUrlLastNumber(lastLink);
console.log(nextLink);
lastLink = nextLink;
const nextPage = await getHTML(nextLink);
const figures = nextPage.querySelectorAll('figure[class*="t"]');
return figures;
}
async function getNextPageFiguresFavorites() {
const nextLink = lastNextPageButton.href;
console.log(nextLink);
lastLink = nextLink;
const nextPage = await getHTML(nextLink);
let currNextPageButton = nextPage.querySelectorAll('a[class="button mobile-button right"][href]');
lastNextPageButton = currNextPageButton[currNextPageButton.length - 1];
const figures = nextPage.querySelectorAll('figure[class*="t"]');
return figures;
}
async function incrementUrlLastNumber(url) {
if (url.endsWith('/?'))
url = url.slice(0, -1);
if (url.endsWith('/'))
url = url.slice(0, -1);
var segments = url.split('/');
var lastSegment = segments[segments.length - 1];
var match = lastSegment.match(/^\d+/);
if (match) {
var nextNumber = parseInt(match[0]) + 1;
return url.replace(/\d+$/, nextNumber);
} else
return url + '/2';
}
function isElementOnScreen(element) {
var rect = element.getBoundingClientRect();
var windowHeight = (window.innerHeight || document.documentElement.clientHeight) * 2;
return (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
}
async function getHTML(url) {
try {
const response = await fetch(url);
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
return doc;
} catch (error) {
console.error(error);
}
}
async function addExSettings() {
const settings = document.querySelector('ul[class="navhideonmobile"]').querySelector('a[href="/controls/settings/"]').parentNode;
if (document.getElementById("extension_settings")) {
document.getElementById('midori_settings').addEventListener('click', function() { localStorage.setItem("igsettings", true.toString()); });
return;
}
let exSettingsHeader = document.createElement("h3");
exSettingsHeader.id = "extension_settings";
exSettingsHeader.textContent = "Extension Settings";
settings.appendChild(exSettingsHeader);
let wfsettings = document.createElement("a");
wfsettings.id = "midori_settings";
wfsettings.textContent = "Midori's Script Settings";
wfsettings.style.cursor = "pointer";
wfsettings.onclick = function() {
localStorage.setItem("igsettings", true.toString());
window.location = "https://www.furaffinity.net/controls/settings";
}
settings.appendChild(wfsettings);
}
async function addExSettingsSidebar() {
const settings = document.getElementById('controlpanelnav');
if (document.getElementById("extension_settings_side")) {
document.getElementById('midori_settings_side').addEventListener('click', function() { localStorage.setItem("igsettings", true.toString()); });
return;
}
let exSettingsHeader = document.createElement("h3");
exSettingsHeader.id = "extension_settings_side";
exSettingsHeader.textContent = "Extension Settings";
settings.appendChild(exSettingsHeader);
let wfsettings = document.createElement("a");
wfsettings.id = "midori_settings_side";
wfsettings.textContent = "Midori's Script Settings";
wfsettings.style.cursor = "pointer";
wfsettings.onclick = function() {
localStorage.setItem("igsettings", true.toString());
window.location = "https://www.furaffinity.net/controls/settings";
}
settings.appendChild(wfsettings);
}
async function createSettings() {
localStorage.setItem("igsettings", false.toString());
const columnPage = document.getElementById("columnpage");
let content = columnPage.querySelector('div[class="content"]');
for (const section of content.querySelectorAll('section:not([class="exsettings"])'))
section.parentNode.removeChild(section);
let section = document.createElement("section");
section.className = 'exsettings';
let headerContainer = document.createElement("div");
headerContainer.className = "section-header";
let header = document.createElement("h2");
header.textContent = "Infini Gallery Settings";
headerContainer.appendChild(header);
section.appendChild(headerContainer);
let bodyContainer = document.createElement("div");
bodyContainer.className = "section-body";
let Item1 = document.createElement("div");
Item1.className = "control-panel-item-container";
let Item1Name = document.createElement("div");
Item1Name.className = "control-panel-item-name";
let Item1NameText = document.createElement("h4");
Item1NameText.textContent = "Page Seperator";
Item1Name.appendChild(Item1NameText);
Item1.appendChild(Item1Name);
let Item1Desc = document.createElement("div");
Item1Desc.className = "control-panel-item-description";
let Item1DescText = document.createTextNode('Sets wether a Page Seperator is shown foreach new Page loaded.');
Item1Desc.appendChild(Item1DescText);
Item1.appendChild(Item1Desc);
let Item1Option = document.createElement("div");
Item1Option.className = "control-panel-item-options";
let Item1OptionContainer = document.createElement("div");
let Item1OptionElem1 = document.createElement("input");
Item1OptionElem1.id = 'igsettings_01';
Item1OptionElem1.type = "checkbox";
Item1OptionElem1.style.cursor = 'pointer';
Item1OptionElem1.style.marginRight = '4px';
Item1OptionElem1.addEventListener('change', function() {
showPageSeperator = Item1OptionElem1.checked;
localStorage.setItem("igsetting_01", showPageSeperator.toString());
});
Item1OptionContainer.appendChild(Item1OptionElem1);
let Item1OptionElem2 = document.createTextNode('Show Page Seperators');
Item1OptionContainer.appendChild(Item1OptionElem2);
Item1Option.appendChild(Item1OptionContainer);
Item1.appendChild(Item1Option);
bodyContainer.appendChild(Item1);
let Item2 = document.createElement("div");
Item2.className = "control-panel-item-container";
let Item2Name = document.createElement("div");
Item2Name.className = "control-panel-item-name";
let Item2NameText = document.createElement("h4");
Item2NameText.textContent = "Disable Button";
Item2Name.appendChild(Item2NameText);
Item2.appendChild(Item2Name);
let Item2Desc = document.createElement("div");
Item2Desc.className = "control-panel-item-description";
let Item2DescText = document.createTextNode("Sets wether the disable Infini Gallery button is shown in each Gallery");
Item2Desc.appendChild(Item2DescText);
Item2.appendChild(Item2Desc);
let Item2Option = document.createElement("div");
Item2Option.className = "control-panel-item-options";
let Item2OptionContainer = document.createElement("div");
let Item2OptionElem1 = document.createElement("input");
Item2OptionElem1.id = 'igsettings_02';
Item2OptionElem1.type = "checkbox";
Item2OptionElem1.style.cursor = 'pointer';
Item2OptionElem1.style.marginRight = '4px';
Item2OptionElem1.addEventListener('change', function() {
showDisableButton = Item2OptionElem1.checked;
localStorage.setItem("igsetting_02", showDisableButton.toString());
});
Item2OptionContainer.appendChild(Item2OptionElem1);
let Item2OptionElem2 = document.createTextNode('Show disable Infini Gallery button');
Item2OptionContainer.appendChild(Item2OptionElem2);
Item2Option.appendChild(Item2OptionContainer);
Item2.appendChild(Item2Option);
bodyContainer.appendChild(Item2);
section.appendChild(bodyContainer);
content.appendChild(section);
fillSettings();
}
async function fillSettings() {
let setting1 = document.getElementById('igsettings_01');
setting1.checked = showPageSeperator;
let setting2 = document.getElementById('igsettings_02');
setting2.checked = showDisableButton;
}