FA Infini-Gallery

Automatically loads the next page of the gallery as you reach the bottom

当前为 2025-02-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name FA Infini-Gallery
  3. // @namespace Violentmonkey Scripts
  4. // @match *://*.furaffinity.net/*
  5. // @require https://update.greasyfork.org/scripts/525666/1530872/Furaffinity-Prototype-Extensions.js
  6. // @require https://update.greasyfork.org/scripts/483952/1530883/Furaffinity-Request-Helper.js
  7. // @require https://update.greasyfork.org/scripts/485827/1530881/Furaffinity-Match-List.js
  8. // @require https://update.greasyfork.org/scripts/485153/1530882/Furaffinity-Loading-Animations.js
  9. // @require https://update.greasyfork.org/scripts/475041/1530885/Furaffinity-Custom-Settings.js
  10. // @grant GM_info
  11. // @version 2.1.0
  12. // @author Midori Dragon
  13. // @description Automatically loads the next page of the gallery as you reach the bottom
  14. // @icon https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png
  15. // @license MIT
  16. // ==/UserScript==
  17. // jshint esversion: 8
  18. (() => {
  19. "use strict";
  20. var LogLevel, __webpack_require__ = {
  21. d: (exports, definition) => {
  22. for (var key in definition) if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
  23. enumerable: true,
  24. get: definition[key]
  25. });
  26. },
  27. o: (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
  28. };
  29. __webpack_require__.d({}, {
  30. I4: () => pageSeparatorTextSetting,
  31. uL: () => requestHelper,
  32. kG: () => showPageSeparatorSetting
  33. });
  34. function createSeparatorElem(pageNo) {
  35. const nextPageDescContainer = document.createElement("div");
  36. nextPageDescContainer.className = "folder-description";
  37. nextPageDescContainer.style.marginTop = "6px";
  38. nextPageDescContainer.style.marginBottom = "6px";
  39. const nextPageDesc = document.createElement("div");
  40. nextPageDesc.className = "container-item-top";
  41. const nextPageDescText = document.createElement("h3"), pageString = pageSeparatorTextSetting.value.replace(/%page%/g, pageNo.toString());
  42. nextPageDescText.textContent = pageString;
  43. nextPageDesc.appendChild(nextPageDescText);
  44. nextPageDescContainer.appendChild(nextPageDesc);
  45. return nextPageDescContainer;
  46. }
  47. function getFiguresFromPage(page) {
  48. const figures = page.querySelectorAll('figure[class*="t"]');
  49. return null == figures ? [] : Array.from(figures).map((figure => figure));
  50. }
  51. function getUserNameFromUrl(url) {
  52. if (url.includes("?")) url = url.substring(0, url.indexOf("?"));
  53. return (url = url.trimEnd("/")).substring(url.lastIndexOf("/") + 1);
  54. }
  55. !function(LogLevel) {
  56. LogLevel[LogLevel.Error = 1] = "Error";
  57. LogLevel[LogLevel.Warning = 2] = "Warning";
  58. LogLevel[LogLevel.Info = 3] = "Info";
  59. }(LogLevel || (LogLevel = {}));
  60. class Logger {
  61. static log(logLevel = LogLevel.Warning, ...args) {
  62. if (null == window.__FF_GLOBAL_LOG_LEVEL__) window.__FF_GLOBAL_LOG_LEVEL__ = LogLevel.Error;
  63. if (!(logLevel > window.__FF_GLOBAL_LOG_LEVEL__)) switch (logLevel) {
  64. case LogLevel.Error:
  65. console.error(...args);
  66. break;
  67.  
  68. case LogLevel.Warning:
  69. console.warn(...args);
  70. break;
  71.  
  72. case LogLevel.Info:
  73. console.log(...args);
  74. }
  75. }
  76. static setLogLevel(logLevel) {
  77. window.__FF_GLOBAL_LOG_LEVEL__ = logLevel;
  78. }
  79. static logError(...args) {
  80. Logger.log(LogLevel.Error, ...args);
  81. }
  82. static logWarning(...args) {
  83. Logger.log(LogLevel.Warning, ...args);
  84. }
  85. static logInfo(...args) {
  86. Logger.log(LogLevel.Info, ...args);
  87. }
  88. }
  89. var __awaiter = function(thisArg, _arguments, P, generator) {
  90. return new (P || (P = Promise))((function(resolve, reject) {
  91. function fulfilled(value) {
  92. try {
  93. step(generator.next(value));
  94. } catch (e) {
  95. reject(e);
  96. }
  97. }
  98. function rejected(value) {
  99. try {
  100. step(generator.throw(value));
  101. } catch (e) {
  102. reject(e);
  103. }
  104. }
  105. function step(result) {
  106. result.done ? resolve(result.value) : function adopt(value) {
  107. return value instanceof P ? value : new P((function(resolve) {
  108. resolve(value);
  109. }));
  110. }(result.value).then(fulfilled, rejected);
  111. }
  112. step((generator = generator.apply(thisArg, _arguments || [])).next());
  113. }));
  114. };
  115. class BrowsePage {
  116. constructor(pageNo) {
  117. this.pageNo = pageNo;
  118. this.gallery = document.querySelector('section[id*="gallery"]');
  119. }
  120. getPage() {
  121. return __awaiter(this, void 0, void 0, (function*() {
  122. Logger.logInfo(`Getting page BrowsePage '${this.pageNo}'`);
  123. return yield requestHelper.UserRequests.SearchRequests.Browse.getPage(this.pageNo, this.getBrowseOptions());
  124. }));
  125. }
  126. getBrowseOptions() {
  127. var _a, _b, _c, _d;
  128. const currBrowseOptions = requestHelper.UserRequests.SearchRequests.Browse.newBrowseOptions, sideBar = document.getElementById("sidebar-options"), optionContainers = null == sideBar ? void 0 : sideBar.querySelectorAll('div[class*="browse-search-flex-item"]');
  129. for (const optionContainer of Array.from(null != optionContainers ? optionContainers : [])) try {
  130. let optionName = null !== (_c = null === (_b = null === (_a = null == optionContainer ? void 0 : optionContainer.querySelector("strong")) || void 0 === _a ? void 0 : _a.textContent) || void 0 === _b ? void 0 : _b.toLowerCase()) && void 0 !== _c ? _c : "";
  131. optionName = optionName.trimEnd(":");
  132. const optionValue = null === (_d = null == optionContainer ? void 0 : optionContainer.querySelector("option[selected]")) || void 0 === _d ? void 0 : _d.getAttribute("value");
  133. if (null != optionValue) switch (optionName) {
  134. case "category":
  135. currBrowseOptions.category = parseInt(optionValue);
  136. break;
  137.  
  138. case "type":
  139. currBrowseOptions.type = parseInt(optionValue);
  140. break;
  141.  
  142. case "species":
  143. currBrowseOptions.species = parseInt(optionValue);
  144. break;
  145.  
  146. case "gender":
  147. currBrowseOptions.gender = parseInt(optionValue);
  148. break;
  149.  
  150. case "results":
  151. currBrowseOptions.results = parseInt(optionValue);
  152. break;
  153.  
  154. case "ratingGeneral":
  155. currBrowseOptions.ratingGeneral = "true" === optionValue;
  156. break;
  157.  
  158. case "ratingMature":
  159. currBrowseOptions.ratingMature = "true" === optionValue;
  160. break;
  161.  
  162. case "ratingAdult":
  163. currBrowseOptions.ratingAdult = "true" === optionValue;
  164. }
  165. } catch (_e) {}
  166. const checkBoxes = null == sideBar ? void 0 : sideBar.querySelectorAll('input[type="checkbox"]');
  167. for (const checkbox of Array.from(null != checkBoxes ? checkBoxes : [])) switch (checkbox.getAttribute("name")) {
  168. case "rating_general":
  169. currBrowseOptions.ratingGeneral = checkbox.hasAttribute("checked");
  170. break;
  171.  
  172. case "rating_mature":
  173. currBrowseOptions.ratingMature = checkbox.hasAttribute("checked");
  174. break;
  175.  
  176. case "rating_adult":
  177. currBrowseOptions.ratingAdult = checkbox.hasAttribute("checked");
  178. }
  179. return currBrowseOptions;
  180. }
  181. loadPage(prevFigures) {
  182. return __awaiter(this, void 0, void 0, (function*() {
  183. const page = yield this.getPage();
  184. if (null == page) throw new Error("No page found");
  185. null != prevFigures || (prevFigures = []);
  186. const prevSids = prevFigures.map((figure => figure.id));
  187. let figures = getFiguresFromPage(page);
  188. figures = figures.filter((figure => !prevSids.includes(figure.id)));
  189. if (0 !== figures.length) {
  190. if (showPageSeparatorSetting.value) {
  191. const separator = createSeparatorElem(this.pageNo);
  192. this.gallery.appendChild(separator);
  193. }
  194. for (const figure of figures) this.gallery.appendChild(figure);
  195. } else throw new Error("No figures found");
  196. window.dispatchEvent(new CustomEvent("ei-update-embedded"));
  197. return figures;
  198. }));
  199. }
  200. }
  201. var FavoritesPage_awaiter = function(thisArg, _arguments, P, generator) {
  202. return new (P || (P = Promise))((function(resolve, reject) {
  203. function fulfilled(value) {
  204. try {
  205. step(generator.next(value));
  206. } catch (e) {
  207. reject(e);
  208. }
  209. }
  210. function rejected(value) {
  211. try {
  212. step(generator.throw(value));
  213. } catch (e) {
  214. reject(e);
  215. }
  216. }
  217. function step(result) {
  218. result.done ? resolve(result.value) : function adopt(value) {
  219. return value instanceof P ? value : new P((function(resolve) {
  220. resolve(value);
  221. }));
  222. }(result.value).then(fulfilled, rejected);
  223. }
  224. step((generator = generator.apply(thisArg, _arguments || [])).next());
  225. }));
  226. };
  227. class FavoritesPage {
  228. constructor(dataFavId, pageNo) {
  229. this.dataFavId = dataFavId;
  230. this.pageNo = pageNo;
  231. this.gallery = document.querySelector('section[id*="gallery"]');
  232. }
  233. getPage() {
  234. return FavoritesPage_awaiter(this, void 0, void 0, (function*() {
  235. Logger.logInfo(`Getting page FavoritesPage '${this.pageNo}'`);
  236. const username = getUserNameFromUrl(window.location.toString());
  237. return yield requestHelper.UserRequests.GalleryRequests.Favorites.getPage(username, this.dataFavId);
  238. }));
  239. }
  240. loadPage(prevFigures) {
  241. return FavoritesPage_awaiter(this, void 0, void 0, (function*() {
  242. const page = yield this.getPage();
  243. if (null == page) throw new Error("No page found");
  244. null != prevFigures || (prevFigures = []);
  245. const prevSids = prevFigures.map((figure => figure.id));
  246. let figures = getFiguresFromPage(page);
  247. figures = figures.filter((figure => !prevSids.includes(figure.id)));
  248. if (0 !== figures.length) {
  249. if (this.dataFavId === figures[figures.length - 1].getAttribute("data-fav-id")) throw new Error("Last page reached");
  250. if (showPageSeparatorSetting.value) {
  251. const separator = createSeparatorElem(this.pageNo);
  252. this.gallery.appendChild(separator);
  253. }
  254. for (const figure of figures) this.gallery.appendChild(figure);
  255. } else throw new Error("No figures found");
  256. window.dispatchEvent(new CustomEvent("ei-update-embedded"));
  257. return figures;
  258. }));
  259. }
  260. }
  261. var GalleryPage_awaiter = function(thisArg, _arguments, P, generator) {
  262. return new (P || (P = Promise))((function(resolve, reject) {
  263. function fulfilled(value) {
  264. try {
  265. step(generator.next(value));
  266. } catch (e) {
  267. reject(e);
  268. }
  269. }
  270. function rejected(value) {
  271. try {
  272. step(generator.throw(value));
  273. } catch (e) {
  274. reject(e);
  275. }
  276. }
  277. function step(result) {
  278. result.done ? resolve(result.value) : function adopt(value) {
  279. return value instanceof P ? value : new P((function(resolve) {
  280. resolve(value);
  281. }));
  282. }(result.value).then(fulfilled, rejected);
  283. }
  284. step((generator = generator.apply(thisArg, _arguments || [])).next());
  285. }));
  286. };
  287. class GalleryPage {
  288. constructor(pageNo) {
  289. this.pageNo = pageNo;
  290. this.gallery = document.querySelector('section[id*="gallery"]');
  291. this.isInFolder = window.location.toString().includes("/folder/");
  292. }
  293. getPage() {
  294. return GalleryPage_awaiter(this, void 0, void 0, (function*() {
  295. Logger.logInfo(`Getting page GalleryPage '${this.pageNo}'`);
  296. const username = getUserNameFromUrl(window.location.toString());
  297. let page;
  298. if (true === this.isInFolder) {
  299. let folderId;
  300. page = yield requestHelper.UserRequests.GalleryRequests.Gallery.getPageInFolder(username, folderId, this.pageNo);
  301. } else page = yield requestHelper.UserRequests.GalleryRequests.Gallery.getPage(username, this.pageNo);
  302. return page;
  303. }));
  304. }
  305. loadPage(prevFigures) {
  306. return GalleryPage_awaiter(this, void 0, void 0, (function*() {
  307. const page = yield this.getPage();
  308. if (null == page) throw new Error("No page found");
  309. null != prevFigures || (prevFigures = []);
  310. const prevSids = prevFigures.map((figure => figure.id));
  311. let figures = getFiguresFromPage(page);
  312. figures = figures.filter((figure => !prevSids.includes(figure.id)));
  313. if (0 !== figures.length) {
  314. if (showPageSeparatorSetting.value) {
  315. const separator = createSeparatorElem(this.pageNo);
  316. this.gallery.appendChild(separator);
  317. }
  318. for (const figure of figures) this.gallery.appendChild(figure);
  319. } else throw new Error("No figures found");
  320. window.dispatchEvent(new CustomEvent("ei-update-embedded"));
  321. return figures;
  322. }));
  323. }
  324. }
  325. var ScrapsPage_awaiter = function(thisArg, _arguments, P, generator) {
  326. return new (P || (P = Promise))((function(resolve, reject) {
  327. function fulfilled(value) {
  328. try {
  329. step(generator.next(value));
  330. } catch (e) {
  331. reject(e);
  332. }
  333. }
  334. function rejected(value) {
  335. try {
  336. step(generator.throw(value));
  337. } catch (e) {
  338. reject(e);
  339. }
  340. }
  341. function step(result) {
  342. result.done ? resolve(result.value) : function adopt(value) {
  343. return value instanceof P ? value : new P((function(resolve) {
  344. resolve(value);
  345. }));
  346. }(result.value).then(fulfilled, rejected);
  347. }
  348. step((generator = generator.apply(thisArg, _arguments || [])).next());
  349. }));
  350. };
  351. class ScrapsPage {
  352. constructor(pageNo) {
  353. this.pageNo = pageNo;
  354. this.gallery = document.querySelector('section[id*="gallery"]');
  355. }
  356. getPage() {
  357. return ScrapsPage_awaiter(this, void 0, void 0, (function*() {
  358. Logger.logInfo(`Getting page ScrapsPage '${this.pageNo}'`);
  359. const username = getUserNameFromUrl(window.location.toString());
  360. return yield requestHelper.UserRequests.GalleryRequests.Scraps.getPage(username, this.pageNo);
  361. }));
  362. }
  363. loadPage(prevFigures) {
  364. return ScrapsPage_awaiter(this, void 0, void 0, (function*() {
  365. const page = yield this.getPage();
  366. if (null == page) throw new Error("No page found");
  367. null != prevFigures || (prevFigures = []);
  368. const prevSids = prevFigures.map((figure => figure.id));
  369. let figures = getFiguresFromPage(page);
  370. figures = figures.filter((figure => !prevSids.includes(figure.id)));
  371. if (0 !== figures.length) {
  372. if (showPageSeparatorSetting.value) {
  373. const separator = createSeparatorElem(this.pageNo);
  374. this.gallery.appendChild(separator);
  375. }
  376. for (const figure of figures) this.gallery.appendChild(figure);
  377. } else throw new Error("No figures found");
  378. window.dispatchEvent(new CustomEvent("ei-update-embedded"));
  379. return figures;
  380. }));
  381. }
  382. }
  383. var SearchPage_awaiter = function(thisArg, _arguments, P, generator) {
  384. return new (P || (P = Promise))((function(resolve, reject) {
  385. function fulfilled(value) {
  386. try {
  387. step(generator.next(value));
  388. } catch (e) {
  389. reject(e);
  390. }
  391. }
  392. function rejected(value) {
  393. try {
  394. step(generator.throw(value));
  395. } catch (e) {
  396. reject(e);
  397. }
  398. }
  399. function step(result) {
  400. result.done ? resolve(result.value) : function adopt(value) {
  401. return value instanceof P ? value : new P((function(resolve) {
  402. resolve(value);
  403. }));
  404. }(result.value).then(fulfilled, rejected);
  405. }
  406. step((generator = generator.apply(thisArg, _arguments || [])).next());
  407. }));
  408. };
  409. class SearchPage {
  410. constructor(pageNo) {
  411. this.pageNo = pageNo;
  412. this.gallery = document.querySelector('section[id*="gallery"]');
  413. }
  414. getPage() {
  415. return SearchPage_awaiter(this, void 0, void 0, (function*() {
  416. Logger.logInfo(`Getting page SearchPage '${this.pageNo}'`);
  417. return yield requestHelper.UserRequests.SearchRequests.Search.getPage(this.pageNo, this.getSearchOptions());
  418. }));
  419. }
  420. getSearchOptions() {
  421. var _a, _b, _c;
  422. const searchOptions = requestHelper.UserRequests.SearchRequests.Search.newSearchOptions, input = document.getElementById("q");
  423. searchOptions.input = null !== (_a = null == input ? void 0 : input.getAttribute("value")) && void 0 !== _a ? _a : "";
  424. const searchContainer = document.getElementById("search-advanced"), options = null == searchContainer ? void 0 : searchContainer.querySelectorAll("option[selected]");
  425. for (const option of Array.from(null != options ? options : [])) {
  426. const name = option.parentNode.getAttribute("name"), value = option.getAttribute("value");
  427. switch (name) {
  428. case "order-by":
  429. searchOptions.orderBy = null != value ? value : void 0;
  430. break;
  431.  
  432. case "order-direction":
  433. searchOptions.orderDirection = null != value ? value : void 0;
  434. }
  435. }
  436. const radioButtons = null == searchContainer ? void 0 : searchContainer.querySelectorAll('input[type="radio"][checked]');
  437. for (const radioButton of Array.from(null != radioButtons ? radioButtons : [])) {
  438. const name = radioButton.getAttribute("name"), value = radioButton.getAttribute("value");
  439. switch (name) {
  440. case "range":
  441. searchOptions.range = null != value ? value : void 0;
  442. break;
  443.  
  444. case "mode":
  445. searchOptions.matching = null != value ? value : void 0;
  446. }
  447. if ("manual" === value) {
  448. const rangeFrom = null == searchContainer ? void 0 : searchContainer.querySelector('input[type="date"][name="range_from"]');
  449. searchOptions.rangeFrom = null !== (_b = null == rangeFrom ? void 0 : rangeFrom.getAttribute("value")) && void 0 !== _b ? _b : void 0;
  450. const rangeTo = null == searchContainer ? void 0 : searchContainer.querySelector('input[type="date"][name="range_to"]');
  451. searchOptions.rangeTo = null !== (_c = null == rangeTo ? void 0 : rangeTo.getAttribute("value")) && void 0 !== _c ? _c : void 0;
  452. }
  453. }
  454. const checkBoxes = null == searchContainer ? void 0 : searchContainer.querySelectorAll('input[type="checkbox"]');
  455. for (const checkBox of Array.from(null != checkBoxes ? checkBoxes : [])) switch (checkBox.getAttribute("name")) {
  456. case "rating-general":
  457. searchOptions.ratingGeneral = checkBox.hasAttribute("checked");
  458. break;
  459.  
  460. case "rating-mature":
  461. searchOptions.ratingMature = checkBox.hasAttribute("checked");
  462. break;
  463.  
  464. case "rating-adult":
  465. searchOptions.ratingAdult = checkBox.hasAttribute("checked");
  466. break;
  467.  
  468. case "type-art":
  469. searchOptions.typeArt = checkBox.hasAttribute("checked");
  470. break;
  471.  
  472. case "type-music":
  473. searchOptions.typeMusic = checkBox.hasAttribute("checked");
  474. break;
  475.  
  476. case "type-flash":
  477. searchOptions.typeFlash = checkBox.hasAttribute("checked");
  478. break;
  479.  
  480. case "type-story":
  481. searchOptions.typeStory = checkBox.hasAttribute("checked");
  482. break;
  483.  
  484. case "type-photo":
  485. searchOptions.typePhotos = checkBox.hasAttribute("checked");
  486. break;
  487.  
  488. case "type-poetry":
  489. searchOptions.typePoetry = checkBox.hasAttribute("checked");
  490. }
  491. return searchOptions;
  492. }
  493. loadPage(prevFigures) {
  494. return SearchPage_awaiter(this, void 0, void 0, (function*() {
  495. const page = yield this.getPage();
  496. if (null == page) throw new Error("No page found");
  497. null != prevFigures || (prevFigures = []);
  498. const prevSids = prevFigures.map((figure => figure.id));
  499. let figures = getFiguresFromPage(page);
  500. figures = figures.filter((figure => !prevSids.includes(figure.id)));
  501. if (0 !== figures.length) {
  502. if (showPageSeparatorSetting.value) {
  503. const separator = createSeparatorElem(this.pageNo);
  504. this.gallery.appendChild(separator);
  505. }
  506. for (const figure of figures) this.gallery.appendChild(figure);
  507. } else throw new Error("No figures found");
  508. window.dispatchEvent(new CustomEvent("ei-update-embedded"));
  509. return figures;
  510. }));
  511. }
  512. }
  513. var GalleryManager_awaiter = function(thisArg, _arguments, P, generator) {
  514. return new (P || (P = Promise))((function(resolve, reject) {
  515. function fulfilled(value) {
  516. try {
  517. step(generator.next(value));
  518. } catch (e) {
  519. reject(e);
  520. }
  521. }
  522. function rejected(value) {
  523. try {
  524. step(generator.throw(value));
  525. } catch (e) {
  526. reject(e);
  527. }
  528. }
  529. function step(result) {
  530. result.done ? resolve(result.value) : function adopt(value) {
  531. return value instanceof P ? value : new P((function(resolve) {
  532. resolve(value);
  533. }));
  534. }(result.value).then(fulfilled, rejected);
  535. }
  536. step((generator = generator.apply(thisArg, _arguments || [])).next());
  537. }));
  538. };
  539. class GalleryManager {
  540. constructor() {
  541. this.pageNo = 1;
  542. this.prevFigures = [];
  543. this.currDataFavId = "";
  544. this.isGallery = window.location.toString().includes("net/gallery");
  545. this.isFavorites = window.location.toString().includes("net/favorites");
  546. this.isScraps = window.location.toString().includes("net/scraps");
  547. this.isBrowse = window.location.toString().includes("net/browse");
  548. if (this.isBrowse) {
  549. const pageOption = document.getElementById("manual-page");
  550. if (pageOption instanceof HTMLInputElement) this.pageNo = parseInt(pageOption.value);
  551. }
  552. this.isSearch = window.location.toString().includes("net/search");
  553. }
  554. loadNextPage() {
  555. return GalleryManager_awaiter(this, void 0, void 0, (function*() {
  556. this.pageNo++;
  557. if (this.isFavorites) {
  558. const gallery = document.body.querySelector('section[id*="gallery"]'), figures = null == gallery ? void 0 : gallery.getElementsByTagName("figure");
  559. if (null != figures && 0 !== figures.length) {
  560. const lastFigureFavId = figures[figures.length - 1].getAttribute("data-fav-id");
  561. if (null != lastFigureFavId) this.currDataFavId = lastFigureFavId;
  562. }
  563. }
  564. let nextPage;
  565. if (true === this.isGallery) nextPage = new GalleryPage(this.pageNo); else if (true === this.isFavorites) nextPage = new FavoritesPage(this.currDataFavId, this.pageNo); else if (true === this.isScraps) nextPage = new ScrapsPage(this.pageNo); else if (true === this.isBrowse) nextPage = new BrowsePage(this.pageNo); else if (true === this.isSearch) nextPage = new SearchPage(this.pageNo);
  566. if (null != nextPage) {
  567. const spacer = document.createElement("div");
  568. spacer.style.height = "20px";
  569. nextPage.gallery.appendChild(spacer);
  570. const loadingSpinner = new window.FALoadingSpinner(nextPage.gallery);
  571. loadingSpinner.spinnerThickness = 5;
  572. loadingSpinner.size = 50;
  573. loadingSpinner.visible = true;
  574. try {
  575. this.prevFigures = yield nextPage.loadPage(this.prevFigures);
  576. } finally {
  577. loadingSpinner.visible = false;
  578. loadingSpinner.dispose();
  579. nextPage.gallery.removeChild(spacer);
  580. }
  581. }
  582. }));
  583. }
  584. }
  585. var InfiniGallery_awaiter = function(thisArg, _arguments, P, generator) {
  586. return new (P || (P = Promise))((function(resolve, reject) {
  587. function fulfilled(value) {
  588. try {
  589. step(generator.next(value));
  590. } catch (e) {
  591. reject(e);
  592. }
  593. }
  594. function rejected(value) {
  595. try {
  596. step(generator.throw(value));
  597. } catch (e) {
  598. reject(e);
  599. }
  600. }
  601. function step(result) {
  602. result.done ? resolve(result.value) : function adopt(value) {
  603. return value instanceof P ? value : new P((function(resolve) {
  604. resolve(value);
  605. }));
  606. }(result.value).then(fulfilled, rejected);
  607. }
  608. step((generator = generator.apply(thisArg, _arguments || [])).next());
  609. }));
  610. };
  611. class InfiniGallery {
  612. constructor() {
  613. this.scanInterval = -1;
  614. this.scanElem = document.getElementById("footer");
  615. this.galleryManager = new GalleryManager;
  616. }
  617. startScrollDetection() {
  618. this.scanInterval = setInterval((() => {
  619. if (function isElementOnScreen(element) {
  620. const rect = element.getBoundingClientRect(), windowHeight = 2 * (window.innerHeight || document.documentElement.clientHeight);
  621. return rect.top <= windowHeight && rect.top + rect.height >= 0;
  622. }(this.scanElem)) {
  623. this.stopScrollDetection();
  624. this.loadNextPage();
  625. }
  626. }), 100);
  627. }
  628. stopScrollDetection() {
  629. clearInterval(this.scanInterval);
  630. }
  631. loadNextPage() {
  632. return InfiniGallery_awaiter(this, void 0, void 0, (function*() {
  633. try {
  634. yield this.galleryManager.loadNextPage();
  635. this.startScrollDetection();
  636. } catch (_a) {
  637. this.stopScrollDetection();
  638. }
  639. }));
  640. }
  641. }
  642. const customSettings = new window.FACustomSettings("Midori's Script Settings", "FA Infini-Gallery Settings"), showPageSeparatorSetting = customSettings.newSetting(window.FASettingType.Boolean, "Page Separator");
  643. showPageSeparatorSetting.description = "Set wether a Page Separator is shown for each new Page loaded. Default: Show Page Separators";
  644. showPageSeparatorSetting.defaultValue = true;
  645. const pageSeparatorTextSetting = customSettings.newSetting(window.FASettingType.Text, "Page Separator Text");
  646. pageSeparatorTextSetting.description = "The Text that is displayed when a new Infini-Gallery Page is loaded (if shown). Number of Page gets inserted instead of: %page% .";
  647. pageSeparatorTextSetting.defaultValue = "Infini-Gallery Page: %page%";
  648. pageSeparatorTextSetting.verifyRegex = /%page%/;
  649. customSettings.loadSettings();
  650. const requestHelper = new window.FARequestHelper(2);
  651. if (customSettings.isFeatureEnabled) {
  652. const matchList = new window.FAMatchList(customSettings);
  653. matchList.matches = [ "net/gallery", "net/favorites", "net/scraps", "net/browse", "net/search" ];
  654. matchList.runInIFrame = false;
  655. if (matchList.hasMatch) {
  656. (new InfiniGallery).startScrollDetection();
  657. }
  658. }
  659. })();