tiny-essentials 1.16.2 → 1.17.0
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/legacy/crypto/decrypt.cjs +1 -0
- package/dist/legacy/crypto/decrypt.d.mts +1 -0
- package/dist/legacy/crypto/decrypt.mjs +1 -0
- package/dist/legacy/crypto/encrypt.cjs +1 -0
- package/dist/legacy/crypto/encrypt.d.mts +1 -0
- package/dist/legacy/crypto/encrypt.mjs +1 -0
- package/dist/legacy/get/decimalColor.cjs +1 -0
- package/dist/legacy/get/decimalColor.d.mts +1 -0
- package/dist/legacy/get/decimalColor.mjs +1 -0
- package/dist/legacy/get/pagination.cjs +1 -0
- package/dist/legacy/get/pagination.d.mts +1 -0
- package/dist/legacy/get/pagination.mjs +1 -0
- package/dist/legacy/get/queryUrlByName.cjs +1 -0
- package/dist/legacy/get/queryUrlByName.d.mts +1 -0
- package/dist/legacy/get/queryUrlByName.mjs +1 -0
- package/dist/legacy/get/queryUrlJSON.cjs +1 -0
- package/dist/legacy/get/queryUrlJSON.d.mts +1 -0
- package/dist/legacy/get/queryUrlJSON.mjs +1 -0
- package/dist/legacy/get/super_string_filter.cjs +1 -0
- package/dist/legacy/get/super_string_filter.d.mts +1 -0
- package/dist/legacy/get/super_string_filter.mjs +1 -0
- package/dist/legacy/get/versionCheck.cjs +1 -0
- package/dist/legacy/get/versionCheck.d.mts +1 -0
- package/dist/legacy/get/versionCheck.mjs +1 -0
- package/dist/legacy/http/HTTP-1.0.cjs +2 -0
- package/dist/legacy/http/HTTP-1.0.mjs +2 -0
- package/dist/legacy/http/auth.cjs +1 -0
- package/dist/legacy/http/auth.d.mts +1 -0
- package/dist/legacy/http/auth.mjs +1 -0
- package/dist/legacy/http/check_domain.cjs +11 -0
- package/dist/legacy/http/check_domain.d.mts +3 -0
- package/dist/legacy/http/check_domain.mjs +11 -0
- package/dist/legacy/http/csrfTokenAnalyze.cjs +1 -0
- package/dist/legacy/http/csrfTokenAnalyze.d.mts +1 -0
- package/dist/legacy/http/csrfTokenAnalyze.mjs +1 -0
- package/dist/legacy/http/domainValidator.cjs +1 -0
- package/dist/legacy/http/domainValidator.d.mts +1 -0
- package/dist/legacy/http/domainValidator.mjs +1 -0
- package/dist/legacy/http/errorsCallback.cjs +1 -0
- package/dist/legacy/http/errorsCallback.d.mts +1 -0
- package/dist/legacy/http/errorsCallback.mjs +1 -0
- package/dist/legacy/http/fetch/json.cjs +1 -0
- package/dist/legacy/http/fetch/json.d.mts +1 -0
- package/dist/legacy/http/fetch/json.mjs +1 -0
- package/dist/legacy/http/fetch/text.cjs +1 -0
- package/dist/legacy/http/fetch/text.d.mts +1 -0
- package/dist/legacy/http/fetch/text.mjs +1 -0
- package/dist/legacy/http/fileCache.cjs +1 -0
- package/dist/legacy/http/fileCache.d.mts +1 -0
- package/dist/legacy/http/fileCache.mjs +1 -0
- package/dist/legacy/http/getDomainURL.cjs +1 -0
- package/dist/legacy/http/getDomainURL.d.mts +1 -0
- package/dist/legacy/http/getDomainURL.mjs +1 -0
- package/dist/legacy/http/userIP.cjs +1 -0
- package/dist/legacy/http/userIP.d.mts +1 -0
- package/dist/legacy/http/userIP.mjs +1 -0
- package/dist/legacy/libs/capitalize.cjs +1 -0
- package/dist/legacy/libs/capitalize.d.mts +1 -0
- package/dist/legacy/libs/capitalize.mjs +1 -0
- package/dist/legacy/libs/convertBytes.cjs +2 -0
- package/dist/legacy/libs/convertBytes.mjs +2 -0
- package/dist/legacy/libs/custom_module_loader.cjs +2 -0
- package/dist/legacy/libs/custom_module_loader.mjs +2 -0
- package/dist/legacy/libs/dice.cjs +2 -0
- package/dist/legacy/libs/dice.mjs +2 -0
- package/dist/legacy/libs/markdown.cjs +1 -0
- package/dist/legacy/libs/markdown.mjs +1 -0
- package/dist/legacy/libs/percentage.cjs +1 -0
- package/dist/legacy/libs/percentage.mjs +1 -0
- package/dist/legacy/libs/regex/getLetter.cjs +2 -0
- package/dist/legacy/libs/regex/getLetter.d.mts +2 -0
- package/dist/legacy/libs/regex/getLetter.mjs +2 -0
- package/dist/legacy/libs/rule3.cjs +1 -0
- package/dist/legacy/libs/rule3.mjs +1 -0
- package/dist/legacy/momentjs/getAge.cjs +1 -0
- package/dist/legacy/momentjs/getAge.d.mts +1 -0
- package/dist/legacy/momentjs/getAge.mjs +1 -0
- package/dist/legacy/momentjs/timeDuration.cjs +1 -0
- package/dist/legacy/momentjs/timeDuration.d.mts +1 -0
- package/dist/legacy/momentjs/timeDuration.mjs +1 -0
- package/dist/legacy/socket.io/antiFlood/install.cjs +1 -0
- package/dist/legacy/socket.io/antiFlood/install.d.mts +1 -0
- package/dist/legacy/socket.io/antiFlood/install.mjs +1 -0
- package/dist/legacy/socket.io/antiFlood/verify.cjs +1 -0
- package/dist/legacy/socket.io/antiFlood/verify.d.mts +1 -0
- package/dist/legacy/socket.io/antiFlood/verify.mjs +1 -0
- package/dist/legacy/socket.io/cookie-session.cjs +1 -0
- package/dist/legacy/socket.io/cookie-session.d.mts +1 -0
- package/dist/legacy/socket.io/cookie-session.mjs +1 -0
- package/dist/legacy/socket.io/discord.cjs +1 -0
- package/dist/legacy/socket.io/discord.d.mts +1 -0
- package/dist/legacy/socket.io/discord.mjs +1 -0
- package/dist/v1/TinyBasicsEs.js +559 -71
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDragger.js +486 -47
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyEssentials.js +2496 -72
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyHtml.js +486 -47
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinySmartScroller.js +6230 -0
- package/dist/v1/TinySmartScroller.min.js +1 -0
- package/dist/v1/TinyUploadClicker.js +1538 -72
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/UltraRandomMsgGen.js +995 -0
- package/dist/v1/UltraRandomMsgGen.min.js +1 -0
- package/dist/v1/basics/html.cjs +74 -24
- package/dist/v1/basics/html.d.mts +38 -15
- package/dist/v1/basics/html.mjs +63 -20
- package/dist/v1/build/TinySmartScroller.cjs +7 -0
- package/dist/v1/build/TinySmartScroller.d.mts +3 -0
- package/dist/v1/build/TinySmartScroller.mjs +2 -0
- package/dist/v1/build/UltraRandomMsgGen.cjs +7 -0
- package/dist/v1/build/UltraRandomMsgGen.d.mts +3 -0
- package/dist/v1/build/UltraRandomMsgGen.mjs +2 -0
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +3 -1
- package/dist/v1/index.mjs +3 -1
- package/dist/v1/libs/TinyHtml.cjs +486 -47
- package/dist/v1/libs/TinyHtml.d.mts +352 -139
- package/dist/v1/libs/TinyHtml.mjs +431 -47
- package/dist/v1/libs/TinySmartScroller.cjs +976 -0
- package/dist/v1/libs/TinySmartScroller.d.mts +458 -0
- package/dist/v1/libs/TinySmartScroller.mjs +856 -0
- package/dist/v1/libs/UltraRandomMsgGen.cjs +956 -0
- package/dist/v1/libs/UltraRandomMsgGen.d.mts +390 -0
- package/dist/v1/libs/UltraRandomMsgGen.mjs +825 -0
- package/docs/v1/README.md +2 -0
- package/docs/v1/basics/html.md +17 -2
- package/docs/v1/libs/TinyHtml.md +197 -8
- package/docs/v1/libs/TinySmartScroller.md +523 -0
- package/docs/v1/libs/UltraRandomMsgGen.md +289 -0
- package/package.json +1 -1
|
@@ -3599,20 +3599,22 @@ function saveJsonFile(filename, data, spaces = 2) {
|
|
|
3599
3599
|
}
|
|
3600
3600
|
|
|
3601
3601
|
/**
|
|
3602
|
-
*
|
|
3603
|
-
*
|
|
3604
|
-
* @
|
|
3605
|
-
* @
|
|
3606
|
-
* @
|
|
3607
|
-
* @
|
|
3608
|
-
* @
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
* @
|
|
3613
|
-
* @
|
|
3602
|
+
* @typedef {Object} FetchTemplateOptions
|
|
3603
|
+
* @property {string} [method="GET"] - HTTP method to use (GET, POST, etc.).
|
|
3604
|
+
* @property {any} [body] - Request body (only for methods like POST, PUT).
|
|
3605
|
+
* @property {number} [timeout=0] - Timeout in milliseconds (ignored if signal is provided).
|
|
3606
|
+
* @property {number} [retries=0] - Number of retry attempts (ignored if signal is provided).
|
|
3607
|
+
* @property {Headers|Record<string, *>} [headers={}] - Additional headers.
|
|
3608
|
+
* @property {AbortSignal|null} [signal] - External AbortSignal; disables timeout and retries.
|
|
3609
|
+
*/
|
|
3610
|
+
|
|
3611
|
+
/**
|
|
3612
|
+
* @param {string} url - The full URL to fetch data from.
|
|
3613
|
+
* @param {FetchTemplateOptions} [options] - Optional settings.
|
|
3614
|
+
* @returns {Promise<Response>} Result data.
|
|
3615
|
+
* @throws {Error} Throws if fetch fails, times out.
|
|
3614
3616
|
*/
|
|
3615
|
-
async function
|
|
3617
|
+
async function fetchTemplate(
|
|
3616
3618
|
url,
|
|
3617
3619
|
{ method = 'GET', body, timeout = 0, retries = 0, headers = {}, signal = null } = {},
|
|
3618
3620
|
) {
|
|
@@ -3671,17 +3673,7 @@ async function fetchJson(
|
|
|
3671
3673
|
if (timer) clearTimeout(timer);
|
|
3672
3674
|
|
|
3673
3675
|
if (!response.ok) throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
|
|
3674
|
-
|
|
3675
|
-
const contentType = response.headers.get('content-type') || '';
|
|
3676
|
-
if (!contentType.includes('application/json'))
|
|
3677
|
-
throw new Error(`Unexpected content-type: ${contentType}`);
|
|
3678
|
-
|
|
3679
|
-
const data = await response.json();
|
|
3680
|
-
|
|
3681
|
-
if (!Array.isArray(data) && !isJsonObject(data))
|
|
3682
|
-
throw new Error('Received invalid data instead of valid JSON.');
|
|
3683
|
-
|
|
3684
|
-
return data;
|
|
3676
|
+
return response;
|
|
3685
3677
|
} catch (err) {
|
|
3686
3678
|
lastError = /** @type {Error} */ (err);
|
|
3687
3679
|
if (signal) break; // if an external signal came, it does not retry
|
|
@@ -3695,6 +3687,63 @@ async function fetchJson(
|
|
|
3695
3687
|
);
|
|
3696
3688
|
}
|
|
3697
3689
|
|
|
3690
|
+
/**
|
|
3691
|
+
* Loads and parses a JSON from a remote URL using Fetch API.
|
|
3692
|
+
*
|
|
3693
|
+
* @param {string} url - The full URL to fetch JSON from.
|
|
3694
|
+
* @param {Object} [options] - Optional settings.
|
|
3695
|
+
* @returns {Promise<any[] | Record<string | number | symbol, unknown>>} Parsed JSON object.
|
|
3696
|
+
* @throws {Error} Throws if fetch fails, times out, or returns invalid JSON.
|
|
3697
|
+
*/
|
|
3698
|
+
async function fetchJson(url, options) {
|
|
3699
|
+
return new Promise((resolve, reject) => {
|
|
3700
|
+
fetchTemplate(url, options)
|
|
3701
|
+
.then(async (res) => {
|
|
3702
|
+
const contentType = res.headers.get('content-type') || '';
|
|
3703
|
+
if (!contentType.includes('application/json'))
|
|
3704
|
+
throw new Error(`Unexpected content-type: ${contentType}`);
|
|
3705
|
+
|
|
3706
|
+
const data = await res.json();
|
|
3707
|
+
|
|
3708
|
+
if (!Array.isArray(data) && !isJsonObject(data))
|
|
3709
|
+
throw new Error('Received invalid data instead of valid JSON.');
|
|
3710
|
+
|
|
3711
|
+
return resolve(data);
|
|
3712
|
+
})
|
|
3713
|
+
.catch(reject);
|
|
3714
|
+
});
|
|
3715
|
+
}
|
|
3716
|
+
|
|
3717
|
+
/**
|
|
3718
|
+
* Loads a remote file as a Blob using Fetch API.
|
|
3719
|
+
*
|
|
3720
|
+
* @param {string} url - The full URL to fetch the file from.
|
|
3721
|
+
* @param {Object} [options] - Optional fetch options.
|
|
3722
|
+
* @param {string[]} [allowedMimeTypes] - Optional list of accepted MIME types (e.g., ['image/jpeg']).
|
|
3723
|
+
* @returns {Promise<Blob>} - The fetched file as a Blob.
|
|
3724
|
+
* @throws {Error} Throws if fetch fails, response is not ok, or MIME type is not allowed.
|
|
3725
|
+
*/
|
|
3726
|
+
async function fetchBlob(url, allowedMimeTypes, options) {
|
|
3727
|
+
return new Promise((resolve, reject) => {
|
|
3728
|
+
fetchTemplate(url, options)
|
|
3729
|
+
.then(async (res) => {
|
|
3730
|
+
const contentType = res.headers.get('content-type') || '';
|
|
3731
|
+
|
|
3732
|
+
if (
|
|
3733
|
+
Array.isArray(allowedMimeTypes) &&
|
|
3734
|
+
allowedMimeTypes.length > 0 &&
|
|
3735
|
+
!allowedMimeTypes.some((type) => contentType.includes(type))
|
|
3736
|
+
) {
|
|
3737
|
+
throw new Error(`Blocked MIME type: ${contentType}`);
|
|
3738
|
+
}
|
|
3739
|
+
|
|
3740
|
+
const data = await res.blob();
|
|
3741
|
+
return resolve(data);
|
|
3742
|
+
})
|
|
3743
|
+
.catch(reject);
|
|
3744
|
+
});
|
|
3745
|
+
}
|
|
3746
|
+
|
|
3698
3747
|
///////////////////////////////////////////////////////////////////////////////
|
|
3699
3748
|
|
|
3700
3749
|
/**
|
|
@@ -4281,6 +4330,21 @@ const {
|
|
|
4281
4330
|
* @typedef {Element|Window} ElementAndWindow
|
|
4282
4331
|
*/
|
|
4283
4332
|
|
|
4333
|
+
/**
|
|
4334
|
+
* Represents a raw DOM element/window/document or an instance of TinyHtml.
|
|
4335
|
+
* This type is used to abstract interactions with both plain elements
|
|
4336
|
+
* and wrapped elements via the TinyHtml class.
|
|
4337
|
+
*
|
|
4338
|
+
* @typedef {ElementAndWinAndDoc|TinyHtml} TinyElementAndWinAndDoc
|
|
4339
|
+
*/
|
|
4340
|
+
|
|
4341
|
+
/**
|
|
4342
|
+
* Represents a value that can be either a DOM Element, or the global Window object, or the document object.
|
|
4343
|
+
* Useful for functions that operate generically on scrollable or measurable targets.
|
|
4344
|
+
*
|
|
4345
|
+
* @typedef {Element|Window|Document} ElementAndWinAndDoc
|
|
4346
|
+
*/
|
|
4347
|
+
|
|
4284
4348
|
/**
|
|
4285
4349
|
* A parameter type used for filtering or matching elements.
|
|
4286
4350
|
* It can be:
|
|
@@ -4297,7 +4361,7 @@ const {
|
|
|
4297
4361
|
* Elements accepted as constructor values for TinyHtml.
|
|
4298
4362
|
* These include common DOM elements and root containers.
|
|
4299
4363
|
*
|
|
4300
|
-
* @typedef {Window|Element|Document} ConstructorElValues
|
|
4364
|
+
* @typedef {Window|Element|Document|Text} ConstructorElValues
|
|
4301
4365
|
*/
|
|
4302
4366
|
|
|
4303
4367
|
/**
|
|
@@ -4418,40 +4482,114 @@ class TinyHtml_TinyHtml {
|
|
|
4418
4482
|
|
|
4419
4483
|
static Utils = { ...collision_namespaceObject };
|
|
4420
4484
|
|
|
4485
|
+
/**
|
|
4486
|
+
* Creates a new DOM element with the specified tag name and options, then wraps it in a TinyHtml instance.
|
|
4487
|
+
*
|
|
4488
|
+
* @param {string} tagName - The tag name of the element to create (e.g., 'div', 'span').
|
|
4489
|
+
* @param {ElementCreationOptions} ops - Optional settings for creating the element.
|
|
4490
|
+
* @returns {TinyHtml} A TinyHtml instance wrapping the newly created DOM element.
|
|
4491
|
+
* @throws {TypeError} If tagName is not a string or ops is not an object.
|
|
4492
|
+
*/
|
|
4493
|
+
static createElement(tagName, ops) {
|
|
4494
|
+
if (typeof tagName !== 'string')
|
|
4495
|
+
throw new TypeError(`[TinyHtml] createElement(): The tagName must be a string.`);
|
|
4496
|
+
if (typeof ops !== 'undefined' && typeof ops !== 'object')
|
|
4497
|
+
throw new TypeError(`[TinyHtml] createElement(): The ops must be a object.`);
|
|
4498
|
+
return new TinyHtml_TinyHtml(document.createElement(tagName, ops));
|
|
4499
|
+
}
|
|
4500
|
+
|
|
4501
|
+
/**
|
|
4502
|
+
* Creates a new TinyHtml instance that wraps a DOM TextNode.
|
|
4503
|
+
*
|
|
4504
|
+
* This method is useful when you want to insert raw text content into the DOM
|
|
4505
|
+
* without it being interpreted as HTML. The returned instance behaves like any
|
|
4506
|
+
* other TinyHtml element and can be appended or manipulated as needed.
|
|
4507
|
+
*
|
|
4508
|
+
* @param {string} value - The plain text content to be wrapped in a TextNode.
|
|
4509
|
+
* @returns {TinyHtml} A TinyHtml instance wrapping the newly created DOM TextNode.
|
|
4510
|
+
* @throws {TypeError} If the provided value is not a string.
|
|
4511
|
+
*/
|
|
4512
|
+
static createTextNode(value) {
|
|
4513
|
+
if (typeof value !== 'string')
|
|
4514
|
+
throw new TypeError(`[TinyHtml] createTextNode(): The value must be a string.`);
|
|
4515
|
+
return new TinyHtml_TinyHtml(document.createTextNode(value));
|
|
4516
|
+
}
|
|
4517
|
+
|
|
4518
|
+
/**
|
|
4519
|
+
* Creates an HTMLElement or TextNode from an HTML string.
|
|
4520
|
+
* Supports both elements and plain text.
|
|
4521
|
+
*
|
|
4522
|
+
* @param {string} htmlString - The HTML string to convert.
|
|
4523
|
+
* @returns {TinyHtml} - A single HTMLElement or TextNode.
|
|
4524
|
+
*/
|
|
4525
|
+
static createElementFromHTML(htmlString) {
|
|
4526
|
+
const template = document.createElement('template');
|
|
4527
|
+
htmlString = htmlString.trim();
|
|
4528
|
+
|
|
4529
|
+
// If it's only text (e.g., no "<" tag), return a TextNode
|
|
4530
|
+
if (!htmlString.startsWith('<')) {
|
|
4531
|
+
return TinyHtml_TinyHtml.createTextNode(htmlString);
|
|
4532
|
+
}
|
|
4533
|
+
|
|
4534
|
+
template.innerHTML = htmlString;
|
|
4535
|
+
if (!(template.content.firstChild instanceof Element)) throw new Error('');
|
|
4536
|
+
return new TinyHtml_TinyHtml(template.content.firstChild);
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4421
4539
|
/**
|
|
4422
4540
|
* Queries the document for the first element matching the CSS selector and wraps it in a TinyHtml instance.
|
|
4423
4541
|
*
|
|
4424
4542
|
* @param {string} selector - A valid CSS selector string.
|
|
4425
|
-
* @
|
|
4426
|
-
* @
|
|
4543
|
+
* @param {Document|Element} elem - Target element.
|
|
4544
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the matched element.
|
|
4427
4545
|
*/
|
|
4428
|
-
static query(selector) {
|
|
4429
|
-
const newEl =
|
|
4430
|
-
if (!newEl)
|
|
4546
|
+
static query(selector, elem = document) {
|
|
4547
|
+
const newEl = elem.querySelector(selector);
|
|
4548
|
+
if (!newEl) return null;
|
|
4431
4549
|
return new TinyHtml_TinyHtml(newEl);
|
|
4432
4550
|
}
|
|
4433
4551
|
|
|
4552
|
+
/**
|
|
4553
|
+
* Queries the element for the first element matching the CSS selector and wraps it in a TinyHtml instance.
|
|
4554
|
+
*
|
|
4555
|
+
* @param {string} selector - A valid CSS selector string.
|
|
4556
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the matched element.
|
|
4557
|
+
*/
|
|
4558
|
+
querySelector(selector) {
|
|
4559
|
+
return TinyHtml_TinyHtml.query(selector, TinyHtml_TinyHtml._preElem(this, 'query'));
|
|
4560
|
+
}
|
|
4561
|
+
|
|
4434
4562
|
/**
|
|
4435
4563
|
* Queries the document for all elements matching the CSS selector and wraps them in TinyHtml instances.
|
|
4436
4564
|
*
|
|
4437
4565
|
* @param {string} selector - A valid CSS selector string.
|
|
4566
|
+
* @param {Document|Element} elem - Target element.
|
|
4438
4567
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the matched elements.
|
|
4439
4568
|
*/
|
|
4440
|
-
static queryAll(selector) {
|
|
4441
|
-
const newEls =
|
|
4569
|
+
static queryAll(selector, elem = document) {
|
|
4570
|
+
const newEls = elem.querySelectorAll(selector);
|
|
4442
4571
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4443
4572
|
}
|
|
4444
4573
|
|
|
4574
|
+
/**
|
|
4575
|
+
* Queries the element for all elements matching the CSS selector and wraps them in TinyHtml instances.
|
|
4576
|
+
*
|
|
4577
|
+
* @param {string} selector - A valid CSS selector string.
|
|
4578
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the matched elements.
|
|
4579
|
+
*/
|
|
4580
|
+
querySelectorAll(selector) {
|
|
4581
|
+
return TinyHtml_TinyHtml.queryAll(selector, TinyHtml_TinyHtml._preElem(this, 'queryAll'));
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4445
4584
|
/**
|
|
4446
4585
|
* Retrieves an element by its ID and wraps it in a TinyHtml instance.
|
|
4447
4586
|
*
|
|
4448
4587
|
* @param {string} selector - The ID of the element to retrieve.
|
|
4449
|
-
* @returns {TinyHtml} A TinyHtml instance wrapping the found element.
|
|
4450
|
-
* @throws {Error} If no element is found with the specified ID.
|
|
4588
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the found element.
|
|
4451
4589
|
*/
|
|
4452
4590
|
static getById(selector) {
|
|
4453
4591
|
const newEl = document.getElementById(selector);
|
|
4454
|
-
if (!newEl)
|
|
4592
|
+
if (!newEl) return null;
|
|
4455
4593
|
return new TinyHtml_TinyHtml(newEl);
|
|
4456
4594
|
}
|
|
4457
4595
|
|
|
@@ -4459,13 +4597,24 @@ class TinyHtml_TinyHtml {
|
|
|
4459
4597
|
* Retrieves all elements with the specified class name and wraps them in TinyHtml instances.
|
|
4460
4598
|
*
|
|
4461
4599
|
* @param {string} selector - The class name to search for.
|
|
4600
|
+
* @param {Document|Element} elem - Target element.
|
|
4462
4601
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4463
4602
|
*/
|
|
4464
|
-
static getByClassName(selector) {
|
|
4465
|
-
const newEls =
|
|
4603
|
+
static getByClassName(selector, elem = document) {
|
|
4604
|
+
const newEls = elem.getElementsByClassName(selector);
|
|
4466
4605
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4467
4606
|
}
|
|
4468
4607
|
|
|
4608
|
+
/**
|
|
4609
|
+
* Retrieves all elements with the specified class name and wraps them in TinyHtml instances.
|
|
4610
|
+
*
|
|
4611
|
+
* @param {string} selector - The class name to search for.
|
|
4612
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4613
|
+
*/
|
|
4614
|
+
getElementsByClassName(selector) {
|
|
4615
|
+
return TinyHtml_TinyHtml.getByClassName(selector, TinyHtml_TinyHtml._preElem(this, 'getByClassName'));
|
|
4616
|
+
}
|
|
4617
|
+
|
|
4469
4618
|
/**
|
|
4470
4619
|
* Retrieves all elements with the specified name attribute and wraps them in TinyHtml instances.
|
|
4471
4620
|
*
|
|
@@ -4483,13 +4632,30 @@ class TinyHtml_TinyHtml {
|
|
|
4483
4632
|
*
|
|
4484
4633
|
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
4485
4634
|
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
4635
|
+
* @param {Document|Element} elem - Target element.
|
|
4486
4636
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4487
4637
|
*/
|
|
4488
|
-
static getByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml') {
|
|
4489
|
-
const newEls =
|
|
4638
|
+
static getByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml', elem = document) {
|
|
4639
|
+
const newEls = elem.getElementsByTagNameNS(namespaceURI, localName);
|
|
4490
4640
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4491
4641
|
}
|
|
4492
4642
|
|
|
4643
|
+
/**
|
|
4644
|
+
* Retrieves all elements with the specified local tag name within the given namespace URI,
|
|
4645
|
+
* and wraps them in TinyHtml instances.
|
|
4646
|
+
*
|
|
4647
|
+
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
4648
|
+
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
4649
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4650
|
+
*/
|
|
4651
|
+
getElementsByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml') {
|
|
4652
|
+
return TinyHtml_TinyHtml.getByTagNameNS(
|
|
4653
|
+
localName,
|
|
4654
|
+
namespaceURI,
|
|
4655
|
+
TinyHtml_TinyHtml._preElem(this, 'getByTagNameNS'),
|
|
4656
|
+
);
|
|
4657
|
+
}
|
|
4658
|
+
|
|
4493
4659
|
//////////////////////////////////////////////////////////////////
|
|
4494
4660
|
|
|
4495
4661
|
/**
|
|
@@ -4770,6 +4936,45 @@ class TinyHtml_TinyHtml {
|
|
|
4770
4936
|
return TinyHtml_TinyHtml._preElemTemplate(elems, where, [Element, Window], ['Element', 'Window']);
|
|
4771
4937
|
}
|
|
4772
4938
|
|
|
4939
|
+
/**
|
|
4940
|
+
* Ensures the input is returned as an array.
|
|
4941
|
+
* Useful to normalize operations across multiple or single element/window/document elements.
|
|
4942
|
+
*
|
|
4943
|
+
* @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
|
|
4944
|
+
* @param {string} where - The method or context name where validation is being called.
|
|
4945
|
+
* @returns {ElementAndWindow[]} - Always returns an array of element/window elements.
|
|
4946
|
+
* @readonly
|
|
4947
|
+
*/
|
|
4948
|
+
static _preElemsAndWinAndDoc(elems, where) {
|
|
4949
|
+
const result = TinyHtml_TinyHtml._preElemsTemplate(
|
|
4950
|
+
elems,
|
|
4951
|
+
where,
|
|
4952
|
+
[Element, Window, Document],
|
|
4953
|
+
['Element', 'Window', 'Document'],
|
|
4954
|
+
);
|
|
4955
|
+
return result.map((elem) => (!(elem instanceof Document) ? elem : elem.documentElement));
|
|
4956
|
+
}
|
|
4957
|
+
|
|
4958
|
+
/**
|
|
4959
|
+
* Ensures the input is returned as an single element/window/document element.
|
|
4960
|
+
* Useful to normalize operations across multiple or single element/window/document elements.
|
|
4961
|
+
*
|
|
4962
|
+
* @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
|
|
4963
|
+
* @param {string} where - The method or context name where validation is being called.
|
|
4964
|
+
* @returns {ElementAndWindow} - Always returns an single element/window element.
|
|
4965
|
+
* @readonly
|
|
4966
|
+
*/
|
|
4967
|
+
static _preElemAndWinAndDoc(elems, where) {
|
|
4968
|
+
const result = TinyHtml_TinyHtml._preElemTemplate(
|
|
4969
|
+
elems,
|
|
4970
|
+
where,
|
|
4971
|
+
[Element, Window, Document],
|
|
4972
|
+
['Element', 'Window', 'Document'],
|
|
4973
|
+
);
|
|
4974
|
+
if (result instanceof Document) return result.documentElement;
|
|
4975
|
+
return result;
|
|
4976
|
+
}
|
|
4977
|
+
|
|
4773
4978
|
/**
|
|
4774
4979
|
* Normalizes and converts one or more DOM elements (or TinyHtml instances)
|
|
4775
4980
|
* into an array of `TinyHtml` instances.
|
|
@@ -5116,12 +5321,13 @@ class TinyHtml_TinyHtml {
|
|
|
5116
5321
|
* @param {string} key - The key under which the data will be stored.
|
|
5117
5322
|
* @param {any} value - The value to store.
|
|
5118
5323
|
* @param {boolean} [isPrivate=false] - Whether to store the data in the private store.
|
|
5119
|
-
* @returns {
|
|
5324
|
+
* @returns {TinyElement}
|
|
5120
5325
|
*/
|
|
5121
5326
|
static setData(el, key, value, isPrivate = false) {
|
|
5122
5327
|
const data = TinyHtml_TinyHtml._dataSelector[!isPrivate ? 'public' : 'private']('setData', el);
|
|
5123
5328
|
if (typeof key !== 'string') throw new TypeError('The key must be a string.');
|
|
5124
5329
|
data[key] = value;
|
|
5330
|
+
return el;
|
|
5125
5331
|
}
|
|
5126
5332
|
|
|
5127
5333
|
/**
|
|
@@ -5130,7 +5336,7 @@ class TinyHtml_TinyHtml {
|
|
|
5130
5336
|
* @param {string} key - The key under which the data will be stored.
|
|
5131
5337
|
* @param {any} value - The value to store.
|
|
5132
5338
|
* @param {boolean} [isPrivate=false] - Whether to store the data in the private store.
|
|
5133
|
-
* @returns {
|
|
5339
|
+
* @returns {TinyElement}
|
|
5134
5340
|
*/
|
|
5135
5341
|
setData(key, value, isPrivate = false) {
|
|
5136
5342
|
return TinyHtml_TinyHtml.setData(this, key, value, isPrivate);
|
|
@@ -5477,18 +5683,21 @@ class TinyHtml_TinyHtml {
|
|
|
5477
5683
|
/**
|
|
5478
5684
|
* Appends child elements or strings to the end of the target element(s).
|
|
5479
5685
|
*
|
|
5480
|
-
* @param {TinyElement
|
|
5686
|
+
* @param {TinyElement} el - The target element(s) to receive children.
|
|
5481
5687
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to append.
|
|
5688
|
+
* @returns {TinyElement}
|
|
5482
5689
|
*/
|
|
5483
5690
|
static append(el, ...children) {
|
|
5484
5691
|
const elem = TinyHtml_TinyHtml._preElem(el, 'append');
|
|
5485
5692
|
elem.append(...TinyHtml_TinyHtml._appendChecker('append', ...children));
|
|
5693
|
+
return el;
|
|
5486
5694
|
}
|
|
5487
5695
|
|
|
5488
5696
|
/**
|
|
5489
5697
|
* Appends child elements or strings to the end of the target element(s).
|
|
5490
5698
|
*
|
|
5491
5699
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to append.
|
|
5700
|
+
* @returns {TinyElement}
|
|
5492
5701
|
*/
|
|
5493
5702
|
append(...children) {
|
|
5494
5703
|
return TinyHtml_TinyHtml.append(this, ...children);
|
|
@@ -5497,18 +5706,21 @@ class TinyHtml_TinyHtml {
|
|
|
5497
5706
|
/**
|
|
5498
5707
|
* Prepends child elements or strings to the beginning of the target element(s).
|
|
5499
5708
|
*
|
|
5500
|
-
* @param {TinyElement
|
|
5709
|
+
* @param {TinyElement} el - The target element(s) to receive children.
|
|
5501
5710
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to prepend.
|
|
5711
|
+
* @returns {TinyElement}
|
|
5502
5712
|
*/
|
|
5503
5713
|
static prepend(el, ...children) {
|
|
5504
5714
|
const elem = TinyHtml_TinyHtml._preElem(el, 'prepend');
|
|
5505
5715
|
elem.prepend(...TinyHtml_TinyHtml._appendChecker('prepend', ...children));
|
|
5716
|
+
return el;
|
|
5506
5717
|
}
|
|
5507
5718
|
|
|
5508
5719
|
/**
|
|
5509
5720
|
* Prepends child elements or strings to the beginning of the target element(s).
|
|
5510
5721
|
*
|
|
5511
5722
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to prepend.
|
|
5723
|
+
* @returns {TinyElement}
|
|
5512
5724
|
*/
|
|
5513
5725
|
prepend(...children) {
|
|
5514
5726
|
return TinyHtml_TinyHtml.prepend(this, ...children);
|
|
@@ -5517,18 +5729,21 @@ class TinyHtml_TinyHtml {
|
|
|
5517
5729
|
/**
|
|
5518
5730
|
* Inserts elements or strings immediately before the target element(s) in the DOM.
|
|
5519
5731
|
*
|
|
5520
|
-
* @param {TinyElement
|
|
5732
|
+
* @param {TinyElement} el - The target element(s) before which new content is inserted.
|
|
5521
5733
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert before the target.
|
|
5734
|
+
* @returns {TinyElement}
|
|
5522
5735
|
*/
|
|
5523
5736
|
static before(el, ...children) {
|
|
5524
5737
|
const elem = TinyHtml_TinyHtml._preElem(el, 'before');
|
|
5525
5738
|
elem.before(...TinyHtml_TinyHtml._appendChecker('before', ...children));
|
|
5739
|
+
return el;
|
|
5526
5740
|
}
|
|
5527
5741
|
|
|
5528
5742
|
/**
|
|
5529
5743
|
* Inserts elements or strings immediately before the target element(s) in the DOM.
|
|
5530
5744
|
*
|
|
5531
5745
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert before the target.
|
|
5746
|
+
* @returns {TinyElement}
|
|
5532
5747
|
*/
|
|
5533
5748
|
before(...children) {
|
|
5534
5749
|
return TinyHtml_TinyHtml.before(this, ...children);
|
|
@@ -5537,18 +5752,21 @@ class TinyHtml_TinyHtml {
|
|
|
5537
5752
|
/**
|
|
5538
5753
|
* Inserts elements or strings immediately after the target element(s) in the DOM.
|
|
5539
5754
|
*
|
|
5540
|
-
* @param {TinyElement
|
|
5755
|
+
* @param {TinyElement} el - The target element(s) after which new content is inserted.
|
|
5541
5756
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert after the target.
|
|
5757
|
+
* @returns {TinyElement}
|
|
5542
5758
|
*/
|
|
5543
5759
|
static after(el, ...children) {
|
|
5544
5760
|
const elem = TinyHtml_TinyHtml._preElem(el, 'after');
|
|
5545
5761
|
elem.after(...TinyHtml_TinyHtml._appendChecker('after', ...children));
|
|
5762
|
+
return el;
|
|
5546
5763
|
}
|
|
5547
5764
|
|
|
5548
5765
|
/**
|
|
5549
5766
|
* Inserts elements or strings immediately after the target element(s) in the DOM.
|
|
5550
5767
|
*
|
|
5551
5768
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert after the target.
|
|
5769
|
+
* @returns {TinyElement}
|
|
5552
5770
|
*/
|
|
5553
5771
|
after(...children) {
|
|
5554
5772
|
return TinyHtml_TinyHtml.after(this, ...children);
|
|
@@ -5557,18 +5775,21 @@ class TinyHtml_TinyHtml {
|
|
|
5557
5775
|
/**
|
|
5558
5776
|
* Replaces the target element(s) in the DOM with new elements or text.
|
|
5559
5777
|
*
|
|
5560
|
-
* @param {TinyElement
|
|
5778
|
+
* @param {TinyElement} el - The element(s) to be replaced.
|
|
5561
5779
|
* @param {...(TinyNode | TinyNode[] | string)} newNodes - New elements or text to replace the target.
|
|
5780
|
+
* @returns {TinyElement}
|
|
5562
5781
|
*/
|
|
5563
5782
|
static replaceWith(el, ...newNodes) {
|
|
5564
5783
|
const elem = TinyHtml_TinyHtml._preElem(el, 'replaceWith');
|
|
5565
5784
|
elem.replaceWith(...TinyHtml_TinyHtml._appendChecker('replaceWith', ...newNodes));
|
|
5785
|
+
return el;
|
|
5566
5786
|
}
|
|
5567
5787
|
|
|
5568
5788
|
/**
|
|
5569
5789
|
* Replaces the target element(s) in the DOM with new elements or text.
|
|
5570
5790
|
*
|
|
5571
5791
|
* @param {...(TinyNode | TinyNode[] | string)} newNodes - New elements or text to replace the target.
|
|
5792
|
+
* @returns {TinyElement}
|
|
5572
5793
|
*/
|
|
5573
5794
|
replaceWith(...newNodes) {
|
|
5574
5795
|
return TinyHtml_TinyHtml.replaceWith(this, ...newNodes);
|
|
@@ -5579,6 +5800,7 @@ class TinyHtml_TinyHtml {
|
|
|
5579
5800
|
*
|
|
5580
5801
|
* @param {TinyNode | TinyNode[]} el - The element(s) to append.
|
|
5581
5802
|
* @param {TinyNode | TinyNode[]} targets - Target element(s) where content will be appended.
|
|
5803
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5582
5804
|
*/
|
|
5583
5805
|
static appendTo(el, targets) {
|
|
5584
5806
|
const elems = TinyHtml_TinyHtml._preNodeElems(el, 'appendTo');
|
|
@@ -5588,12 +5810,14 @@ class TinyHtml_TinyHtml {
|
|
|
5588
5810
|
target.appendChild(i === tars.length - 1 ? elem : elem.cloneNode(true)),
|
|
5589
5811
|
);
|
|
5590
5812
|
});
|
|
5813
|
+
return el;
|
|
5591
5814
|
}
|
|
5592
5815
|
|
|
5593
5816
|
/**
|
|
5594
5817
|
* Appends the given element(s) to each target element in sequence.
|
|
5595
5818
|
*
|
|
5596
5819
|
* @param {TinyNode | TinyNode[]} targets - Target element(s) where content will be appended.
|
|
5820
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5597
5821
|
*/
|
|
5598
5822
|
appendTo(targets) {
|
|
5599
5823
|
return TinyHtml_TinyHtml.appendTo(this, targets);
|
|
@@ -5604,6 +5828,7 @@ class TinyHtml_TinyHtml {
|
|
|
5604
5828
|
*
|
|
5605
5829
|
* @param {TinyElement | TinyElement[]} el - The element(s) to prepend.
|
|
5606
5830
|
* @param {TinyElement | TinyElement[]} targets - Target element(s) where content will be prepended.
|
|
5831
|
+
* @returns {TinyElement|TinyElement[]}
|
|
5607
5832
|
*/
|
|
5608
5833
|
static prependTo(el, targets) {
|
|
5609
5834
|
const elems = TinyHtml_TinyHtml._preElems(el, 'prependTo');
|
|
@@ -5614,12 +5839,14 @@ class TinyHtml_TinyHtml {
|
|
|
5614
5839
|
.reverse()
|
|
5615
5840
|
.forEach((elem) => target.prepend(i === tars.length - 1 ? elem : elem.cloneNode(true)));
|
|
5616
5841
|
});
|
|
5842
|
+
return el;
|
|
5617
5843
|
}
|
|
5618
5844
|
|
|
5619
5845
|
/**
|
|
5620
5846
|
* Prepends the given element(s) to each target element in sequence.
|
|
5621
5847
|
*
|
|
5622
5848
|
* @param {TinyElement | TinyElement[]} targets - Target element(s) where content will be prepended.
|
|
5849
|
+
* @returns {TinyElement|TinyElement[]}
|
|
5623
5850
|
*/
|
|
5624
5851
|
prependTo(targets) {
|
|
5625
5852
|
return TinyHtml_TinyHtml.prependTo(this, targets);
|
|
@@ -5631,6 +5858,7 @@ class TinyHtml_TinyHtml {
|
|
|
5631
5858
|
* @param {TinyNode | TinyNode[]} el - The element(s) to insert.
|
|
5632
5859
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5633
5860
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert before, defaults to target.
|
|
5861
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5634
5862
|
*/
|
|
5635
5863
|
static insertBefore(el, target, child = null) {
|
|
5636
5864
|
const elem = TinyHtml_TinyHtml._preNodeElem(el, 'insertBefore');
|
|
@@ -5638,6 +5866,7 @@ class TinyHtml_TinyHtml {
|
|
|
5638
5866
|
const childNode = TinyHtml_TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
5639
5867
|
if (!targ.parentNode) throw new Error('');
|
|
5640
5868
|
targ.parentNode.insertBefore(elem, childNode || targ);
|
|
5869
|
+
return el;
|
|
5641
5870
|
}
|
|
5642
5871
|
|
|
5643
5872
|
/**
|
|
@@ -5645,6 +5874,7 @@ class TinyHtml_TinyHtml {
|
|
|
5645
5874
|
*
|
|
5646
5875
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5647
5876
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert before, defaults to target.
|
|
5877
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5648
5878
|
*/
|
|
5649
5879
|
insertBefore(target, child) {
|
|
5650
5880
|
return TinyHtml_TinyHtml.insertBefore(this, target, child);
|
|
@@ -5656,6 +5886,7 @@ class TinyHtml_TinyHtml {
|
|
|
5656
5886
|
* @param {TinyNode | TinyNode[]} el - The element(s) to insert.
|
|
5657
5887
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5658
5888
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert after, defaults to target.
|
|
5889
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5659
5890
|
*/
|
|
5660
5891
|
static insertAfter(el, target, child = null) {
|
|
5661
5892
|
const elem = TinyHtml_TinyHtml._preNodeElem(el, 'insertAfter');
|
|
@@ -5663,6 +5894,7 @@ class TinyHtml_TinyHtml {
|
|
|
5663
5894
|
const childNode = TinyHtml_TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
5664
5895
|
if (!targ.parentNode) throw new Error('');
|
|
5665
5896
|
targ.parentNode.insertBefore(elem, childNode || targ.nextSibling);
|
|
5897
|
+
return el;
|
|
5666
5898
|
}
|
|
5667
5899
|
|
|
5668
5900
|
/**
|
|
@@ -5670,6 +5902,7 @@ class TinyHtml_TinyHtml {
|
|
|
5670
5902
|
*
|
|
5671
5903
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5672
5904
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert after, defaults to target.
|
|
5905
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5673
5906
|
*/
|
|
5674
5907
|
insertAfter(target, child) {
|
|
5675
5908
|
return TinyHtml_TinyHtml.insertAfter(this, target, child);
|
|
@@ -5681,6 +5914,7 @@ class TinyHtml_TinyHtml {
|
|
|
5681
5914
|
*
|
|
5682
5915
|
* @param {TinyNode | TinyNode[]} el - The new element(s) to insert.
|
|
5683
5916
|
* @param {TinyNode | TinyNode[]} targets - The elements to be replaced.
|
|
5917
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5684
5918
|
*/
|
|
5685
5919
|
static replaceAll(el, targets) {
|
|
5686
5920
|
const elems = TinyHtml_TinyHtml._preNodeElems(el, 'replaceAll');
|
|
@@ -5692,6 +5926,7 @@ class TinyHtml_TinyHtml {
|
|
|
5692
5926
|
parent.replaceChild(i === tars.length - 1 ? elem : elem.cloneNode(true), target);
|
|
5693
5927
|
});
|
|
5694
5928
|
});
|
|
5929
|
+
return el;
|
|
5695
5930
|
}
|
|
5696
5931
|
|
|
5697
5932
|
/**
|
|
@@ -5699,6 +5934,7 @@ class TinyHtml_TinyHtml {
|
|
|
5699
5934
|
* If multiple targets exist, the inserted elements are cloned accordingly.
|
|
5700
5935
|
*
|
|
5701
5936
|
* @param {TinyNode | TinyNode[]} targets - The elements to be replaced.
|
|
5937
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5702
5938
|
*/
|
|
5703
5939
|
replaceAll(targets) {
|
|
5704
5940
|
return TinyHtml_TinyHtml.replaceAll(this, targets);
|
|
@@ -5722,7 +5958,12 @@ class TinyHtml_TinyHtml {
|
|
|
5722
5958
|
throw new Error(
|
|
5723
5959
|
`[TinyHtml] You are trying to put a TinyHtml inside another TinyHtml in constructor.`,
|
|
5724
5960
|
);
|
|
5725
|
-
if (
|
|
5961
|
+
if (
|
|
5962
|
+
!(el instanceof Element) &&
|
|
5963
|
+
!(el instanceof Window) &&
|
|
5964
|
+
!(el instanceof Document) &&
|
|
5965
|
+
!(el instanceof Text)
|
|
5966
|
+
)
|
|
5726
5967
|
throw new Error(`[TinyHtml] Invalid Target in constructor.`);
|
|
5727
5968
|
this.#el = el;
|
|
5728
5969
|
}
|
|
@@ -6172,6 +6413,7 @@ class TinyHtml_TinyHtml {
|
|
|
6172
6413
|
* @param {TinyHtmlElement|TinyHtmlElement[]} el - The element to inspect.
|
|
6173
6414
|
* @param {string|Object} prop - The property name or an object with key-value pairs
|
|
6174
6415
|
* @param {string|null} [value=null] - The value to set (if `prop` is a string)
|
|
6416
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6175
6417
|
*/
|
|
6176
6418
|
static setStyle(el, prop, value = null) {
|
|
6177
6419
|
TinyHtml_TinyHtml._preHtmlElems(el, 'setStyle').forEach((elem) => {
|
|
@@ -6184,6 +6426,7 @@ class TinyHtml_TinyHtml {
|
|
|
6184
6426
|
}
|
|
6185
6427
|
} else elem.style.setProperty(TinyHtml_TinyHtml.toStyleKc(prop), value);
|
|
6186
6428
|
});
|
|
6429
|
+
return el;
|
|
6187
6430
|
}
|
|
6188
6431
|
|
|
6189
6432
|
/**
|
|
@@ -6194,6 +6437,7 @@ class TinyHtml_TinyHtml {
|
|
|
6194
6437
|
*
|
|
6195
6438
|
* @param {string|Object} prop - The property name or an object with key-value pairs
|
|
6196
6439
|
* @param {string|null} [value=null] - The value to set (if `prop` is a string)
|
|
6440
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6197
6441
|
*/
|
|
6198
6442
|
setStyle(prop, value) {
|
|
6199
6443
|
return TinyHtml_TinyHtml.setStyle(this, prop, value);
|
|
@@ -6289,6 +6533,7 @@ class TinyHtml_TinyHtml {
|
|
|
6289
6533
|
*
|
|
6290
6534
|
* @param {TinyHtmlElement|TinyHtmlElement[]} el - A single element or an array of elements.
|
|
6291
6535
|
* @param {string|string[]} prop - A property name or an array of property names to remove.
|
|
6536
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6292
6537
|
*/
|
|
6293
6538
|
static removeStyle(el, prop) {
|
|
6294
6539
|
TinyHtml_TinyHtml._preHtmlElems(el, 'removeStyle').forEach((elem) => {
|
|
@@ -6298,12 +6543,14 @@ class TinyHtml_TinyHtml {
|
|
|
6298
6543
|
}
|
|
6299
6544
|
} else elem.style.removeProperty(TinyHtml_TinyHtml.toStyleKc(prop));
|
|
6300
6545
|
});
|
|
6546
|
+
return el;
|
|
6301
6547
|
}
|
|
6302
6548
|
|
|
6303
6549
|
/**
|
|
6304
6550
|
* Removes one or more inline CSS properties from the given element(s).
|
|
6305
6551
|
*
|
|
6306
6552
|
* @param {string|string[]} prop - A property name or an array of property names to remove.
|
|
6553
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6307
6554
|
*/
|
|
6308
6555
|
removeStyle(prop) {
|
|
6309
6556
|
return TinyHtml_TinyHtml.removeStyle(this, prop);
|
|
@@ -6318,6 +6565,7 @@ class TinyHtml_TinyHtml {
|
|
|
6318
6565
|
* @param {string} prop - The CSS property to toggle.
|
|
6319
6566
|
* @param {string} val1 - The first value (used as "current" check).
|
|
6320
6567
|
* @param {string} val2 - The second value (used as the "alternative").
|
|
6568
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6321
6569
|
*/
|
|
6322
6570
|
static toggleStyle(el, prop, val1, val2) {
|
|
6323
6571
|
TinyHtml_TinyHtml._preHtmlElems(el, 'toggleStyle').forEach((elem) => {
|
|
@@ -6325,6 +6573,7 @@ class TinyHtml_TinyHtml {
|
|
|
6325
6573
|
const newVal = current === TinyHtml_TinyHtml.toStyleKc(val1) ? val2 : val1;
|
|
6326
6574
|
TinyHtml_TinyHtml.setStyle(elem, prop, newVal);
|
|
6327
6575
|
});
|
|
6576
|
+
return el;
|
|
6328
6577
|
}
|
|
6329
6578
|
|
|
6330
6579
|
/**
|
|
@@ -6335,6 +6584,7 @@ class TinyHtml_TinyHtml {
|
|
|
6335
6584
|
* @param {string} prop - The CSS property to toggle.
|
|
6336
6585
|
* @param {string} val1 - The first value (used as "current" check).
|
|
6337
6586
|
* @param {string} val2 - The second value (used as the "alternative").
|
|
6587
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6338
6588
|
*/
|
|
6339
6589
|
toggleStyle(prop, val1, val2) {
|
|
6340
6590
|
return TinyHtml_TinyHtml.toggleStyle(this, prop, val1, val2);
|
|
@@ -6344,14 +6594,16 @@ class TinyHtml_TinyHtml {
|
|
|
6344
6594
|
* Removes all inline styles (`style` attribute) from the given element(s).
|
|
6345
6595
|
*
|
|
6346
6596
|
* @param {TinyElement|TinyElement[]} el - A single element or an array of elements.
|
|
6597
|
+
* @returns {TinyElement|TinyElement[]}
|
|
6347
6598
|
*/
|
|
6348
6599
|
static clearStyle(el) {
|
|
6349
6600
|
TinyHtml_TinyHtml._preElems(el, 'clearStyle').forEach((elem) => elem.removeAttribute('style'));
|
|
6601
|
+
return el;
|
|
6350
6602
|
}
|
|
6351
6603
|
|
|
6352
6604
|
/**
|
|
6353
6605
|
* Removes all inline styles (`style` attribute) from the given element(s).
|
|
6354
|
-
*
|
|
6606
|
+
* @returns {TinyElement|TinyElement[]}
|
|
6355
6607
|
*/
|
|
6356
6608
|
clearStyle() {
|
|
6357
6609
|
return TinyHtml_TinyHtml.clearStyle(this);
|
|
@@ -6363,14 +6615,17 @@ class TinyHtml_TinyHtml {
|
|
|
6363
6615
|
* Focus the element.
|
|
6364
6616
|
*
|
|
6365
6617
|
* @param {TinyHtmlElement} el - The element or a selector string.
|
|
6618
|
+
* @returns {TinyHtmlElement}
|
|
6366
6619
|
*/
|
|
6367
6620
|
static focus(el) {
|
|
6368
6621
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'focus');
|
|
6369
6622
|
elem.focus();
|
|
6623
|
+
return el;
|
|
6370
6624
|
}
|
|
6371
6625
|
|
|
6372
6626
|
/**
|
|
6373
6627
|
* Focus the element.
|
|
6628
|
+
* @returns {TinyHtmlElement}
|
|
6374
6629
|
*/
|
|
6375
6630
|
focus() {
|
|
6376
6631
|
return TinyHtml_TinyHtml.focus(this);
|
|
@@ -6380,19 +6635,46 @@ class TinyHtml_TinyHtml {
|
|
|
6380
6635
|
* Blur the element.
|
|
6381
6636
|
*
|
|
6382
6637
|
* @param {TinyHtmlElement} el - The element or a selector string.
|
|
6638
|
+
* @returns {TinyHtmlElement}
|
|
6383
6639
|
*/
|
|
6384
6640
|
static blur(el) {
|
|
6385
6641
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'blur');
|
|
6386
6642
|
elem.blur();
|
|
6643
|
+
return el;
|
|
6387
6644
|
}
|
|
6388
6645
|
|
|
6389
6646
|
/**
|
|
6390
6647
|
* Blur the element.
|
|
6648
|
+
* @returns {TinyHtmlElement}
|
|
6391
6649
|
*/
|
|
6392
6650
|
blur() {
|
|
6393
6651
|
return TinyHtml_TinyHtml.blur(this);
|
|
6394
6652
|
}
|
|
6395
6653
|
|
|
6654
|
+
/**
|
|
6655
|
+
* Interprets a value as a boolean `true` if it matches a common truthy representation.
|
|
6656
|
+
*
|
|
6657
|
+
* This method checks if the input is any of the common forms used to represent `true`,
|
|
6658
|
+
* such as the string `'true'`, `'1'`, `'on'`, the boolean `true`, or the number `1`.
|
|
6659
|
+
*
|
|
6660
|
+
* @param {string|boolean|number} [value] - The value to interpret as boolean.
|
|
6661
|
+
* @returns {boolean} `true` if the value represents a truthy state, otherwise `false`.
|
|
6662
|
+
*/
|
|
6663
|
+
static boolCheck(value) {
|
|
6664
|
+
if (
|
|
6665
|
+
typeof value !== 'undefined' &&
|
|
6666
|
+
(value === 'true' ||
|
|
6667
|
+
value === '1' ||
|
|
6668
|
+
value === true ||
|
|
6669
|
+
value === 'on' ||
|
|
6670
|
+
(typeof value === 'number' && value > 0))
|
|
6671
|
+
) {
|
|
6672
|
+
return true;
|
|
6673
|
+
} else {
|
|
6674
|
+
return false;
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
|
|
6396
6678
|
//////////////////////////////////////////////////////////////////////
|
|
6397
6679
|
|
|
6398
6680
|
/**
|
|
@@ -6445,16 +6727,40 @@ class TinyHtml_TinyHtml {
|
|
|
6445
6727
|
return window.innerWidth || document.documentElement.clientWidth;
|
|
6446
6728
|
}
|
|
6447
6729
|
|
|
6730
|
+
/**
|
|
6731
|
+
* Checks if the page is currently scrolled to the very top.
|
|
6732
|
+
*
|
|
6733
|
+
* This method compares the current vertical scroll position with the total document height.
|
|
6734
|
+
* It's useful for detecting if the user has reached the top of the page.
|
|
6735
|
+
*
|
|
6736
|
+
* @returns {boolean} `true` if the page is scrolled to the top, otherwise `false`.
|
|
6737
|
+
*/
|
|
6738
|
+
static isPageTop() {
|
|
6739
|
+
return window.scrollY === 0;
|
|
6740
|
+
}
|
|
6741
|
+
|
|
6742
|
+
/**
|
|
6743
|
+
* Checks if the page is currently scrolled to the very bottom.
|
|
6744
|
+
*
|
|
6745
|
+
* This method uses the `scrollY` and `innerHeight` properties to determine if the
|
|
6746
|
+
* user has reached the end of the document.
|
|
6747
|
+
*
|
|
6748
|
+
* @returns {boolean} `true` if the page is scrolled to the bottom, otherwise `false`.
|
|
6749
|
+
*/
|
|
6750
|
+
static isPageBottom() {
|
|
6751
|
+
return window.innerHeight + window.scrollY >= document.body.offsetHeight;
|
|
6752
|
+
}
|
|
6753
|
+
|
|
6448
6754
|
/**
|
|
6449
6755
|
* Gets the width or height of an element based on the box model.
|
|
6450
|
-
* @param {
|
|
6756
|
+
* @param {TinyElementAndWinAndDoc} el - The element or window.
|
|
6451
6757
|
* @param {"width"|"height"} type - Dimension type.
|
|
6452
6758
|
* @param {"content"|"padding"|"border"|"margin"} [extra='content'] - Box model context.
|
|
6453
6759
|
* @returns {number} - Computed dimension.
|
|
6454
6760
|
* @throws {TypeError} If `type` or `extra` is not a string.
|
|
6455
6761
|
*/
|
|
6456
6762
|
static getDimension(el, type, extra = 'content') {
|
|
6457
|
-
const elem = TinyHtml_TinyHtml.
|
|
6763
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'getDimension');
|
|
6458
6764
|
if (typeof type !== 'string') throw new TypeError('The type must be a string.');
|
|
6459
6765
|
if (typeof extra !== 'string') throw new TypeError('The extra must be a string.');
|
|
6460
6766
|
|
|
@@ -6542,17 +6848,20 @@ class TinyHtml_TinyHtml {
|
|
|
6542
6848
|
* @param {TinyHtmlElement} el - Target element.
|
|
6543
6849
|
* @param {string|number} value - Height value.
|
|
6544
6850
|
* @throws {TypeError} If `value` is neither a string nor number.
|
|
6851
|
+
* @returns {TinyHtmlElement}
|
|
6545
6852
|
*/
|
|
6546
6853
|
static setHeight(el, value) {
|
|
6547
6854
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'setHeight');
|
|
6548
6855
|
if (typeof value !== 'number' && typeof value !== 'string')
|
|
6549
6856
|
throw new TypeError('The value must be a string or number.');
|
|
6550
6857
|
elem.style.height = typeof value === 'number' ? `${value}px` : value;
|
|
6858
|
+
return el;
|
|
6551
6859
|
}
|
|
6552
6860
|
|
|
6553
6861
|
/**
|
|
6554
6862
|
* Sets the height of the element.
|
|
6555
6863
|
* @param {string|number} value - Height value.
|
|
6864
|
+
* @returns {TinyHtmlElement}
|
|
6556
6865
|
*/
|
|
6557
6866
|
setHeight(value) {
|
|
6558
6867
|
return TinyHtml_TinyHtml.setHeight(this, value);
|
|
@@ -6563,17 +6872,20 @@ class TinyHtml_TinyHtml {
|
|
|
6563
6872
|
* @param {TinyHtmlElement} el - Target element.
|
|
6564
6873
|
* @param {string|number} value - Width value.
|
|
6565
6874
|
* @throws {TypeError} If `value` is neither a string nor number.
|
|
6875
|
+
* @returns {TinyHtmlElement}
|
|
6566
6876
|
*/
|
|
6567
6877
|
static setWidth(el, value) {
|
|
6568
6878
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'setWidth');
|
|
6569
6879
|
if (typeof value !== 'number' && typeof value !== 'string')
|
|
6570
6880
|
throw new TypeError('The value must be a string or number.');
|
|
6571
6881
|
elem.style.width = typeof value === 'number' ? `${value}px` : value;
|
|
6882
|
+
return el;
|
|
6572
6883
|
}
|
|
6573
6884
|
|
|
6574
6885
|
/**
|
|
6575
6886
|
* Sets the width of the element.
|
|
6576
6887
|
* @param {string|number} value - Width value.
|
|
6888
|
+
* @returns {TinyHtmlElement}
|
|
6577
6889
|
*/
|
|
6578
6890
|
setWidth(value) {
|
|
6579
6891
|
return TinyHtml_TinyHtml.setWidth(this, value);
|
|
@@ -6581,11 +6893,11 @@ class TinyHtml_TinyHtml {
|
|
|
6581
6893
|
|
|
6582
6894
|
/**
|
|
6583
6895
|
* Returns content box height.
|
|
6584
|
-
* @param {
|
|
6896
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6585
6897
|
* @returns {number}
|
|
6586
6898
|
*/
|
|
6587
6899
|
static height(el) {
|
|
6588
|
-
const elem = TinyHtml_TinyHtml.
|
|
6900
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'height');
|
|
6589
6901
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', 'content');
|
|
6590
6902
|
}
|
|
6591
6903
|
|
|
@@ -6599,11 +6911,11 @@ class TinyHtml_TinyHtml {
|
|
|
6599
6911
|
|
|
6600
6912
|
/**
|
|
6601
6913
|
* Returns content box width.
|
|
6602
|
-
* @param {
|
|
6914
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6603
6915
|
* @returns {number}
|
|
6604
6916
|
*/
|
|
6605
6917
|
static width(el) {
|
|
6606
|
-
const elem = TinyHtml_TinyHtml.
|
|
6918
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'width');
|
|
6607
6919
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', 'content');
|
|
6608
6920
|
}
|
|
6609
6921
|
|
|
@@ -6617,11 +6929,11 @@ class TinyHtml_TinyHtml {
|
|
|
6617
6929
|
|
|
6618
6930
|
/**
|
|
6619
6931
|
* Returns padding box height.
|
|
6620
|
-
* @param {
|
|
6932
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6621
6933
|
* @returns {number}
|
|
6622
6934
|
*/
|
|
6623
6935
|
static innerHeight(el) {
|
|
6624
|
-
const elem = TinyHtml_TinyHtml.
|
|
6936
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'innerHeight');
|
|
6625
6937
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', 'padding');
|
|
6626
6938
|
}
|
|
6627
6939
|
|
|
@@ -6635,11 +6947,11 @@ class TinyHtml_TinyHtml {
|
|
|
6635
6947
|
|
|
6636
6948
|
/**
|
|
6637
6949
|
* Returns padding box width.
|
|
6638
|
-
* @param {
|
|
6950
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6639
6951
|
* @returns {number}
|
|
6640
6952
|
*/
|
|
6641
6953
|
static innerWidth(el) {
|
|
6642
|
-
const elem = TinyHtml_TinyHtml.
|
|
6954
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'innerWidth');
|
|
6643
6955
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', 'padding');
|
|
6644
6956
|
}
|
|
6645
6957
|
|
|
@@ -6653,14 +6965,14 @@ class TinyHtml_TinyHtml {
|
|
|
6653
6965
|
|
|
6654
6966
|
/**
|
|
6655
6967
|
* Returns outer height of the element, optionally including margin.
|
|
6656
|
-
* @param {
|
|
6968
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6657
6969
|
* @param {boolean} [includeMargin=false] - Whether to include margin.
|
|
6658
6970
|
* @returns {number}
|
|
6659
6971
|
*/
|
|
6660
6972
|
static outerHeight(el, includeMargin = false) {
|
|
6661
6973
|
if (typeof includeMargin !== 'boolean')
|
|
6662
6974
|
throw new TypeError('The "includeMargin" must be a boolean.');
|
|
6663
|
-
const elem = TinyHtml_TinyHtml.
|
|
6975
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'outerHeight');
|
|
6664
6976
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', includeMargin ? 'margin' : 'border');
|
|
6665
6977
|
}
|
|
6666
6978
|
|
|
@@ -6675,14 +6987,14 @@ class TinyHtml_TinyHtml {
|
|
|
6675
6987
|
|
|
6676
6988
|
/**
|
|
6677
6989
|
* Returns outer width of the element, optionally including margin.
|
|
6678
|
-
* @param {
|
|
6990
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6679
6991
|
* @param {boolean} [includeMargin=false] - Whether to include margin.
|
|
6680
6992
|
* @returns {number}
|
|
6681
6993
|
*/
|
|
6682
6994
|
static outerWidth(el, includeMargin = false) {
|
|
6683
6995
|
if (typeof includeMargin !== 'boolean')
|
|
6684
6996
|
throw new TypeError('The "includeMargin" must be a boolean.');
|
|
6685
|
-
const elem = TinyHtml_TinyHtml.
|
|
6997
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'outerWidth');
|
|
6686
6998
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', includeMargin ? 'margin' : 'border');
|
|
6687
6999
|
}
|
|
6688
7000
|
|
|
@@ -6855,6 +7167,7 @@ class TinyHtml_TinyHtml {
|
|
|
6855
7167
|
* Sets the vertical scroll position.
|
|
6856
7168
|
* @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
|
|
6857
7169
|
* @param {number} value - Scroll top value.
|
|
7170
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6858
7171
|
*/
|
|
6859
7172
|
static setScrollTop(el, value) {
|
|
6860
7173
|
if (typeof value !== 'number') throw new TypeError('ScrollTop value must be a number.');
|
|
@@ -6868,11 +7181,13 @@ class TinyHtml_TinyHtml {
|
|
|
6868
7181
|
elem.scrollTop = value;
|
|
6869
7182
|
}
|
|
6870
7183
|
});
|
|
7184
|
+
return el;
|
|
6871
7185
|
}
|
|
6872
7186
|
|
|
6873
7187
|
/**
|
|
6874
7188
|
* Sets the vertical scroll position.
|
|
6875
7189
|
* @param {number} value - Scroll top value.
|
|
7190
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6876
7191
|
*/
|
|
6877
7192
|
setScrollTop(value) {
|
|
6878
7193
|
return TinyHtml_TinyHtml.setScrollTop(this, value);
|
|
@@ -6882,6 +7197,7 @@ class TinyHtml_TinyHtml {
|
|
|
6882
7197
|
* Sets the horizontal scroll position.
|
|
6883
7198
|
* @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
|
|
6884
7199
|
* @param {number} value - Scroll left value.
|
|
7200
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6885
7201
|
*/
|
|
6886
7202
|
static setScrollLeft(el, value) {
|
|
6887
7203
|
if (typeof value !== 'number') throw new TypeError('ScrollLeft value must be a number.');
|
|
@@ -6895,11 +7211,13 @@ class TinyHtml_TinyHtml {
|
|
|
6895
7211
|
elem.scrollLeft = value;
|
|
6896
7212
|
}
|
|
6897
7213
|
});
|
|
7214
|
+
return el;
|
|
6898
7215
|
}
|
|
6899
7216
|
|
|
6900
7217
|
/**
|
|
6901
7218
|
* Sets the horizontal scroll position.
|
|
6902
7219
|
* @param {number} value - Scroll left value.
|
|
7220
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6903
7221
|
*/
|
|
6904
7222
|
setScrollLeft(value) {
|
|
6905
7223
|
return TinyHtml_TinyHtml.setScrollLeft(this, value);
|
|
@@ -7030,15 +7348,16 @@ class TinyHtml_TinyHtml {
|
|
|
7030
7348
|
|
|
7031
7349
|
/**
|
|
7032
7350
|
* Adds one or more CSS class names to the element.
|
|
7033
|
-
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) =>
|
|
7351
|
+
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to add.
|
|
7034
7352
|
*/
|
|
7035
7353
|
static addClass(el, ...args) {
|
|
7036
7354
|
TinyHtml_TinyHtml._preElems(el, 'addClass').forEach((elem) => elem.classList.add(...args));
|
|
7355
|
+
return el;
|
|
7037
7356
|
}
|
|
7038
7357
|
|
|
7039
7358
|
/**
|
|
7040
7359
|
* Adds one or more CSS class names to the element.
|
|
7041
|
-
* @type {(...tokens: string[]) =>
|
|
7360
|
+
* @type {(...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to add.
|
|
7042
7361
|
*/
|
|
7043
7362
|
addClass(...args) {
|
|
7044
7363
|
return TinyHtml_TinyHtml.addClass(this, ...args);
|
|
@@ -7046,15 +7365,16 @@ class TinyHtml_TinyHtml {
|
|
|
7046
7365
|
|
|
7047
7366
|
/**
|
|
7048
7367
|
* Removes one or more CSS class names from the element.
|
|
7049
|
-
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) =>
|
|
7368
|
+
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to remove.
|
|
7050
7369
|
*/
|
|
7051
7370
|
static removeClass(el, ...args) {
|
|
7052
7371
|
TinyHtml_TinyHtml._preElems(el, 'removeClass').forEach((elem) => elem.classList.remove(...args));
|
|
7372
|
+
return el;
|
|
7053
7373
|
}
|
|
7054
7374
|
|
|
7055
7375
|
/**
|
|
7056
7376
|
* Removes one or more CSS class names from the element.
|
|
7057
|
-
* @type {(...tokens: string[]) =>
|
|
7377
|
+
* @type {(...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to remove.
|
|
7058
7378
|
*/
|
|
7059
7379
|
removeClass(...args) {
|
|
7060
7380
|
return TinyHtml_TinyHtml.removeClass(this, ...args);
|
|
@@ -7264,15 +7584,18 @@ class TinyHtml_TinyHtml {
|
|
|
7264
7584
|
* Set text content of elements.
|
|
7265
7585
|
* @param {TinyElement|TinyElement[]} el
|
|
7266
7586
|
* @param {string} value
|
|
7587
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7267
7588
|
*/
|
|
7268
7589
|
static setText(el, value) {
|
|
7269
7590
|
if (typeof value !== 'string') throw new Error('Value is not a valid string.');
|
|
7270
7591
|
TinyHtml_TinyHtml._preElems(el, 'setText').forEach((el) => (el.textContent = value));
|
|
7592
|
+
return el;
|
|
7271
7593
|
}
|
|
7272
7594
|
|
|
7273
7595
|
/**
|
|
7274
7596
|
* Set text content of the element.
|
|
7275
7597
|
* @param {string} value
|
|
7598
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7276
7599
|
*/
|
|
7277
7600
|
setText(value) {
|
|
7278
7601
|
return TinyHtml_TinyHtml.setText(this, value);
|
|
@@ -7281,13 +7604,16 @@ class TinyHtml_TinyHtml {
|
|
|
7281
7604
|
/**
|
|
7282
7605
|
* Remove all child nodes from each element.
|
|
7283
7606
|
* @param {TinyElement|TinyElement[]} el
|
|
7607
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7284
7608
|
*/
|
|
7285
7609
|
static empty(el) {
|
|
7286
7610
|
TinyHtml_TinyHtml._preElems(el, 'empty').forEach((el) => (el.textContent = ''));
|
|
7611
|
+
return el;
|
|
7287
7612
|
}
|
|
7288
7613
|
|
|
7289
7614
|
/**
|
|
7290
7615
|
* Remove all child nodes of the element.
|
|
7616
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7291
7617
|
*/
|
|
7292
7618
|
empty() {
|
|
7293
7619
|
return TinyHtml_TinyHtml.empty(this);
|
|
@@ -7295,35 +7621,40 @@ class TinyHtml_TinyHtml {
|
|
|
7295
7621
|
|
|
7296
7622
|
/**
|
|
7297
7623
|
* Get the innerHTML of the element.
|
|
7298
|
-
* @param {TinyElement
|
|
7624
|
+
* @param {TinyElement} el
|
|
7625
|
+
* @param {GetHTMLOptions} [ops]
|
|
7299
7626
|
* @returns {string}
|
|
7300
7627
|
*/
|
|
7301
|
-
static html(el) {
|
|
7628
|
+
static html(el, ops) {
|
|
7302
7629
|
const elem = TinyHtml_TinyHtml._preElem(el, 'html');
|
|
7303
|
-
return elem.
|
|
7630
|
+
return elem.getHTML(ops);
|
|
7304
7631
|
}
|
|
7305
7632
|
|
|
7306
7633
|
/**
|
|
7307
7634
|
* Get the innerHTML of the element.
|
|
7635
|
+
* @param {GetHTMLOptions} [ops]
|
|
7308
7636
|
* @returns {string}
|
|
7309
7637
|
*/
|
|
7310
|
-
html() {
|
|
7311
|
-
return TinyHtml_TinyHtml.html(this);
|
|
7638
|
+
html(ops) {
|
|
7639
|
+
return TinyHtml_TinyHtml.html(this, ops);
|
|
7312
7640
|
}
|
|
7313
7641
|
|
|
7314
7642
|
/**
|
|
7315
7643
|
* Set the innerHTML of each element.
|
|
7316
7644
|
* @param {TinyElement|TinyElement[]} el
|
|
7317
7645
|
* @param {string} value
|
|
7646
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7318
7647
|
*/
|
|
7319
7648
|
static setHtml(el, value) {
|
|
7320
7649
|
if (typeof value !== 'string') throw new Error('Value is not a valid string.');
|
|
7321
7650
|
TinyHtml_TinyHtml._preElems(el, 'setHtml').forEach((el) => (el.innerHTML = value));
|
|
7651
|
+
return el;
|
|
7322
7652
|
}
|
|
7323
7653
|
|
|
7324
7654
|
/**
|
|
7325
7655
|
* Set the innerHTML of the element.
|
|
7326
7656
|
* @param {string} value
|
|
7657
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7327
7658
|
*/
|
|
7328
7659
|
setHtml(value) {
|
|
7329
7660
|
return TinyHtml_TinyHtml.setHtml(this, value);
|
|
@@ -7457,6 +7788,7 @@ class TinyHtml_TinyHtml {
|
|
|
7457
7788
|
* @param {TinyInputElement|TinyInputElement[]} el - Target element.
|
|
7458
7789
|
* @param {SetValueList|((el: InputElement, val: SetValueList) => SetValueList)} value - The value to assign or a function that returns it.
|
|
7459
7790
|
* @throws {Error} If the computed value is not a valid string or boolean.
|
|
7791
|
+
* @returns {TinyInputElement|TinyInputElement[]}
|
|
7460
7792
|
*/
|
|
7461
7793
|
static setVal(el, value) {
|
|
7462
7794
|
TinyHtml_TinyHtml._preInputElems(el, 'setVal').forEach((elem) => {
|
|
@@ -7496,6 +7828,7 @@ class TinyHtml_TinyHtml {
|
|
|
7496
7828
|
if (typeof valToSet === 'string') elem.value = valToSet;
|
|
7497
7829
|
}
|
|
7498
7830
|
});
|
|
7831
|
+
return el;
|
|
7499
7832
|
}
|
|
7500
7833
|
|
|
7501
7834
|
/**
|
|
@@ -7503,6 +7836,7 @@ class TinyHtml_TinyHtml {
|
|
|
7503
7836
|
* Accepts strings, numbers, booleans or arrays of these values, or a callback function that computes them.
|
|
7504
7837
|
*
|
|
7505
7838
|
* @param {SetValueList|((el: InputElement, val: SetValueList) => SetValueList)} value - The value to assign or a function that returns it.
|
|
7839
|
+
* @returns {TinyInputElement|TinyInputElement[]}
|
|
7506
7840
|
* @throws {Error} If the computed value is not a valid string or boolean.
|
|
7507
7841
|
*/
|
|
7508
7842
|
setVal(value) {
|
|
@@ -7772,6 +8106,7 @@ class TinyHtml_TinyHtml {
|
|
|
7772
8106
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7773
8107
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7774
8108
|
* @param {EventRegistryOptions} [options] - Optional event listener options.
|
|
8109
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7775
8110
|
*/
|
|
7776
8111
|
static on(el, event, handler, options) {
|
|
7777
8112
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7784,6 +8119,7 @@ class TinyHtml_TinyHtml {
|
|
|
7784
8119
|
if (!Array.isArray(events[event])) events[event] = [];
|
|
7785
8120
|
events[event].push({ handler, options });
|
|
7786
8121
|
});
|
|
8122
|
+
return el;
|
|
7787
8123
|
}
|
|
7788
8124
|
|
|
7789
8125
|
/**
|
|
@@ -7792,6 +8128,7 @@ class TinyHtml_TinyHtml {
|
|
|
7792
8128
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7793
8129
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7794
8130
|
* @param {EventRegistryOptions} [options] - Optional event listener options.
|
|
8131
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7795
8132
|
*/
|
|
7796
8133
|
on(event, handler, options) {
|
|
7797
8134
|
return TinyHtml_TinyHtml.on(this, event, handler, options);
|
|
@@ -7804,6 +8141,7 @@ class TinyHtml_TinyHtml {
|
|
|
7804
8141
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7805
8142
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7806
8143
|
* @param {EventRegistryOptions} [options={}] - Optional event listener options.
|
|
8144
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7807
8145
|
*/
|
|
7808
8146
|
static once(el, event, handler, options = {}) {
|
|
7809
8147
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7821,6 +8159,7 @@ class TinyHtml_TinyHtml {
|
|
|
7821
8159
|
typeof options === 'boolean' ? options : { ...options, once: true },
|
|
7822
8160
|
);
|
|
7823
8161
|
});
|
|
8162
|
+
return el;
|
|
7824
8163
|
}
|
|
7825
8164
|
|
|
7826
8165
|
/**
|
|
@@ -7829,6 +8168,7 @@ class TinyHtml_TinyHtml {
|
|
|
7829
8168
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7830
8169
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7831
8170
|
* @param {EventRegistryOptions} [options={}] - Optional event listener options.
|
|
8171
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7832
8172
|
*/
|
|
7833
8173
|
once(event, handler, options = {}) {
|
|
7834
8174
|
return TinyHtml_TinyHtml.once(this, event, handler, options);
|
|
@@ -7841,6 +8181,7 @@ class TinyHtml_TinyHtml {
|
|
|
7841
8181
|
* @param {string} event - The event type.
|
|
7842
8182
|
* @param {EventRegistryHandle} handler - The function originally bound to the event.
|
|
7843
8183
|
* @param {boolean|EventListenerOptions} [options] - Optional listener options.
|
|
8184
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7844
8185
|
*/
|
|
7845
8186
|
static off(el, event, handler, options) {
|
|
7846
8187
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7853,6 +8194,7 @@ class TinyHtml_TinyHtml {
|
|
|
7853
8194
|
if (events[event].length === 0) delete events[event];
|
|
7854
8195
|
}
|
|
7855
8196
|
});
|
|
8197
|
+
return el;
|
|
7856
8198
|
}
|
|
7857
8199
|
|
|
7858
8200
|
/**
|
|
@@ -7861,6 +8203,7 @@ class TinyHtml_TinyHtml {
|
|
|
7861
8203
|
* @param {string} event - The event type.
|
|
7862
8204
|
* @param {EventRegistryHandle} handler - The function originally bound to the event.
|
|
7863
8205
|
* @param {boolean|EventListenerOptions} [options] - Optional listener options.
|
|
8206
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7864
8207
|
*/
|
|
7865
8208
|
off(event, handler, options) {
|
|
7866
8209
|
return TinyHtml_TinyHtml.off(this, event, handler, options);
|
|
@@ -7871,6 +8214,7 @@ class TinyHtml_TinyHtml {
|
|
|
7871
8214
|
*
|
|
7872
8215
|
* @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
|
|
7873
8216
|
* @param {string} event - The event type to remove (e.g. 'click').
|
|
8217
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7874
8218
|
*/
|
|
7875
8219
|
static offAll(el, event) {
|
|
7876
8220
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7883,12 +8227,14 @@ class TinyHtml_TinyHtml {
|
|
|
7883
8227
|
delete events[event];
|
|
7884
8228
|
}
|
|
7885
8229
|
});
|
|
8230
|
+
return el;
|
|
7886
8231
|
}
|
|
7887
8232
|
|
|
7888
8233
|
/**
|
|
7889
8234
|
* Removes all event listeners of a specific type from the element.
|
|
7890
8235
|
*
|
|
7891
8236
|
* @param {string} event - The event type to remove (e.g. 'click').
|
|
8237
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7892
8238
|
*/
|
|
7893
8239
|
offAll(event) {
|
|
7894
8240
|
return TinyHtml_TinyHtml.offAll(this, event);
|
|
@@ -7900,6 +8246,7 @@ class TinyHtml_TinyHtml {
|
|
|
7900
8246
|
* @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
|
|
7901
8247
|
* @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
|
|
7902
8248
|
* Optional filter function to selectively remove specific handlers.
|
|
8249
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7903
8250
|
*/
|
|
7904
8251
|
static offAllTypes(el, filterFn = null) {
|
|
7905
8252
|
if (filterFn !== null && typeof filterFn !== 'function')
|
|
@@ -7918,6 +8265,7 @@ class TinyHtml_TinyHtml {
|
|
|
7918
8265
|
|
|
7919
8266
|
__eventRegistry.delete(elem);
|
|
7920
8267
|
});
|
|
8268
|
+
return el;
|
|
7921
8269
|
}
|
|
7922
8270
|
|
|
7923
8271
|
/**
|
|
@@ -7925,6 +8273,7 @@ class TinyHtml_TinyHtml {
|
|
|
7925
8273
|
*
|
|
7926
8274
|
* @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
|
|
7927
8275
|
* Optional filter function to selectively remove specific handlers.
|
|
8276
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7928
8277
|
*/
|
|
7929
8278
|
offAllTypes(filterFn = null) {
|
|
7930
8279
|
return TinyHtml_TinyHtml.offAllTypes(this, filterFn);
|
|
@@ -7936,6 +8285,7 @@ class TinyHtml_TinyHtml {
|
|
|
7936
8285
|
* @param {TinyEventTarget|TinyEventTarget[]} el - Target element where the event should be triggered.
|
|
7937
8286
|
* @param {string} event - Name of the event to trigger.
|
|
7938
8287
|
* @param {Event|CustomEvent|CustomEventInit} [payload] - Optional event object or data to pass.
|
|
8288
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7939
8289
|
*/
|
|
7940
8290
|
static trigger(el, event, payload = {}) {
|
|
7941
8291
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7951,6 +8301,7 @@ class TinyHtml_TinyHtml {
|
|
|
7951
8301
|
|
|
7952
8302
|
elem.dispatchEvent(evt);
|
|
7953
8303
|
});
|
|
8304
|
+
return el;
|
|
7954
8305
|
}
|
|
7955
8306
|
|
|
7956
8307
|
/**
|
|
@@ -7958,6 +8309,7 @@ class TinyHtml_TinyHtml {
|
|
|
7958
8309
|
*
|
|
7959
8310
|
* @param {string} event - Name of the event to trigger.
|
|
7960
8311
|
* @param {Event|CustomEvent|CustomEventInit} [payload] - Optional event object or data to pass.
|
|
8312
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7961
8313
|
*/
|
|
7962
8314
|
trigger(event, payload = {}) {
|
|
7963
8315
|
return TinyHtml_TinyHtml.trigger(this, event, payload);
|
|
@@ -8000,6 +8352,7 @@ class TinyHtml_TinyHtml {
|
|
|
8000
8352
|
* @param {TinyElement|TinyElement[]} el
|
|
8001
8353
|
* @param {string} name
|
|
8002
8354
|
* @param {string|null} [value=null]
|
|
8355
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8003
8356
|
*/
|
|
8004
8357
|
static setAttr(el, name, value = null) {
|
|
8005
8358
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8009,12 +8362,14 @@ class TinyHtml_TinyHtml {
|
|
|
8009
8362
|
if (value === null) elem.removeAttribute(name);
|
|
8010
8363
|
else elem.setAttribute(name, value);
|
|
8011
8364
|
});
|
|
8365
|
+
return el;
|
|
8012
8366
|
}
|
|
8013
8367
|
|
|
8014
8368
|
/**
|
|
8015
8369
|
* Set an attribute on an element.
|
|
8016
8370
|
* @param {string} name
|
|
8017
8371
|
* @param {string|null} [value=null]
|
|
8372
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8018
8373
|
*/
|
|
8019
8374
|
setAttr(name, value) {
|
|
8020
8375
|
return TinyHtml_TinyHtml.setAttr(this, name, value);
|
|
@@ -8024,15 +8379,18 @@ class TinyHtml_TinyHtml {
|
|
|
8024
8379
|
* Remove attribute(s) from an element.
|
|
8025
8380
|
* @param {TinyElement|TinyElement[]} el
|
|
8026
8381
|
* @param {string} name Space-separated list of attributes.
|
|
8382
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8027
8383
|
*/
|
|
8028
8384
|
static removeAttr(el, name) {
|
|
8029
8385
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
8030
8386
|
TinyHtml_TinyHtml._preElems(el, 'removeAttr').forEach((elem) => elem.removeAttribute(name));
|
|
8387
|
+
return el;
|
|
8031
8388
|
}
|
|
8032
8389
|
|
|
8033
8390
|
/**
|
|
8034
8391
|
* Remove attribute(s) from an element.
|
|
8035
8392
|
* @param {string} name Space-separated list of attributes.
|
|
8393
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8036
8394
|
*/
|
|
8037
8395
|
removeAttr(name) {
|
|
8038
8396
|
return TinyHtml_TinyHtml.removeAttr(this, name);
|
|
@@ -8087,6 +8445,7 @@ class TinyHtml_TinyHtml {
|
|
|
8087
8445
|
* Set a property on an element.
|
|
8088
8446
|
* @param {TinyElement|TinyElement[]} el
|
|
8089
8447
|
* @param {string} name
|
|
8448
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8090
8449
|
*/
|
|
8091
8450
|
static addProp(el, name) {
|
|
8092
8451
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8096,11 +8455,13 @@ class TinyHtml_TinyHtml {
|
|
|
8096
8455
|
// @ts-ignore
|
|
8097
8456
|
elem[name] = true;
|
|
8098
8457
|
});
|
|
8458
|
+
return el;
|
|
8099
8459
|
}
|
|
8100
8460
|
|
|
8101
8461
|
/**
|
|
8102
8462
|
* Set a property on an element.
|
|
8103
8463
|
* @param {string} name
|
|
8464
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8104
8465
|
*/
|
|
8105
8466
|
addProp(name) {
|
|
8106
8467
|
return TinyHtml_TinyHtml.addProp(this, name);
|
|
@@ -8110,6 +8471,7 @@ class TinyHtml_TinyHtml {
|
|
|
8110
8471
|
* Remove a property from an element.
|
|
8111
8472
|
* @param {TinyElement|TinyElement[]} el
|
|
8112
8473
|
* @param {string} name
|
|
8474
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8113
8475
|
*/
|
|
8114
8476
|
static removeProp(el, name) {
|
|
8115
8477
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8119,11 +8481,13 @@ class TinyHtml_TinyHtml {
|
|
|
8119
8481
|
// @ts-ignore
|
|
8120
8482
|
elem[name] = false;
|
|
8121
8483
|
});
|
|
8484
|
+
return el;
|
|
8122
8485
|
}
|
|
8123
8486
|
|
|
8124
8487
|
/**
|
|
8125
8488
|
* Remove a property from an element.
|
|
8126
8489
|
* @param {string} name
|
|
8490
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8127
8491
|
*/
|
|
8128
8492
|
removeProp(name) {
|
|
8129
8493
|
return TinyHtml_TinyHtml.removeProp(this, name);
|
|
@@ -8164,13 +8528,16 @@ class TinyHtml_TinyHtml {
|
|
|
8164
8528
|
/**
|
|
8165
8529
|
* Removes an element from the DOM.
|
|
8166
8530
|
* @param {TinyElement|TinyElement[]} el - The DOM element or selector to remove.
|
|
8531
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8167
8532
|
*/
|
|
8168
8533
|
static remove(el) {
|
|
8169
8534
|
TinyHtml_TinyHtml._preElems(el, 'remove').forEach((elem) => elem.remove());
|
|
8535
|
+
return el;
|
|
8170
8536
|
}
|
|
8171
8537
|
|
|
8172
8538
|
/**
|
|
8173
8539
|
* Removes the element from the DOM.
|
|
8540
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8174
8541
|
*/
|
|
8175
8542
|
remove() {
|
|
8176
8543
|
return TinyHtml_TinyHtml.remove(this);
|
|
@@ -8514,6 +8881,14 @@ class TinyHtml_TinyHtml {
|
|
|
8514
8881
|
*/
|
|
8515
8882
|
static isInViewport(el) {
|
|
8516
8883
|
const elem = TinyHtml_TinyHtml._preElem(el, 'isInViewport');
|
|
8884
|
+
if (
|
|
8885
|
+
!elem.checkVisibility({
|
|
8886
|
+
contentVisibilityAuto: false,
|
|
8887
|
+
opacityProperty: false,
|
|
8888
|
+
visibilityProperty: false,
|
|
8889
|
+
})
|
|
8890
|
+
)
|
|
8891
|
+
return false;
|
|
8517
8892
|
const elementTop = TinyHtml_TinyHtml.offset(elem).top;
|
|
8518
8893
|
const elementBottom = elementTop + TinyHtml_TinyHtml.outerHeight(elem);
|
|
8519
8894
|
|
|
@@ -8540,6 +8915,14 @@ class TinyHtml_TinyHtml {
|
|
|
8540
8915
|
*/
|
|
8541
8916
|
static isScrolledIntoView(el) {
|
|
8542
8917
|
const elem = TinyHtml_TinyHtml._preElem(el, 'isScrolledIntoView');
|
|
8918
|
+
if (
|
|
8919
|
+
!elem.checkVisibility({
|
|
8920
|
+
contentVisibilityAuto: false,
|
|
8921
|
+
opacityProperty: false,
|
|
8922
|
+
visibilityProperty: false,
|
|
8923
|
+
})
|
|
8924
|
+
)
|
|
8925
|
+
return false;
|
|
8543
8926
|
const docViewTop = TinyHtml_TinyHtml.scrollTop(window);
|
|
8544
8927
|
const docViewBottom = docViewTop + TinyHtml_TinyHtml.height(window);
|
|
8545
8928
|
|
|
@@ -8557,6 +8940,111 @@ class TinyHtml_TinyHtml {
|
|
|
8557
8940
|
isScrolledIntoView() {
|
|
8558
8941
|
return TinyHtml_TinyHtml.isScrolledIntoView(this);
|
|
8559
8942
|
}
|
|
8943
|
+
|
|
8944
|
+
/**
|
|
8945
|
+
* Checks if the given element is at least partially visible within the boundaries of a container.
|
|
8946
|
+
*
|
|
8947
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
8948
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
8949
|
+
* @returns {boolean} True if the element is partially visible within the container, false otherwise.
|
|
8950
|
+
*/
|
|
8951
|
+
static isInContainer(el, cont) {
|
|
8952
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'isInContainer');
|
|
8953
|
+
const container = TinyHtml_TinyHtml._preElem(cont, 'isInContainer');
|
|
8954
|
+
|
|
8955
|
+
if (
|
|
8956
|
+
!elem.checkVisibility({
|
|
8957
|
+
contentVisibilityAuto: false,
|
|
8958
|
+
opacityProperty: false,
|
|
8959
|
+
visibilityProperty: false,
|
|
8960
|
+
})
|
|
8961
|
+
)
|
|
8962
|
+
return false;
|
|
8963
|
+
const elemRect = elem.getBoundingClientRect();
|
|
8964
|
+
const containerRect = container.getBoundingClientRect();
|
|
8965
|
+
|
|
8966
|
+
const verticallyVisible =
|
|
8967
|
+
elemRect.bottom > containerRect.top && elemRect.top < containerRect.bottom;
|
|
8968
|
+
|
|
8969
|
+
const horizontallyVisible =
|
|
8970
|
+
elemRect.right > containerRect.left && elemRect.left < containerRect.right;
|
|
8971
|
+
|
|
8972
|
+
return verticallyVisible && horizontallyVisible;
|
|
8973
|
+
}
|
|
8974
|
+
|
|
8975
|
+
/**
|
|
8976
|
+
* Checks if the given element is at least partially visible within the boundaries of a container.
|
|
8977
|
+
*
|
|
8978
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
8979
|
+
* @returns {boolean} True if the element is partially visible within the container, false otherwise.
|
|
8980
|
+
*/
|
|
8981
|
+
isInContainer(cont) {
|
|
8982
|
+
return TinyHtml_TinyHtml.isInContainer(this, cont);
|
|
8983
|
+
}
|
|
8984
|
+
|
|
8985
|
+
/**
|
|
8986
|
+
* Checks if the given element is fully visible within the boundaries of a container (top and bottom).
|
|
8987
|
+
*
|
|
8988
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
8989
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
8990
|
+
* @returns {boolean} True if the element is fully visible within the container, false otherwise.
|
|
8991
|
+
*/
|
|
8992
|
+
static isFullyInContainer(el, cont) {
|
|
8993
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'isScrolledIntoView');
|
|
8994
|
+
const container = TinyHtml_TinyHtml._preElem(cont, 'isInContainer');
|
|
8995
|
+
|
|
8996
|
+
if (
|
|
8997
|
+
!elem.checkVisibility({
|
|
8998
|
+
contentVisibilityAuto: false,
|
|
8999
|
+
opacityProperty: false,
|
|
9000
|
+
visibilityProperty: false,
|
|
9001
|
+
})
|
|
9002
|
+
)
|
|
9003
|
+
return false;
|
|
9004
|
+
const elemRect = elem.getBoundingClientRect();
|
|
9005
|
+
const containerRect = container.getBoundingClientRect();
|
|
9006
|
+
|
|
9007
|
+
const isFullyVisible =
|
|
9008
|
+
elemRect.top >= containerRect.top &&
|
|
9009
|
+
elemRect.bottom <= containerRect.bottom &&
|
|
9010
|
+
elemRect.left >= containerRect.left &&
|
|
9011
|
+
elemRect.right <= containerRect.right;
|
|
9012
|
+
|
|
9013
|
+
return isFullyVisible;
|
|
9014
|
+
}
|
|
9015
|
+
|
|
9016
|
+
/**
|
|
9017
|
+
* Checks if the given element is fully visible within the boundaries of a container (top and bottom).
|
|
9018
|
+
*
|
|
9019
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
9020
|
+
* @returns {boolean} True if the element is fully visible within the container, false otherwise.
|
|
9021
|
+
*/
|
|
9022
|
+
isFullyInContainer(cont) {
|
|
9023
|
+
return TinyHtml_TinyHtml.isFullyInContainer(this, cont);
|
|
9024
|
+
}
|
|
9025
|
+
|
|
9026
|
+
/**
|
|
9027
|
+
* Checks if an element has scrollable content.
|
|
9028
|
+
*
|
|
9029
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
9030
|
+
* @returns {{ v: boolean, h: boolean }} - True if scroll is needed in that direction.
|
|
9031
|
+
*/
|
|
9032
|
+
static hasScroll(el) {
|
|
9033
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'hasScroll');
|
|
9034
|
+
return {
|
|
9035
|
+
v: elem.scrollHeight > elem.clientHeight,
|
|
9036
|
+
h: elem.scrollWidth > elem.clientWidth,
|
|
9037
|
+
};
|
|
9038
|
+
}
|
|
9039
|
+
|
|
9040
|
+
/**
|
|
9041
|
+
* Checks if an element has scrollable content.
|
|
9042
|
+
*
|
|
9043
|
+
* @returns {{ v: boolean, h: boolean }} - True if scroll is needed in that direction.
|
|
9044
|
+
*/
|
|
9045
|
+
hasScroll() {
|
|
9046
|
+
return TinyHtml_TinyHtml.hasScroll(this);
|
|
9047
|
+
}
|
|
8560
9048
|
}
|
|
8561
9049
|
|
|
8562
9050
|
/* harmony default export */ const libs_TinyHtml = (TinyHtml_TinyHtml);
|
|
@@ -10327,7 +10815,985 @@ class TinyDragger {
|
|
|
10327
10815
|
|
|
10328
10816
|
/* harmony default export */ const libs_TinyDragger = ((/* unused pure expression or super */ null && (TinyDragger)));
|
|
10329
10817
|
|
|
10330
|
-
;// ./src/v1/
|
|
10818
|
+
;// ./src/v1/libs/TinySmartScroller.mjs
|
|
10819
|
+
|
|
10820
|
+
|
|
10821
|
+
|
|
10822
|
+
/**
|
|
10823
|
+
* Represents the dimensions of a DOM element.
|
|
10824
|
+
*
|
|
10825
|
+
* @typedef {Object} NodeSizes
|
|
10826
|
+
* @property {number} height - The height of the element in pixels.
|
|
10827
|
+
* @property {number} width - The width of the element in pixels.
|
|
10828
|
+
*/
|
|
10829
|
+
|
|
10830
|
+
/**
|
|
10831
|
+
* A callback function that receives node size change data and optionally returns a modified NodeSizes object.
|
|
10832
|
+
*
|
|
10833
|
+
* @callback NodeSizesEvent
|
|
10834
|
+
* @param {Element} elem - The DOM element whose size is being tracked.
|
|
10835
|
+
* @param {{ old: NodeSizes, now: NodeSizes }} sizes - The old and new size measurements of the element.
|
|
10836
|
+
* @param {{ old: number, now: number }} elemAmount - The number of matching elements before and after the update.
|
|
10837
|
+
* @returns {NodeSizes|undefined} A modified NodeSizes object to override the default measurement, or undefined to use the original.
|
|
10838
|
+
*/
|
|
10839
|
+
|
|
10840
|
+
/**
|
|
10841
|
+
* A generic scroll-related event listener callback function.
|
|
10842
|
+
*
|
|
10843
|
+
* @callback ScrollListenersFunc
|
|
10844
|
+
* @param {any} payload - The data payload passed when the scroll event is triggered. The type may vary depending on the event.
|
|
10845
|
+
* @returns {void}
|
|
10846
|
+
*/
|
|
10847
|
+
|
|
10848
|
+
/**
|
|
10849
|
+
* TinySmartScroller is a utility class designed to enhance and manage scroll behaviors within containers or the window.
|
|
10850
|
+
*
|
|
10851
|
+
* It enables advanced scroll monitoring, auto-scrolling to bottom, preserving scroll position during DOM changes,
|
|
10852
|
+
* and detecting visibility changes of elements. This is particularly useful for dynamic UIs like chat applications,
|
|
10853
|
+
* feed viewers, or live content containers.
|
|
10854
|
+
*
|
|
10855
|
+
* Features:
|
|
10856
|
+
* - Detects when the scroll reaches the top, bottom, or custom boundaries
|
|
10857
|
+
* - Supports automatic scrolling to the bottom unless the user scrolls away
|
|
10858
|
+
* - Observes DOM mutations and resizes, and adapts scroll position accordingly
|
|
10859
|
+
* - Emits scroll-related events such as 'onScrollBoundary', 'onAutoScroll', and 'onScrollPause'
|
|
10860
|
+
* - Includes customizable scroll correction filters for layout shift mitigation
|
|
10861
|
+
* - Handles media element load events (e.g. `<img>`, `<iframe>`, `<video>`) to prevent sudden scroll jumps
|
|
10862
|
+
*
|
|
10863
|
+
* This class is **not framework-dependent** and works with vanilla DOM elements and the window object.
|
|
10864
|
+
*/
|
|
10865
|
+
class TinySmartScroller {
|
|
10866
|
+
static Utils = { ...collision_namespaceObject, TinyHtml: libs_TinyHtml };
|
|
10867
|
+
|
|
10868
|
+
/** @type {WeakMap<Element, NodeSizes>} */
|
|
10869
|
+
#oldSizes = new WeakMap();
|
|
10870
|
+
/** @type {WeakMap<Element, NodeSizes>} */
|
|
10871
|
+
#newSizes = new WeakMap();
|
|
10872
|
+
|
|
10873
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
10874
|
+
#newVisibles = new WeakMap();
|
|
10875
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
10876
|
+
#oldVisibles = new WeakMap();
|
|
10877
|
+
|
|
10878
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
10879
|
+
#newVisiblesByTime = new WeakMap();
|
|
10880
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
10881
|
+
#oldVisiblesByTime = new WeakMap();
|
|
10882
|
+
|
|
10883
|
+
/** @type {Record<string, ScrollListenersFunc[]>} */
|
|
10884
|
+
#scrollListeners = {};
|
|
10885
|
+
|
|
10886
|
+
/** @type {ResizeObserver|null} */
|
|
10887
|
+
#resizeObserver = null;
|
|
10888
|
+
/** @type {MutationObserver|null} */
|
|
10889
|
+
#mutationObserver = null;
|
|
10890
|
+
|
|
10891
|
+
/** @type {Set<string>} */
|
|
10892
|
+
#loadTags = new Set(['IMG', 'IFRAME', 'VIDEO']);
|
|
10893
|
+
|
|
10894
|
+
/** @type {null|EventListenerOrEventListenerObject} */
|
|
10895
|
+
#handler = null;
|
|
10896
|
+
|
|
10897
|
+
#isAtBottom = false;
|
|
10898
|
+
#isAtTop = false;
|
|
10899
|
+
#isAtCustomTop = false;
|
|
10900
|
+
#isAtCustomBottom = false;
|
|
10901
|
+
|
|
10902
|
+
#querySelector = '';
|
|
10903
|
+
#useWindow = false;
|
|
10904
|
+
#destroyed = false;
|
|
10905
|
+
#scrollPaused = false;
|
|
10906
|
+
#autoScrollBottom = false;
|
|
10907
|
+
#observeMutations = false;
|
|
10908
|
+
#preserveScrollOnLayoutShift = false;
|
|
10909
|
+
#debounceTime = 0;
|
|
10910
|
+
#elemAmount = 0;
|
|
10911
|
+
#elemOldAmount = 0;
|
|
10912
|
+
#lastKnownScrollBottomOffset = 0;
|
|
10913
|
+
#extraScrollBoundary = 0;
|
|
10914
|
+
|
|
10915
|
+
/** @type {Set<string>} */
|
|
10916
|
+
#attributeFilter;
|
|
10917
|
+
|
|
10918
|
+
/** @type {Element} */
|
|
10919
|
+
#target;
|
|
10920
|
+
|
|
10921
|
+
/** @type {Set<NodeSizesEvent>} */
|
|
10922
|
+
#sizeFilter = new Set();
|
|
10923
|
+
|
|
10924
|
+
/**
|
|
10925
|
+
* Creates a new instance of TinySmartScroller, attaching scroll and resize observers to manage
|
|
10926
|
+
* automatic scroll behaviors, layout shift correction, and visibility tracking.
|
|
10927
|
+
*
|
|
10928
|
+
* @param {Element|Window} target - The scroll container to monitor. Can be an element or `window`.
|
|
10929
|
+
* @param {Object} [options={}] - Optional settings to configure scroll behavior.
|
|
10930
|
+
* @param {number} [options.extraScrollBoundary=0] - Extra margin in pixels to extend scroll boundary detection.
|
|
10931
|
+
* @param {boolean} [options.autoScrollBottom=true] - Whether to auto-scroll to bottom on layout updates.
|
|
10932
|
+
* @param {boolean} [options.observeMutations=true] - Enables MutationObserver to detect DOM changes.
|
|
10933
|
+
* @param {boolean} [options.preserveScrollOnLayoutShift=true] - Prevents scroll jumps when layout changes.
|
|
10934
|
+
* @param {number} [options.debounceTime=100] - Debounce time in milliseconds for scroll events.
|
|
10935
|
+
* @param {string|null} [options.querySelector=null] - Optional CSS selector to filter observed child nodes.
|
|
10936
|
+
* @param {string[]|Set<string>|null} [options.attributeFilter=['class', 'style', 'src', 'data-*', 'height', 'width']]
|
|
10937
|
+
* - Which attributes to observe for changes.
|
|
10938
|
+
*/
|
|
10939
|
+
constructor(
|
|
10940
|
+
target,
|
|
10941
|
+
{
|
|
10942
|
+
extraScrollBoundary = 0,
|
|
10943
|
+
autoScrollBottom = true,
|
|
10944
|
+
observeMutations = true,
|
|
10945
|
+
preserveScrollOnLayoutShift = true,
|
|
10946
|
+
debounceTime = 100,
|
|
10947
|
+
querySelector = null,
|
|
10948
|
+
attributeFilter = ['class', 'style', 'src', 'data-*', 'height', 'width'],
|
|
10949
|
+
} = {},
|
|
10950
|
+
) {
|
|
10951
|
+
// === target ===
|
|
10952
|
+
if (!(target instanceof Element || target === window))
|
|
10953
|
+
throw new TypeError(
|
|
10954
|
+
`TinySmartScroller: 'target' must be a DOM Element or 'window', but got ${typeof target}`,
|
|
10955
|
+
);
|
|
10956
|
+
// === extraScrollBoundary ===
|
|
10957
|
+
if (typeof extraScrollBoundary !== 'number' || Number.isNaN(extraScrollBoundary))
|
|
10958
|
+
throw new TypeError(
|
|
10959
|
+
`TinySmartScroller: 'extraScrollBoundary' must be a valid number, received ${extraScrollBoundary}`,
|
|
10960
|
+
);
|
|
10961
|
+
// === autoScrollBottom ===
|
|
10962
|
+
if (typeof autoScrollBottom !== 'boolean')
|
|
10963
|
+
throw new TypeError(
|
|
10964
|
+
`TinySmartScroller: 'autoScrollBottom' must be a boolean, received ${typeof autoScrollBottom}`,
|
|
10965
|
+
);
|
|
10966
|
+
// === observeMutations ===
|
|
10967
|
+
if (typeof observeMutations !== 'boolean')
|
|
10968
|
+
throw new TypeError(
|
|
10969
|
+
`TinySmartScroller: 'observeMutations' must be a boolean, received ${typeof observeMutations}`,
|
|
10970
|
+
);
|
|
10971
|
+
// === preserveScrollOnLayoutShift ===
|
|
10972
|
+
if (typeof preserveScrollOnLayoutShift !== 'boolean')
|
|
10973
|
+
throw new TypeError(
|
|
10974
|
+
`TinySmartScroller: 'preserveScrollOnLayoutShift' must be a boolean, received ${typeof preserveScrollOnLayoutShift}`,
|
|
10975
|
+
);
|
|
10976
|
+
// === debounceTime ===
|
|
10977
|
+
if (typeof debounceTime !== 'number' || debounceTime < 0 || Number.isNaN(debounceTime))
|
|
10978
|
+
throw new TypeError(
|
|
10979
|
+
`TinySmartScroller: 'debounceTime' must be a non-negative number, received ${debounceTime}`,
|
|
10980
|
+
);
|
|
10981
|
+
// === querySelector ===
|
|
10982
|
+
if (querySelector !== null && typeof querySelector !== 'string')
|
|
10983
|
+
throw new TypeError(
|
|
10984
|
+
`TinySmartScroller: 'querySelector' must be a string or null, received ${typeof querySelector}`,
|
|
10985
|
+
);
|
|
10986
|
+
// === attributeFilter ===
|
|
10987
|
+
const isValidAttrList =
|
|
10988
|
+
attributeFilter === null || Array.isArray(attributeFilter) || attributeFilter instanceof Set;
|
|
10989
|
+
if (!isValidAttrList)
|
|
10990
|
+
throw new TypeError(
|
|
10991
|
+
`TinySmartScroller: 'attributeFilter' must be an array, Set, or null. Got ${typeof attributeFilter}`,
|
|
10992
|
+
);
|
|
10993
|
+
|
|
10994
|
+
// Start values
|
|
10995
|
+
this.#target = target instanceof Window ? document.documentElement : target;
|
|
10996
|
+
this.#useWindow = target instanceof Window;
|
|
10997
|
+
this.#autoScrollBottom = autoScrollBottom;
|
|
10998
|
+
this.#observeMutations = observeMutations;
|
|
10999
|
+
this.#preserveScrollOnLayoutShift = preserveScrollOnLayoutShift;
|
|
11000
|
+
this.#debounceTime = debounceTime;
|
|
11001
|
+
this.#extraScrollBoundary = extraScrollBoundary;
|
|
11002
|
+
this.#querySelector = querySelector || '';
|
|
11003
|
+
this.#attributeFilter = new Set(attributeFilter || undefined);
|
|
11004
|
+
|
|
11005
|
+
// Bind scroll
|
|
11006
|
+
/** @type {NodeJS.Timeout} */
|
|
11007
|
+
let timeout;
|
|
11008
|
+
this.#handler = () => {
|
|
11009
|
+
this._scrollDataUpdater();
|
|
11010
|
+
clearTimeout(timeout);
|
|
11011
|
+
timeout = setTimeout(() => this._onScroll(), this.#debounceTime);
|
|
11012
|
+
};
|
|
11013
|
+
(this.#useWindow ? window : this.#target).addEventListener('scroll', this.#handler, {
|
|
11014
|
+
passive: true,
|
|
11015
|
+
});
|
|
11016
|
+
|
|
11017
|
+
// Mutations
|
|
11018
|
+
if (this.#observeMutations) {
|
|
11019
|
+
this._observeMutations();
|
|
11020
|
+
this._observeResizes(this.#target.children);
|
|
11021
|
+
}
|
|
11022
|
+
|
|
11023
|
+
this._scrollDataUpdater();
|
|
11024
|
+
}
|
|
11025
|
+
|
|
11026
|
+
/**
|
|
11027
|
+
* Returns a size difference callback that only reacts when height changes, filtered by tag name.
|
|
11028
|
+
*
|
|
11029
|
+
* @param {string[]} filter - List of tag names to allow. If empty, all tags are accepted.
|
|
11030
|
+
* @returns {NodeSizesEvent} A function that compares previous and current height, returning height delta.
|
|
11031
|
+
*/
|
|
11032
|
+
getSimpleOnHeight(filter = []) {
|
|
11033
|
+
if (!Array.isArray(filter))
|
|
11034
|
+
throw new TypeError('getSimpleOnHeight(filter): filter must be an array of tag names');
|
|
11035
|
+
return (elem, sizes, amounts) => {
|
|
11036
|
+
if ((filter.length > 0 && !filter.includes(elem.tagName)) || amounts.now !== amounts.old)
|
|
11037
|
+
return;
|
|
11038
|
+
const oldSize = sizes.old;
|
|
11039
|
+
const newSize = sizes.now;
|
|
11040
|
+
const height = newSize.height - oldSize.height;
|
|
11041
|
+
return { height, width: 0 };
|
|
11042
|
+
};
|
|
11043
|
+
}
|
|
11044
|
+
|
|
11045
|
+
/**
|
|
11046
|
+
* Adds a height difference callback to the size filter system.
|
|
11047
|
+
*
|
|
11048
|
+
* @param {string[]} filter - List of tag names to allow.
|
|
11049
|
+
* @returns {NodeSizesEvent} The added size difference callback.
|
|
11050
|
+
*/
|
|
11051
|
+
addSimpleOnHeight(filter) {
|
|
11052
|
+
if (!Array.isArray(filter))
|
|
11053
|
+
throw new TypeError('addSimpleOnHeight(filter): filter must be an array of tag names');
|
|
11054
|
+
const result = this.getSimpleOnHeight(filter);
|
|
11055
|
+
this.onSize(result);
|
|
11056
|
+
return result;
|
|
11057
|
+
}
|
|
11058
|
+
|
|
11059
|
+
/**
|
|
11060
|
+
* Returns a list of all currently tracked load tags.
|
|
11061
|
+
*
|
|
11062
|
+
* @returns {string[]} Array of tag names.
|
|
11063
|
+
*/
|
|
11064
|
+
getLoadTags() {
|
|
11065
|
+
return Array.from(this.#loadTags);
|
|
11066
|
+
}
|
|
11067
|
+
|
|
11068
|
+
/**
|
|
11069
|
+
* Adds a new tag to the set of load tags.
|
|
11070
|
+
*
|
|
11071
|
+
* @param {string} tag - The tag name to add (e.g., 'IMG').
|
|
11072
|
+
*/
|
|
11073
|
+
addLoadTag(tag) {
|
|
11074
|
+
if (typeof tag !== 'string') throw new TypeError('addLoadTag(tag): tag must be a string');
|
|
11075
|
+
this.#loadTags.add(tag.toUpperCase());
|
|
11076
|
+
}
|
|
11077
|
+
|
|
11078
|
+
/**
|
|
11079
|
+
* Removes a tag from the set of load tags.
|
|
11080
|
+
*
|
|
11081
|
+
* @param {string} tag - The tag name to remove.
|
|
11082
|
+
*/
|
|
11083
|
+
removeLoadTag(tag) {
|
|
11084
|
+
if (typeof tag !== 'string') throw new TypeError('removeLoadTag(tag): tag must be a string');
|
|
11085
|
+
this.#loadTags.delete(tag.toUpperCase());
|
|
11086
|
+
}
|
|
11087
|
+
|
|
11088
|
+
/**
|
|
11089
|
+
* Checks whether a tag is tracked as a load tag.
|
|
11090
|
+
*
|
|
11091
|
+
* @param {string} tag - The tag name to check.
|
|
11092
|
+
* @returns {boolean} True if the tag is being tracked.
|
|
11093
|
+
*/
|
|
11094
|
+
hasLoadTag(tag) {
|
|
11095
|
+
if (typeof tag !== 'string') throw new TypeError('hasLoadTag(tag): tag must be a string');
|
|
11096
|
+
return this.#loadTags.has(tag.toUpperCase());
|
|
11097
|
+
}
|
|
11098
|
+
|
|
11099
|
+
/**
|
|
11100
|
+
* Clears the set of load tags. If `addDefault` is true, it will reset to the default tags: 'IMG', 'IFRAME', and 'VIDEO'.
|
|
11101
|
+
*
|
|
11102
|
+
* @param {boolean} [addDefault=false] - Whether to restore the default tags after clearing.
|
|
11103
|
+
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
11104
|
+
*/
|
|
11105
|
+
resetLoadTags(addDefault = false) {
|
|
11106
|
+
if (typeof addDefault !== 'boolean')
|
|
11107
|
+
throw new TypeError('resetLoadTags(addDefault): addDefault must be a boolean');
|
|
11108
|
+
this.#loadTags.clear();
|
|
11109
|
+
if (!addDefault) return;
|
|
11110
|
+
this.#loadTags.add('IMG');
|
|
11111
|
+
this.#loadTags.add('IFRAME');
|
|
11112
|
+
this.#loadTags.add('VIDEO');
|
|
11113
|
+
}
|
|
11114
|
+
|
|
11115
|
+
/**
|
|
11116
|
+
* Returns a list of all currently tracked attribute filters.
|
|
11117
|
+
*
|
|
11118
|
+
* @returns {string[]} Array of attribute names.
|
|
11119
|
+
*/
|
|
11120
|
+
getAttributeFilters() {
|
|
11121
|
+
return Array.from(this.#attributeFilter);
|
|
11122
|
+
}
|
|
11123
|
+
|
|
11124
|
+
/**
|
|
11125
|
+
* Adds an attribute to the filter list.
|
|
11126
|
+
*
|
|
11127
|
+
* @param {string} attr - The attribute name to add.
|
|
11128
|
+
*/
|
|
11129
|
+
addAttributeFilter(attr) {
|
|
11130
|
+
if (typeof attr !== 'string')
|
|
11131
|
+
throw new TypeError('addAttributeFilter(attr): attr must be a string');
|
|
11132
|
+
this.#attributeFilter.add(attr);
|
|
11133
|
+
}
|
|
11134
|
+
|
|
11135
|
+
/**
|
|
11136
|
+
* Removes an attribute from the filter list.
|
|
11137
|
+
*
|
|
11138
|
+
* @param {string} attr - The attribute name to remove.
|
|
11139
|
+
*/
|
|
11140
|
+
removeAttributeFilter(attr) {
|
|
11141
|
+
if (typeof attr !== 'string')
|
|
11142
|
+
throw new TypeError('removeAttributeFilter(attr): attr must be a string');
|
|
11143
|
+
this.#attributeFilter.delete(attr);
|
|
11144
|
+
}
|
|
11145
|
+
|
|
11146
|
+
/**
|
|
11147
|
+
* Checks whether a specific attribute is being filtered.
|
|
11148
|
+
*
|
|
11149
|
+
* @param {string} attr - The attribute name to check.
|
|
11150
|
+
* @returns {boolean} True if the attribute is being filtered.
|
|
11151
|
+
*/
|
|
11152
|
+
hasAttributeFilter(attr) {
|
|
11153
|
+
if (typeof attr !== 'string')
|
|
11154
|
+
throw new TypeError('hasAttributeFilter(attr): attr must be a string');
|
|
11155
|
+
return this.#attributeFilter.has(attr);
|
|
11156
|
+
}
|
|
11157
|
+
|
|
11158
|
+
/**
|
|
11159
|
+
* Clears the set of observed attribute filters. If `addDefault` is true, it will reset to the default attributes:
|
|
11160
|
+
* 'class', 'style', 'src', 'data-*', 'height', and 'width'.
|
|
11161
|
+
*
|
|
11162
|
+
* @param {boolean} [addDefault=false] - Whether to restore the default attribute filters after clearing.
|
|
11163
|
+
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
11164
|
+
*/
|
|
11165
|
+
resetAttributeFilters(addDefault = false) {
|
|
11166
|
+
if (typeof addDefault !== 'boolean')
|
|
11167
|
+
throw new TypeError('resetAttributeFilters(addDefault): addDefault must be a boolean');
|
|
11168
|
+
this.#attributeFilter.clear();
|
|
11169
|
+
if (!addDefault) return;
|
|
11170
|
+
['class', 'style', 'src', 'data-*', 'height', 'width'].forEach((attr) =>
|
|
11171
|
+
this.#attributeFilter.add(attr),
|
|
11172
|
+
);
|
|
11173
|
+
}
|
|
11174
|
+
|
|
11175
|
+
/**
|
|
11176
|
+
* Registers a custom node size change handler to the internal size filter set.
|
|
11177
|
+
*
|
|
11178
|
+
* @param {NodeSizesEvent} handler - Function that compares old and new sizes.
|
|
11179
|
+
*/
|
|
11180
|
+
onSize(handler) {
|
|
11181
|
+
if (this.#destroyed) return;
|
|
11182
|
+
if (typeof handler !== 'function')
|
|
11183
|
+
throw new TypeError('onSize(handler): handler must be a function');
|
|
11184
|
+
this.#sizeFilter.add(handler);
|
|
11185
|
+
}
|
|
11186
|
+
|
|
11187
|
+
/**
|
|
11188
|
+
* Unregisters a previously registered size handler from the internal filter set.
|
|
11189
|
+
*
|
|
11190
|
+
* @param {NodeSizesEvent} handler - The handler function to remove.
|
|
11191
|
+
*/
|
|
11192
|
+
offSize(handler) {
|
|
11193
|
+
if (this.#destroyed) return;
|
|
11194
|
+
if (typeof handler !== 'function')
|
|
11195
|
+
throw new TypeError('offSize(handler): handler must be a function');
|
|
11196
|
+
this.#sizeFilter.delete(handler);
|
|
11197
|
+
}
|
|
11198
|
+
|
|
11199
|
+
/**
|
|
11200
|
+
* Adds a scroll-related event listener.
|
|
11201
|
+
*
|
|
11202
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
11203
|
+
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
|
|
11204
|
+
*/
|
|
11205
|
+
on(event, handler) {
|
|
11206
|
+
if (this.#destroyed) return;
|
|
11207
|
+
if (typeof event !== 'string')
|
|
11208
|
+
throw new TypeError('on(event, handler): event name must be a string');
|
|
11209
|
+
if (typeof handler !== 'function')
|
|
11210
|
+
throw new TypeError('on(event, handler): handler must be a function');
|
|
11211
|
+
|
|
11212
|
+
if (!this.#scrollListeners[event]) this.#scrollListeners[event] = [];
|
|
11213
|
+
this.#scrollListeners[event].push(handler);
|
|
11214
|
+
}
|
|
11215
|
+
|
|
11216
|
+
/**
|
|
11217
|
+
* Removes a previously registered scroll-related event listener.
|
|
11218
|
+
*
|
|
11219
|
+
* @param {string} event - The name of the event to remove the handler from.
|
|
11220
|
+
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
|
|
11221
|
+
*/
|
|
11222
|
+
off(event, handler) {
|
|
11223
|
+
if (this.#destroyed) return;
|
|
11224
|
+
if (typeof event !== 'string')
|
|
11225
|
+
throw new TypeError('off(event, handler): event name must be a string');
|
|
11226
|
+
if (typeof handler !== 'function')
|
|
11227
|
+
throw new TypeError('off(event, handler): handler must be a function');
|
|
11228
|
+
|
|
11229
|
+
const listeners = this.#scrollListeners[event];
|
|
11230
|
+
if (!Array.isArray(listeners)) return;
|
|
11231
|
+
|
|
11232
|
+
const index = listeners.indexOf(handler);
|
|
11233
|
+
if (index !== -1) listeners.splice(index, 1);
|
|
11234
|
+
|
|
11235
|
+
// Optionally clean up empty arrays (optional)
|
|
11236
|
+
if (listeners.length === 0) delete this.#scrollListeners[event];
|
|
11237
|
+
}
|
|
11238
|
+
|
|
11239
|
+
/**
|
|
11240
|
+
* Checks which elements inside the target are currently visible and updates internal maps.
|
|
11241
|
+
*
|
|
11242
|
+
* @returns {Map<Element, { oldIsVisible: boolean; isVisible: boolean }>} Visibility comparison results.
|
|
11243
|
+
*/
|
|
11244
|
+
_scrollDataUpdater() {
|
|
11245
|
+
const results = new Map();
|
|
11246
|
+
this.#target.querySelectorAll(this.#querySelector || '*').forEach((target) => {
|
|
11247
|
+
const oldIsVisible = this.#newVisibles.get(target) ?? false;
|
|
11248
|
+
this.#oldVisibles.set(target, oldIsVisible);
|
|
11249
|
+
|
|
11250
|
+
const isVisible = libs_TinyHtml.isInContainer(this.#target, target);
|
|
11251
|
+
this.#newVisibles.set(target, isVisible);
|
|
11252
|
+
|
|
11253
|
+
results.set(target, { oldIsVisible, isVisible });
|
|
11254
|
+
});
|
|
11255
|
+
return results;
|
|
11256
|
+
}
|
|
11257
|
+
|
|
11258
|
+
/**
|
|
11259
|
+
* Emits a scroll-related event to all registered listeners.
|
|
11260
|
+
*
|
|
11261
|
+
* @param {string} event - Event name.
|
|
11262
|
+
* @param {*} [payload] - Optional event data payload.
|
|
11263
|
+
*/
|
|
11264
|
+
_emit(event, payload) {
|
|
11265
|
+
if (this.#destroyed) return;
|
|
11266
|
+
if (typeof event !== 'string')
|
|
11267
|
+
throw new TypeError('_emit(event, payload): event name must be a string');
|
|
11268
|
+
(this.#scrollListeners[event] || []).forEach((fn) => fn(payload));
|
|
11269
|
+
}
|
|
11270
|
+
|
|
11271
|
+
/**
|
|
11272
|
+
* Handles scroll events, calculates position-related statuses, and emits appropriate events.
|
|
11273
|
+
*/
|
|
11274
|
+
_onScroll() {
|
|
11275
|
+
if (this.#destroyed) return;
|
|
11276
|
+
// Get values
|
|
11277
|
+
const scrollCache = this._scrollDataUpdater();
|
|
11278
|
+
const el = this.#target;
|
|
11279
|
+
const scrollTop = el.scrollTop;
|
|
11280
|
+
const scrollHeight = el.scrollHeight;
|
|
11281
|
+
const clientHeight = el.clientHeight;
|
|
11282
|
+
|
|
11283
|
+
// Prepare sroll values
|
|
11284
|
+
const scrollResult = { scrollTop, scrollHeight, clientHeight };
|
|
11285
|
+
let atResult = null;
|
|
11286
|
+
let atCustomResult = null;
|
|
11287
|
+
|
|
11288
|
+
const atTop = scrollTop === 0;
|
|
11289
|
+
const atBottom = scrollTop + clientHeight >= scrollHeight - 1;
|
|
11290
|
+
|
|
11291
|
+
const atCustomTop = scrollTop <= 0 + this.#extraScrollBoundary;
|
|
11292
|
+
const atCustomBottom = scrollTop + clientHeight >= scrollHeight - 1 - this.#extraScrollBoundary;
|
|
11293
|
+
|
|
11294
|
+
// Scroll results
|
|
11295
|
+
if (atTop && atBottom) atResult = 'all';
|
|
11296
|
+
else if (atTop) atResult = 'top';
|
|
11297
|
+
else if (atBottom) atResult = 'bottom';
|
|
11298
|
+
|
|
11299
|
+
if (atCustomTop && atCustomBottom) atCustomResult = 'all';
|
|
11300
|
+
else if (atCustomTop) atCustomResult = 'top';
|
|
11301
|
+
else if (atCustomBottom) atCustomResult = 'bottom';
|
|
11302
|
+
|
|
11303
|
+
this.#isAtTop = atTop;
|
|
11304
|
+
this.#isAtBottom = atBottom;
|
|
11305
|
+
|
|
11306
|
+
this.#isAtCustomTop = atCustomTop;
|
|
11307
|
+
this.#isAtCustomBottom = atCustomBottom;
|
|
11308
|
+
|
|
11309
|
+
this.#scrollPaused = !(this.#autoScrollBottom && this.#isAtBottom);
|
|
11310
|
+
|
|
11311
|
+
this.#lastKnownScrollBottomOffset = scrollHeight - scrollTop - clientHeight;
|
|
11312
|
+
|
|
11313
|
+
// Send results
|
|
11314
|
+
this._emit('onScrollBoundary', { status: atResult, ...scrollResult, scrollCache });
|
|
11315
|
+
this._emit('onExtraScrollBoundary', { status: atCustomResult, ...scrollResult, scrollCache });
|
|
11316
|
+
|
|
11317
|
+
if (!this.#scrollPaused) {
|
|
11318
|
+
this._emit('onAutoScroll', { ...scrollResult, scrollCache });
|
|
11319
|
+
} else {
|
|
11320
|
+
this._emit('onScrollPause', { ...scrollResult, scrollCache });
|
|
11321
|
+
}
|
|
11322
|
+
}
|
|
11323
|
+
|
|
11324
|
+
/**
|
|
11325
|
+
* Attempts to correct the scroll position when layout shifts happen, preserving the user position if needed.
|
|
11326
|
+
*
|
|
11327
|
+
* @param {Element[]} [targets=[]] - List of elements involved in the size change.
|
|
11328
|
+
*/
|
|
11329
|
+
_fixScroll(targets = []) {
|
|
11330
|
+
if (this.#destroyed) return;
|
|
11331
|
+
// === Validation ===
|
|
11332
|
+
if (!Array.isArray(targets))
|
|
11333
|
+
throw new TypeError('_fixScroll: targets must be an array of Elements');
|
|
11334
|
+
|
|
11335
|
+
// Get Scroll data
|
|
11336
|
+
const prevScrollHeight = this.#target.scrollHeight;
|
|
11337
|
+
const prevScrollTop = this.#target.scrollTop;
|
|
11338
|
+
const prevBottomOffset =
|
|
11339
|
+
this.#target.scrollHeight - this.#target.scrollTop - this.#target.clientHeight;
|
|
11340
|
+
|
|
11341
|
+
// Get new size
|
|
11342
|
+
const newScrollHeight = this.#target.scrollHeight;
|
|
11343
|
+
const heightDelta = newScrollHeight - prevScrollHeight;
|
|
11344
|
+
|
|
11345
|
+
/** @type {() => NodeSizes} */
|
|
11346
|
+
const calculateScrollSize = () => {
|
|
11347
|
+
// Run size getter
|
|
11348
|
+
const scrollSize = { height: 0, width: 0 };
|
|
11349
|
+
for (const target of targets) {
|
|
11350
|
+
const tgOs = this.#oldSizes.get(target) || { height: 0, width: 0 };
|
|
11351
|
+
const tgNs = this.#newSizes.get(target) || { height: 0, width: 0 };
|
|
11352
|
+
this.#sizeFilter.forEach((fn) => {
|
|
11353
|
+
/** @type {NodeSizes| undefined} */
|
|
11354
|
+
const sizes = fn(
|
|
11355
|
+
target,
|
|
11356
|
+
{ old: tgOs, now: tgNs },
|
|
11357
|
+
{ old: this.#elemOldAmount, now: this.#elemAmount },
|
|
11358
|
+
);
|
|
11359
|
+
|
|
11360
|
+
// Fix size
|
|
11361
|
+
if (this.#newVisibles.get(target) || this.#newVisiblesByTime.get(target)) {
|
|
11362
|
+
if (typeof sizes !== 'undefined' && typeof sizes !== 'object')
|
|
11363
|
+
throw new Error('_fixScroll: size filter must return an object or undefined');
|
|
11364
|
+
if (typeof sizes === 'undefined') return;
|
|
11365
|
+
scrollSize.height = sizes.height;
|
|
11366
|
+
scrollSize.width = sizes.width;
|
|
11367
|
+
}
|
|
11368
|
+
});
|
|
11369
|
+
}
|
|
11370
|
+
|
|
11371
|
+
// Checker
|
|
11372
|
+
if (typeof scrollSize.height !== 'number' && scrollSize.height < 0)
|
|
11373
|
+
throw new Error('_fixScroll: invalid scrollSize.height value');
|
|
11374
|
+
if (typeof scrollSize.width !== 'number' && scrollSize.width < 0)
|
|
11375
|
+
throw new Error('_fixScroll: invalid scrollSize.width value');
|
|
11376
|
+
|
|
11377
|
+
if (scrollSize.height !== 0 || scrollSize.width !== 0) {
|
|
11378
|
+
for (const target of targets) {
|
|
11379
|
+
this.#newVisiblesByTime.set(target, this.#newVisibles.get(target) ?? false);
|
|
11380
|
+
this.#oldVisiblesByTime.set(target, this.#oldVisibles.get(target) ?? false);
|
|
11381
|
+
}
|
|
11382
|
+
}
|
|
11383
|
+
|
|
11384
|
+
return scrollSize;
|
|
11385
|
+
};
|
|
11386
|
+
|
|
11387
|
+
// Fix scroll size
|
|
11388
|
+
if (
|
|
11389
|
+
this.#elemOldAmount > 0 &&
|
|
11390
|
+
libs_TinyHtml.hasScroll(this.#target).v &&
|
|
11391
|
+
this.#autoScrollBottom &&
|
|
11392
|
+
this.#preserveScrollOnLayoutShift &&
|
|
11393
|
+
!this.#isAtBottom &&
|
|
11394
|
+
!this.#isAtTop
|
|
11395
|
+
) {
|
|
11396
|
+
const scrollSize = calculateScrollSize();
|
|
11397
|
+
// Complete
|
|
11398
|
+
this.#target.scrollTop = prevScrollTop + heightDelta + scrollSize.height;
|
|
11399
|
+
if (scrollSize.width > 0)
|
|
11400
|
+
this.#target.scrollLeft = this.#target.scrollLeft + scrollSize.width;
|
|
11401
|
+
}
|
|
11402
|
+
|
|
11403
|
+
// Normal stuff
|
|
11404
|
+
else if (!this.#scrollPaused && this.#autoScrollBottom) {
|
|
11405
|
+
calculateScrollSize();
|
|
11406
|
+
this.scrollToBottom();
|
|
11407
|
+
} else if (!this.#autoScrollBottom && !this.#isAtBottom) {
|
|
11408
|
+
calculateScrollSize();
|
|
11409
|
+
this.#target.scrollTop =
|
|
11410
|
+
this.#target.scrollHeight - this.#target.clientHeight - prevBottomOffset;
|
|
11411
|
+
}
|
|
11412
|
+
}
|
|
11413
|
+
/**
|
|
11414
|
+
* Sets up a MutationObserver to watch for DOM changes and react accordingly to maintain scroll consistency.
|
|
11415
|
+
*/
|
|
11416
|
+
_observeMutations() {
|
|
11417
|
+
this.#mutationObserver = new MutationObserver((mutations) => {
|
|
11418
|
+
if (this.#destroyed) return;
|
|
11419
|
+
this._scrollDataUpdater();
|
|
11420
|
+
this.#elemOldAmount = this.#elemAmount;
|
|
11421
|
+
this.#elemAmount = this.#target.childElementCount;
|
|
11422
|
+
|
|
11423
|
+
mutations.forEach((mutation) => {
|
|
11424
|
+
mutation.addedNodes.forEach((node) => {
|
|
11425
|
+
if (!(node instanceof Element) || node.nodeType !== 1) return;
|
|
11426
|
+
|
|
11427
|
+
this._observeResizes([node]);
|
|
11428
|
+
this._listenLoadEvents(node);
|
|
11429
|
+
|
|
11430
|
+
if (this.#querySelector) {
|
|
11431
|
+
const children = node.querySelectorAll(this.#querySelector);
|
|
11432
|
+
this._observeResizes(children);
|
|
11433
|
+
this._listenLoadEvents(children);
|
|
11434
|
+
}
|
|
11435
|
+
});
|
|
11436
|
+
});
|
|
11437
|
+
|
|
11438
|
+
this._fixScroll();
|
|
11439
|
+
});
|
|
11440
|
+
|
|
11441
|
+
// Install observer
|
|
11442
|
+
this.#mutationObserver.observe(this.#target, {
|
|
11443
|
+
childList: true,
|
|
11444
|
+
subtree: true,
|
|
11445
|
+
attributes: true,
|
|
11446
|
+
attributeFilter:
|
|
11447
|
+
this.#attributeFilter.size > 0 ? Array.from(this.#attributeFilter) : undefined,
|
|
11448
|
+
});
|
|
11449
|
+
}
|
|
11450
|
+
|
|
11451
|
+
/**
|
|
11452
|
+
* Adds a ResizeObserver to monitor elements' size changes and trigger layout adjustments.
|
|
11453
|
+
*
|
|
11454
|
+
* @param {NodeListOf<Element>|Element[]|HTMLCollection} elements - Elements to observe.
|
|
11455
|
+
*/
|
|
11456
|
+
_observeResizes(elements) {
|
|
11457
|
+
// Add resize observer
|
|
11458
|
+
if (!this.#resizeObserver) {
|
|
11459
|
+
this.#resizeObserver = new ResizeObserver((entries) => {
|
|
11460
|
+
if (this.#destroyed) return;
|
|
11461
|
+
this._scrollDataUpdater();
|
|
11462
|
+
/** @type {Element[]} */
|
|
11463
|
+
const targets = [];
|
|
11464
|
+
for (const entry of entries) {
|
|
11465
|
+
// Target
|
|
11466
|
+
const target = entry.target;
|
|
11467
|
+
|
|
11468
|
+
// Update old size
|
|
11469
|
+
const oldSize = this.#newSizes.get(target);
|
|
11470
|
+
if (oldSize) this.#oldSizes.set(target, oldSize);
|
|
11471
|
+
|
|
11472
|
+
// Set new size
|
|
11473
|
+
const { width, height } = entry.contentRect;
|
|
11474
|
+
this.#newSizes.set(target, { width, height });
|
|
11475
|
+
targets.push(target);
|
|
11476
|
+
}
|
|
11477
|
+
|
|
11478
|
+
// Animation frame
|
|
11479
|
+
this._fixScroll(targets);
|
|
11480
|
+
});
|
|
11481
|
+
}
|
|
11482
|
+
|
|
11483
|
+
// Execute observer
|
|
11484
|
+
Array.from(elements).forEach((el) => {
|
|
11485
|
+
if (!this.#resizeObserver)
|
|
11486
|
+
throw new Error('_observeResizes: ResizeObserver instance is not initialized');
|
|
11487
|
+
this.#resizeObserver.observe(el);
|
|
11488
|
+
});
|
|
11489
|
+
}
|
|
11490
|
+
|
|
11491
|
+
/**
|
|
11492
|
+
* Listens for media/content load events (e.g., images, iframes, videos) to trigger scroll updates.
|
|
11493
|
+
*
|
|
11494
|
+
* @param {NodeListOf<Element>|Element} elements - Target element(s) to listen on.
|
|
11495
|
+
*/
|
|
11496
|
+
_listenLoadEvents(elements) {
|
|
11497
|
+
if (this.#destroyed) return;
|
|
11498
|
+
const list = elements instanceof NodeList ? Array.from(elements) : [elements];
|
|
11499
|
+
|
|
11500
|
+
list.forEach((el) => {
|
|
11501
|
+
if (this.#loadTags.has(el.tagName)) {
|
|
11502
|
+
// @ts-ignore
|
|
11503
|
+
if (!el.complete) {
|
|
11504
|
+
el.addEventListener('load', () => {
|
|
11505
|
+
this._scrollDataUpdater();
|
|
11506
|
+
if (!this.#scrollPaused && this.#autoScrollBottom) {
|
|
11507
|
+
this.scrollToBottom();
|
|
11508
|
+
}
|
|
11509
|
+
});
|
|
11510
|
+
}
|
|
11511
|
+
}
|
|
11512
|
+
});
|
|
11513
|
+
}
|
|
11514
|
+
|
|
11515
|
+
/**
|
|
11516
|
+
* Returns the internal scroll container element being monitored.
|
|
11517
|
+
*
|
|
11518
|
+
* @returns {Element} The DOM element used as the scroll container target.
|
|
11519
|
+
*/
|
|
11520
|
+
get target() {
|
|
11521
|
+
return this.#target;
|
|
11522
|
+
}
|
|
11523
|
+
|
|
11524
|
+
/**
|
|
11525
|
+
* Returns the previous size of a given element, or undefined if not tracked.
|
|
11526
|
+
*
|
|
11527
|
+
* @param {Element} el - The DOM element to query.
|
|
11528
|
+
* @returns {NodeSizes|null} The old size, or undefined.
|
|
11529
|
+
*/
|
|
11530
|
+
getOldSize(el) {
|
|
11531
|
+
return this.#oldSizes.get(el) ?? null;
|
|
11532
|
+
}
|
|
11533
|
+
|
|
11534
|
+
/**
|
|
11535
|
+
* Returns the current size of a given element, or undefined if not tracked.
|
|
11536
|
+
*
|
|
11537
|
+
* @param {Element} el - The DOM element to query.
|
|
11538
|
+
* @returns {NodeSizes|null} The new size, or undefined.
|
|
11539
|
+
*/
|
|
11540
|
+
getNewSize(el) {
|
|
11541
|
+
return this.#newSizes.get(el) ?? null;
|
|
11542
|
+
}
|
|
11543
|
+
|
|
11544
|
+
/**
|
|
11545
|
+
* Returns whether the given element was visible in the last scroll update.
|
|
11546
|
+
*
|
|
11547
|
+
* @param {Element} el - The DOM element to check.
|
|
11548
|
+
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
11549
|
+
*/
|
|
11550
|
+
wasVisible(el) {
|
|
11551
|
+
return this.#oldVisibles.get(el) ?? false;
|
|
11552
|
+
}
|
|
11553
|
+
|
|
11554
|
+
/**
|
|
11555
|
+
* Returns whether the given element is currently visible.
|
|
11556
|
+
*
|
|
11557
|
+
* @param {Element} el - The DOM element to check.
|
|
11558
|
+
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
11559
|
+
*/
|
|
11560
|
+
isVisible(el) {
|
|
11561
|
+
return this.#newVisibles.get(el) ?? false;
|
|
11562
|
+
}
|
|
11563
|
+
|
|
11564
|
+
/**
|
|
11565
|
+
* Returns whether the element was visible in the last time-based visibility check.
|
|
11566
|
+
*
|
|
11567
|
+
* @param {Element} el - The DOM element to check.
|
|
11568
|
+
* @returns {boolean} Visibility state from the previous timed check.
|
|
11569
|
+
*/
|
|
11570
|
+
wasTimedVisible(el) {
|
|
11571
|
+
return this.#oldVisiblesByTime.get(el) ?? false;
|
|
11572
|
+
}
|
|
11573
|
+
|
|
11574
|
+
/**
|
|
11575
|
+
* Returns whether the element is currently visible in the time-based check.
|
|
11576
|
+
*
|
|
11577
|
+
* @param {Element} el - The DOM element to check.
|
|
11578
|
+
* @returns {boolean} Visibility state from the current timed check.
|
|
11579
|
+
*/
|
|
11580
|
+
isTimedVisible(el) {
|
|
11581
|
+
return this.#newVisiblesByTime.get(el) ?? false;
|
|
11582
|
+
}
|
|
11583
|
+
|
|
11584
|
+
/**
|
|
11585
|
+
* Sets the extra scroll boundary margin used when determining if the user is at a "custom" bottom or top.
|
|
11586
|
+
*
|
|
11587
|
+
* @param {number} value - Pixels of additional margin to use.
|
|
11588
|
+
*/
|
|
11589
|
+
setExtraScrollBoundary(value) {
|
|
11590
|
+
if (typeof value !== 'number' || Number.isNaN(value))
|
|
11591
|
+
throw new TypeError('setExtraScrollBoundary(value): value must be a valid number');
|
|
11592
|
+
this.#extraScrollBoundary = value;
|
|
11593
|
+
}
|
|
11594
|
+
|
|
11595
|
+
/**
|
|
11596
|
+
* Returns the current extra scroll boundary setting.
|
|
11597
|
+
*
|
|
11598
|
+
* @returns {number}
|
|
11599
|
+
*/
|
|
11600
|
+
getExtraScrollBoundary() {
|
|
11601
|
+
return this.#extraScrollBoundary;
|
|
11602
|
+
}
|
|
11603
|
+
|
|
11604
|
+
/**
|
|
11605
|
+
* Returns the last known distance (in pixels) from the bottom of the scroll container.
|
|
11606
|
+
*
|
|
11607
|
+
* @returns {number}
|
|
11608
|
+
*/
|
|
11609
|
+
getLastKnownScrollBottomOffset() {
|
|
11610
|
+
return this.#lastKnownScrollBottomOffset;
|
|
11611
|
+
}
|
|
11612
|
+
|
|
11613
|
+
/**
|
|
11614
|
+
* Forces the scroll position to move to the very bottom of the target.
|
|
11615
|
+
*/
|
|
11616
|
+
scrollToBottom() {
|
|
11617
|
+
this.#target.scrollTop = this.#target.scrollHeight;
|
|
11618
|
+
}
|
|
11619
|
+
|
|
11620
|
+
/**
|
|
11621
|
+
* Forces the scroll position to move to the very top of the target.
|
|
11622
|
+
*/
|
|
11623
|
+
scrollToTop() {
|
|
11624
|
+
this.#target.scrollTop = 0;
|
|
11625
|
+
}
|
|
11626
|
+
|
|
11627
|
+
/**
|
|
11628
|
+
* Checks if the user is within the defined extra scroll boundary from the bottom.
|
|
11629
|
+
*
|
|
11630
|
+
* @returns {boolean}
|
|
11631
|
+
*/
|
|
11632
|
+
isUserAtCustomBottom() {
|
|
11633
|
+
return this.#isAtCustomBottom;
|
|
11634
|
+
}
|
|
11635
|
+
|
|
11636
|
+
/**
|
|
11637
|
+
* Checks if the user is within the defined extra scroll boundary from the top.
|
|
11638
|
+
*
|
|
11639
|
+
* @returns {boolean}
|
|
11640
|
+
*/
|
|
11641
|
+
isUserAtCustomTop() {
|
|
11642
|
+
return this.#isAtCustomTop;
|
|
11643
|
+
}
|
|
11644
|
+
|
|
11645
|
+
/**
|
|
11646
|
+
* Returns true if the user is currently scrolled to the bottom of the element.
|
|
11647
|
+
*
|
|
11648
|
+
* @returns {boolean}
|
|
11649
|
+
*/
|
|
11650
|
+
isUserAtBottom() {
|
|
11651
|
+
return this.#isAtBottom;
|
|
11652
|
+
}
|
|
11653
|
+
|
|
11654
|
+
/**
|
|
11655
|
+
* Returns true if the user is currently scrolled to the top of the element.
|
|
11656
|
+
*
|
|
11657
|
+
* @returns {boolean}
|
|
11658
|
+
*/
|
|
11659
|
+
isUserAtTop() {
|
|
11660
|
+
return this.#isAtTop;
|
|
11661
|
+
}
|
|
11662
|
+
|
|
11663
|
+
/**
|
|
11664
|
+
* Returns true if automatic scrolling is currently paused.
|
|
11665
|
+
*
|
|
11666
|
+
* @returns {boolean}
|
|
11667
|
+
*/
|
|
11668
|
+
isScrollPaused() {
|
|
11669
|
+
return this.#scrollPaused;
|
|
11670
|
+
}
|
|
11671
|
+
|
|
11672
|
+
/**
|
|
11673
|
+
* Returns whether the target is the window object.
|
|
11674
|
+
*
|
|
11675
|
+
* @returns {boolean} True if the scroll target is window, false otherwise.
|
|
11676
|
+
*/
|
|
11677
|
+
isWindow() {
|
|
11678
|
+
return this.#useWindow;
|
|
11679
|
+
}
|
|
11680
|
+
|
|
11681
|
+
/**
|
|
11682
|
+
* Returns whether the instance has been destroyed.
|
|
11683
|
+
*
|
|
11684
|
+
* @returns {boolean} True if the instance is destroyed, false otherwise.
|
|
11685
|
+
*/
|
|
11686
|
+
isDestroyed() {
|
|
11687
|
+
return this.#destroyed;
|
|
11688
|
+
}
|
|
11689
|
+
|
|
11690
|
+
/**
|
|
11691
|
+
* Returns whether auto-scroll-to-bottom is enabled.
|
|
11692
|
+
*
|
|
11693
|
+
* @returns {boolean} True if auto-scroll is active, false otherwise.
|
|
11694
|
+
*/
|
|
11695
|
+
getAutoScrollBottom() {
|
|
11696
|
+
return this.#autoScrollBottom;
|
|
11697
|
+
}
|
|
11698
|
+
|
|
11699
|
+
/**
|
|
11700
|
+
* Returns whether MutationObserver is enabled.
|
|
11701
|
+
*
|
|
11702
|
+
* @returns {boolean} True if mutation observation is active, false otherwise.
|
|
11703
|
+
*/
|
|
11704
|
+
getObserveMutations() {
|
|
11705
|
+
return this.#observeMutations;
|
|
11706
|
+
}
|
|
11707
|
+
|
|
11708
|
+
/**
|
|
11709
|
+
* Returns whether layout shift protection is enabled.
|
|
11710
|
+
*
|
|
11711
|
+
* @returns {boolean} True if scroll preservation is active, false otherwise.
|
|
11712
|
+
*/
|
|
11713
|
+
getPreserveScrollOnLayoutShift() {
|
|
11714
|
+
return this.#preserveScrollOnLayoutShift;
|
|
11715
|
+
}
|
|
11716
|
+
|
|
11717
|
+
/**
|
|
11718
|
+
* Returns the debounce delay in milliseconds used for scroll events.
|
|
11719
|
+
*
|
|
11720
|
+
* @returns {number} Debounce delay time.
|
|
11721
|
+
*/
|
|
11722
|
+
getDebounceTime() {
|
|
11723
|
+
return this.#debounceTime;
|
|
11724
|
+
}
|
|
11725
|
+
|
|
11726
|
+
/**
|
|
11727
|
+
* Returns the current number of matching elements observed inside the scroll target.
|
|
11728
|
+
*
|
|
11729
|
+
* @returns {number} Current count of matching elements.
|
|
11730
|
+
*/
|
|
11731
|
+
getElemAmount() {
|
|
11732
|
+
return this.#elemAmount;
|
|
11733
|
+
}
|
|
11734
|
+
|
|
11735
|
+
/**
|
|
11736
|
+
* Returns the previous known count of matching elements from the last update.
|
|
11737
|
+
*
|
|
11738
|
+
* @returns {number} Previous count of matching elements.
|
|
11739
|
+
*/
|
|
11740
|
+
getPrevElemAmount() {
|
|
11741
|
+
return this.#elemOldAmount;
|
|
11742
|
+
}
|
|
11743
|
+
|
|
11744
|
+
/**
|
|
11745
|
+
* Returns the query selector string used to filter observed elements.
|
|
11746
|
+
*
|
|
11747
|
+
* @returns {string} The CSS selector string, or an empty string if none was provided.
|
|
11748
|
+
*/
|
|
11749
|
+
getQuerySelector() {
|
|
11750
|
+
return this.#querySelector;
|
|
11751
|
+
}
|
|
11752
|
+
|
|
11753
|
+
/**
|
|
11754
|
+
* Disconnects all listeners, observers, and clears memory structures.
|
|
11755
|
+
* Once destroyed, this instance should no longer be used.
|
|
11756
|
+
*/
|
|
11757
|
+
destroy() {
|
|
11758
|
+
if (this.#destroyed) return;
|
|
11759
|
+
this.#destroyed = true;
|
|
11760
|
+
|
|
11761
|
+
// Disconnects MutationObserver
|
|
11762
|
+
if (this.#mutationObserver) {
|
|
11763
|
+
this.#mutationObserver.disconnect();
|
|
11764
|
+
this.#mutationObserver = null;
|
|
11765
|
+
}
|
|
11766
|
+
|
|
11767
|
+
// Disconnect ResizeObserver
|
|
11768
|
+
if (this.#resizeObserver) {
|
|
11769
|
+
this.#resizeObserver.disconnect();
|
|
11770
|
+
this.#resizeObserver = null;
|
|
11771
|
+
}
|
|
11772
|
+
|
|
11773
|
+
// Removes scroll listener
|
|
11774
|
+
const target = this.#useWindow ? window : this.#target;
|
|
11775
|
+
if (this.#handler) target.removeEventListener('scroll', this.#handler);
|
|
11776
|
+
|
|
11777
|
+
// Clean the WeakMaps
|
|
11778
|
+
this.#oldSizes = new WeakMap();
|
|
11779
|
+
this.#newSizes = new WeakMap();
|
|
11780
|
+
this.#newVisibles = new WeakMap();
|
|
11781
|
+
this.#oldVisibles = new WeakMap();
|
|
11782
|
+
this.#newVisiblesByTime = new WeakMap();
|
|
11783
|
+
this.#oldVisiblesByTime = new WeakMap();
|
|
11784
|
+
|
|
11785
|
+
// Cleans listeners and filters
|
|
11786
|
+
this.#scrollListeners = {};
|
|
11787
|
+
this.#sizeFilter.clear();
|
|
11788
|
+
this.#loadTags.clear();
|
|
11789
|
+
}
|
|
11790
|
+
}
|
|
11791
|
+
|
|
11792
|
+
/* harmony default export */ const libs_TinySmartScroller = ((/* unused pure expression or super */ null && (TinySmartScroller)));
|
|
11793
|
+
|
|
11794
|
+
;// ./src/v1/index.mjs
|
|
11795
|
+
|
|
11796
|
+
|
|
10331
11797
|
|
|
10332
11798
|
|
|
10333
11799
|
|