billy-herrington-utils 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/billy-herrington-utils.es.js +17 -127
- package/dist/billy-herrington-utils.es.js.map +1 -1
- package/dist/billy-herrington-utils.umd.js +17 -127
- package/dist/billy-herrington-utils.umd.js.map +1 -1
- package/dist/index.d.ts +24 -72
- package/package.json +1 -1
- package/src/data-manager/index.ts +16 -19
- package/src/index.ts +0 -2
- package/src/utils/jabroni-outfit-wrap/index.ts +17 -2
- package/src/utils/parsers/index.ts +3 -2
- package/src/utils/userscript-utils/pagination-strategies.ts +59 -0
- package/src/utils/userscript-utils/rules.ts +0 -272
|
@@ -24,8 +24,9 @@ function parseIntegerOr(n, or) {
|
|
|
24
24
|
return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
|
|
25
25
|
}
|
|
26
26
|
function parseDataParams(str) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const paramsStr = decodeURI(str.trim()).split(";");
|
|
28
|
+
return paramsStr.reduce((acc, s) => {
|
|
29
|
+
const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
|
|
29
30
|
if (parsed) {
|
|
30
31
|
const [, key, value] = parsed;
|
|
31
32
|
if (value) {
|
|
@@ -303,12 +304,10 @@ function range(size, startAt = 1, step = 1) {
|
|
|
303
304
|
}
|
|
304
305
|
class DataFilter {
|
|
305
306
|
constructor(rules, state) {
|
|
306
|
-
__publicField(this, "state");
|
|
307
|
-
__publicField(this, "rules");
|
|
308
307
|
__publicField(this, "filters");
|
|
309
308
|
__publicField(this, "filterPublic", () => {
|
|
310
309
|
return (v) => {
|
|
311
|
-
const isPublic = !this.rules.
|
|
310
|
+
const isPublic = !this.rules.isPrivate(v.element);
|
|
312
311
|
return {
|
|
313
312
|
tag: "filter-public",
|
|
314
313
|
condition: this.state.filterPublic && isPublic
|
|
@@ -317,7 +316,7 @@ class DataFilter {
|
|
|
317
316
|
});
|
|
318
317
|
__publicField(this, "filterPrivate", () => {
|
|
319
318
|
return (v) => {
|
|
320
|
-
const isPrivate = this.rules.
|
|
319
|
+
const isPrivate = this.rules.isPrivate(v.element);
|
|
321
320
|
return {
|
|
322
321
|
tag: "filter-private",
|
|
323
322
|
condition: this.state.filterPrivate && isPrivate
|
|
@@ -326,7 +325,7 @@ class DataFilter {
|
|
|
326
325
|
});
|
|
327
326
|
__publicField(this, "filterHD", () => {
|
|
328
327
|
return (v) => {
|
|
329
|
-
const isHD = this.rules.
|
|
328
|
+
const isHD = this.rules.isHD(v.element);
|
|
330
329
|
return {
|
|
331
330
|
tag: "filter-hd",
|
|
332
331
|
condition: this.state.filterHD && isHD
|
|
@@ -362,8 +361,9 @@ class DataFilter {
|
|
|
362
361
|
};
|
|
363
362
|
};
|
|
364
363
|
});
|
|
365
|
-
this.state = state;
|
|
366
364
|
this.rules = rules;
|
|
365
|
+
this.state = state;
|
|
366
|
+
this.state = state;
|
|
367
367
|
const methods = Object.getOwnPropertyNames(this);
|
|
368
368
|
this.filters = methods.reduce((acc, k) => {
|
|
369
369
|
if (k in this.state) {
|
|
@@ -408,21 +408,21 @@ class DataManager {
|
|
|
408
408
|
this.applyFilters(filters, offset);
|
|
409
409
|
});
|
|
410
410
|
__publicField(this, "parseData", (html, container, removeDuplicates = false, shouldLazify = true) => {
|
|
411
|
-
const thumbs = this.rules.
|
|
411
|
+
const thumbs = this.rules.getThumbs(html);
|
|
412
412
|
const data_offset = this.data.size;
|
|
413
413
|
for (const thumbElement of thumbs) {
|
|
414
|
-
const url = this.rules.
|
|
414
|
+
const url = this.rules.getThumbUrl(thumbElement);
|
|
415
415
|
if (!url || this.data.has(url)) {
|
|
416
416
|
if (removeDuplicates) thumbElement.remove();
|
|
417
417
|
continue;
|
|
418
418
|
}
|
|
419
|
-
const data = this.rules.
|
|
419
|
+
const data = this.rules.getThumbData(thumbElement);
|
|
420
420
|
this.data.set(url, { element: thumbElement, ...data });
|
|
421
421
|
if (shouldLazify) {
|
|
422
|
-
const { img, imgSrc } = this.rules.
|
|
422
|
+
const { img, imgSrc } = this.rules.getThumbImgData(thumbElement);
|
|
423
423
|
this.lazyImgLoader.lazify(thumbElement, img, imgSrc);
|
|
424
424
|
}
|
|
425
|
-
const parent = container || this.rules.
|
|
425
|
+
const parent = container || this.rules.container;
|
|
426
426
|
if (!parent.contains(thumbElement)) parent.appendChild(thumbElement);
|
|
427
427
|
}
|
|
428
428
|
this.filterAll(data_offset);
|
|
@@ -532,6 +532,10 @@ class InfiniteScroller {
|
|
|
532
532
|
}
|
|
533
533
|
function createInfiniteScroller(store, handleHtmlCallback, rules) {
|
|
534
534
|
const enabled = store.state.infiniteScrollEnabled;
|
|
535
|
+
rules.paginationOffset = rules.paginationStrategy.getPaginationOffset();
|
|
536
|
+
rules.paginationLast = rules.paginationStrategy.getPaginationLast();
|
|
537
|
+
rules.paginationUrlGenerator = rules.paginationStrategy.getPaginationUrlGenerator();
|
|
538
|
+
rules.paginationElement = rules.paginationStrategy.getPaginationElement();
|
|
535
539
|
const iscroller = new InfiniteScroller({
|
|
536
540
|
enabled,
|
|
537
541
|
handleHtmlCallback,
|
|
@@ -545,119 +549,6 @@ function createInfiniteScroller(store, handleHtmlCallback, rules) {
|
|
|
545
549
|
});
|
|
546
550
|
return iscroller;
|
|
547
551
|
}
|
|
548
|
-
class RulesHelper {
|
|
549
|
-
constructor(options) {
|
|
550
|
-
__publicField(this, "delay", 250);
|
|
551
|
-
__publicField(this, "IS_VIDEO_PAGE");
|
|
552
|
-
__publicField(this, "IS_SEARCH_PAGE");
|
|
553
|
-
__publicField(this, "paginationElement");
|
|
554
|
-
__publicField(this, "paginationOffset");
|
|
555
|
-
__publicField(this, "paginationLast");
|
|
556
|
-
__publicField(this, "URL_DATA");
|
|
557
|
-
__publicField(this, "paginationUrlGenerator", (offset) => {
|
|
558
|
-
const opt = this.options.paginationUrlGenerator;
|
|
559
|
-
if (typeof opt === "function") return opt(offset);
|
|
560
|
-
const url = new URL(location.href);
|
|
561
|
-
if (opt.searchPage) {
|
|
562
|
-
url.searchParams.set(opt.searchPage, offset.toString());
|
|
563
|
-
return url.href;
|
|
564
|
-
}
|
|
565
|
-
if (opt.pathnameLast) {
|
|
566
|
-
if (url.pathname === "/") url.pathname = "/1";
|
|
567
|
-
if (/\d+$/.test(url.pathname)) {
|
|
568
|
-
url.pathname = url.pathname.replace(/\d+$/, offset.toString());
|
|
569
|
-
} else {
|
|
570
|
-
url.pathname = `${url.pathname}/${offset}`;
|
|
571
|
-
}
|
|
572
|
-
return url.href;
|
|
573
|
-
}
|
|
574
|
-
return url.href;
|
|
575
|
-
});
|
|
576
|
-
__publicField(this, "_IS_VIDEO_PAGE", () => {
|
|
577
|
-
if (typeof this.options.IS_VIDEO_PAGE === "boolean") {
|
|
578
|
-
return this.options.IS_VIDEO_PAGE;
|
|
579
|
-
}
|
|
580
|
-
return this.options.IS_VIDEO_PAGE.test(location.pathname);
|
|
581
|
-
});
|
|
582
|
-
__publicField(this, "_IS_SEARCH_PAGE", () => {
|
|
583
|
-
if (typeof this.options.IS_SEARCH_PAGE === "boolean") {
|
|
584
|
-
return this.options.IS_SEARCH_PAGE;
|
|
585
|
-
}
|
|
586
|
-
return this.options.IS_SEARCH_PAGE.test(location.pathname);
|
|
587
|
-
});
|
|
588
|
-
__publicField(this, "_paginationElement", (html = document) => {
|
|
589
|
-
if (typeof this.options.paginationElement === "function") {
|
|
590
|
-
return this.options.paginationElement(html);
|
|
591
|
-
}
|
|
592
|
-
return [...html.querySelectorAll(this.options.paginationElement)].pop();
|
|
593
|
-
});
|
|
594
|
-
__publicField(this, "CONTAINER", (html = document) => {
|
|
595
|
-
if (typeof this.options.CONTAINER === "function") {
|
|
596
|
-
return this.options.CONTAINER(html);
|
|
597
|
-
}
|
|
598
|
-
return [...html.querySelectorAll(this.options.CONTAINER)].pop();
|
|
599
|
-
});
|
|
600
|
-
__publicField(this, "THUMB_URL", (thumb) => {
|
|
601
|
-
if (typeof this.options.THUMB_URL === "string") {
|
|
602
|
-
return thumb.querySelector(this.options.THUMB_URL).href || "";
|
|
603
|
-
}
|
|
604
|
-
return this.options.THUMB_URL(thumb);
|
|
605
|
-
});
|
|
606
|
-
__publicField(this, "GET_THUMBS", (html) => {
|
|
607
|
-
if (typeof this.options.GET_THUMBS === "string") {
|
|
608
|
-
return [...html.querySelectorAll(this.options.GET_THUMBS)];
|
|
609
|
-
}
|
|
610
|
-
return this.options.GET_THUMBS(html);
|
|
611
|
-
});
|
|
612
|
-
__publicField(this, "THUMB_DATA", (thumb) => {
|
|
613
|
-
const opt = this.options.THUMB_DATA;
|
|
614
|
-
if (typeof opt === "function") return opt(thumb);
|
|
615
|
-
let title = sanitizeStr(thumb.querySelector(opt.title)?.innerText || "");
|
|
616
|
-
if (opt.uploader) {
|
|
617
|
-
const uploader = sanitizeStr(
|
|
618
|
-
thumb.querySelector(opt.title)?.innerText || ""
|
|
619
|
-
);
|
|
620
|
-
title = `${title} user:${uploader}`;
|
|
621
|
-
}
|
|
622
|
-
const duration = !opt.duration ? 0 : timeToSeconds(
|
|
623
|
-
sanitizeStr(thumb.querySelector(opt.duration)?.innerText || "")
|
|
624
|
-
);
|
|
625
|
-
return { title, duration };
|
|
626
|
-
});
|
|
627
|
-
__publicField(this, "THUMB_IMG_DATA", (thumb) => {
|
|
628
|
-
const opt = this.options.THUMB_IMG_DATA;
|
|
629
|
-
if (typeof opt === "function") return opt(thumb);
|
|
630
|
-
const result = {};
|
|
631
|
-
if (opt.img) {
|
|
632
|
-
const img = thumb.querySelector(opt.img);
|
|
633
|
-
const imgSrc = img.getAttribute(opt.imgSrc || "data-src") || img.getAttribute("src");
|
|
634
|
-
if (opt.lazyloading) {
|
|
635
|
-
img.classList.remove(opt.lazyloading);
|
|
636
|
-
}
|
|
637
|
-
Object.assign(result, { img, imgSrc });
|
|
638
|
-
if (img.complete && img.getAttribute("src") && !img.src.includes("data:image")) {
|
|
639
|
-
return {};
|
|
640
|
-
}
|
|
641
|
-
} else return {};
|
|
642
|
-
});
|
|
643
|
-
this.options = options;
|
|
644
|
-
this.delay = options?.delay || this.delay;
|
|
645
|
-
this.paginationOffset = this.options.paginationOffset;
|
|
646
|
-
this.paginationLast = this.options.paginationLast;
|
|
647
|
-
this.IS_VIDEO_PAGE = this._IS_VIDEO_PAGE();
|
|
648
|
-
this.IS_SEARCH_PAGE = this._IS_SEARCH_PAGE();
|
|
649
|
-
this.paginationElement = this._paginationElement();
|
|
650
|
-
if (options.URL_DATA) {
|
|
651
|
-
this.URL_DATA = options.URL_DATA;
|
|
652
|
-
Object.assign(this, this.URL_DATA());
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
router(store, handleHtmlCallback) {
|
|
656
|
-
if (!this.options.router) return;
|
|
657
|
-
const scroller = createInfiniteScroller(store, handleHtmlCallback, this);
|
|
658
|
-
this.options.router(this, store, handleHtmlCallback, scroller);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
552
|
export {
|
|
662
553
|
AsyncPool,
|
|
663
554
|
DataManager,
|
|
@@ -665,7 +556,6 @@ export {
|
|
|
665
556
|
LazyImgLoader,
|
|
666
557
|
MOBILE_UA,
|
|
667
558
|
Observer,
|
|
668
|
-
RulesHelper,
|
|
669
559
|
Tick,
|
|
670
560
|
chunks,
|
|
671
561
|
circularShift,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billy-herrington-utils.es.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts","../src/data-manager/index.ts","../src/utils/infinite-scroll/index.ts","../src/utils/jabroni-outfit-wrap/index.ts","../src/utils/userscript-utils/rules.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\n}\n\nexport function sanitizeStr(s: string) {\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\n}\n","export function formatTimeToHHMMSS(timeString: string): string {\n const regex: RegExp = /(?:(\\d+)\\s*h\\s*)?(?:(\\d+)\\s*mi?n?\\s*)?(?:(\\d+)\\s*sec)?/;\n const match: RegExpMatchArray | null = timeString.match(regex);\n const h: number = parseInt(match?.[1] || '0');\n const m: number = parseInt(match?.[2] || '0');\n const s: number = parseInt(match?.[3] || '0');\n const pad = (num: number): string => String(num).padStart(2, '0');\n return `${pad(h)}:${pad(m)}:${pad(s)}`;\n}\n\n// \"01:22:03\" -> 4923\nexport function timeToSeconds(t: string): number {\n const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;\n return (r?.match(/\\d+/gm) || [0])\n .reverse()\n .map((s, i) => parseInt(s as string) * 60 ** i)\n .reduce((a, b) => a + b);\n}\n\nexport function parseIntegerOr(n: string | number, or: number): number {\n return (num => Number.isNaN(num) ? or : num)(parseInt(n as string));\n}\n\n// \"data:02;body+head:async;void:;zero:;\"\nexport function parseDataParams(str: string): Record<string, string> {\n return str.split(';').reduce((acc, s) => {\n const parsed = s.match(/([\\+\\w]+):(\\w+)?/);\n if (parsed) {\n const [, key, value] = parsed;\n if (value) {\n key.split('+').forEach(p => { acc[p] = value; });\n }\n }\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport function parseCSSUrl(s: string) {\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\n}\n","export class Observer {\n public observer: IntersectionObserver;\n constructor(private callback: (entry: Element) => void) {\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\n }\n\n observe(target: Element) {\n this.observer.observe(target);\n }\n\n throttle(target: Element, throttleTime: number) {\n this.observer.unobserve(target);\n setTimeout(() => this.observer.observe(target), throttleTime);\n }\n\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n this.callback(entry.target);\n }\n }\n }\n\n static observeWhile(\n target: Element,\n callback: () => Promise<boolean> | boolean,\n throttleTime: number,\n ) {\n const observer_ = new Observer(async (target: Element) => {\n const condition = await callback();\n if (condition) observer_.throttle(target, throttleTime);\n });\n observer_.observe(target);\n return observer_;\n }\n}\n\nexport class LazyImgLoader {\n public lazyImgObserver: Observer;\n private attributeName = 'data-lazy-load';\n\n constructor(shouldDelazify: (target: Element) => boolean) {\n this.lazyImgObserver = new Observer((target: Element) => {\n if (shouldDelazify(target)) {\n this.delazify(target as HTMLImageElement);\n }\n });\n }\n\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\n if (!img || !imgSrc) return;\n img.setAttribute(this.attributeName, imgSrc);\n img.src = '';\n this.lazyImgObserver.observe(img);\n }\n\n delazify = (target: HTMLImageElement) => {\n this.lazyImgObserver.observer.unobserve(target);\n target.src = target.getAttribute(this.attributeName) as string;\n target.removeAttribute(this.attributeName);\n };\n}\n","export function circularShift(n: number, c = 6, s = 1): number {\n return (n + s) % c || c;\n}\n","export function parseDom(html: string): HTMLElement {\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\n}\n\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\n for (const attr of source.attributes) {\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\n }\n}\n\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\n const newTagElement = document.createElement(tagName);\n copyAttributes(newTagElement, e);\n newTagElement.innerHTML = e.innerHTML;\n e.parentNode?.replaceChild(newTagElement, e);\n return newTagElement;\n}\n\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\n return Array.from(elements).reduce((acc, v) => {\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\n return acc;\n }, [] as Array<HTMLElement | Element>);\n}\n\nexport function findNextSibling(el: HTMLElement | Element) {\n if (el.nextElementSibling) return el.nextElementSibling;\n if (el.parentElement) return findNextSibling(el.parentElement);\n return null;\n}\n\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void {\n const observer = new MutationObserver((_mutations) => {\n const el = parent.querySelector(selector);\n if (el) {\n observer.disconnect();\n callback(el);\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n}\n\nexport function watchElementChildrenCount(element: HTMLElement | Element,\n callback: (observer: MutationObserver, count: number) => void): void {\n let count = element.children.length;\n const observer = new MutationObserver((mutationList, observer) => {\n for (const mutation of mutationList) {\n if (mutation.type === \"childList\") {\n if (count !== element.children.length) {\n count = element.children.length;\n callback(observer, count);\n }\n }\n }\n });\n observer.observe(element, { childList: true });\n}\n\nexport function watchDomChangesWithThrottle(\n element: HTMLElement | Element, \n callback: () => void,\n throttle = 1000,\n times = Infinity,\n options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }\n) {\n let lastMutationTime: number;\n let timeout: number;\n let times_ = times;\n const observer = new MutationObserver((_mutationList, _observer) => {\n if (times_ !== Infinity && times_ < 1) {\n observer.disconnect();\n return;\n }\n times_--;\n const now = Date.now();\n if (lastMutationTime && now - lastMutationTime < throttle) {\n timeout && clearTimeout(timeout);\n }\n timeout = setTimeout(callback, throttle);\n lastMutationTime = now;\n });\n observer.observe(element, options);\n return observer;\n}\n\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\n const btn = parseDom(options.button);\n\n if (options.append) document.querySelector(options.append)?.append(btn);\n if (options.after) document.querySelector(options.after)?.after(btn);\n\n btn.addEventListener('click', (e) => {\n e.preventDefault();\n\n if (options.cbBefore) options.cbBefore();\n\n waitForElementExists(document.body, 'video', (video: Element) => {\n window.location.href = video.getAttribute('src') as string;\n });\n });\n}\n\nexport function exterminateVideo(video: HTMLVideoElement) {\n video.removeAttribute('src');\n video.load();\n video.remove();\n}","import { parseDom } from '../dom';\n\nexport const MOBILE_UA = [\n 'Mozilla/5.0 (Linux; Android 10; K)',\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\n 'Chrome/114.0.0.0 Mobile Safari/537.36',\n].join(' ');\n\nexport function fetchWith(\n url: string,\n options: Record<string, boolean> = { html: false, mobile: false },\n) {\n const reqOpts = {};\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ 'User-Agent': MOBILE_UA }) });\n return fetch(url, reqOpts)\n .then((r) => r.text())\n .then((r) => (options.html ? parseDom(r) : r));\n}\n\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true }) as Promise<HTMLElement>;\n\nexport const fetchText = (url: string) => fetchWith(url) as Promise<string>;\n\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\n const formData = new FormData();\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\n return formData;\n}\n","export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void {\n for (const e of events) {\n dom.addEventListener(e, callback, true);\n }\n}\n\nexport class Tick {\n private tick?: number;\n private callbackFinal?: () => void;\n\n constructor(private delay: number, private startImmediate: boolean = true) {}\n\n public start(callback: () => void, callbackFinal?: () => void): void {\n this.stop();\n this.callbackFinal = callbackFinal;\n if (this.startImmediate) callback();\n this.tick = window.setInterval(callback, this.delay);\n }\n\n public stop(): void {\n if (this.tick !== undefined) {\n clearInterval(this.tick);\n this.tick = undefined;\n }\n if (this.callbackFinal) {\n this.callbackFinal();\n this.callbackFinal = undefined;\n }\n }\n}\n","export function isMob() {\n return /iPhone|Android/i.test(navigator.userAgent);\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\nexport async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>) {\n const res = [];\n for await (const f of iterable) {\n res.push(await f());\n }\n return res;\n}\n\nexport function wait(milliseconds: number) {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\ninterface AsyncPoolTask {\n v: () => Promise<void>;\n p: number;\n}\n\nexport class AsyncPool {\n private cur = 0;\n private finished: Promise<boolean>;\n private _resolve?: (value: boolean | PromiseLike<boolean>) => void;\n\n public static async doNAsyncAtOnce(max = 1, pool: Array<AsyncPoolTask | (() => Promise<void>)> = []) {\n const spool = new AsyncPool(max);\n pool.forEach(f => spool.push(f));\n return spool.run();\n }\n\n constructor(private max = 1, private pool: Array<AsyncPoolTask> = []) {\n this.finished = new Promise((resolve) => {\n this._resolve = resolve;\n });\n }\n\n private getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\n if (p > 3 || this.pool.length === 0) return undefined;\n const i = this.pool.findIndex((e) => e.p === p);\n if (i >= 0) {\n const res = this.pool[i].v;\n this.pool.splice(i, 1);\n return res;\n }\n return this.getHighPriorityFirst(p + 1);\n }\n\n private async runTask() {\n this.cur++;\n const f = this.getHighPriorityFirst();\n await f?.();\n this.cur--;\n this.runTasks();\n }\n\n private runTasks() {\n if (!this.pool.length) {\n this._resolve?.(true);\n return;\n }\n if (this.cur < this.max) {\n this.runTask();\n this.runTasks();\n }\n }\n\n public async run() {\n this.runTasks();\n return this.finished;\n }\n\n public push(x: AsyncPoolTask | (() => Promise<void>)) {\n this.pool.push('p' in x ? x : { v: x, p: 0 });\n }\n}\n\n","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\n return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));\n}\n\nexport function range(size: number, startAt: number = 1, step: number = 1): number[] {\n return Array.from({ length: size }, (_, index) => startAt + index * step);\n}\n","import { LazyImgLoader } from '../utils/observers';\nimport { stringToWords } from '../utils/strings';\n\ninterface DataFilterState {\n filterPublic: boolean;\n filterPrivate: boolean;\n filterHD: boolean;\n filterDuration: boolean;\n filterDurationFrom: number;\n filterDurationTo: number;\n filterExclude: boolean;\n filterExcludeWords: string;\n filterInclude: boolean;\n filterIncludeWords: string;\n}\n\ninterface FilterResult {\n tag: string;\n condition: boolean;\n}\n\ntype FilterInput = Record<string, string | number | boolean | HTMLElement>;\ntype FilterFunction = (v: FilterInput) => FilterResult;\n\nclass DataFilter {\n private state: DataFilterState;\n private rules: IRules;\n public filters: { [key: string]: () => FilterFunction };\n\n constructor(rules: IRules, state: DataFilterState) {\n this.state = state;\n this.rules = rules;\n\n const methods = Object.getOwnPropertyNames(this);\n this.filters = methods.reduce((acc: { [key: string]: () => FilterFunction }, k) => {\n if (k in this.state) {\n acc[k] = this[k as keyof DataFilter] as unknown as () => FilterFunction;\n //@ts-ignore\n GM_addStyle(`.filter-${k.toLowerCase().slice(6)} { display: none !important; }`);\n }\n return acc;\n }, {});\n }\n\n filterPublic = (): FilterFunction => {\n return (v: FilterInput) => {\n const isPublic = !this.rules.IS_PRIVATE(v.element as HTMLElement);\n return {\n tag: 'filter-public',\n condition: this.state.filterPublic && isPublic,\n };\n };\n };\n\n filterPrivate = (): FilterFunction => {\n return (v: FilterInput) => {\n const isPrivate = this.rules.IS_PRIVATE(v.element as HTMLElement);\n return {\n tag: 'filter-private',\n condition: this.state.filterPrivate && isPrivate,\n };\n };\n };\n\n filterHD = (): FilterFunction => {\n return (v: FilterInput) => {\n const isHD = this.rules.IS_HD(v.element as HTMLElement);\n return {\n tag: 'filter-hd',\n condition: this.state.filterHD && isHD,\n };\n };\n };\n\n filterDuration = (): FilterFunction => {\n return (v: FilterInput) => {\n const notInRange =\n (v.duration as number) < this.state.filterDurationFrom ||\n (v.duration as number) > this.state.filterDurationTo;\n return {\n tag: 'filter-duration',\n condition: this.state.filterDuration && notInRange,\n };\n };\n };\n\n filterExclude = (): FilterFunction => {\n const tags = DataManager.filterDSLToRegex(this.state.filterExcludeWords);\n return (v: FilterInput) => {\n const containTags = tags.some((tag) => tag.test(v.title as string));\n return {\n tag: 'filter-exclude',\n condition: this.state.filterExclude && containTags,\n };\n };\n };\n\n filterInclude = (): FilterFunction => {\n const tags = DataManager.filterDSLToRegex(this.state.filterIncludeWords);\n return (v: FilterInput) => {\n const containTagsNot = tags.some((tag) => !tag.test(v.title as string));\n return {\n tag: 'filter-include',\n condition: this.state.filterInclude && containTagsNot,\n };\n };\n };\n}\n\ninterface IRules {\n GET_THUMBS: (html: HTMLElement) => HTMLElement[];\n THUMB_URL: (thumbElement: HTMLElement) => string;\n THUMB_DATA: (thumbElement: HTMLElement) => { title: string; duration: number };\n THUMB_IMG_DATA: (thumbElement: HTMLElement) => { img: HTMLElement; imgSrc: string };\n CONTAINER: HTMLElement;\n IS_PRIVATE: (element: HTMLElement) => boolean;\n IS_HD: (element: HTMLElement) => boolean;\n}\n\nexport class DataManager {\n private rules: IRules;\n private state: DataFilterState;\n private data: Map<string, FilterInput>;\n private lazyImgLoader: LazyImgLoader;\n public dataFilters: { [key: string]: () => FilterFunction };\n\n constructor(rules: IRules, state: DataFilterState) {\n this.rules = rules;\n this.state = state;\n this.data = new Map();\n this.lazyImgLoader = new LazyImgLoader(\n (target: Element) => !this.isFiltered(target as HTMLElement),\n );\n this.dataFilters = new DataFilter(rules, state).filters;\n\n // @ts-ignore\n [window, unsafeWindow || ({})].forEach(w => {\n Object.assign(w, {\n sortByViews: () => this.sort('view'),\n sortByDuration: () => this.sort('duration'),\n });\n });\n }\n\n static filterDSLToRegex(str: string): RegExp[] {\n const toFullWord = (w: string) => `(^|\\\\ )${w}($|\\\\ )`;\n const str_ = str.replace(/f\\:(\\w+)/g, (_, w) => toFullWord(w));\n return stringToWords(str_).map((expr: string) => new RegExp(expr, 'i'));\n }\n\n isFiltered(el: HTMLElement): boolean {\n return el.className.includes('filtered');\n }\n\n applyFilters = (filters: { [key: string]: boolean }, offset = 0): void => {\n const filtersToApply = Object.keys(filters)\n .filter((k) => Object.hasOwn(this.dataFilters, k))\n .map((k) => this.dataFilters[k]());\n\n if (filtersToApply.length === 0) return;\n\n const updates: (() => void)[] = [];\n let offset_counter = 1;\n for (const v of this.data.values()) {\n if (++offset_counter > offset) {\n for (const f of filtersToApply) {\n const { tag, condition } = f(v as FilterInput);\n updates.push(() => (v.element as HTMLElement).classList.toggle(tag, condition));\n }\n }\n }\n\n requestAnimationFrame(() => {\n updates.forEach((update) => update());\n });\n };\n\n filterAll = (offset?: number): void => {\n const filters = Object.assign(\n {},\n ...Object.keys(this.dataFilters).map((f) => ({\n [f]: this.state[f as keyof DataFilterState],\n })),\n );\n this.applyFilters(filters, offset);\n };\n\n parseData = (\n html: HTMLElement,\n container?: HTMLElement,\n removeDuplicates = false,\n shouldLazify = true,\n ): void => {\n const thumbs = this.rules.GET_THUMBS(html);\n const data_offset = this.data.size;\n\n for (const thumbElement of thumbs) {\n const url = this.rules.THUMB_URL(thumbElement);\n if (!url || this.data.has(url)) {\n if (removeDuplicates) thumbElement.remove();\n continue;\n }\n\n const data = this.rules.THUMB_DATA(thumbElement);\n this.data.set(url, { element: thumbElement, ...data });\n\n if (shouldLazify) {\n const { img, imgSrc } = this.rules.THUMB_IMG_DATA(thumbElement);\n this.lazyImgLoader.lazify(thumbElement, img as HTMLImageElement, imgSrc);\n }\n\n const parent = container || this.rules.CONTAINER;\n if (!parent.contains(thumbElement)) parent.appendChild(thumbElement);\n }\n\n this.filterAll(data_offset);\n };\n\n sort(propName: string) {\n if (this.data.size < 2) return;\n\n const sorted = Array.from(this.data.keys()).sort((b, a) => {\n return ((this.data.get(a) as FilterInput)[propName] as number) -\n ((this.data.get(b) as FilterInput)[propName] as number);\n });\n\n const container = ((this.data.get(sorted[0]) as FilterInput).element as HTMLElement).parentElement as HTMLElement;\n\n sorted.forEach(s => {\n const e = (this.data.get(s) as FilterInput).element as HTMLElement;\n container.append(e);\n });\n }\n}\n","import { fetchHtml } from '../fetch';\nimport { Observer } from '../observers';\n\ninterface IInfiniteScroller {\n delay: number;\n enabled: boolean;\n writeHistory?: boolean;\n paginationOffset: number;\n paginationLast: number;\n paginationElement: HTMLElement;\n paginationUrlGenerator: (offset: number) => string;\n handleHtmlCallback: (document: HTMLElement) => void;\n intersectionObservable?: HTMLElement;\n alternativeGenerator?: () => OffsetGenerator;\n}\n\ninterface GeneratorResult {\n url: string;\n offset: number;\n}\n\ntype OffsetGenerator = Generator<GeneratorResult> | AsyncGenerator<GeneratorResult>;\n\nexport class InfiniteScroller {\n public paginationGenerator: OffsetGenerator;\n public enabled: boolean;\n public delay: number;\n public paginationOffset: number;\n public paginationLast: number;\n public writeHistory: boolean;\n private handleHtmlCallback: (document: HTMLElement) => void;\n\n constructor({\n enabled = true,\n delay = 350,\n writeHistory = false,\n paginationOffset,\n paginationLast,\n paginationElement,\n paginationUrlGenerator,\n handleHtmlCallback,\n alternativeGenerator,\n intersectionObservable,\n }: IInfiniteScroller) {\n this.enabled = enabled;\n this.delay = delay;\n this.writeHistory = writeHistory;\n this.paginationOffset = paginationOffset;\n this.paginationLast = paginationLast;\n this.handleHtmlCallback = handleHtmlCallback;\n\n this.paginationGenerator =\n alternativeGenerator?.() ??\n InfiniteScroller.createPaginationGenerator(\n paginationOffset,\n paginationLast,\n paginationUrlGenerator,\n );\n\n const observable = intersectionObservable || paginationElement;\n Observer.observeWhile(observable, this.generatorConsumer, this.delay);\n }\n\n private onScrollCBs: Array<(scroller: InfiniteScroller) => void> = [];\n\n public onScroll(callback: (scroller: InfiniteScroller) => void, initCall = false) {\n if (initCall) callback(this);\n this.onScrollCBs.push(callback);\n return this;\n }\n\n private _onScroll() {\n this.onScrollCBs.forEach((cb) => cb(this));\n }\n\n generatorConsumer = async () => {\n if (!this.enabled) return false;\n const {\n value: { url, offset } = {},\n done,\n } = await this.paginationGenerator.next();\n if (!done) {\n const nextPageHTML = await fetchHtml(url);\n const prevScrollPos = document.documentElement.scrollTop;\n this.paginationOffset = offset;\n this.handleHtmlCallback(nextPageHTML);\n this._onScroll();\n window.scrollTo(0, prevScrollPos);\n if (this.writeHistory) {\n history.replaceState({}, '', url);\n }\n }\n return !done;\n };\n\n static *createPaginationGenerator(\n currentPage: number,\n totalPages: number,\n generateURL: (offset: number) => string,\n ): OffsetGenerator {\n for (let offset = currentPage + 1; offset <= totalPages; offset++) {\n const url = generateURL(offset);\n yield { url, offset };\n }\n }\n}\n","import { InfiniteScroller } from '../infinite-scroll';\nimport type { RulesHelper } from '../userscript-utils/rules';\n\nexport interface JabroniStore {\n state: Record<string, boolean | string | number>;\n localState: Record<string, boolean | string | number>;\n subscribe: (callback: () => void) => void;\n}\n\nexport function createInfiniteScroller(\n store: JabroniStore,\n handleHtmlCallback: (document: HTMLElement) => void,\n rules: RulesHelper,\n) {\n const enabled = store.state.infiniteScrollEnabled as boolean;\n const iscroller = new InfiniteScroller({\n enabled,\n handleHtmlCallback,\n ...rules,\n }).onScroll(({ paginationLast, paginationOffset }) => {\n store.localState.pagIndexLast = paginationLast;\n store.localState.pagIndexCur = paginationOffset;\n }, true);\n\n store.subscribe(() => {\n iscroller.enabled = store.state.infiniteScrollEnabled as boolean;\n });\n\n return iscroller;\n}\n","import type { InfiniteScroller } from '../infinite-scroll';\nimport type { JabroniStore } from '../jabroni-outfit-wrap';\nimport { createInfiniteScroller } from '../jabroni-outfit-wrap';\nimport { timeToSeconds } from '../parsers';\nimport { sanitizeStr } from '../strings';\n\nexport interface IRulesHelper {\n delay?: number;\n IS_VIDEO_PAGE: boolean | RegExp;\n IS_SEARCH_PAGE: boolean | RegExp;\n THUMB_URL: string | ((thumb: HTMLElement) => string);\n GET_THUMBS: string | ((html: HTMLElement) => Array<HTMLElement>);\n THUMB_DATA:\n | { title: string; uploader?: string; duration?: string }\n | ((thumb: HTMLElement) => { title: string; duration: number });\n THUMB_IMG_DATA:\n | { img?: string; imgSrc?: string; lazyloading?: string }\n | ((thumb: HTMLElement) => { img?: HTMLElement; imgSrc?: string });\n paginationUrlGenerator:\n | ((offset: number) => string)\n | { searchPage?: string; pathnameLast?: boolean };\n paginationElement: string | ((html?: HTMLElement) => HTMLElement);\n paginationOffset: number;\n paginationLast: number;\n CONTAINER: string | ((html?: HTMLElement) => HTMLElement);\n router?: (\n rules: RulesHelper,\n store: JabroniStore,\n handleHtmlCallback: (document: HTMLElement) => void,\n scroller: InfiniteScroller,\n ) => void;\n URL_DATA?: () => {\n paginationOffset: number;\n paginationUrlGenerator: (offset: number) => string;\n };\n}\n\nexport class RulesHelper {\n public delay = 250;\n public IS_VIDEO_PAGE: boolean;\n public IS_SEARCH_PAGE: boolean;\n public paginationElement: HTMLElement;\n public paginationOffset: number;\n public paginationLast: number;\n public URL_DATA:\n | undefined\n | (() => {\n paginationOffset: number;\n paginationUrlGenerator: (offset: number) => string;\n });\n\n constructor(private options: IRulesHelper) {\n this.delay = options?.delay || this.delay;\n\n this.paginationOffset = this.options.paginationOffset;\n this.paginationLast = this.options.paginationLast;\n\n this.IS_VIDEO_PAGE = this._IS_VIDEO_PAGE();\n this.IS_SEARCH_PAGE = this._IS_SEARCH_PAGE();\n\n this.paginationElement = this._paginationElement();\n\n if (options.URL_DATA) {\n this.URL_DATA = options.URL_DATA;\n Object.assign(this, this.URL_DATA());\n }\n }\n\n public router(store: JabroniStore, handleHtmlCallback: (document: HTMLElement) => void): void {\n if (!this.options.router) return;\n const scroller = createInfiniteScroller(store, handleHtmlCallback, this);\n this.options.router(this, store, handleHtmlCallback, scroller);\n }\n\n public paginationUrlGenerator = (offset: number): string => {\n const opt = this.options.paginationUrlGenerator;\n if (typeof opt === 'function') return opt(offset);\n\n const url = new URL(location.href);\n\n if (opt.searchPage) {\n url.searchParams.set(opt.searchPage, offset.toString());\n return url.href;\n }\n\n if (opt.pathnameLast) {\n if (url.pathname === '/') url.pathname = '/1';\n if (/\\d+$/.test(url.pathname)) {\n url.pathname = url.pathname.replace(/\\d+$/, offset.toString());\n } else {\n url.pathname = `${url.pathname}/${offset}`;\n }\n return url.href;\n }\n\n return url.href;\n };\n\n public _IS_VIDEO_PAGE = () => {\n if (typeof this.options.IS_VIDEO_PAGE === 'boolean') {\n return this.options.IS_VIDEO_PAGE;\n }\n return this.options.IS_VIDEO_PAGE.test(location.pathname);\n };\n\n public _IS_SEARCH_PAGE = () => {\n if (typeof this.options.IS_SEARCH_PAGE === 'boolean') {\n return this.options.IS_SEARCH_PAGE;\n }\n return this.options.IS_SEARCH_PAGE.test(location.pathname);\n };\n\n public _paginationElement = (html = document): HTMLElement => {\n if (typeof this.options.paginationElement === 'function') {\n return this.options.paginationElement(html as unknown as HTMLElement);\n }\n return [...html.querySelectorAll(this.options.paginationElement)].pop() as HTMLElement;\n };\n\n public CONTAINER = (html = document): HTMLElement => {\n if (typeof this.options.CONTAINER === 'function') {\n return this.options.CONTAINER(html as unknown as HTMLElement);\n }\n return [...html.querySelectorAll(this.options.CONTAINER)].pop() as HTMLElement;\n };\n\n public THUMB_URL = (thumb: HTMLElement) => {\n if (typeof this.options.THUMB_URL === 'string') {\n return (thumb.querySelector(this.options.THUMB_URL) as HTMLAnchorElement).href || '';\n }\n return this.options.THUMB_URL(thumb);\n };\n\n public GET_THUMBS = (html: HTMLElement) => {\n if (typeof this.options.GET_THUMBS === 'string') {\n return [...html.querySelectorAll(this.options.GET_THUMBS)] as Array<HTMLElement>;\n }\n return this.options.GET_THUMBS(html);\n };\n\n public THUMB_DATA = (thumb: HTMLElement): { title: string; duration: number } => {\n const opt = this.options.THUMB_DATA;\n if (typeof opt === 'function') return opt(thumb);\n\n let title = sanitizeStr((thumb.querySelector(opt.title) as HTMLElement)?.innerText || '');\n\n if (opt.uploader) {\n const uploader = sanitizeStr(\n (thumb.querySelector(opt.title) as HTMLElement)?.innerText || '',\n );\n\n title = `${title} user:${uploader}`;\n }\n\n const duration = !opt.duration\n ? 0\n : timeToSeconds(\n sanitizeStr((thumb.querySelector(opt.duration) as HTMLElement)?.innerText || ''),\n );\n\n return { title, duration };\n };\n\n public THUMB_IMG_DATA = (thumb: HTMLElement) => {\n const opt = this.options.THUMB_IMG_DATA;\n if (typeof opt === 'function') return opt(thumb);\n\n const result = {};\n\n if (opt.img) {\n const img = thumb.querySelector(opt.img) as HTMLImageElement;\n const imgSrc = img.getAttribute(opt.imgSrc || 'data-src') || img.getAttribute('src');\n\n if (opt.lazyloading) {\n img.classList.remove(opt.lazyloading);\n }\n\n Object.assign(result, { img, imgSrc });\n\n if (img.complete && img.getAttribute('src') && !img.src.includes('data:image')) {\n return {};\n }\n } else return {};\n };\n}\n\n// const _3HENTAI_RULES = new RulesHelper({\n// IS_VIDEO_PAGE: /^\\/g\\/\\d+/.test(location.pathname),\n// IS_SEARCH_PAGE: /^\\/search\\//.test(location.pathname),\n// THUMB_URL: 'a',\n// GET_THUMBS: '.doujin-col',\n// THUMB_DATA: { title: '.title' },\n// THUMB_IMG_DATA: { img: 'img', lazyloading: 'lazy' },\n// paginationUrlGenerator: { searchPage: 'page' },\n// paginationElement: '.pagination',\n// paginationOffset: 1,\n// paginationLast: Math.max(\n// ...Array.from(document.querySelectorAll('.pagination .page-link') || [], (e) =>\n// parseInt((e as HTMLElement).innerText),\n// ).filter(Number),\n// 1,\n// ),\n// CONTAINER: '.listing-container',\n\n/*\n PARSE LINKS AND PAGINATION FOR IT!!!!\n\n*/\n\n\n// URL_DATA() {\n// const IS_SEARCH_PAGE = /^\\/search\\//.test(location.pathname);\n// const url = new URL(window.location.href);\n\n// let paginationOffset = parseInt(url.searchParams.get('page') || \"1\");\n// let paginationUrlGenerator = (offset: number) => {\n// url.searchParams.set('page', offset.toString());\n// return url.href;\n// };\n\n// if (!IS_SEARCH_PAGE) {\n// paginationOffset = parseInt(url.pathname.match(/\\d+$/)?.[0] || \"1\");\n// if (url.pathname === '/') url.pathname = '/1';\n// paginationUrlGenerator = (offset: number) => {\n// if (/\\d+$/.test(url.pathname)) {\n// url.pathname = url.pathname.replace(/\\d+$/, offset.toString());\n// } else {\n// url.pathname = `${url.pathname}/${offset}`;\n// }\n// return url.href;\n// };\n// }\n\n// return { paginationOffset, paginationUrlGenerator };\n// },\n// router: () => {},\n// });\n\n\n\n// const __NHENTAI_RULES = new RulesHelper({\n// IS_VIDEO_PAGE: /^\\/g\\/\\d+/.test(location.pathname),\n// IS_SEARCH_PAGE: /^\\/search\\//,\n// THUMB_URL: \".cover\",\n// GET_THUMBS: \".gallery\",\n// THUMB_DATA: { title: \".caption\" },\n// THUMB_IMG_DATA: thumb => {\n// const img = thumb.querySelector(\".cover img\")\n// let imgSrc = img.getAttribute(\"data-src\") || img.getAttribute(\"src\") || \"\"\n// if (!/^\\/g\\/\\d+/.test(location.pathname))\n// imgSrc = imgSrc?.replace(\"t5\", \"t3\")\n// img.classList.remove(\"lazyload\")\n// if (\n// img.complete &&\n// img.getAttribute(\"src\") &&\n// !img.src.includes(\"data:image\")\n// ) {\n// return {}\n// }\n// return { img, imgSrc }\n// },\n// paginationUrlGenerator: { searchPage: \"page\" },\n// paginationElement: \".pagination\",\n// paginationOffset:\n// parseInt(new URL(location.href).searchParams.get(\"page\")) || 1,\n// paginationLast: parseInt(\n// document.querySelector(\".pagination .last\")?.href.match(/\\d+/)?.[0] || \"1\"\n// ),\n// CONTAINER: \".index-container, .container\",\n// router: () => {}\n// }}\n// "],"names":["s","target","observer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"billy-herrington-utils.es.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts","../src/data-manager/index.ts","../src/utils/infinite-scroll/index.ts","../src/utils/jabroni-outfit-wrap/index.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\n}\n\nexport function sanitizeStr(s: string) {\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\n}\n","export function formatTimeToHHMMSS(timeString: string): string {\n const regex: RegExp = /(?:(\\d+)\\s*h\\s*)?(?:(\\d+)\\s*mi?n?\\s*)?(?:(\\d+)\\s*sec)?/;\n const match: RegExpMatchArray | null = timeString.match(regex);\n const h: number = parseInt(match?.[1] || '0');\n const m: number = parseInt(match?.[2] || '0');\n const s: number = parseInt(match?.[3] || '0');\n const pad = (num: number): string => String(num).padStart(2, '0');\n return `${pad(h)}:${pad(m)}:${pad(s)}`;\n}\n\n// \"01:22:03\" -> 4923\nexport function timeToSeconds(t: string): number {\n const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;\n return (r?.match(/\\d+/gm) || [0])\n .reverse()\n .map((s, i) => parseInt(s as string) * 60 ** i)\n .reduce((a, b) => a + b);\n}\n\nexport function parseIntegerOr(n: string | number, or: number): number {\n return (num => Number.isNaN(num) ? or : num)(parseInt(n as string));\n}\n\n// \"data:02;body+head:async;void:;zero:;\"\nexport function parseDataParams(str: string): Record<string, string> {\n const paramsStr = decodeURI(str.trim()).split(';');\n return paramsStr.reduce((acc, s) => {\n const parsed = s.match(/([\\+\\w]+):([\\w\\-\\ ]+)?/);\n if (parsed) {\n const [, key, value] = parsed;\n if (value) {\n key.split('+').forEach(p => { acc[p] = value; });\n }\n }\n return acc;\n }, {} as Record<string, string>);\n}\n\nexport function parseCSSUrl(s: string) {\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\n}\n","export class Observer {\n public observer: IntersectionObserver;\n constructor(private callback: (entry: Element) => void) {\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\n }\n\n observe(target: Element) {\n this.observer.observe(target);\n }\n\n throttle(target: Element, throttleTime: number) {\n this.observer.unobserve(target);\n setTimeout(() => this.observer.observe(target), throttleTime);\n }\n\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n this.callback(entry.target);\n }\n }\n }\n\n static observeWhile(\n target: Element,\n callback: () => Promise<boolean> | boolean,\n throttleTime: number,\n ) {\n const observer_ = new Observer(async (target: Element) => {\n const condition = await callback();\n if (condition) observer_.throttle(target, throttleTime);\n });\n observer_.observe(target);\n return observer_;\n }\n}\n\nexport class LazyImgLoader {\n public lazyImgObserver: Observer;\n private attributeName = 'data-lazy-load';\n\n constructor(shouldDelazify: (target: Element) => boolean) {\n this.lazyImgObserver = new Observer((target: Element) => {\n if (shouldDelazify(target)) {\n this.delazify(target as HTMLImageElement);\n }\n });\n }\n\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\n if (!img || !imgSrc) return;\n img.setAttribute(this.attributeName, imgSrc);\n img.src = '';\n this.lazyImgObserver.observe(img);\n }\n\n delazify = (target: HTMLImageElement) => {\n this.lazyImgObserver.observer.unobserve(target);\n target.src = target.getAttribute(this.attributeName) as string;\n target.removeAttribute(this.attributeName);\n };\n}\n","export function circularShift(n: number, c = 6, s = 1): number {\n return (n + s) % c || c;\n}\n","export function parseDom(html: string): HTMLElement {\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\n}\n\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\n for (const attr of source.attributes) {\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\n }\n}\n\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\n const newTagElement = document.createElement(tagName);\n copyAttributes(newTagElement, e);\n newTagElement.innerHTML = e.innerHTML;\n e.parentNode?.replaceChild(newTagElement, e);\n return newTagElement;\n}\n\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\n return Array.from(elements).reduce((acc, v) => {\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\n return acc;\n }, [] as Array<HTMLElement | Element>);\n}\n\nexport function findNextSibling(el: HTMLElement | Element) {\n if (el.nextElementSibling) return el.nextElementSibling;\n if (el.parentElement) return findNextSibling(el.parentElement);\n return null;\n}\n\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void {\n const observer = new MutationObserver((_mutations) => {\n const el = parent.querySelector(selector);\n if (el) {\n observer.disconnect();\n callback(el);\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n}\n\nexport function watchElementChildrenCount(element: HTMLElement | Element,\n callback: (observer: MutationObserver, count: number) => void): void {\n let count = element.children.length;\n const observer = new MutationObserver((mutationList, observer) => {\n for (const mutation of mutationList) {\n if (mutation.type === \"childList\") {\n if (count !== element.children.length) {\n count = element.children.length;\n callback(observer, count);\n }\n }\n }\n });\n observer.observe(element, { childList: true });\n}\n\nexport function watchDomChangesWithThrottle(\n element: HTMLElement | Element, \n callback: () => void,\n throttle = 1000,\n times = Infinity,\n options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }\n) {\n let lastMutationTime: number;\n let timeout: number;\n let times_ = times;\n const observer = new MutationObserver((_mutationList, _observer) => {\n if (times_ !== Infinity && times_ < 1) {\n observer.disconnect();\n return;\n }\n times_--;\n const now = Date.now();\n if (lastMutationTime && now - lastMutationTime < throttle) {\n timeout && clearTimeout(timeout);\n }\n timeout = setTimeout(callback, throttle);\n lastMutationTime = now;\n });\n observer.observe(element, options);\n return observer;\n}\n\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\n const btn = parseDom(options.button);\n\n if (options.append) document.querySelector(options.append)?.append(btn);\n if (options.after) document.querySelector(options.after)?.after(btn);\n\n btn.addEventListener('click', (e) => {\n e.preventDefault();\n\n if (options.cbBefore) options.cbBefore();\n\n waitForElementExists(document.body, 'video', (video: Element) => {\n window.location.href = video.getAttribute('src') as string;\n });\n });\n}\n\nexport function exterminateVideo(video: HTMLVideoElement) {\n video.removeAttribute('src');\n video.load();\n video.remove();\n}","import { parseDom } from '../dom';\n\nexport const MOBILE_UA = [\n 'Mozilla/5.0 (Linux; Android 10; K)',\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\n 'Chrome/114.0.0.0 Mobile Safari/537.36',\n].join(' ');\n\nexport function fetchWith(\n url: string,\n options: Record<string, boolean> = { html: false, mobile: false },\n) {\n const reqOpts = {};\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ 'User-Agent': MOBILE_UA }) });\n return fetch(url, reqOpts)\n .then((r) => r.text())\n .then((r) => (options.html ? parseDom(r) : r));\n}\n\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true }) as Promise<HTMLElement>;\n\nexport const fetchText = (url: string) => fetchWith(url) as Promise<string>;\n\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\n const formData = new FormData();\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\n return formData;\n}\n","export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void {\n for (const e of events) {\n dom.addEventListener(e, callback, true);\n }\n}\n\nexport class Tick {\n private tick?: number;\n private callbackFinal?: () => void;\n\n constructor(private delay: number, private startImmediate: boolean = true) {}\n\n public start(callback: () => void, callbackFinal?: () => void): void {\n this.stop();\n this.callbackFinal = callbackFinal;\n if (this.startImmediate) callback();\n this.tick = window.setInterval(callback, this.delay);\n }\n\n public stop(): void {\n if (this.tick !== undefined) {\n clearInterval(this.tick);\n this.tick = undefined;\n }\n if (this.callbackFinal) {\n this.callbackFinal();\n this.callbackFinal = undefined;\n }\n }\n}\n","export function isMob() {\n return /iPhone|Android/i.test(navigator.userAgent);\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\nexport async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>) {\n const res = [];\n for await (const f of iterable) {\n res.push(await f());\n }\n return res;\n}\n\nexport function wait(milliseconds: number) {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\ninterface AsyncPoolTask {\n v: () => Promise<void>;\n p: number;\n}\n\nexport class AsyncPool {\n private cur = 0;\n private finished: Promise<boolean>;\n private _resolve?: (value: boolean | PromiseLike<boolean>) => void;\n\n public static async doNAsyncAtOnce(max = 1, pool: Array<AsyncPoolTask | (() => Promise<void>)> = []) {\n const spool = new AsyncPool(max);\n pool.forEach(f => spool.push(f));\n return spool.run();\n }\n\n constructor(private max = 1, private pool: Array<AsyncPoolTask> = []) {\n this.finished = new Promise((resolve) => {\n this._resolve = resolve;\n });\n }\n\n private getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\n if (p > 3 || this.pool.length === 0) return undefined;\n const i = this.pool.findIndex((e) => e.p === p);\n if (i >= 0) {\n const res = this.pool[i].v;\n this.pool.splice(i, 1);\n return res;\n }\n return this.getHighPriorityFirst(p + 1);\n }\n\n private async runTask() {\n this.cur++;\n const f = this.getHighPriorityFirst();\n await f?.();\n this.cur--;\n this.runTasks();\n }\n\n private runTasks() {\n if (!this.pool.length) {\n this._resolve?.(true);\n return;\n }\n if (this.cur < this.max) {\n this.runTask();\n this.runTasks();\n }\n }\n\n public async run() {\n this.runTasks();\n return this.finished;\n }\n\n public push(x: AsyncPoolTask | (() => Promise<void>)) {\n this.pool.push('p' in x ? x : { v: x, p: 0 });\n }\n}\n\n","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\n return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));\n}\n\nexport function range(size: number, startAt: number = 1, step: number = 1): number[] {\n return Array.from({ length: size }, (_, index) => startAt + index * step);\n}\n","import { LazyImgLoader } from '../utils/observers';\nimport { stringToWords } from '../utils/strings';\n\ninterface DataFilterState {\n filterPublic: boolean;\n filterPrivate: boolean;\n filterHD: boolean;\n filterDuration: boolean;\n filterDurationFrom: number;\n filterDurationTo: number;\n filterExclude: boolean;\n filterExcludeWords: string;\n filterInclude: boolean;\n filterIncludeWords: string;\n}\n\ninterface FilterResult {\n tag: string;\n condition: boolean;\n}\n\ntype FilterInput = Record<string, string | number | boolean | HTMLElement>;\ntype FilterFunction = (v: FilterInput) => FilterResult;\n\nclass DataFilter {\n public filters: { [key: string]: () => FilterFunction };\n\n constructor(private rules: IRules, private state: DataFilterState) {\n this.state = state;\n\n const methods = Object.getOwnPropertyNames(this);\n this.filters = methods.reduce((acc: { [key: string]: () => FilterFunction }, k) => {\n if (k in this.state) {\n acc[k] = this[k as keyof DataFilter] as unknown as () => FilterFunction;\n //@ts-ignore\n GM_addStyle(`.filter-${k.toLowerCase().slice(6)} { display: none !important; }`);\n }\n return acc;\n }, {});\n }\n\n filterPublic = (): FilterFunction => {\n return (v: FilterInput) => {\n const isPublic = !this.rules.isPrivate(v.element as HTMLElement);\n return {\n tag: 'filter-public',\n condition: this.state.filterPublic && isPublic,\n };\n };\n };\n\n filterPrivate = (): FilterFunction => {\n return (v: FilterInput) => {\n const isPrivate = this.rules.isPrivate(v.element as HTMLElement);\n return {\n tag: 'filter-private',\n condition: this.state.filterPrivate && isPrivate,\n };\n };\n };\n\n filterHD = (): FilterFunction => {\n return (v: FilterInput) => {\n const isHD = this.rules.isHD(v.element as HTMLElement);\n return {\n tag: 'filter-hd',\n condition: this.state.filterHD && isHD,\n };\n };\n };\n\n filterDuration = (): FilterFunction => {\n return (v: FilterInput) => {\n const notInRange =\n (v.duration as number) < this.state.filterDurationFrom ||\n (v.duration as number) > this.state.filterDurationTo;\n return {\n tag: 'filter-duration',\n condition: this.state.filterDuration && notInRange,\n };\n };\n };\n\n filterExclude = (): FilterFunction => {\n const tags = DataManager.filterDSLToRegex(this.state.filterExcludeWords);\n return (v: FilterInput) => {\n const containTags = tags.some((tag) => tag.test(v.title as string));\n return {\n tag: 'filter-exclude',\n condition: this.state.filterExclude && containTags,\n };\n };\n };\n\n filterInclude = (): FilterFunction => {\n const tags = DataManager.filterDSLToRegex(this.state.filterIncludeWords);\n return (v: FilterInput) => {\n const containTagsNot = tags.some((tag) => !tag.test(v.title as string));\n return {\n tag: 'filter-include',\n condition: this.state.filterInclude && containTagsNot,\n };\n };\n };\n}\n\ninterface IRules {\n getThumbs: (html: HTMLElement) => HTMLElement[];\n getThumbUrl: (thumbElement: HTMLElement) => string;\n getThumbData: (thumbElement: HTMLElement) => { title: string; duration: number };\n getThumbImgData: (thumbElement: HTMLElement) => { img: HTMLElement; imgSrc: string };\n container: HTMLElement;\n isPrivate: (element: HTMLElement) => boolean;\n isHD: (element: HTMLElement) => boolean;\n}\n\nexport class DataManager {\n private rules: IRules;\n private state: DataFilterState;\n private data: Map<string, FilterInput>;\n private lazyImgLoader: LazyImgLoader;\n public dataFilters: { [key: string]: () => FilterFunction };\n\n constructor(rules: IRules, state: DataFilterState) {\n this.rules = rules;\n this.state = state;\n this.data = new Map();\n this.lazyImgLoader = new LazyImgLoader(\n (target: Element) => !this.isFiltered(target as HTMLElement),\n );\n this.dataFilters = new DataFilter(rules, state).filters;\n\n // @ts-ignore\n [window, unsafeWindow || ({})].forEach(w => {\n Object.assign(w, {\n sortByViews: () => this.sort('view'),\n sortByDuration: () => this.sort('duration'),\n });\n });\n }\n\n static filterDSLToRegex(str: string): RegExp[] {\n const toFullWord = (w: string) => `(^|\\\\ )${w}($|\\\\ )`;\n const str_ = str.replace(/f\\:(\\w+)/g, (_, w) => toFullWord(w));\n return stringToWords(str_).map((expr: string) => new RegExp(expr, 'i'));\n }\n\n isFiltered(el: HTMLElement): boolean {\n return el.className.includes('filtered');\n }\n\n applyFilters = (filters: { [key: string]: boolean }, offset = 0): void => {\n const filtersToApply = Object.keys(filters)\n .filter((k) => Object.hasOwn(this.dataFilters, k))\n .map((k) => this.dataFilters[k]());\n\n if (filtersToApply.length === 0) return;\n\n const updates: (() => void)[] = [];\n let offset_counter = 1;\n for (const v of this.data.values()) {\n if (++offset_counter > offset) {\n for (const f of filtersToApply) {\n const { tag, condition } = f(v as FilterInput);\n updates.push(() => (v.element as HTMLElement).classList.toggle(tag, condition));\n }\n }\n }\n\n requestAnimationFrame(() => {\n updates.forEach((update) => update());\n });\n };\n\n filterAll = (offset?: number): void => {\n const filters = Object.assign(\n {},\n ...Object.keys(this.dataFilters).map((f) => ({\n [f]: this.state[f as keyof DataFilterState],\n })),\n );\n this.applyFilters(filters, offset);\n };\n\n parseData = (\n html: HTMLElement,\n container?: HTMLElement,\n removeDuplicates = false,\n shouldLazify = true,\n ): void => {\n const thumbs = this.rules.getThumbs(html);\n const data_offset = this.data.size;\n\n for (const thumbElement of thumbs) {\n const url = this.rules.getThumbUrl(thumbElement);\n if (!url || this.data.has(url)) {\n if (removeDuplicates) thumbElement.remove();\n continue;\n }\n\n const data = this.rules.getThumbData(thumbElement);\n this.data.set(url, { element: thumbElement, ...data });\n\n if (shouldLazify) {\n const { img, imgSrc } = this.rules.getThumbImgData(thumbElement);\n this.lazyImgLoader.lazify(thumbElement, img as HTMLImageElement, imgSrc);\n }\n\n const parent = container || this.rules.container;\n if (!parent.contains(thumbElement)) parent.appendChild(thumbElement);\n }\n\n this.filterAll(data_offset);\n };\n\n sort(propName: string) {\n if (this.data.size < 2) return;\n\n const sorted = Array.from(this.data.keys()).sort((b, a) => {\n return ((this.data.get(a) as FilterInput)[propName] as number) -\n ((this.data.get(b) as FilterInput)[propName] as number);\n });\n\n const container = ((this.data.get(sorted[0]) as FilterInput).element as HTMLElement).parentElement as HTMLElement;\n\n sorted.forEach(s => {\n const e = (this.data.get(s) as FilterInput).element as HTMLElement;\n container.append(e);\n });\n }\n}\n","import { fetchHtml } from '../fetch';\nimport { Observer } from '../observers';\n\ninterface IInfiniteScroller {\n delay: number;\n enabled: boolean;\n writeHistory?: boolean;\n paginationOffset: number;\n paginationLast: number;\n paginationElement: HTMLElement;\n paginationUrlGenerator: (offset: number) => string;\n handleHtmlCallback: (document: HTMLElement) => void;\n intersectionObservable?: HTMLElement;\n alternativeGenerator?: () => OffsetGenerator;\n}\n\ninterface GeneratorResult {\n url: string;\n offset: number;\n}\n\ntype OffsetGenerator = Generator<GeneratorResult> | AsyncGenerator<GeneratorResult>;\n\nexport class InfiniteScroller {\n public paginationGenerator: OffsetGenerator;\n public enabled: boolean;\n public delay: number;\n public paginationOffset: number;\n public paginationLast: number;\n public writeHistory: boolean;\n private handleHtmlCallback: (document: HTMLElement) => void;\n\n constructor({\n enabled = true,\n delay = 350,\n writeHistory = false,\n paginationOffset,\n paginationLast,\n paginationElement,\n paginationUrlGenerator,\n handleHtmlCallback,\n alternativeGenerator,\n intersectionObservable,\n }: IInfiniteScroller) {\n this.enabled = enabled;\n this.delay = delay;\n this.writeHistory = writeHistory;\n this.paginationOffset = paginationOffset;\n this.paginationLast = paginationLast;\n this.handleHtmlCallback = handleHtmlCallback;\n\n this.paginationGenerator =\n alternativeGenerator?.() ??\n InfiniteScroller.createPaginationGenerator(\n paginationOffset,\n paginationLast,\n paginationUrlGenerator,\n );\n\n const observable = intersectionObservable || paginationElement;\n Observer.observeWhile(observable, this.generatorConsumer, this.delay);\n }\n\n private onScrollCBs: Array<(scroller: InfiniteScroller) => void> = [];\n\n public onScroll(callback: (scroller: InfiniteScroller) => void, initCall = false) {\n if (initCall) callback(this);\n this.onScrollCBs.push(callback);\n return this;\n }\n\n private _onScroll() {\n this.onScrollCBs.forEach((cb) => cb(this));\n }\n\n generatorConsumer = async () => {\n if (!this.enabled) return false;\n const {\n value: { url, offset } = {},\n done,\n } = await this.paginationGenerator.next();\n if (!done) {\n const nextPageHTML = await fetchHtml(url);\n const prevScrollPos = document.documentElement.scrollTop;\n this.paginationOffset = offset;\n this.handleHtmlCallback(nextPageHTML);\n this._onScroll();\n window.scrollTo(0, prevScrollPos);\n if (this.writeHistory) {\n history.replaceState({}, '', url);\n }\n }\n return !done;\n };\n\n static *createPaginationGenerator(\n currentPage: number,\n totalPages: number,\n generateURL: (offset: number) => string,\n ): OffsetGenerator {\n for (let offset = currentPage + 1; offset <= totalPages; offset++) {\n const url = generateURL(offset);\n yield { url, offset };\n }\n }\n}\n","import { InfiniteScroller } from '../infinite-scroll';\nimport { PaginationStrategy } from '../userscript-utils/pagination-strategies';\n\ninterface IRules {\n paginationStrategy: PaginationStrategy,\n delay: number, \n paginationOffset: number, \n paginationLast: number, \n paginationElement: HTMLElement,\n paginationUrlGenerator: (n: number) => string;\n}\n\nexport interface JabroniStore {\n state: Record<string, boolean | string | number>;\n localState: Record<string, boolean | string | number>;\n subscribe: (callback: () => void) => void;\n}\n\nexport function createInfiniteScroller(\n store: JabroniStore,\n handleHtmlCallback: (document: HTMLElement) => void,\n rules: IRules,\n) {\n const enabled = store.state.infiniteScrollEnabled as boolean;\n \n rules.paginationOffset = rules.paginationStrategy.getPaginationOffset();\n rules.paginationLast = rules.paginationStrategy.getPaginationLast();\n rules.paginationUrlGenerator = rules.paginationStrategy.getPaginationUrlGenerator();\n rules.paginationElement = rules.paginationStrategy.getPaginationElement();\n\n const iscroller = new InfiniteScroller({\n enabled,\n handleHtmlCallback,\n ...rules,\n }).onScroll(({ paginationLast, paginationOffset }) => {\n store.localState.pagIndexLast = paginationLast;\n store.localState.pagIndexCur = paginationOffset;\n }, true);\n\n store.subscribe(() => {\n iscroller.enabled = store.state.infiniteScrollEnabled as boolean;\n });\n\n return iscroller;\n}\n"],"names":["s","target","observer"],"mappings":"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"}
|
|
@@ -28,8 +28,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
28
28
|
return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
|
|
29
29
|
}
|
|
30
30
|
function parseDataParams(str) {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const paramsStr = decodeURI(str.trim()).split(";");
|
|
32
|
+
return paramsStr.reduce((acc, s) => {
|
|
33
|
+
const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
|
|
33
34
|
if (parsed) {
|
|
34
35
|
const [, key, value] = parsed;
|
|
35
36
|
if (value) {
|
|
@@ -307,12 +308,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
307
308
|
}
|
|
308
309
|
class DataFilter {
|
|
309
310
|
constructor(rules, state) {
|
|
310
|
-
__publicField(this, "state");
|
|
311
|
-
__publicField(this, "rules");
|
|
312
311
|
__publicField(this, "filters");
|
|
313
312
|
__publicField(this, "filterPublic", () => {
|
|
314
313
|
return (v) => {
|
|
315
|
-
const isPublic = !this.rules.
|
|
314
|
+
const isPublic = !this.rules.isPrivate(v.element);
|
|
316
315
|
return {
|
|
317
316
|
tag: "filter-public",
|
|
318
317
|
condition: this.state.filterPublic && isPublic
|
|
@@ -321,7 +320,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
321
320
|
});
|
|
322
321
|
__publicField(this, "filterPrivate", () => {
|
|
323
322
|
return (v) => {
|
|
324
|
-
const isPrivate = this.rules.
|
|
323
|
+
const isPrivate = this.rules.isPrivate(v.element);
|
|
325
324
|
return {
|
|
326
325
|
tag: "filter-private",
|
|
327
326
|
condition: this.state.filterPrivate && isPrivate
|
|
@@ -330,7 +329,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
330
329
|
});
|
|
331
330
|
__publicField(this, "filterHD", () => {
|
|
332
331
|
return (v) => {
|
|
333
|
-
const isHD = this.rules.
|
|
332
|
+
const isHD = this.rules.isHD(v.element);
|
|
334
333
|
return {
|
|
335
334
|
tag: "filter-hd",
|
|
336
335
|
condition: this.state.filterHD && isHD
|
|
@@ -366,8 +365,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
366
365
|
};
|
|
367
366
|
};
|
|
368
367
|
});
|
|
369
|
-
this.state = state;
|
|
370
368
|
this.rules = rules;
|
|
369
|
+
this.state = state;
|
|
370
|
+
this.state = state;
|
|
371
371
|
const methods = Object.getOwnPropertyNames(this);
|
|
372
372
|
this.filters = methods.reduce((acc, k) => {
|
|
373
373
|
if (k in this.state) {
|
|
@@ -412,21 +412,21 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
412
412
|
this.applyFilters(filters, offset);
|
|
413
413
|
});
|
|
414
414
|
__publicField(this, "parseData", (html, container, removeDuplicates = false, shouldLazify = true) => {
|
|
415
|
-
const thumbs = this.rules.
|
|
415
|
+
const thumbs = this.rules.getThumbs(html);
|
|
416
416
|
const data_offset = this.data.size;
|
|
417
417
|
for (const thumbElement of thumbs) {
|
|
418
|
-
const url = this.rules.
|
|
418
|
+
const url = this.rules.getThumbUrl(thumbElement);
|
|
419
419
|
if (!url || this.data.has(url)) {
|
|
420
420
|
if (removeDuplicates) thumbElement.remove();
|
|
421
421
|
continue;
|
|
422
422
|
}
|
|
423
|
-
const data = this.rules.
|
|
423
|
+
const data = this.rules.getThumbData(thumbElement);
|
|
424
424
|
this.data.set(url, { element: thumbElement, ...data });
|
|
425
425
|
if (shouldLazify) {
|
|
426
|
-
const { img, imgSrc } = this.rules.
|
|
426
|
+
const { img, imgSrc } = this.rules.getThumbImgData(thumbElement);
|
|
427
427
|
this.lazyImgLoader.lazify(thumbElement, img, imgSrc);
|
|
428
428
|
}
|
|
429
|
-
const parent = container || this.rules.
|
|
429
|
+
const parent = container || this.rules.container;
|
|
430
430
|
if (!parent.contains(thumbElement)) parent.appendChild(thumbElement);
|
|
431
431
|
}
|
|
432
432
|
this.filterAll(data_offset);
|
|
@@ -536,6 +536,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
536
536
|
}
|
|
537
537
|
function createInfiniteScroller(store, handleHtmlCallback, rules) {
|
|
538
538
|
const enabled = store.state.infiniteScrollEnabled;
|
|
539
|
+
rules.paginationOffset = rules.paginationStrategy.getPaginationOffset();
|
|
540
|
+
rules.paginationLast = rules.paginationStrategy.getPaginationLast();
|
|
541
|
+
rules.paginationUrlGenerator = rules.paginationStrategy.getPaginationUrlGenerator();
|
|
542
|
+
rules.paginationElement = rules.paginationStrategy.getPaginationElement();
|
|
539
543
|
const iscroller = new InfiniteScroller({
|
|
540
544
|
enabled,
|
|
541
545
|
handleHtmlCallback,
|
|
@@ -549,126 +553,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
549
553
|
});
|
|
550
554
|
return iscroller;
|
|
551
555
|
}
|
|
552
|
-
class RulesHelper {
|
|
553
|
-
constructor(options) {
|
|
554
|
-
__publicField(this, "delay", 250);
|
|
555
|
-
__publicField(this, "IS_VIDEO_PAGE");
|
|
556
|
-
__publicField(this, "IS_SEARCH_PAGE");
|
|
557
|
-
__publicField(this, "paginationElement");
|
|
558
|
-
__publicField(this, "paginationOffset");
|
|
559
|
-
__publicField(this, "paginationLast");
|
|
560
|
-
__publicField(this, "URL_DATA");
|
|
561
|
-
__publicField(this, "paginationUrlGenerator", (offset) => {
|
|
562
|
-
const opt = this.options.paginationUrlGenerator;
|
|
563
|
-
if (typeof opt === "function") return opt(offset);
|
|
564
|
-
const url = new URL(location.href);
|
|
565
|
-
if (opt.searchPage) {
|
|
566
|
-
url.searchParams.set(opt.searchPage, offset.toString());
|
|
567
|
-
return url.href;
|
|
568
|
-
}
|
|
569
|
-
if (opt.pathnameLast) {
|
|
570
|
-
if (url.pathname === "/") url.pathname = "/1";
|
|
571
|
-
if (/\d+$/.test(url.pathname)) {
|
|
572
|
-
url.pathname = url.pathname.replace(/\d+$/, offset.toString());
|
|
573
|
-
} else {
|
|
574
|
-
url.pathname = `${url.pathname}/${offset}`;
|
|
575
|
-
}
|
|
576
|
-
return url.href;
|
|
577
|
-
}
|
|
578
|
-
return url.href;
|
|
579
|
-
});
|
|
580
|
-
__publicField(this, "_IS_VIDEO_PAGE", () => {
|
|
581
|
-
if (typeof this.options.IS_VIDEO_PAGE === "boolean") {
|
|
582
|
-
return this.options.IS_VIDEO_PAGE;
|
|
583
|
-
}
|
|
584
|
-
return this.options.IS_VIDEO_PAGE.test(location.pathname);
|
|
585
|
-
});
|
|
586
|
-
__publicField(this, "_IS_SEARCH_PAGE", () => {
|
|
587
|
-
if (typeof this.options.IS_SEARCH_PAGE === "boolean") {
|
|
588
|
-
return this.options.IS_SEARCH_PAGE;
|
|
589
|
-
}
|
|
590
|
-
return this.options.IS_SEARCH_PAGE.test(location.pathname);
|
|
591
|
-
});
|
|
592
|
-
__publicField(this, "_paginationElement", (html = document) => {
|
|
593
|
-
if (typeof this.options.paginationElement === "function") {
|
|
594
|
-
return this.options.paginationElement(html);
|
|
595
|
-
}
|
|
596
|
-
return [...html.querySelectorAll(this.options.paginationElement)].pop();
|
|
597
|
-
});
|
|
598
|
-
__publicField(this, "CONTAINER", (html = document) => {
|
|
599
|
-
if (typeof this.options.CONTAINER === "function") {
|
|
600
|
-
return this.options.CONTAINER(html);
|
|
601
|
-
}
|
|
602
|
-
return [...html.querySelectorAll(this.options.CONTAINER)].pop();
|
|
603
|
-
});
|
|
604
|
-
__publicField(this, "THUMB_URL", (thumb) => {
|
|
605
|
-
if (typeof this.options.THUMB_URL === "string") {
|
|
606
|
-
return thumb.querySelector(this.options.THUMB_URL).href || "";
|
|
607
|
-
}
|
|
608
|
-
return this.options.THUMB_URL(thumb);
|
|
609
|
-
});
|
|
610
|
-
__publicField(this, "GET_THUMBS", (html) => {
|
|
611
|
-
if (typeof this.options.GET_THUMBS === "string") {
|
|
612
|
-
return [...html.querySelectorAll(this.options.GET_THUMBS)];
|
|
613
|
-
}
|
|
614
|
-
return this.options.GET_THUMBS(html);
|
|
615
|
-
});
|
|
616
|
-
__publicField(this, "THUMB_DATA", (thumb) => {
|
|
617
|
-
const opt = this.options.THUMB_DATA;
|
|
618
|
-
if (typeof opt === "function") return opt(thumb);
|
|
619
|
-
let title = sanitizeStr(thumb.querySelector(opt.title)?.innerText || "");
|
|
620
|
-
if (opt.uploader) {
|
|
621
|
-
const uploader = sanitizeStr(
|
|
622
|
-
thumb.querySelector(opt.title)?.innerText || ""
|
|
623
|
-
);
|
|
624
|
-
title = `${title} user:${uploader}`;
|
|
625
|
-
}
|
|
626
|
-
const duration = !opt.duration ? 0 : timeToSeconds(
|
|
627
|
-
sanitizeStr(thumb.querySelector(opt.duration)?.innerText || "")
|
|
628
|
-
);
|
|
629
|
-
return { title, duration };
|
|
630
|
-
});
|
|
631
|
-
__publicField(this, "THUMB_IMG_DATA", (thumb) => {
|
|
632
|
-
const opt = this.options.THUMB_IMG_DATA;
|
|
633
|
-
if (typeof opt === "function") return opt(thumb);
|
|
634
|
-
const result = {};
|
|
635
|
-
if (opt.img) {
|
|
636
|
-
const img = thumb.querySelector(opt.img);
|
|
637
|
-
const imgSrc = img.getAttribute(opt.imgSrc || "data-src") || img.getAttribute("src");
|
|
638
|
-
if (opt.lazyloading) {
|
|
639
|
-
img.classList.remove(opt.lazyloading);
|
|
640
|
-
}
|
|
641
|
-
Object.assign(result, { img, imgSrc });
|
|
642
|
-
if (img.complete && img.getAttribute("src") && !img.src.includes("data:image")) {
|
|
643
|
-
return {};
|
|
644
|
-
}
|
|
645
|
-
} else return {};
|
|
646
|
-
});
|
|
647
|
-
this.options = options;
|
|
648
|
-
this.delay = options?.delay || this.delay;
|
|
649
|
-
this.paginationOffset = this.options.paginationOffset;
|
|
650
|
-
this.paginationLast = this.options.paginationLast;
|
|
651
|
-
this.IS_VIDEO_PAGE = this._IS_VIDEO_PAGE();
|
|
652
|
-
this.IS_SEARCH_PAGE = this._IS_SEARCH_PAGE();
|
|
653
|
-
this.paginationElement = this._paginationElement();
|
|
654
|
-
if (options.URL_DATA) {
|
|
655
|
-
this.URL_DATA = options.URL_DATA;
|
|
656
|
-
Object.assign(this, this.URL_DATA());
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
router(store, handleHtmlCallback) {
|
|
660
|
-
if (!this.options.router) return;
|
|
661
|
-
const scroller = createInfiniteScroller(store, handleHtmlCallback, this);
|
|
662
|
-
this.options.router(this, store, handleHtmlCallback, scroller);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
556
|
exports2.AsyncPool = AsyncPool;
|
|
666
557
|
exports2.DataManager = DataManager;
|
|
667
558
|
exports2.InfiniteScroller = InfiniteScroller;
|
|
668
559
|
exports2.LazyImgLoader = LazyImgLoader;
|
|
669
560
|
exports2.MOBILE_UA = MOBILE_UA;
|
|
670
561
|
exports2.Observer = Observer;
|
|
671
|
-
exports2.RulesHelper = RulesHelper;
|
|
672
562
|
exports2.Tick = Tick;
|
|
673
563
|
exports2.chunks = chunks;
|
|
674
564
|
exports2.circularShift = circularShift;
|