billy-herrington-utils 1.4.4 → 1.4.5

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.
@@ -1,46 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- function stringToWords(s) {
5
- return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
6
- }
7
- function sanitizeStr(s) {
8
- return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
9
- }
10
- function formatTimeToHHMMSS(timeString) {
11
- const regex = /(?:(\d+)\s*h\s*)?(?:(\d+)\s*mi?n?\s*)?(?:(\d+)\s*sec)?/;
12
- const match = timeString.match(regex);
13
- const h = parseInt(match?.[1] || "0");
14
- const m = parseInt(match?.[2] || "0");
15
- const s = parseInt(match?.[3] || "0");
16
- const pad = (num) => String(num).padStart(2, "0");
17
- return `${pad(h)}:${pad(m)}:${pad(s)}`;
18
- }
19
- function timeToSeconds(t) {
20
- const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;
21
- return (r?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
22
- }
23
- function parseIntegerOr(n, or) {
24
- return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
25
- }
26
- function parseDataParams(str) {
27
- const paramsStr = decodeURI(str.trim()).split(";");
28
- return paramsStr.reduce((acc, s) => {
29
- const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
30
- if (parsed) {
31
- const [, key, value] = parsed;
32
- if (value) {
33
- key.split("+").forEach((p) => {
34
- acc[p] = value;
35
- });
36
- }
37
- }
38
- return acc;
39
- }, {});
40
- }
41
- function parseCSSUrl(s) {
42
- return s.replace(/url\("|\"\).*/g, "");
43
- }
44
4
  class Observer {
45
5
  constructor(callback) {
46
6
  __publicField(this, "observer");
@@ -92,215 +52,11 @@ class LazyImgLoader {
92
52
  this.lazyImgObserver.observe(img);
93
53
  }
94
54
  }
95
- function circularShift(n, c = 6, s = 1) {
96
- return (n + s) % c || c;
97
- }
98
- function parseDom(html) {
99
- const parsed = new DOMParser().parseFromString(html, "text/html").body;
100
- return parsed.children.length > 1 ? parsed : parsed.firstElementChild;
101
- }
102
- function copyAttributes(target, source) {
103
- for (const attr of source.attributes) {
104
- attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);
105
- }
106
- }
107
- function replaceElementTag(e, tagName) {
108
- const newTagElement = document.createElement(tagName);
109
- copyAttributes(newTagElement, e);
110
- newTagElement.innerHTML = e.innerHTML;
111
- e.parentNode?.replaceChild(newTagElement, e);
112
- return newTagElement;
113
- }
114
- function getAllUniqueParents(elements) {
115
- return Array.from(elements).reduce((acc, v) => {
116
- if (v.parentElement && !acc.includes(v.parentElement)) {
117
- acc.push(v.parentElement);
118
- }
119
- return acc;
120
- }, []);
121
- }
122
- function findNextSibling(el) {
123
- if (el.nextElementSibling) return el.nextElementSibling;
124
- if (el.parentElement) return findNextSibling(el.parentElement);
125
- return null;
126
- }
127
- function waitForElementExists(parent, selector, callback) {
128
- const observer = new MutationObserver((_mutations) => {
129
- const el = parent.querySelector(selector);
130
- if (el) {
131
- observer.disconnect();
132
- callback(el);
133
- }
134
- });
135
- observer.observe(document.body, { childList: true, subtree: true });
136
- }
137
- function watchElementChildrenCount(element, callback) {
138
- let count = element.children.length;
139
- const observer = new MutationObserver((mutationList, observer2) => {
140
- for (const mutation of mutationList) {
141
- if (mutation.type === "childList") {
142
- if (count !== element.children.length) {
143
- count = element.children.length;
144
- callback(observer2, count);
145
- }
146
- }
147
- }
148
- });
149
- observer.observe(element, { childList: true });
150
- }
151
- function watchDomChangesWithThrottle(element, callback, throttle = 1e3, times = Infinity, options = { childList: true, subtree: true, attributes: true }) {
152
- let lastMutationTime;
153
- let timeout;
154
- let times_ = times;
155
- const observer = new MutationObserver((_mutationList, _observer) => {
156
- if (times_ !== Infinity && times_ < 1) {
157
- observer.disconnect();
158
- return;
159
- }
160
- times_--;
161
- const now = Date.now();
162
- if (lastMutationTime && now - lastMutationTime < throttle) {
163
- timeout && clearTimeout(timeout);
164
- }
165
- timeout = setTimeout(callback, throttle);
166
- lastMutationTime = now;
167
- });
168
- observer.observe(element, options);
169
- return observer;
170
- }
171
- function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
172
- } }) {
173
- const btn = parseDom(options.button);
174
- if (options.append) document.querySelector(options.append)?.append(btn);
175
- if (options.after) document.querySelector(options.after)?.after(btn);
176
- btn.addEventListener("click", (e) => {
177
- e.preventDefault();
178
- if (options.cbBefore) options.cbBefore();
179
- waitForElementExists(document.body, "video", (video) => {
180
- window.location.href = video.getAttribute("src");
181
- });
182
- });
183
- }
184
- function exterminateVideo(video) {
185
- video.removeAttribute("src");
186
- video.load();
187
- video.remove();
188
- }
189
- const MOBILE_UA = [
190
- "Mozilla/5.0 (Linux; Android 10; K)",
191
- "AppleWebKit/537.36 (KHTML, like Gecko)",
192
- "Chrome/114.0.0.0 Mobile Safari/537.36"
193
- ].join(" ");
194
- function fetchWith(url, options = { html: false, mobile: false }) {
195
- const reqOpts = {};
196
- if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ "User-Agent": MOBILE_UA }) });
197
- return fetch(url, reqOpts).then((r) => r.text()).then((r) => options.html ? parseDom(r) : r);
198
- }
199
- const fetchHtml = (url) => fetchWith(url, { html: true });
200
- const fetchText = (url) => fetchWith(url);
201
- function objectToFormData(object) {
202
- const formData = new FormData();
203
- Object.entries(object).forEach(([k, v]) => formData.append(k, v));
204
- return formData;
205
- }
206
- function listenEvents(dom, events, callback) {
207
- for (const e of events) {
208
- dom.addEventListener(e, callback, true);
209
- }
210
- }
211
- class Tick {
212
- constructor(delay, startImmediate = true) {
213
- __publicField(this, "tick");
214
- __publicField(this, "callbackFinal");
215
- this.delay = delay;
216
- this.startImmediate = startImmediate;
217
- }
218
- start(callback, callbackFinal) {
219
- this.stop();
220
- this.callbackFinal = callbackFinal;
221
- if (this.startImmediate) callback();
222
- this.tick = window.setInterval(callback, this.delay);
223
- }
224
- stop() {
225
- if (this.tick !== void 0) {
226
- clearInterval(this.tick);
227
- this.tick = void 0;
228
- }
229
- if (this.callbackFinal) {
230
- this.callbackFinal();
231
- this.callbackFinal = void 0;
232
- }
233
- }
234
- }
235
- function isMob() {
236
- return /iPhone|Android/i.test(navigator.userAgent);
237
- }
238
- async function computeAsyncOneAtTime(iterable) {
239
- const res = [];
240
- for await (const f of iterable) {
241
- res.push(await f());
242
- }
243
- return res;
244
- }
245
- function wait(milliseconds) {
246
- return new Promise((resolve) => setTimeout(resolve, milliseconds));
247
- }
248
- class AsyncPool {
249
- constructor(max = 1, pool = []) {
250
- __publicField(this, "cur", 0);
251
- __publicField(this, "finished");
252
- __publicField(this, "_resolve");
253
- this.max = max;
254
- this.pool = pool;
255
- this.finished = new Promise((resolve) => {
256
- this._resolve = resolve;
257
- });
258
- }
259
- static async doNAsyncAtOnce(max = 1, pool = []) {
260
- const spool = new AsyncPool(max);
261
- pool.forEach((f) => spool.push(f));
262
- return spool.run();
263
- }
264
- getHighPriorityFirst(p = 0) {
265
- if (p > 3 || this.pool.length === 0) return void 0;
266
- const i = this.pool.findIndex((e) => e.p === p);
267
- if (i >= 0) {
268
- const res = this.pool[i].v;
269
- this.pool.splice(i, 1);
270
- return res;
271
- }
272
- return this.getHighPriorityFirst(p + 1);
273
- }
274
- async runTask() {
275
- this.cur++;
276
- const f = this.getHighPriorityFirst();
277
- await f?.();
278
- this.cur--;
279
- this.runTasks();
280
- }
281
- runTasks() {
282
- if (!this.pool.length) {
283
- this._resolve?.(true);
284
- return;
285
- }
286
- if (this.cur < this.max) {
287
- this.runTask();
288
- this.runTasks();
289
- }
290
- }
291
- async run() {
292
- this.runTasks();
293
- return this.finished;
294
- }
295
- push(x) {
296
- this.pool.push("p" in x ? x : { v: x, p: 0 });
297
- }
298
- }
299
- function chunks(arr, n) {
300
- return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));
55
+ function stringToWords(s) {
56
+ return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
301
57
  }
302
- function range(size, startAt = 1, step = 1) {
303
- return Array.from({ length: size }, (_, index) => startAt + index * step);
58
+ function sanitizeStr(s) {
59
+ return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
304
60
  }
305
61
  class DataFilter {
306
62
  constructor(rules, state) {
@@ -395,7 +151,9 @@ class DataManager {
395
151
  }
396
152
  }
397
153
  requestAnimationFrame(() => {
398
- updates.forEach((update) => update());
154
+ updates.forEach((update) => {
155
+ update();
156
+ });
399
157
  });
400
158
  });
401
159
  __publicField(this, "filterAll", (offset) => {
@@ -434,7 +192,8 @@ class DataManager {
434
192
  (target) => !this.isFiltered(target)
435
193
  );
436
194
  this.dataFilters = new DataFilter(rules, state).filters;
437
- [window, unsafeWindow || {}].forEach((w) => {
195
+ const targets = [window, globalThis.unsafeWindow].filter(Boolean);
196
+ targets.forEach((w) => {
438
197
  Object.assign(w, {
439
198
  sortByViews: () => this.sort("view"),
440
199
  sortByDuration: () => this.sort("duration")
@@ -443,7 +202,7 @@ class DataManager {
443
202
  }
444
203
  static filterDSLToRegex(str) {
445
204
  const toFullWord = (w) => `(^|\\ )${w}($|\\ )`;
446
- const str_ = str.replace(/f\:(\w+)/g, (_, w) => toFullWord(w));
205
+ const str_ = str.replace(/f:(\w+)/g, (_, w) => toFullWord(w));
447
206
  return stringToWords(str_).map((expr) => new RegExp(expr, "i"));
448
207
  }
449
208
  isFiltered(el) {
@@ -461,6 +220,114 @@ class DataManager {
461
220
  });
462
221
  }
463
222
  }
223
+ function parseDom(html) {
224
+ const parsed = new DOMParser().parseFromString(html, "text/html").body;
225
+ return parsed.children.length > 1 ? parsed : parsed.firstElementChild;
226
+ }
227
+ function copyAttributes(target, source) {
228
+ for (const attr of source.attributes) {
229
+ attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);
230
+ }
231
+ }
232
+ function replaceElementTag(e, tagName) {
233
+ const newTagElement = document.createElement(tagName);
234
+ copyAttributes(newTagElement, e);
235
+ newTagElement.innerHTML = e.innerHTML;
236
+ e.parentNode?.replaceChild(newTagElement, e);
237
+ return newTagElement;
238
+ }
239
+ function getAllUniqueParents(elements) {
240
+ return Array.from(elements).reduce((acc, v) => {
241
+ if (v.parentElement && !acc.includes(v.parentElement)) {
242
+ acc.push(v.parentElement);
243
+ }
244
+ return acc;
245
+ }, []);
246
+ }
247
+ function findNextSibling(el) {
248
+ if (el.nextElementSibling) return el.nextElementSibling;
249
+ if (el.parentElement) return findNextSibling(el.parentElement);
250
+ return null;
251
+ }
252
+ function waitForElementExists(parent, selector, callback) {
253
+ const observer = new MutationObserver((_mutations) => {
254
+ const el = parent.querySelector(selector);
255
+ if (el) {
256
+ observer.disconnect();
257
+ callback(el);
258
+ }
259
+ });
260
+ observer.observe(document.body, { childList: true, subtree: true });
261
+ }
262
+ function watchElementChildrenCount(element, callback) {
263
+ let count = element.children.length;
264
+ const observer = new MutationObserver((mutationList, observer2) => {
265
+ for (const mutation of mutationList) {
266
+ if (mutation.type === "childList") {
267
+ if (count !== element.children.length) {
268
+ count = element.children.length;
269
+ callback(observer2, count);
270
+ }
271
+ }
272
+ }
273
+ });
274
+ observer.observe(element, { childList: true });
275
+ }
276
+ function watchDomChangesWithThrottle(element, callback, throttle = 1e3, times = Infinity, options = { childList: true, subtree: true, attributes: true }) {
277
+ let lastMutationTime;
278
+ let timeout;
279
+ let times_ = times;
280
+ const observer = new MutationObserver((_mutationList, _observer) => {
281
+ if (times_ !== Infinity && times_ < 1) {
282
+ observer.disconnect();
283
+ return;
284
+ }
285
+ times_--;
286
+ const now = Date.now();
287
+ if (lastMutationTime && now - lastMutationTime < throttle) {
288
+ timeout && clearTimeout(timeout);
289
+ }
290
+ timeout = setTimeout(callback, throttle);
291
+ lastMutationTime = now;
292
+ });
293
+ observer.observe(element, options);
294
+ return observer;
295
+ }
296
+ function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
297
+ } }) {
298
+ const btn = parseDom(options.button);
299
+ if (options.append) document.querySelector(options.append)?.append(btn);
300
+ if (options.after) document.querySelector(options.after)?.after(btn);
301
+ btn.addEventListener("click", (e) => {
302
+ e.preventDefault();
303
+ if (options.cbBefore) options.cbBefore();
304
+ waitForElementExists(document.body, "video", (video) => {
305
+ window.location.href = video.getAttribute("src");
306
+ });
307
+ });
308
+ }
309
+ function exterminateVideo(video) {
310
+ video.removeAttribute("src");
311
+ video.load();
312
+ video.remove();
313
+ }
314
+ const MOBILE_UA = [
315
+ "Mozilla/5.0 (Linux; Android 10; K)",
316
+ "AppleWebKit/537.36 (KHTML, like Gecko)",
317
+ "Chrome/114.0.0.0 Mobile Safari/537.36"
318
+ ].join(" ");
319
+ function fetchWith(url, options = { html: false, mobile: false }) {
320
+ const reqOpts = {};
321
+ if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ "User-Agent": MOBILE_UA }) });
322
+ return fetch(url, reqOpts).then((r) => r.text()).then((r) => options.html ? parseDom(r) : r);
323
+ }
324
+ const fetchHtml = (url) => fetchWith(url, { html: true });
325
+ const fetchText = (url) => fetchWith(url);
326
+ function objectToFormData(object) {
327
+ const formData = new FormData();
328
+ Object.entries(object).forEach(([k, v]) => formData.append(k, v));
329
+ return formData;
330
+ }
464
331
  class InfiniteScroller {
465
332
  constructor({
466
333
  enabled = true,
@@ -484,10 +351,7 @@ class InfiniteScroller {
484
351
  __publicField(this, "onScrollCBs", []);
485
352
  __publicField(this, "generatorConsumer", async () => {
486
353
  if (!this.enabled) return false;
487
- const {
488
- value: { url, offset } = {},
489
- done
490
- } = await this.paginationGenerator.next();
354
+ const { value: { url, offset } = {}, done } = await this.paginationGenerator.next();
491
355
  if (!done) {
492
356
  const nextPageHTML = await fetchHtml(url);
493
357
  const prevScrollPos = document.documentElement.scrollTop;
@@ -521,7 +385,9 @@ class InfiniteScroller {
521
385
  return this;
522
386
  }
523
387
  _onScroll() {
524
- this.onScrollCBs.forEach((cb) => cb(this));
388
+ this.onScrollCBs.forEach((cb) => {
389
+ cb(this);
390
+ });
525
391
  }
526
392
  static *createPaginationGenerator(currentPage, totalPages, generateURL) {
527
393
  for (let offset = currentPage + 1; offset <= totalPages; offset++) {
@@ -532,10 +398,6 @@ class InfiniteScroller {
532
398
  }
533
399
  function createInfiniteScroller(store, handleHtmlCallback, rules) {
534
400
  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();
539
401
  const iscroller = new InfiniteScroller({
540
402
  enabled,
541
403
  handleHtmlCallback,
@@ -549,6 +411,142 @@ function createInfiniteScroller(store, handleHtmlCallback, rules) {
549
411
  });
550
412
  return iscroller;
551
413
  }
414
+ function chunks(arr, n) {
415
+ return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));
416
+ }
417
+ function range(size, startAt = 1, step = 1) {
418
+ return Array.from({ length: size }, (_, index) => startAt + index * step);
419
+ }
420
+ async function computeAsyncOneAtTime(iterable) {
421
+ const res = [];
422
+ for await (const f of iterable) {
423
+ res.push(await f());
424
+ }
425
+ return res;
426
+ }
427
+ function wait(milliseconds) {
428
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
429
+ }
430
+ class AsyncPool {
431
+ constructor(max = 1, pool = []) {
432
+ __publicField(this, "cur", 0);
433
+ __publicField(this, "finished");
434
+ __publicField(this, "_resolve");
435
+ this.max = max;
436
+ this.pool = pool;
437
+ this.finished = new Promise((resolve) => {
438
+ this._resolve = resolve;
439
+ });
440
+ }
441
+ static async doNAsyncAtOnce(max = 1, pool = []) {
442
+ const spool = new AsyncPool(max);
443
+ pool.forEach((f) => spool.push(f));
444
+ return spool.run();
445
+ }
446
+ getHighPriorityFirst(p = 0) {
447
+ if (p > 3 || this.pool.length === 0) return void 0;
448
+ const i = this.pool.findIndex((e) => e.p === p);
449
+ if (i >= 0) {
450
+ const res = this.pool[i].v;
451
+ this.pool.splice(i, 1);
452
+ return res;
453
+ }
454
+ return this.getHighPriorityFirst(p + 1);
455
+ }
456
+ async runTask() {
457
+ this.cur++;
458
+ const f = this.getHighPriorityFirst();
459
+ await f?.();
460
+ this.cur--;
461
+ this.runTasks();
462
+ }
463
+ runTasks() {
464
+ if (!this.pool.length) {
465
+ this._resolve?.(true);
466
+ return;
467
+ }
468
+ if (this.cur < this.max) {
469
+ this.runTask();
470
+ this.runTasks();
471
+ }
472
+ }
473
+ async run() {
474
+ this.runTasks();
475
+ return this.finished;
476
+ }
477
+ push(x) {
478
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
479
+ }
480
+ }
481
+ function isMob() {
482
+ return /iPhone|Android/i.test(navigator.userAgent);
483
+ }
484
+ function listenEvents(dom, events, callback) {
485
+ for (const e of events) {
486
+ dom.addEventListener(e, callback, true);
487
+ }
488
+ }
489
+ class Tick {
490
+ constructor(delay, startImmediate = true) {
491
+ __publicField(this, "tick");
492
+ __publicField(this, "callbackFinal");
493
+ this.delay = delay;
494
+ this.startImmediate = startImmediate;
495
+ }
496
+ start(callback, callbackFinal) {
497
+ this.stop();
498
+ this.callbackFinal = callbackFinal;
499
+ if (this.startImmediate) callback();
500
+ this.tick = window.setInterval(callback, this.delay);
501
+ }
502
+ stop() {
503
+ if (this.tick !== void 0) {
504
+ clearInterval(this.tick);
505
+ this.tick = void 0;
506
+ }
507
+ if (this.callbackFinal) {
508
+ this.callbackFinal();
509
+ this.callbackFinal = void 0;
510
+ }
511
+ }
512
+ }
513
+ function circularShift(n, c = 6, s = 1) {
514
+ return (n + s) % c || c;
515
+ }
516
+ function formatTimeToHHMMSS(timeString) {
517
+ const regex = /(?:(\d+)\s*h\s*)?(?:(\d+)\s*mi?n?\s*)?(?:(\d+)\s*sec)?/;
518
+ const match = timeString.match(regex);
519
+ const h = parseInt(match?.[1] || "0");
520
+ const m = parseInt(match?.[2] || "0");
521
+ const s = parseInt(match?.[3] || "0");
522
+ const pad = (num) => String(num).padStart(2, "0");
523
+ return `${pad(h)}:${pad(m)}:${pad(s)}`;
524
+ }
525
+ function timeToSeconds(t) {
526
+ const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;
527
+ return (r?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
528
+ }
529
+ function parseIntegerOr(n, or) {
530
+ return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
531
+ }
532
+ function parseDataParams(str) {
533
+ const paramsStr = decodeURI(str.trim()).split(";");
534
+ return paramsStr.reduce((acc, s) => {
535
+ const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
536
+ if (parsed) {
537
+ const [, key, value] = parsed;
538
+ if (value) {
539
+ key.split("+").forEach((p) => {
540
+ acc[p] = value;
541
+ });
542
+ }
543
+ }
544
+ return acc;
545
+ }, {});
546
+ }
547
+ function parseCSSUrl(s) {
548
+ return s.replace(/url\("|\"\).*/g, "");
549
+ }
552
550
  export {
553
551
  AsyncPool,
554
552
  DataManager,