tiny-essentials 1.16.2 → 1.17.1
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 +729 -93
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDragger.js +656 -69
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyEssentials.js +2688 -116
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyHtml.js +656 -69
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinySmartScroller.js +6378 -0
- package/dist/v1/TinySmartScroller.min.js +1 -0
- package/dist/v1/TinyUploadClicker.js +1732 -118
- 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 +656 -69
- package/dist/v1/libs/TinyHtml.d.mts +440 -139
- package/dist/v1/libs/TinyHtml.mjs +591 -72
- 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 +296 -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
|
/**
|
|
@@ -4226,6 +4275,19 @@ const {
|
|
|
4226
4275
|
areElsCollRight: TinyHtml_areElsCollRight,
|
|
4227
4276
|
} = collision_namespaceObject;
|
|
4228
4277
|
|
|
4278
|
+
/**
|
|
4279
|
+
* Callback invoked on each animation frame with the current scroll position,
|
|
4280
|
+
* normalized animation time (`0` to `1`), and a completion flag.
|
|
4281
|
+
*
|
|
4282
|
+
* @typedef {(progress: { x: number, y: number, isComplete: boolean, time: number }) => void} OnScrollAnimation
|
|
4283
|
+
*/
|
|
4284
|
+
|
|
4285
|
+
/**
|
|
4286
|
+
* A list of supported easing function names for smooth animations.
|
|
4287
|
+
*
|
|
4288
|
+
* @typedef {'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic'} Easings
|
|
4289
|
+
*/
|
|
4290
|
+
|
|
4229
4291
|
/**
|
|
4230
4292
|
* Represents a raw Node element or an instance of TinyHtml.
|
|
4231
4293
|
* This type is used to abstract interactions with both plain elements
|
|
@@ -4281,6 +4343,21 @@ const {
|
|
|
4281
4343
|
* @typedef {Element|Window} ElementAndWindow
|
|
4282
4344
|
*/
|
|
4283
4345
|
|
|
4346
|
+
/**
|
|
4347
|
+
* Represents a raw DOM element/window/document or an instance of TinyHtml.
|
|
4348
|
+
* This type is used to abstract interactions with both plain elements
|
|
4349
|
+
* and wrapped elements via the TinyHtml class.
|
|
4350
|
+
*
|
|
4351
|
+
* @typedef {ElementAndWinAndDoc|TinyHtml} TinyElementAndWinAndDoc
|
|
4352
|
+
*/
|
|
4353
|
+
|
|
4354
|
+
/**
|
|
4355
|
+
* Represents a value that can be either a DOM Element, or the global Window object, or the document object.
|
|
4356
|
+
* Useful for functions that operate generically on scrollable or measurable targets.
|
|
4357
|
+
*
|
|
4358
|
+
* @typedef {Element|Window|Document} ElementAndWinAndDoc
|
|
4359
|
+
*/
|
|
4360
|
+
|
|
4284
4361
|
/**
|
|
4285
4362
|
* A parameter type used for filtering or matching elements.
|
|
4286
4363
|
* It can be:
|
|
@@ -4297,7 +4374,7 @@ const {
|
|
|
4297
4374
|
* Elements accepted as constructor values for TinyHtml.
|
|
4298
4375
|
* These include common DOM elements and root containers.
|
|
4299
4376
|
*
|
|
4300
|
-
* @typedef {Window|Element|Document} ConstructorElValues
|
|
4377
|
+
* @typedef {Window|Element|Document|Text} ConstructorElValues
|
|
4301
4378
|
*/
|
|
4302
4379
|
|
|
4303
4380
|
/**
|
|
@@ -4418,40 +4495,114 @@ class TinyHtml_TinyHtml {
|
|
|
4418
4495
|
|
|
4419
4496
|
static Utils = { ...collision_namespaceObject };
|
|
4420
4497
|
|
|
4498
|
+
/**
|
|
4499
|
+
* Creates a new DOM element with the specified tag name and options, then wraps it in a TinyHtml instance.
|
|
4500
|
+
*
|
|
4501
|
+
* @param {string} tagName - The tag name of the element to create (e.g., 'div', 'span').
|
|
4502
|
+
* @param {ElementCreationOptions} ops - Optional settings for creating the element.
|
|
4503
|
+
* @returns {TinyHtml} A TinyHtml instance wrapping the newly created DOM element.
|
|
4504
|
+
* @throws {TypeError} If tagName is not a string or ops is not an object.
|
|
4505
|
+
*/
|
|
4506
|
+
static createElement(tagName, ops) {
|
|
4507
|
+
if (typeof tagName !== 'string')
|
|
4508
|
+
throw new TypeError(`[TinyHtml] createElement(): The tagName must be a string.`);
|
|
4509
|
+
if (typeof ops !== 'undefined' && typeof ops !== 'object')
|
|
4510
|
+
throw new TypeError(`[TinyHtml] createElement(): The ops must be a object.`);
|
|
4511
|
+
return new TinyHtml_TinyHtml(document.createElement(tagName, ops));
|
|
4512
|
+
}
|
|
4513
|
+
|
|
4514
|
+
/**
|
|
4515
|
+
* Creates a new TinyHtml instance that wraps a DOM TextNode.
|
|
4516
|
+
*
|
|
4517
|
+
* This method is useful when you want to insert raw text content into the DOM
|
|
4518
|
+
* without it being interpreted as HTML. The returned instance behaves like any
|
|
4519
|
+
* other TinyHtml element and can be appended or manipulated as needed.
|
|
4520
|
+
*
|
|
4521
|
+
* @param {string} value - The plain text content to be wrapped in a TextNode.
|
|
4522
|
+
* @returns {TinyHtml} A TinyHtml instance wrapping the newly created DOM TextNode.
|
|
4523
|
+
* @throws {TypeError} If the provided value is not a string.
|
|
4524
|
+
*/
|
|
4525
|
+
static createTextNode(value) {
|
|
4526
|
+
if (typeof value !== 'string')
|
|
4527
|
+
throw new TypeError(`[TinyHtml] createTextNode(): The value must be a string.`);
|
|
4528
|
+
return new TinyHtml_TinyHtml(document.createTextNode(value));
|
|
4529
|
+
}
|
|
4530
|
+
|
|
4531
|
+
/**
|
|
4532
|
+
* Creates an HTMLElement or TextNode from an HTML string.
|
|
4533
|
+
* Supports both elements and plain text.
|
|
4534
|
+
*
|
|
4535
|
+
* @param {string} htmlString - The HTML string to convert.
|
|
4536
|
+
* @returns {TinyHtml} - A single HTMLElement or TextNode.
|
|
4537
|
+
*/
|
|
4538
|
+
static createElementFromHTML(htmlString) {
|
|
4539
|
+
const template = document.createElement('template');
|
|
4540
|
+
htmlString = htmlString.trim();
|
|
4541
|
+
|
|
4542
|
+
// If it's only text (e.g., no "<" tag), return a TextNode
|
|
4543
|
+
if (!htmlString.startsWith('<')) {
|
|
4544
|
+
return TinyHtml_TinyHtml.createTextNode(htmlString);
|
|
4545
|
+
}
|
|
4546
|
+
|
|
4547
|
+
template.innerHTML = htmlString;
|
|
4548
|
+
if (!(template.content.firstChild instanceof Element)) throw new Error('');
|
|
4549
|
+
return new TinyHtml_TinyHtml(template.content.firstChild);
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4421
4552
|
/**
|
|
4422
4553
|
* Queries the document for the first element matching the CSS selector and wraps it in a TinyHtml instance.
|
|
4423
4554
|
*
|
|
4424
4555
|
* @param {string} selector - A valid CSS selector string.
|
|
4425
|
-
* @
|
|
4426
|
-
* @
|
|
4556
|
+
* @param {Document|Element} elem - Target element.
|
|
4557
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the matched element.
|
|
4427
4558
|
*/
|
|
4428
|
-
static query(selector) {
|
|
4429
|
-
const newEl =
|
|
4430
|
-
if (!newEl)
|
|
4559
|
+
static query(selector, elem = document) {
|
|
4560
|
+
const newEl = elem.querySelector(selector);
|
|
4561
|
+
if (!newEl) return null;
|
|
4431
4562
|
return new TinyHtml_TinyHtml(newEl);
|
|
4432
4563
|
}
|
|
4433
4564
|
|
|
4565
|
+
/**
|
|
4566
|
+
* Queries the element for the first element matching the CSS selector and wraps it in a TinyHtml instance.
|
|
4567
|
+
*
|
|
4568
|
+
* @param {string} selector - A valid CSS selector string.
|
|
4569
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the matched element.
|
|
4570
|
+
*/
|
|
4571
|
+
querySelector(selector) {
|
|
4572
|
+
return TinyHtml_TinyHtml.query(selector, TinyHtml_TinyHtml._preElem(this, 'query'));
|
|
4573
|
+
}
|
|
4574
|
+
|
|
4434
4575
|
/**
|
|
4435
4576
|
* Queries the document for all elements matching the CSS selector and wraps them in TinyHtml instances.
|
|
4436
4577
|
*
|
|
4437
4578
|
* @param {string} selector - A valid CSS selector string.
|
|
4579
|
+
* @param {Document|Element} elem - Target element.
|
|
4438
4580
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the matched elements.
|
|
4439
4581
|
*/
|
|
4440
|
-
static queryAll(selector) {
|
|
4441
|
-
const newEls =
|
|
4582
|
+
static queryAll(selector, elem = document) {
|
|
4583
|
+
const newEls = elem.querySelectorAll(selector);
|
|
4442
4584
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4443
4585
|
}
|
|
4444
4586
|
|
|
4587
|
+
/**
|
|
4588
|
+
* Queries the element for all elements matching the CSS selector and wraps them in TinyHtml instances.
|
|
4589
|
+
*
|
|
4590
|
+
* @param {string} selector - A valid CSS selector string.
|
|
4591
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the matched elements.
|
|
4592
|
+
*/
|
|
4593
|
+
querySelectorAll(selector) {
|
|
4594
|
+
return TinyHtml_TinyHtml.queryAll(selector, TinyHtml_TinyHtml._preElem(this, 'queryAll'));
|
|
4595
|
+
}
|
|
4596
|
+
|
|
4445
4597
|
/**
|
|
4446
4598
|
* Retrieves an element by its ID and wraps it in a TinyHtml instance.
|
|
4447
4599
|
*
|
|
4448
4600
|
* @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.
|
|
4601
|
+
* @returns {TinyHtml|null} A TinyHtml instance wrapping the found element.
|
|
4451
4602
|
*/
|
|
4452
4603
|
static getById(selector) {
|
|
4453
4604
|
const newEl = document.getElementById(selector);
|
|
4454
|
-
if (!newEl)
|
|
4605
|
+
if (!newEl) return null;
|
|
4455
4606
|
return new TinyHtml_TinyHtml(newEl);
|
|
4456
4607
|
}
|
|
4457
4608
|
|
|
@@ -4459,13 +4610,24 @@ class TinyHtml_TinyHtml {
|
|
|
4459
4610
|
* Retrieves all elements with the specified class name and wraps them in TinyHtml instances.
|
|
4460
4611
|
*
|
|
4461
4612
|
* @param {string} selector - The class name to search for.
|
|
4613
|
+
* @param {Document|Element} elem - Target element.
|
|
4462
4614
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4463
4615
|
*/
|
|
4464
|
-
static getByClassName(selector) {
|
|
4465
|
-
const newEls =
|
|
4616
|
+
static getByClassName(selector, elem = document) {
|
|
4617
|
+
const newEls = elem.getElementsByClassName(selector);
|
|
4466
4618
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4467
4619
|
}
|
|
4468
4620
|
|
|
4621
|
+
/**
|
|
4622
|
+
* Retrieves all elements with the specified class name and wraps them in TinyHtml instances.
|
|
4623
|
+
*
|
|
4624
|
+
* @param {string} selector - The class name to search for.
|
|
4625
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4626
|
+
*/
|
|
4627
|
+
getElementsByClassName(selector) {
|
|
4628
|
+
return TinyHtml_TinyHtml.getByClassName(selector, TinyHtml_TinyHtml._preElem(this, 'getByClassName'));
|
|
4629
|
+
}
|
|
4630
|
+
|
|
4469
4631
|
/**
|
|
4470
4632
|
* Retrieves all elements with the specified name attribute and wraps them in TinyHtml instances.
|
|
4471
4633
|
*
|
|
@@ -4483,13 +4645,30 @@ class TinyHtml_TinyHtml {
|
|
|
4483
4645
|
*
|
|
4484
4646
|
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
4485
4647
|
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
4648
|
+
* @param {Document|Element} elem - Target element.
|
|
4486
4649
|
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4487
4650
|
*/
|
|
4488
|
-
static getByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml') {
|
|
4489
|
-
const newEls =
|
|
4651
|
+
static getByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml', elem = document) {
|
|
4652
|
+
const newEls = elem.getElementsByTagNameNS(namespaceURI, localName);
|
|
4490
4653
|
return TinyHtml_TinyHtml.toTinyElm([...newEls]);
|
|
4491
4654
|
}
|
|
4492
4655
|
|
|
4656
|
+
/**
|
|
4657
|
+
* Retrieves all elements with the specified local tag name within the given namespace URI,
|
|
4658
|
+
* and wraps them in TinyHtml instances.
|
|
4659
|
+
*
|
|
4660
|
+
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
4661
|
+
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
4662
|
+
* @returns {TinyHtml[]} An array of TinyHtml instances wrapping the found elements.
|
|
4663
|
+
*/
|
|
4664
|
+
getElementsByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml') {
|
|
4665
|
+
return TinyHtml_TinyHtml.getByTagNameNS(
|
|
4666
|
+
localName,
|
|
4667
|
+
namespaceURI,
|
|
4668
|
+
TinyHtml_TinyHtml._preElem(this, 'getByTagNameNS'),
|
|
4669
|
+
);
|
|
4670
|
+
}
|
|
4671
|
+
|
|
4493
4672
|
//////////////////////////////////////////////////////////////////
|
|
4494
4673
|
|
|
4495
4674
|
/**
|
|
@@ -4770,6 +4949,45 @@ class TinyHtml_TinyHtml {
|
|
|
4770
4949
|
return TinyHtml_TinyHtml._preElemTemplate(elems, where, [Element, Window], ['Element', 'Window']);
|
|
4771
4950
|
}
|
|
4772
4951
|
|
|
4952
|
+
/**
|
|
4953
|
+
* Ensures the input is returned as an array.
|
|
4954
|
+
* Useful to normalize operations across multiple or single element/window/document elements.
|
|
4955
|
+
*
|
|
4956
|
+
* @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
|
|
4957
|
+
* @param {string} where - The method or context name where validation is being called.
|
|
4958
|
+
* @returns {ElementAndWindow[]} - Always returns an array of element/window elements.
|
|
4959
|
+
* @readonly
|
|
4960
|
+
*/
|
|
4961
|
+
static _preElemsAndWinAndDoc(elems, where) {
|
|
4962
|
+
const result = TinyHtml_TinyHtml._preElemsTemplate(
|
|
4963
|
+
elems,
|
|
4964
|
+
where,
|
|
4965
|
+
[Element, Window, Document],
|
|
4966
|
+
['Element', 'Window', 'Document'],
|
|
4967
|
+
);
|
|
4968
|
+
return result.map((elem) => (!(elem instanceof Document) ? elem : elem.documentElement));
|
|
4969
|
+
}
|
|
4970
|
+
|
|
4971
|
+
/**
|
|
4972
|
+
* Ensures the input is returned as an single element/window/document element.
|
|
4973
|
+
* Useful to normalize operations across multiple or single element/window/document elements.
|
|
4974
|
+
*
|
|
4975
|
+
* @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
|
|
4976
|
+
* @param {string} where - The method or context name where validation is being called.
|
|
4977
|
+
* @returns {ElementAndWindow} - Always returns an single element/window element.
|
|
4978
|
+
* @readonly
|
|
4979
|
+
*/
|
|
4980
|
+
static _preElemAndWinAndDoc(elems, where) {
|
|
4981
|
+
const result = TinyHtml_TinyHtml._preElemTemplate(
|
|
4982
|
+
elems,
|
|
4983
|
+
where,
|
|
4984
|
+
[Element, Window, Document],
|
|
4985
|
+
['Element', 'Window', 'Document'],
|
|
4986
|
+
);
|
|
4987
|
+
if (result instanceof Document) return result.documentElement;
|
|
4988
|
+
return result;
|
|
4989
|
+
}
|
|
4990
|
+
|
|
4773
4991
|
/**
|
|
4774
4992
|
* Normalizes and converts one or more DOM elements (or TinyHtml instances)
|
|
4775
4993
|
* into an array of `TinyHtml` instances.
|
|
@@ -5116,12 +5334,13 @@ class TinyHtml_TinyHtml {
|
|
|
5116
5334
|
* @param {string} key - The key under which the data will be stored.
|
|
5117
5335
|
* @param {any} value - The value to store.
|
|
5118
5336
|
* @param {boolean} [isPrivate=false] - Whether to store the data in the private store.
|
|
5119
|
-
* @returns {
|
|
5337
|
+
* @returns {TinyElement}
|
|
5120
5338
|
*/
|
|
5121
5339
|
static setData(el, key, value, isPrivate = false) {
|
|
5122
5340
|
const data = TinyHtml_TinyHtml._dataSelector[!isPrivate ? 'public' : 'private']('setData', el);
|
|
5123
5341
|
if (typeof key !== 'string') throw new TypeError('The key must be a string.');
|
|
5124
5342
|
data[key] = value;
|
|
5343
|
+
return el;
|
|
5125
5344
|
}
|
|
5126
5345
|
|
|
5127
5346
|
/**
|
|
@@ -5130,7 +5349,7 @@ class TinyHtml_TinyHtml {
|
|
|
5130
5349
|
* @param {string} key - The key under which the data will be stored.
|
|
5131
5350
|
* @param {any} value - The value to store.
|
|
5132
5351
|
* @param {boolean} [isPrivate=false] - Whether to store the data in the private store.
|
|
5133
|
-
* @returns {
|
|
5352
|
+
* @returns {TinyElement}
|
|
5134
5353
|
*/
|
|
5135
5354
|
setData(key, value, isPrivate = false) {
|
|
5136
5355
|
return TinyHtml_TinyHtml.setData(this, key, value, isPrivate);
|
|
@@ -5477,18 +5696,21 @@ class TinyHtml_TinyHtml {
|
|
|
5477
5696
|
/**
|
|
5478
5697
|
* Appends child elements or strings to the end of the target element(s).
|
|
5479
5698
|
*
|
|
5480
|
-
* @param {TinyElement
|
|
5699
|
+
* @param {TinyElement} el - The target element(s) to receive children.
|
|
5481
5700
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to append.
|
|
5701
|
+
* @returns {TinyElement}
|
|
5482
5702
|
*/
|
|
5483
5703
|
static append(el, ...children) {
|
|
5484
5704
|
const elem = TinyHtml_TinyHtml._preElem(el, 'append');
|
|
5485
5705
|
elem.append(...TinyHtml_TinyHtml._appendChecker('append', ...children));
|
|
5706
|
+
return el;
|
|
5486
5707
|
}
|
|
5487
5708
|
|
|
5488
5709
|
/**
|
|
5489
5710
|
* Appends child elements or strings to the end of the target element(s).
|
|
5490
5711
|
*
|
|
5491
5712
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to append.
|
|
5713
|
+
* @returns {TinyElement}
|
|
5492
5714
|
*/
|
|
5493
5715
|
append(...children) {
|
|
5494
5716
|
return TinyHtml_TinyHtml.append(this, ...children);
|
|
@@ -5497,18 +5719,21 @@ class TinyHtml_TinyHtml {
|
|
|
5497
5719
|
/**
|
|
5498
5720
|
* Prepends child elements or strings to the beginning of the target element(s).
|
|
5499
5721
|
*
|
|
5500
|
-
* @param {TinyElement
|
|
5722
|
+
* @param {TinyElement} el - The target element(s) to receive children.
|
|
5501
5723
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to prepend.
|
|
5724
|
+
* @returns {TinyElement}
|
|
5502
5725
|
*/
|
|
5503
5726
|
static prepend(el, ...children) {
|
|
5504
5727
|
const elem = TinyHtml_TinyHtml._preElem(el, 'prepend');
|
|
5505
5728
|
elem.prepend(...TinyHtml_TinyHtml._appendChecker('prepend', ...children));
|
|
5729
|
+
return el;
|
|
5506
5730
|
}
|
|
5507
5731
|
|
|
5508
5732
|
/**
|
|
5509
5733
|
* Prepends child elements or strings to the beginning of the target element(s).
|
|
5510
5734
|
*
|
|
5511
5735
|
* @param {...(TinyNode | TinyNode[] | string)} children - The child elements or text to prepend.
|
|
5736
|
+
* @returns {TinyElement}
|
|
5512
5737
|
*/
|
|
5513
5738
|
prepend(...children) {
|
|
5514
5739
|
return TinyHtml_TinyHtml.prepend(this, ...children);
|
|
@@ -5517,18 +5742,21 @@ class TinyHtml_TinyHtml {
|
|
|
5517
5742
|
/**
|
|
5518
5743
|
* Inserts elements or strings immediately before the target element(s) in the DOM.
|
|
5519
5744
|
*
|
|
5520
|
-
* @param {TinyElement
|
|
5745
|
+
* @param {TinyElement} el - The target element(s) before which new content is inserted.
|
|
5521
5746
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert before the target.
|
|
5747
|
+
* @returns {TinyElement}
|
|
5522
5748
|
*/
|
|
5523
5749
|
static before(el, ...children) {
|
|
5524
5750
|
const elem = TinyHtml_TinyHtml._preElem(el, 'before');
|
|
5525
5751
|
elem.before(...TinyHtml_TinyHtml._appendChecker('before', ...children));
|
|
5752
|
+
return el;
|
|
5526
5753
|
}
|
|
5527
5754
|
|
|
5528
5755
|
/**
|
|
5529
5756
|
* Inserts elements or strings immediately before the target element(s) in the DOM.
|
|
5530
5757
|
*
|
|
5531
5758
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert before the target.
|
|
5759
|
+
* @returns {TinyElement}
|
|
5532
5760
|
*/
|
|
5533
5761
|
before(...children) {
|
|
5534
5762
|
return TinyHtml_TinyHtml.before(this, ...children);
|
|
@@ -5537,18 +5765,21 @@ class TinyHtml_TinyHtml {
|
|
|
5537
5765
|
/**
|
|
5538
5766
|
* Inserts elements or strings immediately after the target element(s) in the DOM.
|
|
5539
5767
|
*
|
|
5540
|
-
* @param {TinyElement
|
|
5768
|
+
* @param {TinyElement} el - The target element(s) after which new content is inserted.
|
|
5541
5769
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert after the target.
|
|
5770
|
+
* @returns {TinyElement}
|
|
5542
5771
|
*/
|
|
5543
5772
|
static after(el, ...children) {
|
|
5544
5773
|
const elem = TinyHtml_TinyHtml._preElem(el, 'after');
|
|
5545
5774
|
elem.after(...TinyHtml_TinyHtml._appendChecker('after', ...children));
|
|
5775
|
+
return el;
|
|
5546
5776
|
}
|
|
5547
5777
|
|
|
5548
5778
|
/**
|
|
5549
5779
|
* Inserts elements or strings immediately after the target element(s) in the DOM.
|
|
5550
5780
|
*
|
|
5551
5781
|
* @param {...(TinyNode | TinyNode[] | string)} children - Elements or text to insert after the target.
|
|
5782
|
+
* @returns {TinyElement}
|
|
5552
5783
|
*/
|
|
5553
5784
|
after(...children) {
|
|
5554
5785
|
return TinyHtml_TinyHtml.after(this, ...children);
|
|
@@ -5557,18 +5788,21 @@ class TinyHtml_TinyHtml {
|
|
|
5557
5788
|
/**
|
|
5558
5789
|
* Replaces the target element(s) in the DOM with new elements or text.
|
|
5559
5790
|
*
|
|
5560
|
-
* @param {TinyElement
|
|
5791
|
+
* @param {TinyElement} el - The element(s) to be replaced.
|
|
5561
5792
|
* @param {...(TinyNode | TinyNode[] | string)} newNodes - New elements or text to replace the target.
|
|
5793
|
+
* @returns {TinyElement}
|
|
5562
5794
|
*/
|
|
5563
5795
|
static replaceWith(el, ...newNodes) {
|
|
5564
5796
|
const elem = TinyHtml_TinyHtml._preElem(el, 'replaceWith');
|
|
5565
5797
|
elem.replaceWith(...TinyHtml_TinyHtml._appendChecker('replaceWith', ...newNodes));
|
|
5798
|
+
return el;
|
|
5566
5799
|
}
|
|
5567
5800
|
|
|
5568
5801
|
/**
|
|
5569
5802
|
* Replaces the target element(s) in the DOM with new elements or text.
|
|
5570
5803
|
*
|
|
5571
5804
|
* @param {...(TinyNode | TinyNode[] | string)} newNodes - New elements or text to replace the target.
|
|
5805
|
+
* @returns {TinyElement}
|
|
5572
5806
|
*/
|
|
5573
5807
|
replaceWith(...newNodes) {
|
|
5574
5808
|
return TinyHtml_TinyHtml.replaceWith(this, ...newNodes);
|
|
@@ -5579,6 +5813,7 @@ class TinyHtml_TinyHtml {
|
|
|
5579
5813
|
*
|
|
5580
5814
|
* @param {TinyNode | TinyNode[]} el - The element(s) to append.
|
|
5581
5815
|
* @param {TinyNode | TinyNode[]} targets - Target element(s) where content will be appended.
|
|
5816
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5582
5817
|
*/
|
|
5583
5818
|
static appendTo(el, targets) {
|
|
5584
5819
|
const elems = TinyHtml_TinyHtml._preNodeElems(el, 'appendTo');
|
|
@@ -5588,12 +5823,14 @@ class TinyHtml_TinyHtml {
|
|
|
5588
5823
|
target.appendChild(i === tars.length - 1 ? elem : elem.cloneNode(true)),
|
|
5589
5824
|
);
|
|
5590
5825
|
});
|
|
5826
|
+
return el;
|
|
5591
5827
|
}
|
|
5592
5828
|
|
|
5593
5829
|
/**
|
|
5594
5830
|
* Appends the given element(s) to each target element in sequence.
|
|
5595
5831
|
*
|
|
5596
5832
|
* @param {TinyNode | TinyNode[]} targets - Target element(s) where content will be appended.
|
|
5833
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5597
5834
|
*/
|
|
5598
5835
|
appendTo(targets) {
|
|
5599
5836
|
return TinyHtml_TinyHtml.appendTo(this, targets);
|
|
@@ -5604,6 +5841,7 @@ class TinyHtml_TinyHtml {
|
|
|
5604
5841
|
*
|
|
5605
5842
|
* @param {TinyElement | TinyElement[]} el - The element(s) to prepend.
|
|
5606
5843
|
* @param {TinyElement | TinyElement[]} targets - Target element(s) where content will be prepended.
|
|
5844
|
+
* @returns {TinyElement|TinyElement[]}
|
|
5607
5845
|
*/
|
|
5608
5846
|
static prependTo(el, targets) {
|
|
5609
5847
|
const elems = TinyHtml_TinyHtml._preElems(el, 'prependTo');
|
|
@@ -5614,12 +5852,14 @@ class TinyHtml_TinyHtml {
|
|
|
5614
5852
|
.reverse()
|
|
5615
5853
|
.forEach((elem) => target.prepend(i === tars.length - 1 ? elem : elem.cloneNode(true)));
|
|
5616
5854
|
});
|
|
5855
|
+
return el;
|
|
5617
5856
|
}
|
|
5618
5857
|
|
|
5619
5858
|
/**
|
|
5620
5859
|
* Prepends the given element(s) to each target element in sequence.
|
|
5621
5860
|
*
|
|
5622
5861
|
* @param {TinyElement | TinyElement[]} targets - Target element(s) where content will be prepended.
|
|
5862
|
+
* @returns {TinyElement|TinyElement[]}
|
|
5623
5863
|
*/
|
|
5624
5864
|
prependTo(targets) {
|
|
5625
5865
|
return TinyHtml_TinyHtml.prependTo(this, targets);
|
|
@@ -5631,6 +5871,7 @@ class TinyHtml_TinyHtml {
|
|
|
5631
5871
|
* @param {TinyNode | TinyNode[]} el - The element(s) to insert.
|
|
5632
5872
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5633
5873
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert before, defaults to target.
|
|
5874
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5634
5875
|
*/
|
|
5635
5876
|
static insertBefore(el, target, child = null) {
|
|
5636
5877
|
const elem = TinyHtml_TinyHtml._preNodeElem(el, 'insertBefore');
|
|
@@ -5638,6 +5879,7 @@ class TinyHtml_TinyHtml {
|
|
|
5638
5879
|
const childNode = TinyHtml_TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
5639
5880
|
if (!targ.parentNode) throw new Error('');
|
|
5640
5881
|
targ.parentNode.insertBefore(elem, childNode || targ);
|
|
5882
|
+
return el;
|
|
5641
5883
|
}
|
|
5642
5884
|
|
|
5643
5885
|
/**
|
|
@@ -5645,6 +5887,7 @@ class TinyHtml_TinyHtml {
|
|
|
5645
5887
|
*
|
|
5646
5888
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5647
5889
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert before, defaults to target.
|
|
5890
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5648
5891
|
*/
|
|
5649
5892
|
insertBefore(target, child) {
|
|
5650
5893
|
return TinyHtml_TinyHtml.insertBefore(this, target, child);
|
|
@@ -5656,6 +5899,7 @@ class TinyHtml_TinyHtml {
|
|
|
5656
5899
|
* @param {TinyNode | TinyNode[]} el - The element(s) to insert.
|
|
5657
5900
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5658
5901
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert after, defaults to target.
|
|
5902
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5659
5903
|
*/
|
|
5660
5904
|
static insertAfter(el, target, child = null) {
|
|
5661
5905
|
const elem = TinyHtml_TinyHtml._preNodeElem(el, 'insertAfter');
|
|
@@ -5663,6 +5907,7 @@ class TinyHtml_TinyHtml {
|
|
|
5663
5907
|
const childNode = TinyHtml_TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
5664
5908
|
if (!targ.parentNode) throw new Error('');
|
|
5665
5909
|
targ.parentNode.insertBefore(elem, childNode || targ.nextSibling);
|
|
5910
|
+
return el;
|
|
5666
5911
|
}
|
|
5667
5912
|
|
|
5668
5913
|
/**
|
|
@@ -5670,6 +5915,7 @@ class TinyHtml_TinyHtml {
|
|
|
5670
5915
|
*
|
|
5671
5916
|
* @param {TinyNode | TinyNode[]} target - The reference element where insertion happens.
|
|
5672
5917
|
* @param {TinyNode | TinyNode[] | null} [child=null] - Optional child to insert after, defaults to target.
|
|
5918
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5673
5919
|
*/
|
|
5674
5920
|
insertAfter(target, child) {
|
|
5675
5921
|
return TinyHtml_TinyHtml.insertAfter(this, target, child);
|
|
@@ -5681,6 +5927,7 @@ class TinyHtml_TinyHtml {
|
|
|
5681
5927
|
*
|
|
5682
5928
|
* @param {TinyNode | TinyNode[]} el - The new element(s) to insert.
|
|
5683
5929
|
* @param {TinyNode | TinyNode[]} targets - The elements to be replaced.
|
|
5930
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5684
5931
|
*/
|
|
5685
5932
|
static replaceAll(el, targets) {
|
|
5686
5933
|
const elems = TinyHtml_TinyHtml._preNodeElems(el, 'replaceAll');
|
|
@@ -5692,6 +5939,7 @@ class TinyHtml_TinyHtml {
|
|
|
5692
5939
|
parent.replaceChild(i === tars.length - 1 ? elem : elem.cloneNode(true), target);
|
|
5693
5940
|
});
|
|
5694
5941
|
});
|
|
5942
|
+
return el;
|
|
5695
5943
|
}
|
|
5696
5944
|
|
|
5697
5945
|
/**
|
|
@@ -5699,6 +5947,7 @@ class TinyHtml_TinyHtml {
|
|
|
5699
5947
|
* If multiple targets exist, the inserted elements are cloned accordingly.
|
|
5700
5948
|
*
|
|
5701
5949
|
* @param {TinyNode | TinyNode[]} targets - The elements to be replaced.
|
|
5950
|
+
* @returns {TinyNode|TinyNode[]}
|
|
5702
5951
|
*/
|
|
5703
5952
|
replaceAll(targets) {
|
|
5704
5953
|
return TinyHtml_TinyHtml.replaceAll(this, targets);
|
|
@@ -5722,7 +5971,12 @@ class TinyHtml_TinyHtml {
|
|
|
5722
5971
|
throw new Error(
|
|
5723
5972
|
`[TinyHtml] You are trying to put a TinyHtml inside another TinyHtml in constructor.`,
|
|
5724
5973
|
);
|
|
5725
|
-
if (
|
|
5974
|
+
if (
|
|
5975
|
+
!(el instanceof Element) &&
|
|
5976
|
+
!(el instanceof Window) &&
|
|
5977
|
+
!(el instanceof Document) &&
|
|
5978
|
+
!(el instanceof Text)
|
|
5979
|
+
)
|
|
5726
5980
|
throw new Error(`[TinyHtml] Invalid Target in constructor.`);
|
|
5727
5981
|
this.#el = el;
|
|
5728
5982
|
}
|
|
@@ -6172,6 +6426,7 @@ class TinyHtml_TinyHtml {
|
|
|
6172
6426
|
* @param {TinyHtmlElement|TinyHtmlElement[]} el - The element to inspect.
|
|
6173
6427
|
* @param {string|Object} prop - The property name or an object with key-value pairs
|
|
6174
6428
|
* @param {string|null} [value=null] - The value to set (if `prop` is a string)
|
|
6429
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6175
6430
|
*/
|
|
6176
6431
|
static setStyle(el, prop, value = null) {
|
|
6177
6432
|
TinyHtml_TinyHtml._preHtmlElems(el, 'setStyle').forEach((elem) => {
|
|
@@ -6184,6 +6439,7 @@ class TinyHtml_TinyHtml {
|
|
|
6184
6439
|
}
|
|
6185
6440
|
} else elem.style.setProperty(TinyHtml_TinyHtml.toStyleKc(prop), value);
|
|
6186
6441
|
});
|
|
6442
|
+
return el;
|
|
6187
6443
|
}
|
|
6188
6444
|
|
|
6189
6445
|
/**
|
|
@@ -6194,6 +6450,7 @@ class TinyHtml_TinyHtml {
|
|
|
6194
6450
|
*
|
|
6195
6451
|
* @param {string|Object} prop - The property name or an object with key-value pairs
|
|
6196
6452
|
* @param {string|null} [value=null] - The value to set (if `prop` is a string)
|
|
6453
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6197
6454
|
*/
|
|
6198
6455
|
setStyle(prop, value) {
|
|
6199
6456
|
return TinyHtml_TinyHtml.setStyle(this, prop, value);
|
|
@@ -6289,6 +6546,7 @@ class TinyHtml_TinyHtml {
|
|
|
6289
6546
|
*
|
|
6290
6547
|
* @param {TinyHtmlElement|TinyHtmlElement[]} el - A single element or an array of elements.
|
|
6291
6548
|
* @param {string|string[]} prop - A property name or an array of property names to remove.
|
|
6549
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6292
6550
|
*/
|
|
6293
6551
|
static removeStyle(el, prop) {
|
|
6294
6552
|
TinyHtml_TinyHtml._preHtmlElems(el, 'removeStyle').forEach((elem) => {
|
|
@@ -6298,12 +6556,14 @@ class TinyHtml_TinyHtml {
|
|
|
6298
6556
|
}
|
|
6299
6557
|
} else elem.style.removeProperty(TinyHtml_TinyHtml.toStyleKc(prop));
|
|
6300
6558
|
});
|
|
6559
|
+
return el;
|
|
6301
6560
|
}
|
|
6302
6561
|
|
|
6303
6562
|
/**
|
|
6304
6563
|
* Removes one or more inline CSS properties from the given element(s).
|
|
6305
6564
|
*
|
|
6306
6565
|
* @param {string|string[]} prop - A property name or an array of property names to remove.
|
|
6566
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6307
6567
|
*/
|
|
6308
6568
|
removeStyle(prop) {
|
|
6309
6569
|
return TinyHtml_TinyHtml.removeStyle(this, prop);
|
|
@@ -6318,6 +6578,7 @@ class TinyHtml_TinyHtml {
|
|
|
6318
6578
|
* @param {string} prop - The CSS property to toggle.
|
|
6319
6579
|
* @param {string} val1 - The first value (used as "current" check).
|
|
6320
6580
|
* @param {string} val2 - The second value (used as the "alternative").
|
|
6581
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6321
6582
|
*/
|
|
6322
6583
|
static toggleStyle(el, prop, val1, val2) {
|
|
6323
6584
|
TinyHtml_TinyHtml._preHtmlElems(el, 'toggleStyle').forEach((elem) => {
|
|
@@ -6325,6 +6586,7 @@ class TinyHtml_TinyHtml {
|
|
|
6325
6586
|
const newVal = current === TinyHtml_TinyHtml.toStyleKc(val1) ? val2 : val1;
|
|
6326
6587
|
TinyHtml_TinyHtml.setStyle(elem, prop, newVal);
|
|
6327
6588
|
});
|
|
6589
|
+
return el;
|
|
6328
6590
|
}
|
|
6329
6591
|
|
|
6330
6592
|
/**
|
|
@@ -6335,6 +6597,7 @@ class TinyHtml_TinyHtml {
|
|
|
6335
6597
|
* @param {string} prop - The CSS property to toggle.
|
|
6336
6598
|
* @param {string} val1 - The first value (used as "current" check).
|
|
6337
6599
|
* @param {string} val2 - The second value (used as the "alternative").
|
|
6600
|
+
* @returns {TinyHtmlElement|TinyHtmlElement[]}
|
|
6338
6601
|
*/
|
|
6339
6602
|
toggleStyle(prop, val1, val2) {
|
|
6340
6603
|
return TinyHtml_TinyHtml.toggleStyle(this, prop, val1, val2);
|
|
@@ -6344,14 +6607,16 @@ class TinyHtml_TinyHtml {
|
|
|
6344
6607
|
* Removes all inline styles (`style` attribute) from the given element(s).
|
|
6345
6608
|
*
|
|
6346
6609
|
* @param {TinyElement|TinyElement[]} el - A single element or an array of elements.
|
|
6610
|
+
* @returns {TinyElement|TinyElement[]}
|
|
6347
6611
|
*/
|
|
6348
6612
|
static clearStyle(el) {
|
|
6349
6613
|
TinyHtml_TinyHtml._preElems(el, 'clearStyle').forEach((elem) => elem.removeAttribute('style'));
|
|
6614
|
+
return el;
|
|
6350
6615
|
}
|
|
6351
6616
|
|
|
6352
6617
|
/**
|
|
6353
6618
|
* Removes all inline styles (`style` attribute) from the given element(s).
|
|
6354
|
-
*
|
|
6619
|
+
* @returns {TinyElement|TinyElement[]}
|
|
6355
6620
|
*/
|
|
6356
6621
|
clearStyle() {
|
|
6357
6622
|
return TinyHtml_TinyHtml.clearStyle(this);
|
|
@@ -6363,14 +6628,17 @@ class TinyHtml_TinyHtml {
|
|
|
6363
6628
|
* Focus the element.
|
|
6364
6629
|
*
|
|
6365
6630
|
* @param {TinyHtmlElement} el - The element or a selector string.
|
|
6631
|
+
* @returns {TinyHtmlElement}
|
|
6366
6632
|
*/
|
|
6367
6633
|
static focus(el) {
|
|
6368
6634
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'focus');
|
|
6369
6635
|
elem.focus();
|
|
6636
|
+
return el;
|
|
6370
6637
|
}
|
|
6371
6638
|
|
|
6372
6639
|
/**
|
|
6373
6640
|
* Focus the element.
|
|
6641
|
+
* @returns {TinyHtmlElement}
|
|
6374
6642
|
*/
|
|
6375
6643
|
focus() {
|
|
6376
6644
|
return TinyHtml_TinyHtml.focus(this);
|
|
@@ -6380,19 +6648,46 @@ class TinyHtml_TinyHtml {
|
|
|
6380
6648
|
* Blur the element.
|
|
6381
6649
|
*
|
|
6382
6650
|
* @param {TinyHtmlElement} el - The element or a selector string.
|
|
6651
|
+
* @returns {TinyHtmlElement}
|
|
6383
6652
|
*/
|
|
6384
6653
|
static blur(el) {
|
|
6385
6654
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'blur');
|
|
6386
6655
|
elem.blur();
|
|
6656
|
+
return el;
|
|
6387
6657
|
}
|
|
6388
6658
|
|
|
6389
6659
|
/**
|
|
6390
6660
|
* Blur the element.
|
|
6661
|
+
* @returns {TinyHtmlElement}
|
|
6391
6662
|
*/
|
|
6392
6663
|
blur() {
|
|
6393
6664
|
return TinyHtml_TinyHtml.blur(this);
|
|
6394
6665
|
}
|
|
6395
6666
|
|
|
6667
|
+
/**
|
|
6668
|
+
* Interprets a value as a boolean `true` if it matches a common truthy representation.
|
|
6669
|
+
*
|
|
6670
|
+
* This method checks if the input is any of the common forms used to represent `true`,
|
|
6671
|
+
* such as the string `'true'`, `'1'`, `'on'`, the boolean `true`, or the number `1`.
|
|
6672
|
+
*
|
|
6673
|
+
* @param {string|boolean|number} [value] - The value to interpret as boolean.
|
|
6674
|
+
* @returns {boolean} `true` if the value represents a truthy state, otherwise `false`.
|
|
6675
|
+
*/
|
|
6676
|
+
static boolCheck(value) {
|
|
6677
|
+
if (
|
|
6678
|
+
typeof value !== 'undefined' &&
|
|
6679
|
+
(value === 'true' ||
|
|
6680
|
+
value === '1' ||
|
|
6681
|
+
value === true ||
|
|
6682
|
+
value === 'on' ||
|
|
6683
|
+
(typeof value === 'number' && value > 0))
|
|
6684
|
+
) {
|
|
6685
|
+
return true;
|
|
6686
|
+
} else {
|
|
6687
|
+
return false;
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6396
6691
|
//////////////////////////////////////////////////////////////////////
|
|
6397
6692
|
|
|
6398
6693
|
/**
|
|
@@ -6401,7 +6696,7 @@ class TinyHtml_TinyHtml {
|
|
|
6401
6696
|
*/
|
|
6402
6697
|
static setWinScrollTop(value) {
|
|
6403
6698
|
if (typeof value !== 'number') throw new TypeError('The value must be a number.');
|
|
6404
|
-
|
|
6699
|
+
TinyHtml_TinyHtml.setScrollTop(window, value);
|
|
6405
6700
|
}
|
|
6406
6701
|
|
|
6407
6702
|
/**
|
|
@@ -6410,7 +6705,7 @@ class TinyHtml_TinyHtml {
|
|
|
6410
6705
|
*/
|
|
6411
6706
|
static setWinScrollLeft(value) {
|
|
6412
6707
|
if (typeof value !== 'number') throw new TypeError('The value must be a number.');
|
|
6413
|
-
|
|
6708
|
+
TinyHtml_TinyHtml.setScrollLeft(window, value);
|
|
6414
6709
|
}
|
|
6415
6710
|
|
|
6416
6711
|
/**
|
|
@@ -6445,16 +6740,40 @@ class TinyHtml_TinyHtml {
|
|
|
6445
6740
|
return window.innerWidth || document.documentElement.clientWidth;
|
|
6446
6741
|
}
|
|
6447
6742
|
|
|
6743
|
+
/**
|
|
6744
|
+
* Checks if the page is currently scrolled to the very top.
|
|
6745
|
+
*
|
|
6746
|
+
* This method compares the current vertical scroll position with the total document height.
|
|
6747
|
+
* It's useful for detecting if the user has reached the top of the page.
|
|
6748
|
+
*
|
|
6749
|
+
* @returns {boolean} `true` if the page is scrolled to the top, otherwise `false`.
|
|
6750
|
+
*/
|
|
6751
|
+
static isPageTop() {
|
|
6752
|
+
return window.scrollY === 0;
|
|
6753
|
+
}
|
|
6754
|
+
|
|
6755
|
+
/**
|
|
6756
|
+
* Checks if the page is currently scrolled to the very bottom.
|
|
6757
|
+
*
|
|
6758
|
+
* This method uses the `scrollY` and `innerHeight` properties to determine if the
|
|
6759
|
+
* user has reached the end of the document.
|
|
6760
|
+
*
|
|
6761
|
+
* @returns {boolean} `true` if the page is scrolled to the bottom, otherwise `false`.
|
|
6762
|
+
*/
|
|
6763
|
+
static isPageBottom() {
|
|
6764
|
+
return window.innerHeight + window.scrollY >= document.body.offsetHeight;
|
|
6765
|
+
}
|
|
6766
|
+
|
|
6448
6767
|
/**
|
|
6449
6768
|
* Gets the width or height of an element based on the box model.
|
|
6450
|
-
* @param {
|
|
6769
|
+
* @param {TinyElementAndWinAndDoc} el - The element or window.
|
|
6451
6770
|
* @param {"width"|"height"} type - Dimension type.
|
|
6452
6771
|
* @param {"content"|"padding"|"border"|"margin"} [extra='content'] - Box model context.
|
|
6453
6772
|
* @returns {number} - Computed dimension.
|
|
6454
6773
|
* @throws {TypeError} If `type` or `extra` is not a string.
|
|
6455
6774
|
*/
|
|
6456
6775
|
static getDimension(el, type, extra = 'content') {
|
|
6457
|
-
const elem = TinyHtml_TinyHtml.
|
|
6776
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'getDimension');
|
|
6458
6777
|
if (typeof type !== 'string') throw new TypeError('The type must be a string.');
|
|
6459
6778
|
if (typeof extra !== 'string') throw new TypeError('The extra must be a string.');
|
|
6460
6779
|
|
|
@@ -6542,17 +6861,20 @@ class TinyHtml_TinyHtml {
|
|
|
6542
6861
|
* @param {TinyHtmlElement} el - Target element.
|
|
6543
6862
|
* @param {string|number} value - Height value.
|
|
6544
6863
|
* @throws {TypeError} If `value` is neither a string nor number.
|
|
6864
|
+
* @returns {TinyHtmlElement}
|
|
6545
6865
|
*/
|
|
6546
6866
|
static setHeight(el, value) {
|
|
6547
6867
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'setHeight');
|
|
6548
6868
|
if (typeof value !== 'number' && typeof value !== 'string')
|
|
6549
6869
|
throw new TypeError('The value must be a string or number.');
|
|
6550
6870
|
elem.style.height = typeof value === 'number' ? `${value}px` : value;
|
|
6871
|
+
return el;
|
|
6551
6872
|
}
|
|
6552
6873
|
|
|
6553
6874
|
/**
|
|
6554
6875
|
* Sets the height of the element.
|
|
6555
6876
|
* @param {string|number} value - Height value.
|
|
6877
|
+
* @returns {TinyHtmlElement}
|
|
6556
6878
|
*/
|
|
6557
6879
|
setHeight(value) {
|
|
6558
6880
|
return TinyHtml_TinyHtml.setHeight(this, value);
|
|
@@ -6563,17 +6885,20 @@ class TinyHtml_TinyHtml {
|
|
|
6563
6885
|
* @param {TinyHtmlElement} el - Target element.
|
|
6564
6886
|
* @param {string|number} value - Width value.
|
|
6565
6887
|
* @throws {TypeError} If `value` is neither a string nor number.
|
|
6888
|
+
* @returns {TinyHtmlElement}
|
|
6566
6889
|
*/
|
|
6567
6890
|
static setWidth(el, value) {
|
|
6568
6891
|
const elem = TinyHtml_TinyHtml._preHtmlElem(el, 'setWidth');
|
|
6569
6892
|
if (typeof value !== 'number' && typeof value !== 'string')
|
|
6570
6893
|
throw new TypeError('The value must be a string or number.');
|
|
6571
6894
|
elem.style.width = typeof value === 'number' ? `${value}px` : value;
|
|
6895
|
+
return el;
|
|
6572
6896
|
}
|
|
6573
6897
|
|
|
6574
6898
|
/**
|
|
6575
6899
|
* Sets the width of the element.
|
|
6576
6900
|
* @param {string|number} value - Width value.
|
|
6901
|
+
* @returns {TinyHtmlElement}
|
|
6577
6902
|
*/
|
|
6578
6903
|
setWidth(value) {
|
|
6579
6904
|
return TinyHtml_TinyHtml.setWidth(this, value);
|
|
@@ -6581,11 +6906,11 @@ class TinyHtml_TinyHtml {
|
|
|
6581
6906
|
|
|
6582
6907
|
/**
|
|
6583
6908
|
* Returns content box height.
|
|
6584
|
-
* @param {
|
|
6909
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6585
6910
|
* @returns {number}
|
|
6586
6911
|
*/
|
|
6587
6912
|
static height(el) {
|
|
6588
|
-
const elem = TinyHtml_TinyHtml.
|
|
6913
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'height');
|
|
6589
6914
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', 'content');
|
|
6590
6915
|
}
|
|
6591
6916
|
|
|
@@ -6599,11 +6924,11 @@ class TinyHtml_TinyHtml {
|
|
|
6599
6924
|
|
|
6600
6925
|
/**
|
|
6601
6926
|
* Returns content box width.
|
|
6602
|
-
* @param {
|
|
6927
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6603
6928
|
* @returns {number}
|
|
6604
6929
|
*/
|
|
6605
6930
|
static width(el) {
|
|
6606
|
-
const elem = TinyHtml_TinyHtml.
|
|
6931
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'width');
|
|
6607
6932
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', 'content');
|
|
6608
6933
|
}
|
|
6609
6934
|
|
|
@@ -6617,11 +6942,11 @@ class TinyHtml_TinyHtml {
|
|
|
6617
6942
|
|
|
6618
6943
|
/**
|
|
6619
6944
|
* Returns padding box height.
|
|
6620
|
-
* @param {
|
|
6945
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6621
6946
|
* @returns {number}
|
|
6622
6947
|
*/
|
|
6623
6948
|
static innerHeight(el) {
|
|
6624
|
-
const elem = TinyHtml_TinyHtml.
|
|
6949
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'innerHeight');
|
|
6625
6950
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', 'padding');
|
|
6626
6951
|
}
|
|
6627
6952
|
|
|
@@ -6635,11 +6960,11 @@ class TinyHtml_TinyHtml {
|
|
|
6635
6960
|
|
|
6636
6961
|
/**
|
|
6637
6962
|
* Returns padding box width.
|
|
6638
|
-
* @param {
|
|
6963
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6639
6964
|
* @returns {number}
|
|
6640
6965
|
*/
|
|
6641
6966
|
static innerWidth(el) {
|
|
6642
|
-
const elem = TinyHtml_TinyHtml.
|
|
6967
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'innerWidth');
|
|
6643
6968
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', 'padding');
|
|
6644
6969
|
}
|
|
6645
6970
|
|
|
@@ -6653,14 +6978,14 @@ class TinyHtml_TinyHtml {
|
|
|
6653
6978
|
|
|
6654
6979
|
/**
|
|
6655
6980
|
* Returns outer height of the element, optionally including margin.
|
|
6656
|
-
* @param {
|
|
6981
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6657
6982
|
* @param {boolean} [includeMargin=false] - Whether to include margin.
|
|
6658
6983
|
* @returns {number}
|
|
6659
6984
|
*/
|
|
6660
6985
|
static outerHeight(el, includeMargin = false) {
|
|
6661
6986
|
if (typeof includeMargin !== 'boolean')
|
|
6662
6987
|
throw new TypeError('The "includeMargin" must be a boolean.');
|
|
6663
|
-
const elem = TinyHtml_TinyHtml.
|
|
6988
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'outerHeight');
|
|
6664
6989
|
return TinyHtml_TinyHtml.getDimension(elem, 'height', includeMargin ? 'margin' : 'border');
|
|
6665
6990
|
}
|
|
6666
6991
|
|
|
@@ -6675,14 +7000,14 @@ class TinyHtml_TinyHtml {
|
|
|
6675
7000
|
|
|
6676
7001
|
/**
|
|
6677
7002
|
* Returns outer width of the element, optionally including margin.
|
|
6678
|
-
* @param {
|
|
7003
|
+
* @param {TinyElementAndWinAndDoc} el - Target element.
|
|
6679
7004
|
* @param {boolean} [includeMargin=false] - Whether to include margin.
|
|
6680
7005
|
* @returns {number}
|
|
6681
7006
|
*/
|
|
6682
7007
|
static outerWidth(el, includeMargin = false) {
|
|
6683
7008
|
if (typeof includeMargin !== 'boolean')
|
|
6684
7009
|
throw new TypeError('The "includeMargin" must be a boolean.');
|
|
6685
|
-
const elem = TinyHtml_TinyHtml.
|
|
7010
|
+
const elem = TinyHtml_TinyHtml._preElemAndWinAndDoc(el, 'outerWidth');
|
|
6686
7011
|
return TinyHtml_TinyHtml.getDimension(elem, 'width', includeMargin ? 'margin' : 'border');
|
|
6687
7012
|
}
|
|
6688
7013
|
|
|
@@ -6697,6 +7022,30 @@ class TinyHtml_TinyHtml {
|
|
|
6697
7022
|
|
|
6698
7023
|
//////////////////////////////////////////////////
|
|
6699
7024
|
|
|
7025
|
+
/**
|
|
7026
|
+
* Applies an animation to one or multiple TinyElement instances.
|
|
7027
|
+
*
|
|
7028
|
+
* @param {TinyElement|TinyElement[]} el - A single TinyElement or an array of TinyElements to animate.
|
|
7029
|
+
* @param {Keyframe[] | PropertyIndexedKeyframes | null} keyframes - The keyframes used to define the animation.
|
|
7030
|
+
* @param {number | KeyframeAnimationOptions} [ops] - Timing or configuration options for the animation.
|
|
7031
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7032
|
+
*/
|
|
7033
|
+
static animate(el, keyframes, ops) {
|
|
7034
|
+
TinyHtml_TinyHtml._preElems(el, 'animate').forEach((elem) => elem.animate(keyframes, ops));
|
|
7035
|
+
return el;
|
|
7036
|
+
}
|
|
7037
|
+
|
|
7038
|
+
/**
|
|
7039
|
+
* Applies an animation to one or multiple TinyElement instances.
|
|
7040
|
+
*
|
|
7041
|
+
* @param {Keyframe[] | PropertyIndexedKeyframes | null} keyframes - The keyframes used to define the animation.
|
|
7042
|
+
* @param {number | KeyframeAnimationOptions} [ops] - Timing or configuration options for the animation.
|
|
7043
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7044
|
+
*/
|
|
7045
|
+
animate(keyframes, ops) {
|
|
7046
|
+
return TinyHtml_TinyHtml.animate(this, keyframes, ops);
|
|
7047
|
+
}
|
|
7048
|
+
|
|
6700
7049
|
/**
|
|
6701
7050
|
* Gets the offset of the element relative to the document.
|
|
6702
7051
|
* @param {TinyElement} el - Target element.
|
|
@@ -6852,27 +7201,151 @@ class TinyHtml_TinyHtml {
|
|
|
6852
7201
|
}
|
|
6853
7202
|
|
|
6854
7203
|
/**
|
|
6855
|
-
*
|
|
6856
|
-
*
|
|
6857
|
-
*
|
|
7204
|
+
* Collection of easing functions used for scroll and animation calculations.
|
|
7205
|
+
* Each function receives a normalized time value (`t` from 0 to 1) and returns the eased progress.
|
|
7206
|
+
*
|
|
7207
|
+
* @type {Record<string, (t: number) => number>}
|
|
6858
7208
|
*/
|
|
6859
|
-
static
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
7209
|
+
static easings = {
|
|
7210
|
+
linear: (t) => t,
|
|
7211
|
+
easeInQuad: (t) => t * t,
|
|
7212
|
+
easeOutQuad: (t) => t * (2 - t),
|
|
7213
|
+
easeInOutQuad: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
|
|
7214
|
+
easeInCubic: (t) => t * t * t,
|
|
7215
|
+
easeOutCubic: (t) => --t * t * t + 1,
|
|
7216
|
+
easeInOutCubic: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
|
|
7217
|
+
};
|
|
7218
|
+
|
|
7219
|
+
/**
|
|
7220
|
+
* Smoothly scrolls one or more elements (or the window) to the specified X and Y coordinates
|
|
7221
|
+
* using a custom duration and easing function.
|
|
7222
|
+
*
|
|
7223
|
+
* If `duration` or a valid `easing` is not provided, the scroll will be performed immediately.
|
|
7224
|
+
*
|
|
7225
|
+
* @param {TinyElementAndWindow | TinyElementAndWindow[]} el - A single element, array of elements, or the window to scroll.
|
|
7226
|
+
* @param {Object} [settings={}] - Configuration object for the scroll animation.
|
|
7227
|
+
* @param {number} [settings.targetX] - The horizontal scroll target in pixels.
|
|
7228
|
+
* @param {number} [settings.targetY] - The vertical scroll target in pixels.
|
|
7229
|
+
* @param {number} [settings.duration] - The duration of the animation in milliseconds.
|
|
7230
|
+
* @param {Easings} [settings.easing] - The easing function name to use for the scroll animation.
|
|
7231
|
+
* @param {OnScrollAnimation} [settings.onAnimation] - Optional callback invoked on each animation
|
|
7232
|
+
* frame with the current scroll position, normalized animation time (`0` to `1`), and a completion flag.
|
|
7233
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
7234
|
+
* @throws {TypeError} If `el` is not a valid element, array, or window.
|
|
7235
|
+
* @throws {TypeError} If `targetX` or `targetY` is defined but not a number.
|
|
7236
|
+
* @throws {TypeError} If `duration` is defined but not a number.
|
|
7237
|
+
* @throws {TypeError} If `easing` is defined but not a valid easing function name.
|
|
7238
|
+
* @throws {TypeError} If `onAnimation` is defined but not a function.
|
|
7239
|
+
*/
|
|
7240
|
+
static scrollToXY(el, { targetX, targetY, duration, easing, onAnimation } = {}) {
|
|
7241
|
+
if (targetX !== undefined && typeof targetX !== 'number')
|
|
7242
|
+
throw new TypeError('`targetX` must be a number if provided.');
|
|
7243
|
+
if (targetY !== undefined && typeof targetY !== 'number')
|
|
7244
|
+
throw new TypeError('`targetY` must be a number if provided.');
|
|
7245
|
+
if (duration !== undefined && typeof duration !== 'number')
|
|
7246
|
+
throw new TypeError('`duration` must be a number if provided.');
|
|
7247
|
+
if (easing !== undefined && typeof easing !== 'string')
|
|
7248
|
+
throw new TypeError('`easing` must be a string if provided.');
|
|
7249
|
+
if (easing !== undefined && typeof TinyHtml_TinyHtml.easings[easing] !== 'function')
|
|
7250
|
+
throw new TypeError(`Unknown easing function: "${easing}".`);
|
|
7251
|
+
if (onAnimation !== undefined && typeof onAnimation !== 'function')
|
|
7252
|
+
throw new TypeError('`onAnimation` must be a function if provided.');
|
|
7253
|
+
|
|
7254
|
+
/**
|
|
7255
|
+
* Performs an instant scroll to the given coordinates.
|
|
7256
|
+
*
|
|
7257
|
+
* @param {ElementAndWindow} elem - The element or window to scroll.
|
|
7258
|
+
* @param {number} newX - The final horizontal scroll position.
|
|
7259
|
+
* @param {number} newY - The final vertical scroll position.
|
|
7260
|
+
* @param {number} time - Normalized progress value.
|
|
7261
|
+
*/
|
|
7262
|
+
const executeScroll = (elem, newX, newY, time) => {
|
|
7263
|
+
if (elem instanceof Window) {
|
|
7264
|
+
window.scrollTo(newX, newY);
|
|
6864
7265
|
} else if (elem.nodeType === 9) {
|
|
6865
7266
|
// @ts-ignore
|
|
6866
|
-
elem.defaultView.scrollTo(
|
|
7267
|
+
elem.defaultView.scrollTo(newX, newY);
|
|
6867
7268
|
} else {
|
|
6868
|
-
elem.
|
|
7269
|
+
const startX = elem instanceof Window ? window.scrollX : elem.scrollLeft;
|
|
7270
|
+
const startY = elem instanceof Window ? window.scrollY : elem.scrollTop;
|
|
7271
|
+
if (startX !== newX) elem.scrollLeft = newX;
|
|
7272
|
+
if (startY !== newY) elem.scrollTop = newY;
|
|
7273
|
+
}
|
|
7274
|
+
if (typeof onAnimation === 'function')
|
|
7275
|
+
onAnimation({ x: newX, y: newY, isComplete: time >= 1, time });
|
|
7276
|
+
};
|
|
7277
|
+
|
|
7278
|
+
TinyHtml_TinyHtml._preElemsAndWindow(el, 'scrollToXY').forEach((elem) => {
|
|
7279
|
+
const startX = elem instanceof Window ? window.scrollX : elem.scrollLeft;
|
|
7280
|
+
const startY = elem instanceof Window ? window.scrollY : elem.scrollTop;
|
|
7281
|
+
const targX = targetX ?? startX;
|
|
7282
|
+
const targY = targetY ?? startY;
|
|
7283
|
+
|
|
7284
|
+
const changeX = targX - startX;
|
|
7285
|
+
const changeY = targY - startY;
|
|
7286
|
+
|
|
7287
|
+
const ease = (typeof easing === 'string' && TinyHtml_TinyHtml.easings[easing]) || null;
|
|
7288
|
+
if (typeof duration !== 'number' || typeof ease !== 'function')
|
|
7289
|
+
return executeScroll(elem, targX, targY, 1);
|
|
7290
|
+
const startTime = performance.now();
|
|
7291
|
+
const dur = duration ?? 0;
|
|
7292
|
+
|
|
7293
|
+
/**
|
|
7294
|
+
* Animates the scroll position based on easing and time.
|
|
7295
|
+
*
|
|
7296
|
+
* @param {number} currentTime - Timestamp provided by requestAnimationFrame.
|
|
7297
|
+
*/
|
|
7298
|
+
function animateScroll(currentTime) {
|
|
7299
|
+
if (typeof ease !== 'function') return;
|
|
7300
|
+
const time = Math.min(1, (currentTime - startTime) / dur);
|
|
7301
|
+
const easedTime = ease(time);
|
|
7302
|
+
|
|
7303
|
+
const newX = startX + changeX * easedTime;
|
|
7304
|
+
const newY = startY + changeY * easedTime;
|
|
7305
|
+
executeScroll(elem, newX, newY, time);
|
|
7306
|
+
|
|
7307
|
+
if (time < 1) requestAnimationFrame(animateScroll);
|
|
6869
7308
|
}
|
|
7309
|
+
|
|
7310
|
+
requestAnimationFrame(animateScroll);
|
|
6870
7311
|
});
|
|
7312
|
+
return el;
|
|
7313
|
+
}
|
|
7314
|
+
|
|
7315
|
+
/**
|
|
7316
|
+
* Smoothly scrolls one or more elements (or the window) to the specified X and Y coordinates
|
|
7317
|
+
* using a custom duration and easing function.
|
|
7318
|
+
*
|
|
7319
|
+
* If `duration` or a valid `easing` is not provided, the scroll will be performed immediately.
|
|
7320
|
+
*
|
|
7321
|
+
* @param {Object} [settings={}] - Configuration object for the scroll animation.
|
|
7322
|
+
* @param {number} [settings.targetX] - The horizontal scroll target in pixels.
|
|
7323
|
+
* @param {number} [settings.targetY] - The vertical scroll target in pixels.
|
|
7324
|
+
* @param {number} [settings.duration] - The duration of the animation in milliseconds.
|
|
7325
|
+
* @param {Easings} [settings.easing] - The easing function name to use for the scroll animation.
|
|
7326
|
+
* @param {OnScrollAnimation} [settings.onAnimation] - Optional callback invoked on each animation
|
|
7327
|
+
* frame with the current scroll position, normalized animation time (`0` to `1`), and a completion flag.
|
|
7328
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
7329
|
+
*/
|
|
7330
|
+
scrollToXY({ targetX, targetY, duration, easing, onAnimation } = {}) {
|
|
7331
|
+
return TinyHtml_TinyHtml.scrollToXY(this, { targetX, targetY, duration, easing, onAnimation });
|
|
7332
|
+
}
|
|
7333
|
+
|
|
7334
|
+
/**
|
|
7335
|
+
* Sets the vertical scroll position.
|
|
7336
|
+
* @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
|
|
7337
|
+
* @param {number} value - Scroll top value.
|
|
7338
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
7339
|
+
*/
|
|
7340
|
+
static setScrollTop(el, value) {
|
|
7341
|
+
if (typeof value !== 'number') throw new TypeError('ScrollTop value must be a number.');
|
|
7342
|
+
return TinyHtml_TinyHtml.scrollToXY(el, { targetY: value });
|
|
6871
7343
|
}
|
|
6872
7344
|
|
|
6873
7345
|
/**
|
|
6874
7346
|
* Sets the vertical scroll position.
|
|
6875
7347
|
* @param {number} value - Scroll top value.
|
|
7348
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6876
7349
|
*/
|
|
6877
7350
|
setScrollTop(value) {
|
|
6878
7351
|
return TinyHtml_TinyHtml.setScrollTop(this, value);
|
|
@@ -6882,24 +7355,17 @@ class TinyHtml_TinyHtml {
|
|
|
6882
7355
|
* Sets the horizontal scroll position.
|
|
6883
7356
|
* @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
|
|
6884
7357
|
* @param {number} value - Scroll left value.
|
|
7358
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6885
7359
|
*/
|
|
6886
7360
|
static setScrollLeft(el, value) {
|
|
6887
7361
|
if (typeof value !== 'number') throw new TypeError('ScrollLeft value must be a number.');
|
|
6888
|
-
TinyHtml_TinyHtml.
|
|
6889
|
-
if (TinyHtml_TinyHtml.isWindow(elem)) {
|
|
6890
|
-
elem.scrollTo(value, elem.pageYOffset);
|
|
6891
|
-
} else if (elem.nodeType === 9) {
|
|
6892
|
-
// @ts-ignore
|
|
6893
|
-
elem.defaultView.scrollTo(value, elem.defaultView.pageYOffset);
|
|
6894
|
-
} else {
|
|
6895
|
-
elem.scrollLeft = value;
|
|
6896
|
-
}
|
|
6897
|
-
});
|
|
7362
|
+
return TinyHtml_TinyHtml.scrollToXY(el, { targetX: value });
|
|
6898
7363
|
}
|
|
6899
7364
|
|
|
6900
7365
|
/**
|
|
6901
7366
|
* Sets the horizontal scroll position.
|
|
6902
7367
|
* @param {number} value - Scroll left value.
|
|
7368
|
+
* @returns {TinyElementAndWindow|TinyElementAndWindow[]}
|
|
6903
7369
|
*/
|
|
6904
7370
|
setScrollLeft(value) {
|
|
6905
7371
|
return TinyHtml_TinyHtml.setScrollLeft(this, value);
|
|
@@ -7030,15 +7496,16 @@ class TinyHtml_TinyHtml {
|
|
|
7030
7496
|
|
|
7031
7497
|
/**
|
|
7032
7498
|
* Adds one or more CSS class names to the element.
|
|
7033
|
-
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) =>
|
|
7499
|
+
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to add.
|
|
7034
7500
|
*/
|
|
7035
7501
|
static addClass(el, ...args) {
|
|
7036
7502
|
TinyHtml_TinyHtml._preElems(el, 'addClass').forEach((elem) => elem.classList.add(...args));
|
|
7503
|
+
return el;
|
|
7037
7504
|
}
|
|
7038
7505
|
|
|
7039
7506
|
/**
|
|
7040
7507
|
* Adds one or more CSS class names to the element.
|
|
7041
|
-
* @type {(...tokens: string[]) =>
|
|
7508
|
+
* @type {(...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to add.
|
|
7042
7509
|
*/
|
|
7043
7510
|
addClass(...args) {
|
|
7044
7511
|
return TinyHtml_TinyHtml.addClass(this, ...args);
|
|
@@ -7046,15 +7513,16 @@ class TinyHtml_TinyHtml {
|
|
|
7046
7513
|
|
|
7047
7514
|
/**
|
|
7048
7515
|
* Removes one or more CSS class names from the element.
|
|
7049
|
-
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) =>
|
|
7516
|
+
* @type {(el: TinyElement|TinyElement[], ...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to remove.
|
|
7050
7517
|
*/
|
|
7051
7518
|
static removeClass(el, ...args) {
|
|
7052
7519
|
TinyHtml_TinyHtml._preElems(el, 'removeClass').forEach((elem) => elem.classList.remove(...args));
|
|
7520
|
+
return el;
|
|
7053
7521
|
}
|
|
7054
7522
|
|
|
7055
7523
|
/**
|
|
7056
7524
|
* Removes one or more CSS class names from the element.
|
|
7057
|
-
* @type {(...tokens: string[]) =>
|
|
7525
|
+
* @type {(...tokens: string[]) => (TinyElement|TinyElement[])} - One or more class names to remove.
|
|
7058
7526
|
*/
|
|
7059
7527
|
removeClass(...args) {
|
|
7060
7528
|
return TinyHtml_TinyHtml.removeClass(this, ...args);
|
|
@@ -7264,15 +7732,18 @@ class TinyHtml_TinyHtml {
|
|
|
7264
7732
|
* Set text content of elements.
|
|
7265
7733
|
* @param {TinyElement|TinyElement[]} el
|
|
7266
7734
|
* @param {string} value
|
|
7735
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7267
7736
|
*/
|
|
7268
7737
|
static setText(el, value) {
|
|
7269
7738
|
if (typeof value !== 'string') throw new Error('Value is not a valid string.');
|
|
7270
7739
|
TinyHtml_TinyHtml._preElems(el, 'setText').forEach((el) => (el.textContent = value));
|
|
7740
|
+
return el;
|
|
7271
7741
|
}
|
|
7272
7742
|
|
|
7273
7743
|
/**
|
|
7274
7744
|
* Set text content of the element.
|
|
7275
7745
|
* @param {string} value
|
|
7746
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7276
7747
|
*/
|
|
7277
7748
|
setText(value) {
|
|
7278
7749
|
return TinyHtml_TinyHtml.setText(this, value);
|
|
@@ -7281,13 +7752,16 @@ class TinyHtml_TinyHtml {
|
|
|
7281
7752
|
/**
|
|
7282
7753
|
* Remove all child nodes from each element.
|
|
7283
7754
|
* @param {TinyElement|TinyElement[]} el
|
|
7755
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7284
7756
|
*/
|
|
7285
7757
|
static empty(el) {
|
|
7286
7758
|
TinyHtml_TinyHtml._preElems(el, 'empty').forEach((el) => (el.textContent = ''));
|
|
7759
|
+
return el;
|
|
7287
7760
|
}
|
|
7288
7761
|
|
|
7289
7762
|
/**
|
|
7290
7763
|
* Remove all child nodes of the element.
|
|
7764
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7291
7765
|
*/
|
|
7292
7766
|
empty() {
|
|
7293
7767
|
return TinyHtml_TinyHtml.empty(this);
|
|
@@ -7295,35 +7769,40 @@ class TinyHtml_TinyHtml {
|
|
|
7295
7769
|
|
|
7296
7770
|
/**
|
|
7297
7771
|
* Get the innerHTML of the element.
|
|
7298
|
-
* @param {TinyElement
|
|
7772
|
+
* @param {TinyElement} el
|
|
7773
|
+
* @param {GetHTMLOptions} [ops]
|
|
7299
7774
|
* @returns {string}
|
|
7300
7775
|
*/
|
|
7301
|
-
static html(el) {
|
|
7776
|
+
static html(el, ops) {
|
|
7302
7777
|
const elem = TinyHtml_TinyHtml._preElem(el, 'html');
|
|
7303
|
-
return elem.
|
|
7778
|
+
return elem.getHTML(ops);
|
|
7304
7779
|
}
|
|
7305
7780
|
|
|
7306
7781
|
/**
|
|
7307
7782
|
* Get the innerHTML of the element.
|
|
7783
|
+
* @param {GetHTMLOptions} [ops]
|
|
7308
7784
|
* @returns {string}
|
|
7309
7785
|
*/
|
|
7310
|
-
html() {
|
|
7311
|
-
return TinyHtml_TinyHtml.html(this);
|
|
7786
|
+
html(ops) {
|
|
7787
|
+
return TinyHtml_TinyHtml.html(this, ops);
|
|
7312
7788
|
}
|
|
7313
7789
|
|
|
7314
7790
|
/**
|
|
7315
7791
|
* Set the innerHTML of each element.
|
|
7316
7792
|
* @param {TinyElement|TinyElement[]} el
|
|
7317
7793
|
* @param {string} value
|
|
7794
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7318
7795
|
*/
|
|
7319
7796
|
static setHtml(el, value) {
|
|
7320
7797
|
if (typeof value !== 'string') throw new Error('Value is not a valid string.');
|
|
7321
7798
|
TinyHtml_TinyHtml._preElems(el, 'setHtml').forEach((el) => (el.innerHTML = value));
|
|
7799
|
+
return el;
|
|
7322
7800
|
}
|
|
7323
7801
|
|
|
7324
7802
|
/**
|
|
7325
7803
|
* Set the innerHTML of the element.
|
|
7326
7804
|
* @param {string} value
|
|
7805
|
+
* @returns {TinyElement|TinyElement[]}
|
|
7327
7806
|
*/
|
|
7328
7807
|
setHtml(value) {
|
|
7329
7808
|
return TinyHtml_TinyHtml.setHtml(this, value);
|
|
@@ -7457,6 +7936,7 @@ class TinyHtml_TinyHtml {
|
|
|
7457
7936
|
* @param {TinyInputElement|TinyInputElement[]} el - Target element.
|
|
7458
7937
|
* @param {SetValueList|((el: InputElement, val: SetValueList) => SetValueList)} value - The value to assign or a function that returns it.
|
|
7459
7938
|
* @throws {Error} If the computed value is not a valid string or boolean.
|
|
7939
|
+
* @returns {TinyInputElement|TinyInputElement[]}
|
|
7460
7940
|
*/
|
|
7461
7941
|
static setVal(el, value) {
|
|
7462
7942
|
TinyHtml_TinyHtml._preInputElems(el, 'setVal').forEach((elem) => {
|
|
@@ -7496,6 +7976,7 @@ class TinyHtml_TinyHtml {
|
|
|
7496
7976
|
if (typeof valToSet === 'string') elem.value = valToSet;
|
|
7497
7977
|
}
|
|
7498
7978
|
});
|
|
7979
|
+
return el;
|
|
7499
7980
|
}
|
|
7500
7981
|
|
|
7501
7982
|
/**
|
|
@@ -7503,6 +7984,7 @@ class TinyHtml_TinyHtml {
|
|
|
7503
7984
|
* Accepts strings, numbers, booleans or arrays of these values, or a callback function that computes them.
|
|
7504
7985
|
*
|
|
7505
7986
|
* @param {SetValueList|((el: InputElement, val: SetValueList) => SetValueList)} value - The value to assign or a function that returns it.
|
|
7987
|
+
* @returns {TinyInputElement|TinyInputElement[]}
|
|
7506
7988
|
* @throws {Error} If the computed value is not a valid string or boolean.
|
|
7507
7989
|
*/
|
|
7508
7990
|
setVal(value) {
|
|
@@ -7772,6 +8254,7 @@ class TinyHtml_TinyHtml {
|
|
|
7772
8254
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7773
8255
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7774
8256
|
* @param {EventRegistryOptions} [options] - Optional event listener options.
|
|
8257
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7775
8258
|
*/
|
|
7776
8259
|
static on(el, event, handler, options) {
|
|
7777
8260
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7784,6 +8267,7 @@ class TinyHtml_TinyHtml {
|
|
|
7784
8267
|
if (!Array.isArray(events[event])) events[event] = [];
|
|
7785
8268
|
events[event].push({ handler, options });
|
|
7786
8269
|
});
|
|
8270
|
+
return el;
|
|
7787
8271
|
}
|
|
7788
8272
|
|
|
7789
8273
|
/**
|
|
@@ -7792,6 +8276,7 @@ class TinyHtml_TinyHtml {
|
|
|
7792
8276
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7793
8277
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7794
8278
|
* @param {EventRegistryOptions} [options] - Optional event listener options.
|
|
8279
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7795
8280
|
*/
|
|
7796
8281
|
on(event, handler, options) {
|
|
7797
8282
|
return TinyHtml_TinyHtml.on(this, event, handler, options);
|
|
@@ -7804,6 +8289,7 @@ class TinyHtml_TinyHtml {
|
|
|
7804
8289
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7805
8290
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7806
8291
|
* @param {EventRegistryOptions} [options={}] - Optional event listener options.
|
|
8292
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7807
8293
|
*/
|
|
7808
8294
|
static once(el, event, handler, options = {}) {
|
|
7809
8295
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7821,6 +8307,7 @@ class TinyHtml_TinyHtml {
|
|
|
7821
8307
|
typeof options === 'boolean' ? options : { ...options, once: true },
|
|
7822
8308
|
);
|
|
7823
8309
|
});
|
|
8310
|
+
return el;
|
|
7824
8311
|
}
|
|
7825
8312
|
|
|
7826
8313
|
/**
|
|
@@ -7829,6 +8316,7 @@ class TinyHtml_TinyHtml {
|
|
|
7829
8316
|
* @param {string} event - The event type (e.g. 'click', 'keydown').
|
|
7830
8317
|
* @param {EventRegistryHandle} handler - The callback function to run on event.
|
|
7831
8318
|
* @param {EventRegistryOptions} [options={}] - Optional event listener options.
|
|
8319
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7832
8320
|
*/
|
|
7833
8321
|
once(event, handler, options = {}) {
|
|
7834
8322
|
return TinyHtml_TinyHtml.once(this, event, handler, options);
|
|
@@ -7841,6 +8329,7 @@ class TinyHtml_TinyHtml {
|
|
|
7841
8329
|
* @param {string} event - The event type.
|
|
7842
8330
|
* @param {EventRegistryHandle} handler - The function originally bound to the event.
|
|
7843
8331
|
* @param {boolean|EventListenerOptions} [options] - Optional listener options.
|
|
8332
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7844
8333
|
*/
|
|
7845
8334
|
static off(el, event, handler, options) {
|
|
7846
8335
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7853,6 +8342,7 @@ class TinyHtml_TinyHtml {
|
|
|
7853
8342
|
if (events[event].length === 0) delete events[event];
|
|
7854
8343
|
}
|
|
7855
8344
|
});
|
|
8345
|
+
return el;
|
|
7856
8346
|
}
|
|
7857
8347
|
|
|
7858
8348
|
/**
|
|
@@ -7861,6 +8351,7 @@ class TinyHtml_TinyHtml {
|
|
|
7861
8351
|
* @param {string} event - The event type.
|
|
7862
8352
|
* @param {EventRegistryHandle} handler - The function originally bound to the event.
|
|
7863
8353
|
* @param {boolean|EventListenerOptions} [options] - Optional listener options.
|
|
8354
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7864
8355
|
*/
|
|
7865
8356
|
off(event, handler, options) {
|
|
7866
8357
|
return TinyHtml_TinyHtml.off(this, event, handler, options);
|
|
@@ -7871,6 +8362,7 @@ class TinyHtml_TinyHtml {
|
|
|
7871
8362
|
*
|
|
7872
8363
|
* @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
|
|
7873
8364
|
* @param {string} event - The event type to remove (e.g. 'click').
|
|
8365
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7874
8366
|
*/
|
|
7875
8367
|
static offAll(el, event) {
|
|
7876
8368
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7883,12 +8375,14 @@ class TinyHtml_TinyHtml {
|
|
|
7883
8375
|
delete events[event];
|
|
7884
8376
|
}
|
|
7885
8377
|
});
|
|
8378
|
+
return el;
|
|
7886
8379
|
}
|
|
7887
8380
|
|
|
7888
8381
|
/**
|
|
7889
8382
|
* Removes all event listeners of a specific type from the element.
|
|
7890
8383
|
*
|
|
7891
8384
|
* @param {string} event - The event type to remove (e.g. 'click').
|
|
8385
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7892
8386
|
*/
|
|
7893
8387
|
offAll(event) {
|
|
7894
8388
|
return TinyHtml_TinyHtml.offAll(this, event);
|
|
@@ -7900,6 +8394,7 @@ class TinyHtml_TinyHtml {
|
|
|
7900
8394
|
* @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
|
|
7901
8395
|
* @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
|
|
7902
8396
|
* Optional filter function to selectively remove specific handlers.
|
|
8397
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7903
8398
|
*/
|
|
7904
8399
|
static offAllTypes(el, filterFn = null) {
|
|
7905
8400
|
if (filterFn !== null && typeof filterFn !== 'function')
|
|
@@ -7918,6 +8413,7 @@ class TinyHtml_TinyHtml {
|
|
|
7918
8413
|
|
|
7919
8414
|
__eventRegistry.delete(elem);
|
|
7920
8415
|
});
|
|
8416
|
+
return el;
|
|
7921
8417
|
}
|
|
7922
8418
|
|
|
7923
8419
|
/**
|
|
@@ -7925,6 +8421,7 @@ class TinyHtml_TinyHtml {
|
|
|
7925
8421
|
*
|
|
7926
8422
|
* @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
|
|
7927
8423
|
* Optional filter function to selectively remove specific handlers.
|
|
8424
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7928
8425
|
*/
|
|
7929
8426
|
offAllTypes(filterFn = null) {
|
|
7930
8427
|
return TinyHtml_TinyHtml.offAllTypes(this, filterFn);
|
|
@@ -7936,6 +8433,7 @@ class TinyHtml_TinyHtml {
|
|
|
7936
8433
|
* @param {TinyEventTarget|TinyEventTarget[]} el - Target element where the event should be triggered.
|
|
7937
8434
|
* @param {string} event - Name of the event to trigger.
|
|
7938
8435
|
* @param {Event|CustomEvent|CustomEventInit} [payload] - Optional event object or data to pass.
|
|
8436
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7939
8437
|
*/
|
|
7940
8438
|
static trigger(el, event, payload = {}) {
|
|
7941
8439
|
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
@@ -7951,6 +8449,7 @@ class TinyHtml_TinyHtml {
|
|
|
7951
8449
|
|
|
7952
8450
|
elem.dispatchEvent(evt);
|
|
7953
8451
|
});
|
|
8452
|
+
return el;
|
|
7954
8453
|
}
|
|
7955
8454
|
|
|
7956
8455
|
/**
|
|
@@ -7958,6 +8457,7 @@ class TinyHtml_TinyHtml {
|
|
|
7958
8457
|
*
|
|
7959
8458
|
* @param {string} event - Name of the event to trigger.
|
|
7960
8459
|
* @param {Event|CustomEvent|CustomEventInit} [payload] - Optional event object or data to pass.
|
|
8460
|
+
* @returns {TinyEventTarget|TinyEventTarget[]}
|
|
7961
8461
|
*/
|
|
7962
8462
|
trigger(event, payload = {}) {
|
|
7963
8463
|
return TinyHtml_TinyHtml.trigger(this, event, payload);
|
|
@@ -8000,6 +8500,7 @@ class TinyHtml_TinyHtml {
|
|
|
8000
8500
|
* @param {TinyElement|TinyElement[]} el
|
|
8001
8501
|
* @param {string} name
|
|
8002
8502
|
* @param {string|null} [value=null]
|
|
8503
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8003
8504
|
*/
|
|
8004
8505
|
static setAttr(el, name, value = null) {
|
|
8005
8506
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8009,12 +8510,14 @@ class TinyHtml_TinyHtml {
|
|
|
8009
8510
|
if (value === null) elem.removeAttribute(name);
|
|
8010
8511
|
else elem.setAttribute(name, value);
|
|
8011
8512
|
});
|
|
8513
|
+
return el;
|
|
8012
8514
|
}
|
|
8013
8515
|
|
|
8014
8516
|
/**
|
|
8015
8517
|
* Set an attribute on an element.
|
|
8016
8518
|
* @param {string} name
|
|
8017
8519
|
* @param {string|null} [value=null]
|
|
8520
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8018
8521
|
*/
|
|
8019
8522
|
setAttr(name, value) {
|
|
8020
8523
|
return TinyHtml_TinyHtml.setAttr(this, name, value);
|
|
@@ -8024,15 +8527,18 @@ class TinyHtml_TinyHtml {
|
|
|
8024
8527
|
* Remove attribute(s) from an element.
|
|
8025
8528
|
* @param {TinyElement|TinyElement[]} el
|
|
8026
8529
|
* @param {string} name Space-separated list of attributes.
|
|
8530
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8027
8531
|
*/
|
|
8028
8532
|
static removeAttr(el, name) {
|
|
8029
8533
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
8030
8534
|
TinyHtml_TinyHtml._preElems(el, 'removeAttr').forEach((elem) => elem.removeAttribute(name));
|
|
8535
|
+
return el;
|
|
8031
8536
|
}
|
|
8032
8537
|
|
|
8033
8538
|
/**
|
|
8034
8539
|
* Remove attribute(s) from an element.
|
|
8035
8540
|
* @param {string} name Space-separated list of attributes.
|
|
8541
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8036
8542
|
*/
|
|
8037
8543
|
removeAttr(name) {
|
|
8038
8544
|
return TinyHtml_TinyHtml.removeAttr(this, name);
|
|
@@ -8087,6 +8593,7 @@ class TinyHtml_TinyHtml {
|
|
|
8087
8593
|
* Set a property on an element.
|
|
8088
8594
|
* @param {TinyElement|TinyElement[]} el
|
|
8089
8595
|
* @param {string} name
|
|
8596
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8090
8597
|
*/
|
|
8091
8598
|
static addProp(el, name) {
|
|
8092
8599
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8096,11 +8603,13 @@ class TinyHtml_TinyHtml {
|
|
|
8096
8603
|
// @ts-ignore
|
|
8097
8604
|
elem[name] = true;
|
|
8098
8605
|
});
|
|
8606
|
+
return el;
|
|
8099
8607
|
}
|
|
8100
8608
|
|
|
8101
8609
|
/**
|
|
8102
8610
|
* Set a property on an element.
|
|
8103
8611
|
* @param {string} name
|
|
8612
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8104
8613
|
*/
|
|
8105
8614
|
addProp(name) {
|
|
8106
8615
|
return TinyHtml_TinyHtml.addProp(this, name);
|
|
@@ -8110,6 +8619,7 @@ class TinyHtml_TinyHtml {
|
|
|
8110
8619
|
* Remove a property from an element.
|
|
8111
8620
|
* @param {TinyElement|TinyElement[]} el
|
|
8112
8621
|
* @param {string} name
|
|
8622
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8113
8623
|
*/
|
|
8114
8624
|
static removeProp(el, name) {
|
|
8115
8625
|
if (typeof name !== 'string') throw new TypeError('The "name" must be a string.');
|
|
@@ -8119,11 +8629,13 @@ class TinyHtml_TinyHtml {
|
|
|
8119
8629
|
// @ts-ignore
|
|
8120
8630
|
elem[name] = false;
|
|
8121
8631
|
});
|
|
8632
|
+
return el;
|
|
8122
8633
|
}
|
|
8123
8634
|
|
|
8124
8635
|
/**
|
|
8125
8636
|
* Remove a property from an element.
|
|
8126
8637
|
* @param {string} name
|
|
8638
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8127
8639
|
*/
|
|
8128
8640
|
removeProp(name) {
|
|
8129
8641
|
return TinyHtml_TinyHtml.removeProp(this, name);
|
|
@@ -8164,13 +8676,16 @@ class TinyHtml_TinyHtml {
|
|
|
8164
8676
|
/**
|
|
8165
8677
|
* Removes an element from the DOM.
|
|
8166
8678
|
* @param {TinyElement|TinyElement[]} el - The DOM element or selector to remove.
|
|
8679
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8167
8680
|
*/
|
|
8168
8681
|
static remove(el) {
|
|
8169
8682
|
TinyHtml_TinyHtml._preElems(el, 'remove').forEach((elem) => elem.remove());
|
|
8683
|
+
return el;
|
|
8170
8684
|
}
|
|
8171
8685
|
|
|
8172
8686
|
/**
|
|
8173
8687
|
* Removes the element from the DOM.
|
|
8688
|
+
* @returns {TinyElement|TinyElement[]}
|
|
8174
8689
|
*/
|
|
8175
8690
|
remove() {
|
|
8176
8691
|
return TinyHtml_TinyHtml.remove(this);
|
|
@@ -8514,6 +9029,14 @@ class TinyHtml_TinyHtml {
|
|
|
8514
9029
|
*/
|
|
8515
9030
|
static isInViewport(el) {
|
|
8516
9031
|
const elem = TinyHtml_TinyHtml._preElem(el, 'isInViewport');
|
|
9032
|
+
if (
|
|
9033
|
+
!elem.checkVisibility({
|
|
9034
|
+
contentVisibilityAuto: false,
|
|
9035
|
+
opacityProperty: false,
|
|
9036
|
+
visibilityProperty: false,
|
|
9037
|
+
})
|
|
9038
|
+
)
|
|
9039
|
+
return false;
|
|
8517
9040
|
const elementTop = TinyHtml_TinyHtml.offset(elem).top;
|
|
8518
9041
|
const elementBottom = elementTop + TinyHtml_TinyHtml.outerHeight(elem);
|
|
8519
9042
|
|
|
@@ -8540,6 +9063,14 @@ class TinyHtml_TinyHtml {
|
|
|
8540
9063
|
*/
|
|
8541
9064
|
static isScrolledIntoView(el) {
|
|
8542
9065
|
const elem = TinyHtml_TinyHtml._preElem(el, 'isScrolledIntoView');
|
|
9066
|
+
if (
|
|
9067
|
+
!elem.checkVisibility({
|
|
9068
|
+
contentVisibilityAuto: false,
|
|
9069
|
+
opacityProperty: false,
|
|
9070
|
+
visibilityProperty: false,
|
|
9071
|
+
})
|
|
9072
|
+
)
|
|
9073
|
+
return false;
|
|
8543
9074
|
const docViewTop = TinyHtml_TinyHtml.scrollTop(window);
|
|
8544
9075
|
const docViewBottom = docViewTop + TinyHtml_TinyHtml.height(window);
|
|
8545
9076
|
|
|
@@ -8557,36 +9088,141 @@ class TinyHtml_TinyHtml {
|
|
|
8557
9088
|
isScrolledIntoView() {
|
|
8558
9089
|
return TinyHtml_TinyHtml.isScrolledIntoView(this);
|
|
8559
9090
|
}
|
|
8560
|
-
}
|
|
8561
9091
|
|
|
8562
|
-
|
|
9092
|
+
/**
|
|
9093
|
+
* Checks if the given element is at least partially visible within the boundaries of a container.
|
|
9094
|
+
*
|
|
9095
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
9096
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
9097
|
+
* @returns {boolean} True if the element is partially visible within the container, false otherwise.
|
|
9098
|
+
*/
|
|
9099
|
+
static isInContainer(el, cont) {
|
|
9100
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'isInContainer');
|
|
9101
|
+
const container = TinyHtml_TinyHtml._preElem(cont, 'isInContainer');
|
|
8563
9102
|
|
|
8564
|
-
|
|
9103
|
+
if (
|
|
9104
|
+
!elem.checkVisibility({
|
|
9105
|
+
contentVisibilityAuto: false,
|
|
9106
|
+
opacityProperty: false,
|
|
9107
|
+
visibilityProperty: false,
|
|
9108
|
+
})
|
|
9109
|
+
)
|
|
9110
|
+
return false;
|
|
9111
|
+
const elemRect = elem.getBoundingClientRect();
|
|
9112
|
+
const containerRect = container.getBoundingClientRect();
|
|
8565
9113
|
|
|
9114
|
+
const verticallyVisible =
|
|
9115
|
+
elemRect.bottom > containerRect.top && elemRect.top < containerRect.bottom;
|
|
8566
9116
|
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
*
|
|
8570
|
-
* @param {Element} elem1 - First DOM element.
|
|
8571
|
-
* @param {Element} elem2 - Second DOM element.
|
|
8572
|
-
* @returns {boolean} - Returns true if the elements are colliding.
|
|
8573
|
-
* @deprecated - Use TinyHtml.isCollWith instead.
|
|
8574
|
-
*/
|
|
8575
|
-
function areHtmlElsColliding(elem1, elem2) {
|
|
8576
|
-
return TinyHtml.isCollWith(elem1, elem2);
|
|
8577
|
-
}
|
|
9117
|
+
const horizontallyVisible =
|
|
9118
|
+
elemRect.right > containerRect.left && elemRect.left < containerRect.right;
|
|
8578
9119
|
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
9120
|
+
return verticallyVisible && horizontallyVisible;
|
|
9121
|
+
}
|
|
9122
|
+
|
|
9123
|
+
/**
|
|
9124
|
+
* Checks if the given element is at least partially visible within the boundaries of a container.
|
|
9125
|
+
*
|
|
9126
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
9127
|
+
* @returns {boolean} True if the element is partially visible within the container, false otherwise.
|
|
9128
|
+
*/
|
|
9129
|
+
isInContainer(cont) {
|
|
9130
|
+
return TinyHtml_TinyHtml.isInContainer(this, cont);
|
|
9131
|
+
}
|
|
9132
|
+
|
|
9133
|
+
/**
|
|
9134
|
+
* Checks if the given element is fully visible within the boundaries of a container (top and bottom).
|
|
9135
|
+
*
|
|
9136
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
9137
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
9138
|
+
* @returns {boolean} True if the element is fully visible within the container, false otherwise.
|
|
9139
|
+
*/
|
|
9140
|
+
static isFullyInContainer(el, cont) {
|
|
9141
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'isScrolledIntoView');
|
|
9142
|
+
const container = TinyHtml_TinyHtml._preElem(cont, 'isInContainer');
|
|
9143
|
+
|
|
9144
|
+
if (
|
|
9145
|
+
!elem.checkVisibility({
|
|
9146
|
+
contentVisibilityAuto: false,
|
|
9147
|
+
opacityProperty: false,
|
|
9148
|
+
visibilityProperty: false,
|
|
9149
|
+
})
|
|
9150
|
+
)
|
|
9151
|
+
return false;
|
|
9152
|
+
const elemRect = elem.getBoundingClientRect();
|
|
9153
|
+
const containerRect = container.getBoundingClientRect();
|
|
9154
|
+
|
|
9155
|
+
const isFullyVisible =
|
|
9156
|
+
elemRect.top >= containerRect.top &&
|
|
9157
|
+
elemRect.bottom <= containerRect.bottom &&
|
|
9158
|
+
elemRect.left >= containerRect.left &&
|
|
9159
|
+
elemRect.right <= containerRect.right;
|
|
9160
|
+
|
|
9161
|
+
return isFullyVisible;
|
|
9162
|
+
}
|
|
9163
|
+
|
|
9164
|
+
/**
|
|
9165
|
+
* Checks if the given element is fully visible within the boundaries of a container (top and bottom).
|
|
9166
|
+
*
|
|
9167
|
+
* @param {TinyElement} cont - The container element acting as the viewport.
|
|
9168
|
+
* @returns {boolean} True if the element is fully visible within the container, false otherwise.
|
|
9169
|
+
*/
|
|
9170
|
+
isFullyInContainer(cont) {
|
|
9171
|
+
return TinyHtml_TinyHtml.isFullyInContainer(this, cont);
|
|
9172
|
+
}
|
|
9173
|
+
|
|
9174
|
+
/**
|
|
9175
|
+
* Checks if an element has scrollable content.
|
|
9176
|
+
*
|
|
9177
|
+
* @param {TinyElement} el - The DOM element to check.
|
|
9178
|
+
* @returns {{ v: boolean, h: boolean }} - True if scroll is needed in that direction.
|
|
9179
|
+
*/
|
|
9180
|
+
static hasScroll(el) {
|
|
9181
|
+
const elem = TinyHtml_TinyHtml._preElem(el, 'hasScroll');
|
|
9182
|
+
return {
|
|
9183
|
+
v: elem.scrollHeight > elem.clientHeight,
|
|
9184
|
+
h: elem.scrollWidth > elem.clientWidth,
|
|
9185
|
+
};
|
|
9186
|
+
}
|
|
9187
|
+
|
|
9188
|
+
/**
|
|
9189
|
+
* Checks if an element has scrollable content.
|
|
9190
|
+
*
|
|
9191
|
+
* @returns {{ v: boolean, h: boolean }} - True if scroll is needed in that direction.
|
|
9192
|
+
*/
|
|
9193
|
+
hasScroll() {
|
|
9194
|
+
return TinyHtml_TinyHtml.hasScroll(this);
|
|
9195
|
+
}
|
|
9196
|
+
}
|
|
9197
|
+
|
|
9198
|
+
/* harmony default export */ const libs_TinyHtml = (TinyHtml_TinyHtml);
|
|
9199
|
+
|
|
9200
|
+
;// ./src/v1/basics/html_deprecated.mjs
|
|
9201
|
+
|
|
9202
|
+
|
|
9203
|
+
/**
|
|
9204
|
+
* Checks if two DOM elements are colliding on the screen.
|
|
9205
|
+
*
|
|
9206
|
+
* @param {Element} elem1 - First DOM element.
|
|
9207
|
+
* @param {Element} elem2 - Second DOM element.
|
|
9208
|
+
* @returns {boolean} - Returns true if the elements are colliding.
|
|
9209
|
+
* @deprecated - Use TinyHtml.isCollWith instead.
|
|
9210
|
+
*/
|
|
9211
|
+
function areHtmlElsColliding(elem1, elem2) {
|
|
9212
|
+
return TinyHtml.isCollWith(elem1, elem2);
|
|
9213
|
+
}
|
|
9214
|
+
|
|
9215
|
+
/**
|
|
9216
|
+
* Checks if two DOM elements are colliding on the screen.
|
|
9217
|
+
*
|
|
9218
|
+
* @param {Element} elem1 - First DOM element.
|
|
9219
|
+
* @param {Element} elem2 - Second DOM element.
|
|
9220
|
+
* @returns {boolean} - Returns true if the elements are colliding.
|
|
9221
|
+
* @deprecated - Use TinyHtml.isCollPerfWith instead.
|
|
9222
|
+
*/
|
|
9223
|
+
function areHtmlElsPerfColliding(elem1, elem2) {
|
|
9224
|
+
return TinyHtml.isCollPerfWith(elem1, elem2);
|
|
9225
|
+
}
|
|
8590
9226
|
|
|
8591
9227
|
///////////////////////////////////////////////////////////////////////////
|
|
8592
9228
|
|
|
@@ -10327,6 +10963,982 @@ class TinyDragger {
|
|
|
10327
10963
|
|
|
10328
10964
|
/* harmony default export */ const libs_TinyDragger = ((/* unused pure expression or super */ null && (TinyDragger)));
|
|
10329
10965
|
|
|
10966
|
+
;// ./src/v1/libs/TinySmartScroller.mjs
|
|
10967
|
+
|
|
10968
|
+
|
|
10969
|
+
|
|
10970
|
+
/**
|
|
10971
|
+
* Represents the dimensions of a DOM element.
|
|
10972
|
+
*
|
|
10973
|
+
* @typedef {Object} NodeSizes
|
|
10974
|
+
* @property {number} height - The height of the element in pixels.
|
|
10975
|
+
* @property {number} width - The width of the element in pixels.
|
|
10976
|
+
*/
|
|
10977
|
+
|
|
10978
|
+
/**
|
|
10979
|
+
* A callback function that receives node size change data and optionally returns a modified NodeSizes object.
|
|
10980
|
+
*
|
|
10981
|
+
* @callback NodeSizesEvent
|
|
10982
|
+
* @param {Element} elem - The DOM element whose size is being tracked.
|
|
10983
|
+
* @param {{ old: NodeSizes, now: NodeSizes }} sizes - The old and new size measurements of the element.
|
|
10984
|
+
* @param {{ old: number, now: number }} elemAmount - The number of matching elements before and after the update.
|
|
10985
|
+
* @returns {NodeSizes|undefined} A modified NodeSizes object to override the default measurement, or undefined to use the original.
|
|
10986
|
+
*/
|
|
10987
|
+
|
|
10988
|
+
/**
|
|
10989
|
+
* A generic scroll-related event listener callback function.
|
|
10990
|
+
*
|
|
10991
|
+
* @callback ScrollListenersFunc
|
|
10992
|
+
* @param {any} payload - The data payload passed when the scroll event is triggered. The type may vary depending on the event.
|
|
10993
|
+
* @returns {void}
|
|
10994
|
+
*/
|
|
10995
|
+
|
|
10996
|
+
/**
|
|
10997
|
+
* TinySmartScroller is a utility class designed to enhance and manage scroll behaviors within containers or the window.
|
|
10998
|
+
*
|
|
10999
|
+
* It enables advanced scroll monitoring, auto-scrolling to bottom, preserving scroll position during DOM changes,
|
|
11000
|
+
* and detecting visibility changes of elements. This is particularly useful for dynamic UIs like chat applications,
|
|
11001
|
+
* feed viewers, or live content containers.
|
|
11002
|
+
*
|
|
11003
|
+
* Features:
|
|
11004
|
+
* - Detects when the scroll reaches the top, bottom, or custom boundaries
|
|
11005
|
+
* - Supports automatic scrolling to the bottom unless the user scrolls away
|
|
11006
|
+
* - Observes DOM mutations and resizes, and adapts scroll position accordingly
|
|
11007
|
+
* - Emits scroll-related events such as 'onScrollBoundary', 'onAutoScroll', and 'onScrollPause'
|
|
11008
|
+
* - Includes customizable scroll correction filters for layout shift mitigation
|
|
11009
|
+
* - Handles media element load events (e.g. `<img>`, `<iframe>`, `<video>`) to prevent sudden scroll jumps
|
|
11010
|
+
*
|
|
11011
|
+
* This class is **not framework-dependent** and works with vanilla DOM elements and the window object.
|
|
11012
|
+
*/
|
|
11013
|
+
class TinySmartScroller {
|
|
11014
|
+
static Utils = { ...collision_namespaceObject, TinyHtml: libs_TinyHtml };
|
|
11015
|
+
|
|
11016
|
+
/** @type {WeakMap<Element, NodeSizes>} */
|
|
11017
|
+
#oldSizes = new WeakMap();
|
|
11018
|
+
/** @type {WeakMap<Element, NodeSizes>} */
|
|
11019
|
+
#newSizes = new WeakMap();
|
|
11020
|
+
|
|
11021
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
11022
|
+
#newVisibles = new WeakMap();
|
|
11023
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
11024
|
+
#oldVisibles = new WeakMap();
|
|
11025
|
+
|
|
11026
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
11027
|
+
#newVisiblesByTime = new WeakMap();
|
|
11028
|
+
/** @type {WeakMap<Element, boolean>} */
|
|
11029
|
+
#oldVisiblesByTime = new WeakMap();
|
|
11030
|
+
|
|
11031
|
+
/** @type {Record<string, ScrollListenersFunc[]>} */
|
|
11032
|
+
#scrollListeners = {};
|
|
11033
|
+
|
|
11034
|
+
/** @type {ResizeObserver|null} */
|
|
11035
|
+
#resizeObserver = null;
|
|
11036
|
+
/** @type {MutationObserver|null} */
|
|
11037
|
+
#mutationObserver = null;
|
|
11038
|
+
|
|
11039
|
+
/** @type {Set<string>} */
|
|
11040
|
+
#loadTags = new Set(['IMG', 'IFRAME', 'VIDEO']);
|
|
11041
|
+
|
|
11042
|
+
/** @type {null|EventListenerOrEventListenerObject} */
|
|
11043
|
+
#handler = null;
|
|
11044
|
+
|
|
11045
|
+
#isAtBottom = false;
|
|
11046
|
+
#isAtTop = false;
|
|
11047
|
+
#isAtCustomTop = false;
|
|
11048
|
+
#isAtCustomBottom = false;
|
|
11049
|
+
|
|
11050
|
+
#querySelector = '';
|
|
11051
|
+
#useWindow = false;
|
|
11052
|
+
#destroyed = false;
|
|
11053
|
+
#scrollPaused = false;
|
|
11054
|
+
#autoScrollBottom = false;
|
|
11055
|
+
#observeMutations = false;
|
|
11056
|
+
#preserveScrollOnLayoutShift = false;
|
|
11057
|
+
#debounceTime = 0;
|
|
11058
|
+
#elemAmount = 0;
|
|
11059
|
+
#elemOldAmount = 0;
|
|
11060
|
+
#lastKnownScrollBottomOffset = 0;
|
|
11061
|
+
#extraScrollBoundary = 0;
|
|
11062
|
+
|
|
11063
|
+
/** @type {Set<string>} */
|
|
11064
|
+
#attributeFilter;
|
|
11065
|
+
|
|
11066
|
+
/** @type {Element} */
|
|
11067
|
+
#target;
|
|
11068
|
+
|
|
11069
|
+
/** @type {Set<NodeSizesEvent>} */
|
|
11070
|
+
#sizeFilter = new Set();
|
|
11071
|
+
|
|
11072
|
+
/**
|
|
11073
|
+
* Creates a new instance of TinySmartScroller, attaching scroll and resize observers to manage
|
|
11074
|
+
* automatic scroll behaviors, layout shift correction, and visibility tracking.
|
|
11075
|
+
*
|
|
11076
|
+
* @param {Element|Window} target - The scroll container to monitor. Can be an element or `window`.
|
|
11077
|
+
* @param {Object} [options={}] - Optional settings to configure scroll behavior.
|
|
11078
|
+
* @param {number} [options.extraScrollBoundary=0] - Extra margin in pixels to extend scroll boundary detection.
|
|
11079
|
+
* @param {boolean} [options.autoScrollBottom=true] - Whether to auto-scroll to bottom on layout updates.
|
|
11080
|
+
* @param {boolean} [options.observeMutations=true] - Enables MutationObserver to detect DOM changes.
|
|
11081
|
+
* @param {boolean} [options.preserveScrollOnLayoutShift=true] - Prevents scroll jumps when layout changes.
|
|
11082
|
+
* @param {number} [options.debounceTime=100] - Debounce time in milliseconds for scroll events.
|
|
11083
|
+
* @param {string|null} [options.querySelector=null] - Optional CSS selector to filter observed child nodes.
|
|
11084
|
+
* @param {string[]|Set<string>|null} [options.attributeFilter=['class', 'style', 'src', 'data-*', 'height', 'width']]
|
|
11085
|
+
* - Which attributes to observe for changes.
|
|
11086
|
+
*/
|
|
11087
|
+
constructor(
|
|
11088
|
+
target,
|
|
11089
|
+
{
|
|
11090
|
+
extraScrollBoundary = 0,
|
|
11091
|
+
autoScrollBottom = true,
|
|
11092
|
+
observeMutations = true,
|
|
11093
|
+
preserveScrollOnLayoutShift = true,
|
|
11094
|
+
debounceTime = 100,
|
|
11095
|
+
querySelector = null,
|
|
11096
|
+
attributeFilter = ['class', 'style', 'src', 'data-*', 'height', 'width'],
|
|
11097
|
+
} = {},
|
|
11098
|
+
) {
|
|
11099
|
+
// === target ===
|
|
11100
|
+
if (!(target instanceof Element || target === window))
|
|
11101
|
+
throw new TypeError(
|
|
11102
|
+
`TinySmartScroller: 'target' must be a DOM Element or 'window', but got ${typeof target}`,
|
|
11103
|
+
);
|
|
11104
|
+
// === extraScrollBoundary ===
|
|
11105
|
+
if (typeof extraScrollBoundary !== 'number' || Number.isNaN(extraScrollBoundary))
|
|
11106
|
+
throw new TypeError(
|
|
11107
|
+
`TinySmartScroller: 'extraScrollBoundary' must be a valid number, received ${extraScrollBoundary}`,
|
|
11108
|
+
);
|
|
11109
|
+
// === autoScrollBottom ===
|
|
11110
|
+
if (typeof autoScrollBottom !== 'boolean')
|
|
11111
|
+
throw new TypeError(
|
|
11112
|
+
`TinySmartScroller: 'autoScrollBottom' must be a boolean, received ${typeof autoScrollBottom}`,
|
|
11113
|
+
);
|
|
11114
|
+
// === observeMutations ===
|
|
11115
|
+
if (typeof observeMutations !== 'boolean')
|
|
11116
|
+
throw new TypeError(
|
|
11117
|
+
`TinySmartScroller: 'observeMutations' must be a boolean, received ${typeof observeMutations}`,
|
|
11118
|
+
);
|
|
11119
|
+
// === preserveScrollOnLayoutShift ===
|
|
11120
|
+
if (typeof preserveScrollOnLayoutShift !== 'boolean')
|
|
11121
|
+
throw new TypeError(
|
|
11122
|
+
`TinySmartScroller: 'preserveScrollOnLayoutShift' must be a boolean, received ${typeof preserveScrollOnLayoutShift}`,
|
|
11123
|
+
);
|
|
11124
|
+
// === debounceTime ===
|
|
11125
|
+
if (typeof debounceTime !== 'number' || debounceTime < 0 || Number.isNaN(debounceTime))
|
|
11126
|
+
throw new TypeError(
|
|
11127
|
+
`TinySmartScroller: 'debounceTime' must be a non-negative number, received ${debounceTime}`,
|
|
11128
|
+
);
|
|
11129
|
+
// === querySelector ===
|
|
11130
|
+
if (querySelector !== null && typeof querySelector !== 'string')
|
|
11131
|
+
throw new TypeError(
|
|
11132
|
+
`TinySmartScroller: 'querySelector' must be a string or null, received ${typeof querySelector}`,
|
|
11133
|
+
);
|
|
11134
|
+
// === attributeFilter ===
|
|
11135
|
+
const isValidAttrList =
|
|
11136
|
+
attributeFilter === null || Array.isArray(attributeFilter) || attributeFilter instanceof Set;
|
|
11137
|
+
if (!isValidAttrList)
|
|
11138
|
+
throw new TypeError(
|
|
11139
|
+
`TinySmartScroller: 'attributeFilter' must be an array, Set, or null. Got ${typeof attributeFilter}`,
|
|
11140
|
+
);
|
|
11141
|
+
|
|
11142
|
+
// Start values
|
|
11143
|
+
this.#target = target instanceof Window ? document.documentElement : target;
|
|
11144
|
+
this.#useWindow = target instanceof Window;
|
|
11145
|
+
this.#autoScrollBottom = autoScrollBottom;
|
|
11146
|
+
this.#observeMutations = observeMutations;
|
|
11147
|
+
this.#preserveScrollOnLayoutShift = preserveScrollOnLayoutShift;
|
|
11148
|
+
this.#debounceTime = debounceTime;
|
|
11149
|
+
this.#extraScrollBoundary = extraScrollBoundary;
|
|
11150
|
+
this.#querySelector = querySelector || '';
|
|
11151
|
+
this.#attributeFilter = new Set(attributeFilter || undefined);
|
|
11152
|
+
|
|
11153
|
+
// Bind scroll
|
|
11154
|
+
/** @type {NodeJS.Timeout} */
|
|
11155
|
+
let timeout;
|
|
11156
|
+
this.#handler = () => {
|
|
11157
|
+
this._scrollDataUpdater();
|
|
11158
|
+
clearTimeout(timeout);
|
|
11159
|
+
timeout = setTimeout(() => this._onScroll(), this.#debounceTime);
|
|
11160
|
+
};
|
|
11161
|
+
(this.#useWindow ? window : this.#target).addEventListener('scroll', this.#handler, {
|
|
11162
|
+
passive: true,
|
|
11163
|
+
});
|
|
11164
|
+
|
|
11165
|
+
// Mutations
|
|
11166
|
+
if (this.#observeMutations) {
|
|
11167
|
+
this._observeMutations();
|
|
11168
|
+
this._observeResizes(this.#target.children);
|
|
11169
|
+
}
|
|
11170
|
+
|
|
11171
|
+
this._scrollDataUpdater();
|
|
11172
|
+
}
|
|
11173
|
+
|
|
11174
|
+
/**
|
|
11175
|
+
* Returns a size difference callback that only reacts when height changes, filtered by tag name.
|
|
11176
|
+
*
|
|
11177
|
+
* @param {string[]} filter - List of tag names to allow. If empty, all tags are accepted.
|
|
11178
|
+
* @returns {NodeSizesEvent} A function that compares previous and current height, returning height delta.
|
|
11179
|
+
*/
|
|
11180
|
+
getSimpleOnHeight(filter = []) {
|
|
11181
|
+
if (!Array.isArray(filter))
|
|
11182
|
+
throw new TypeError('getSimpleOnHeight(filter): filter must be an array of tag names');
|
|
11183
|
+
return (elem, sizes, amounts) => {
|
|
11184
|
+
if ((filter.length > 0 && !filter.includes(elem.tagName)) || amounts.now !== amounts.old)
|
|
11185
|
+
return;
|
|
11186
|
+
const oldSize = sizes.old;
|
|
11187
|
+
const newSize = sizes.now;
|
|
11188
|
+
const height = newSize.height - oldSize.height;
|
|
11189
|
+
return { height, width: 0 };
|
|
11190
|
+
};
|
|
11191
|
+
}
|
|
11192
|
+
|
|
11193
|
+
/**
|
|
11194
|
+
* Adds a height difference callback to the size filter system.
|
|
11195
|
+
*
|
|
11196
|
+
* @param {string[]} filter - List of tag names to allow.
|
|
11197
|
+
* @returns {NodeSizesEvent} The added size difference callback.
|
|
11198
|
+
*/
|
|
11199
|
+
addSimpleOnHeight(filter) {
|
|
11200
|
+
if (!Array.isArray(filter))
|
|
11201
|
+
throw new TypeError('addSimpleOnHeight(filter): filter must be an array of tag names');
|
|
11202
|
+
const result = this.getSimpleOnHeight(filter);
|
|
11203
|
+
this.onSize(result);
|
|
11204
|
+
return result;
|
|
11205
|
+
}
|
|
11206
|
+
|
|
11207
|
+
/**
|
|
11208
|
+
* Returns a list of all currently tracked load tags.
|
|
11209
|
+
*
|
|
11210
|
+
* @returns {string[]} Array of tag names.
|
|
11211
|
+
*/
|
|
11212
|
+
getLoadTags() {
|
|
11213
|
+
return Array.from(this.#loadTags);
|
|
11214
|
+
}
|
|
11215
|
+
|
|
11216
|
+
/**
|
|
11217
|
+
* Adds a new tag to the set of load tags.
|
|
11218
|
+
*
|
|
11219
|
+
* @param {string} tag - The tag name to add (e.g., 'IMG').
|
|
11220
|
+
*/
|
|
11221
|
+
addLoadTag(tag) {
|
|
11222
|
+
if (typeof tag !== 'string') throw new TypeError('addLoadTag(tag): tag must be a string');
|
|
11223
|
+
this.#loadTags.add(tag.toUpperCase());
|
|
11224
|
+
}
|
|
11225
|
+
|
|
11226
|
+
/**
|
|
11227
|
+
* Removes a tag from the set of load tags.
|
|
11228
|
+
*
|
|
11229
|
+
* @param {string} tag - The tag name to remove.
|
|
11230
|
+
*/
|
|
11231
|
+
removeLoadTag(tag) {
|
|
11232
|
+
if (typeof tag !== 'string') throw new TypeError('removeLoadTag(tag): tag must be a string');
|
|
11233
|
+
this.#loadTags.delete(tag.toUpperCase());
|
|
11234
|
+
}
|
|
11235
|
+
|
|
11236
|
+
/**
|
|
11237
|
+
* Checks whether a tag is tracked as a load tag.
|
|
11238
|
+
*
|
|
11239
|
+
* @param {string} tag - The tag name to check.
|
|
11240
|
+
* @returns {boolean} True if the tag is being tracked.
|
|
11241
|
+
*/
|
|
11242
|
+
hasLoadTag(tag) {
|
|
11243
|
+
if (typeof tag !== 'string') throw new TypeError('hasLoadTag(tag): tag must be a string');
|
|
11244
|
+
return this.#loadTags.has(tag.toUpperCase());
|
|
11245
|
+
}
|
|
11246
|
+
|
|
11247
|
+
/**
|
|
11248
|
+
* Clears the set of load tags. If `addDefault` is true, it will reset to the default tags: 'IMG', 'IFRAME', and 'VIDEO'.
|
|
11249
|
+
*
|
|
11250
|
+
* @param {boolean} [addDefault=false] - Whether to restore the default tags after clearing.
|
|
11251
|
+
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
11252
|
+
*/
|
|
11253
|
+
resetLoadTags(addDefault = false) {
|
|
11254
|
+
if (typeof addDefault !== 'boolean')
|
|
11255
|
+
throw new TypeError('resetLoadTags(addDefault): addDefault must be a boolean');
|
|
11256
|
+
this.#loadTags.clear();
|
|
11257
|
+
if (!addDefault) return;
|
|
11258
|
+
this.#loadTags.add('IMG');
|
|
11259
|
+
this.#loadTags.add('IFRAME');
|
|
11260
|
+
this.#loadTags.add('VIDEO');
|
|
11261
|
+
}
|
|
11262
|
+
|
|
11263
|
+
/**
|
|
11264
|
+
* Returns a list of all currently tracked attribute filters.
|
|
11265
|
+
*
|
|
11266
|
+
* @returns {string[]} Array of attribute names.
|
|
11267
|
+
*/
|
|
11268
|
+
getAttributeFilters() {
|
|
11269
|
+
return Array.from(this.#attributeFilter);
|
|
11270
|
+
}
|
|
11271
|
+
|
|
11272
|
+
/**
|
|
11273
|
+
* Adds an attribute to the filter list.
|
|
11274
|
+
*
|
|
11275
|
+
* @param {string} attr - The attribute name to add.
|
|
11276
|
+
*/
|
|
11277
|
+
addAttributeFilter(attr) {
|
|
11278
|
+
if (typeof attr !== 'string')
|
|
11279
|
+
throw new TypeError('addAttributeFilter(attr): attr must be a string');
|
|
11280
|
+
this.#attributeFilter.add(attr);
|
|
11281
|
+
}
|
|
11282
|
+
|
|
11283
|
+
/**
|
|
11284
|
+
* Removes an attribute from the filter list.
|
|
11285
|
+
*
|
|
11286
|
+
* @param {string} attr - The attribute name to remove.
|
|
11287
|
+
*/
|
|
11288
|
+
removeAttributeFilter(attr) {
|
|
11289
|
+
if (typeof attr !== 'string')
|
|
11290
|
+
throw new TypeError('removeAttributeFilter(attr): attr must be a string');
|
|
11291
|
+
this.#attributeFilter.delete(attr);
|
|
11292
|
+
}
|
|
11293
|
+
|
|
11294
|
+
/**
|
|
11295
|
+
* Checks whether a specific attribute is being filtered.
|
|
11296
|
+
*
|
|
11297
|
+
* @param {string} attr - The attribute name to check.
|
|
11298
|
+
* @returns {boolean} True if the attribute is being filtered.
|
|
11299
|
+
*/
|
|
11300
|
+
hasAttributeFilter(attr) {
|
|
11301
|
+
if (typeof attr !== 'string')
|
|
11302
|
+
throw new TypeError('hasAttributeFilter(attr): attr must be a string');
|
|
11303
|
+
return this.#attributeFilter.has(attr);
|
|
11304
|
+
}
|
|
11305
|
+
|
|
11306
|
+
/**
|
|
11307
|
+
* Clears the set of observed attribute filters. If `addDefault` is true, it will reset to the default attributes:
|
|
11308
|
+
* 'class', 'style', 'src', 'data-*', 'height', and 'width'.
|
|
11309
|
+
*
|
|
11310
|
+
* @param {boolean} [addDefault=false] - Whether to restore the default attribute filters after clearing.
|
|
11311
|
+
* @throws {TypeError} If `addDefault` is not a boolean.
|
|
11312
|
+
*/
|
|
11313
|
+
resetAttributeFilters(addDefault = false) {
|
|
11314
|
+
if (typeof addDefault !== 'boolean')
|
|
11315
|
+
throw new TypeError('resetAttributeFilters(addDefault): addDefault must be a boolean');
|
|
11316
|
+
this.#attributeFilter.clear();
|
|
11317
|
+
if (!addDefault) return;
|
|
11318
|
+
['class', 'style', 'src', 'data-*', 'height', 'width'].forEach((attr) =>
|
|
11319
|
+
this.#attributeFilter.add(attr),
|
|
11320
|
+
);
|
|
11321
|
+
}
|
|
11322
|
+
|
|
11323
|
+
/**
|
|
11324
|
+
* Registers a custom node size change handler to the internal size filter set.
|
|
11325
|
+
*
|
|
11326
|
+
* @param {NodeSizesEvent} handler - Function that compares old and new sizes.
|
|
11327
|
+
*/
|
|
11328
|
+
onSize(handler) {
|
|
11329
|
+
if (this.#destroyed) return;
|
|
11330
|
+
if (typeof handler !== 'function')
|
|
11331
|
+
throw new TypeError('onSize(handler): handler must be a function');
|
|
11332
|
+
this.#sizeFilter.add(handler);
|
|
11333
|
+
}
|
|
11334
|
+
|
|
11335
|
+
/**
|
|
11336
|
+
* Unregisters a previously registered size handler from the internal filter set.
|
|
11337
|
+
*
|
|
11338
|
+
* @param {NodeSizesEvent} handler - The handler function to remove.
|
|
11339
|
+
*/
|
|
11340
|
+
offSize(handler) {
|
|
11341
|
+
if (this.#destroyed) return;
|
|
11342
|
+
if (typeof handler !== 'function')
|
|
11343
|
+
throw new TypeError('offSize(handler): handler must be a function');
|
|
11344
|
+
this.#sizeFilter.delete(handler);
|
|
11345
|
+
}
|
|
11346
|
+
|
|
11347
|
+
/**
|
|
11348
|
+
* Adds a scroll-related event listener.
|
|
11349
|
+
*
|
|
11350
|
+
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
11351
|
+
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
|
|
11352
|
+
*/
|
|
11353
|
+
on(event, handler) {
|
|
11354
|
+
if (this.#destroyed) return;
|
|
11355
|
+
if (typeof event !== 'string')
|
|
11356
|
+
throw new TypeError('on(event, handler): event name must be a string');
|
|
11357
|
+
if (typeof handler !== 'function')
|
|
11358
|
+
throw new TypeError('on(event, handler): handler must be a function');
|
|
11359
|
+
|
|
11360
|
+
if (!this.#scrollListeners[event]) this.#scrollListeners[event] = [];
|
|
11361
|
+
this.#scrollListeners[event].push(handler);
|
|
11362
|
+
}
|
|
11363
|
+
|
|
11364
|
+
/**
|
|
11365
|
+
* Removes a previously registered scroll-related event listener.
|
|
11366
|
+
*
|
|
11367
|
+
* @param {string} event - The name of the event to remove the handler from.
|
|
11368
|
+
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
|
|
11369
|
+
*/
|
|
11370
|
+
off(event, handler) {
|
|
11371
|
+
if (this.#destroyed) return;
|
|
11372
|
+
if (typeof event !== 'string')
|
|
11373
|
+
throw new TypeError('off(event, handler): event name must be a string');
|
|
11374
|
+
if (typeof handler !== 'function')
|
|
11375
|
+
throw new TypeError('off(event, handler): handler must be a function');
|
|
11376
|
+
|
|
11377
|
+
const listeners = this.#scrollListeners[event];
|
|
11378
|
+
if (!Array.isArray(listeners)) return;
|
|
11379
|
+
|
|
11380
|
+
const index = listeners.indexOf(handler);
|
|
11381
|
+
if (index !== -1) listeners.splice(index, 1);
|
|
11382
|
+
|
|
11383
|
+
// Optionally clean up empty arrays (optional)
|
|
11384
|
+
if (listeners.length === 0) delete this.#scrollListeners[event];
|
|
11385
|
+
}
|
|
11386
|
+
|
|
11387
|
+
/**
|
|
11388
|
+
* Checks which elements inside the target are currently visible and updates internal maps.
|
|
11389
|
+
*
|
|
11390
|
+
* @returns {Map<Element, { oldIsVisible: boolean; isVisible: boolean }>} Visibility comparison results.
|
|
11391
|
+
*/
|
|
11392
|
+
_scrollDataUpdater() {
|
|
11393
|
+
const results = new Map();
|
|
11394
|
+
this.#target.querySelectorAll(this.#querySelector || '*').forEach((target) => {
|
|
11395
|
+
const oldIsVisible = this.#newVisibles.get(target) ?? false;
|
|
11396
|
+
this.#oldVisibles.set(target, oldIsVisible);
|
|
11397
|
+
|
|
11398
|
+
const isVisible = libs_TinyHtml.isInContainer(this.#target, target);
|
|
11399
|
+
this.#newVisibles.set(target, isVisible);
|
|
11400
|
+
|
|
11401
|
+
results.set(target, { oldIsVisible, isVisible });
|
|
11402
|
+
});
|
|
11403
|
+
return results;
|
|
11404
|
+
}
|
|
11405
|
+
|
|
11406
|
+
/**
|
|
11407
|
+
* Emits a scroll-related event to all registered listeners.
|
|
11408
|
+
*
|
|
11409
|
+
* @param {string} event - Event name.
|
|
11410
|
+
* @param {*} [payload] - Optional event data payload.
|
|
11411
|
+
*/
|
|
11412
|
+
_emit(event, payload) {
|
|
11413
|
+
if (this.#destroyed) return;
|
|
11414
|
+
if (typeof event !== 'string')
|
|
11415
|
+
throw new TypeError('_emit(event, payload): event name must be a string');
|
|
11416
|
+
(this.#scrollListeners[event] || []).forEach((fn) => fn(payload));
|
|
11417
|
+
}
|
|
11418
|
+
|
|
11419
|
+
/**
|
|
11420
|
+
* Handles scroll events, calculates position-related statuses, and emits appropriate events.
|
|
11421
|
+
*/
|
|
11422
|
+
_onScroll() {
|
|
11423
|
+
if (this.#destroyed) return;
|
|
11424
|
+
// Get values
|
|
11425
|
+
const scrollCache = this._scrollDataUpdater();
|
|
11426
|
+
const el = this.#target;
|
|
11427
|
+
const scrollTop = el.scrollTop;
|
|
11428
|
+
const scrollHeight = el.scrollHeight;
|
|
11429
|
+
const clientHeight = el.clientHeight;
|
|
11430
|
+
|
|
11431
|
+
// Prepare sroll values
|
|
11432
|
+
const scrollResult = { scrollTop, scrollHeight, clientHeight };
|
|
11433
|
+
let atResult = null;
|
|
11434
|
+
let atCustomResult = null;
|
|
11435
|
+
|
|
11436
|
+
const atTop = scrollTop === 0;
|
|
11437
|
+
const atBottom = scrollTop + clientHeight >= scrollHeight - 1;
|
|
11438
|
+
|
|
11439
|
+
const atCustomTop = scrollTop <= 0 + this.#extraScrollBoundary;
|
|
11440
|
+
const atCustomBottom = scrollTop + clientHeight >= scrollHeight - 1 - this.#extraScrollBoundary;
|
|
11441
|
+
|
|
11442
|
+
// Scroll results
|
|
11443
|
+
if (atTop && atBottom) atResult = 'all';
|
|
11444
|
+
else if (atTop) atResult = 'top';
|
|
11445
|
+
else if (atBottom) atResult = 'bottom';
|
|
11446
|
+
|
|
11447
|
+
if (atCustomTop && atCustomBottom) atCustomResult = 'all';
|
|
11448
|
+
else if (atCustomTop) atCustomResult = 'top';
|
|
11449
|
+
else if (atCustomBottom) atCustomResult = 'bottom';
|
|
11450
|
+
|
|
11451
|
+
this.#isAtTop = atTop;
|
|
11452
|
+
this.#isAtBottom = atBottom;
|
|
11453
|
+
|
|
11454
|
+
this.#isAtCustomTop = atCustomTop;
|
|
11455
|
+
this.#isAtCustomBottom = atCustomBottom;
|
|
11456
|
+
|
|
11457
|
+
this.#scrollPaused = !(this.#autoScrollBottom && this.#isAtBottom);
|
|
11458
|
+
|
|
11459
|
+
this.#lastKnownScrollBottomOffset = scrollHeight - scrollTop - clientHeight;
|
|
11460
|
+
|
|
11461
|
+
// Send results
|
|
11462
|
+
this._emit('onScrollBoundary', { status: atResult, ...scrollResult, scrollCache });
|
|
11463
|
+
this._emit('onExtraScrollBoundary', { status: atCustomResult, ...scrollResult, scrollCache });
|
|
11464
|
+
|
|
11465
|
+
if (!this.#scrollPaused) {
|
|
11466
|
+
this._emit('onAutoScroll', { ...scrollResult, scrollCache });
|
|
11467
|
+
} else {
|
|
11468
|
+
this._emit('onScrollPause', { ...scrollResult, scrollCache });
|
|
11469
|
+
}
|
|
11470
|
+
}
|
|
11471
|
+
|
|
11472
|
+
/**
|
|
11473
|
+
* Attempts to correct the scroll position when layout shifts happen, preserving the user position if needed.
|
|
11474
|
+
*
|
|
11475
|
+
* @param {Element[]} [targets=[]] - List of elements involved in the size change.
|
|
11476
|
+
*/
|
|
11477
|
+
_fixScroll(targets = []) {
|
|
11478
|
+
if (this.#destroyed) return;
|
|
11479
|
+
// === Validation ===
|
|
11480
|
+
if (!Array.isArray(targets))
|
|
11481
|
+
throw new TypeError('_fixScroll: targets must be an array of Elements');
|
|
11482
|
+
|
|
11483
|
+
// Get Scroll data
|
|
11484
|
+
const prevScrollHeight = this.#target.scrollHeight;
|
|
11485
|
+
const prevScrollTop = this.#target.scrollTop;
|
|
11486
|
+
const prevBottomOffset =
|
|
11487
|
+
this.#target.scrollHeight - this.#target.scrollTop - this.#target.clientHeight;
|
|
11488
|
+
|
|
11489
|
+
// Get new size
|
|
11490
|
+
const newScrollHeight = this.#target.scrollHeight;
|
|
11491
|
+
const heightDelta = newScrollHeight - prevScrollHeight;
|
|
11492
|
+
|
|
11493
|
+
/** @type {() => NodeSizes} */
|
|
11494
|
+
const calculateScrollSize = () => {
|
|
11495
|
+
// Run size getter
|
|
11496
|
+
const scrollSize = { height: 0, width: 0 };
|
|
11497
|
+
for (const target of targets) {
|
|
11498
|
+
const tgOs = this.#oldSizes.get(target) || { height: 0, width: 0 };
|
|
11499
|
+
const tgNs = this.#newSizes.get(target) || { height: 0, width: 0 };
|
|
11500
|
+
this.#sizeFilter.forEach((fn) => {
|
|
11501
|
+
/** @type {NodeSizes| undefined} */
|
|
11502
|
+
const sizes = fn(
|
|
11503
|
+
target,
|
|
11504
|
+
{ old: tgOs, now: tgNs },
|
|
11505
|
+
{ old: this.#elemOldAmount, now: this.#elemAmount },
|
|
11506
|
+
);
|
|
11507
|
+
|
|
11508
|
+
// Fix size
|
|
11509
|
+
if (this.#newVisibles.get(target) || this.#newVisiblesByTime.get(target)) {
|
|
11510
|
+
if (typeof sizes !== 'undefined' && typeof sizes !== 'object')
|
|
11511
|
+
throw new Error('_fixScroll: size filter must return an object or undefined');
|
|
11512
|
+
if (typeof sizes === 'undefined') return;
|
|
11513
|
+
scrollSize.height = sizes.height;
|
|
11514
|
+
scrollSize.width = sizes.width;
|
|
11515
|
+
}
|
|
11516
|
+
});
|
|
11517
|
+
}
|
|
11518
|
+
|
|
11519
|
+
// Checker
|
|
11520
|
+
if (typeof scrollSize.height !== 'number' && scrollSize.height < 0)
|
|
11521
|
+
throw new Error('_fixScroll: invalid scrollSize.height value');
|
|
11522
|
+
if (typeof scrollSize.width !== 'number' && scrollSize.width < 0)
|
|
11523
|
+
throw new Error('_fixScroll: invalid scrollSize.width value');
|
|
11524
|
+
|
|
11525
|
+
if (scrollSize.height !== 0 || scrollSize.width !== 0) {
|
|
11526
|
+
for (const target of targets) {
|
|
11527
|
+
this.#newVisiblesByTime.set(target, this.#newVisibles.get(target) ?? false);
|
|
11528
|
+
this.#oldVisiblesByTime.set(target, this.#oldVisibles.get(target) ?? false);
|
|
11529
|
+
}
|
|
11530
|
+
}
|
|
11531
|
+
|
|
11532
|
+
return scrollSize;
|
|
11533
|
+
};
|
|
11534
|
+
|
|
11535
|
+
// Fix scroll size
|
|
11536
|
+
if (
|
|
11537
|
+
this.#elemOldAmount > 0 &&
|
|
11538
|
+
libs_TinyHtml.hasScroll(this.#target).v &&
|
|
11539
|
+
this.#autoScrollBottom &&
|
|
11540
|
+
this.#preserveScrollOnLayoutShift &&
|
|
11541
|
+
!this.#isAtBottom &&
|
|
11542
|
+
!this.#isAtTop
|
|
11543
|
+
) {
|
|
11544
|
+
const scrollSize = calculateScrollSize();
|
|
11545
|
+
// Complete
|
|
11546
|
+
this.#target.scrollTop = prevScrollTop + heightDelta + scrollSize.height;
|
|
11547
|
+
if (scrollSize.width > 0)
|
|
11548
|
+
this.#target.scrollLeft = this.#target.scrollLeft + scrollSize.width;
|
|
11549
|
+
}
|
|
11550
|
+
|
|
11551
|
+
// Normal stuff
|
|
11552
|
+
else if (!this.#scrollPaused && this.#autoScrollBottom) {
|
|
11553
|
+
calculateScrollSize();
|
|
11554
|
+
this.scrollToBottom();
|
|
11555
|
+
} else if (!this.#autoScrollBottom && !this.#isAtBottom) {
|
|
11556
|
+
calculateScrollSize();
|
|
11557
|
+
this.#target.scrollTop =
|
|
11558
|
+
this.#target.scrollHeight - this.#target.clientHeight - prevBottomOffset;
|
|
11559
|
+
}
|
|
11560
|
+
}
|
|
11561
|
+
/**
|
|
11562
|
+
* Sets up a MutationObserver to watch for DOM changes and react accordingly to maintain scroll consistency.
|
|
11563
|
+
*/
|
|
11564
|
+
_observeMutations() {
|
|
11565
|
+
this.#mutationObserver = new MutationObserver((mutations) => {
|
|
11566
|
+
if (this.#destroyed) return;
|
|
11567
|
+
this._scrollDataUpdater();
|
|
11568
|
+
this.#elemOldAmount = this.#elemAmount;
|
|
11569
|
+
this.#elemAmount = this.#target.childElementCount;
|
|
11570
|
+
|
|
11571
|
+
mutations.forEach((mutation) => {
|
|
11572
|
+
mutation.addedNodes.forEach((node) => {
|
|
11573
|
+
if (!(node instanceof Element) || node.nodeType !== 1) return;
|
|
11574
|
+
|
|
11575
|
+
this._observeResizes([node]);
|
|
11576
|
+
this._listenLoadEvents(node);
|
|
11577
|
+
|
|
11578
|
+
if (this.#querySelector) {
|
|
11579
|
+
const children = node.querySelectorAll(this.#querySelector);
|
|
11580
|
+
this._observeResizes(children);
|
|
11581
|
+
this._listenLoadEvents(children);
|
|
11582
|
+
}
|
|
11583
|
+
});
|
|
11584
|
+
});
|
|
11585
|
+
|
|
11586
|
+
this._fixScroll();
|
|
11587
|
+
});
|
|
11588
|
+
|
|
11589
|
+
// Install observer
|
|
11590
|
+
this.#mutationObserver.observe(this.#target, {
|
|
11591
|
+
childList: true,
|
|
11592
|
+
subtree: true,
|
|
11593
|
+
attributes: true,
|
|
11594
|
+
attributeFilter:
|
|
11595
|
+
this.#attributeFilter.size > 0 ? Array.from(this.#attributeFilter) : undefined,
|
|
11596
|
+
});
|
|
11597
|
+
}
|
|
11598
|
+
|
|
11599
|
+
/**
|
|
11600
|
+
* Adds a ResizeObserver to monitor elements' size changes and trigger layout adjustments.
|
|
11601
|
+
*
|
|
11602
|
+
* @param {NodeListOf<Element>|Element[]|HTMLCollection} elements - Elements to observe.
|
|
11603
|
+
*/
|
|
11604
|
+
_observeResizes(elements) {
|
|
11605
|
+
// Add resize observer
|
|
11606
|
+
if (!this.#resizeObserver) {
|
|
11607
|
+
this.#resizeObserver = new ResizeObserver((entries) => {
|
|
11608
|
+
if (this.#destroyed) return;
|
|
11609
|
+
this._scrollDataUpdater();
|
|
11610
|
+
/** @type {Element[]} */
|
|
11611
|
+
const targets = [];
|
|
11612
|
+
for (const entry of entries) {
|
|
11613
|
+
// Target
|
|
11614
|
+
const target = entry.target;
|
|
11615
|
+
|
|
11616
|
+
// Update old size
|
|
11617
|
+
const oldSize = this.#newSizes.get(target);
|
|
11618
|
+
if (oldSize) this.#oldSizes.set(target, oldSize);
|
|
11619
|
+
|
|
11620
|
+
// Set new size
|
|
11621
|
+
const { width, height } = entry.contentRect;
|
|
11622
|
+
this.#newSizes.set(target, { width, height });
|
|
11623
|
+
targets.push(target);
|
|
11624
|
+
}
|
|
11625
|
+
|
|
11626
|
+
// Animation frame
|
|
11627
|
+
this._fixScroll(targets);
|
|
11628
|
+
});
|
|
11629
|
+
}
|
|
11630
|
+
|
|
11631
|
+
// Execute observer
|
|
11632
|
+
Array.from(elements).forEach((el) => {
|
|
11633
|
+
if (!this.#resizeObserver)
|
|
11634
|
+
throw new Error('_observeResizes: ResizeObserver instance is not initialized');
|
|
11635
|
+
this.#resizeObserver.observe(el);
|
|
11636
|
+
});
|
|
11637
|
+
}
|
|
11638
|
+
|
|
11639
|
+
/**
|
|
11640
|
+
* Listens for media/content load events (e.g., images, iframes, videos) to trigger scroll updates.
|
|
11641
|
+
*
|
|
11642
|
+
* @param {NodeListOf<Element>|Element} elements - Target element(s) to listen on.
|
|
11643
|
+
*/
|
|
11644
|
+
_listenLoadEvents(elements) {
|
|
11645
|
+
if (this.#destroyed) return;
|
|
11646
|
+
const list = elements instanceof NodeList ? Array.from(elements) : [elements];
|
|
11647
|
+
|
|
11648
|
+
list.forEach((el) => {
|
|
11649
|
+
if (this.#loadTags.has(el.tagName)) {
|
|
11650
|
+
// @ts-ignore
|
|
11651
|
+
if (!el.complete) {
|
|
11652
|
+
el.addEventListener('load', () => {
|
|
11653
|
+
this._scrollDataUpdater();
|
|
11654
|
+
if (!this.#scrollPaused && this.#autoScrollBottom) {
|
|
11655
|
+
this.scrollToBottom();
|
|
11656
|
+
}
|
|
11657
|
+
});
|
|
11658
|
+
}
|
|
11659
|
+
}
|
|
11660
|
+
});
|
|
11661
|
+
}
|
|
11662
|
+
|
|
11663
|
+
/**
|
|
11664
|
+
* Returns the internal scroll container element being monitored.
|
|
11665
|
+
*
|
|
11666
|
+
* @returns {Element} The DOM element used as the scroll container target.
|
|
11667
|
+
*/
|
|
11668
|
+
get target() {
|
|
11669
|
+
return this.#target;
|
|
11670
|
+
}
|
|
11671
|
+
|
|
11672
|
+
/**
|
|
11673
|
+
* Returns the previous size of a given element, or undefined if not tracked.
|
|
11674
|
+
*
|
|
11675
|
+
* @param {Element} el - The DOM element to query.
|
|
11676
|
+
* @returns {NodeSizes|null} The old size, or undefined.
|
|
11677
|
+
*/
|
|
11678
|
+
getOldSize(el) {
|
|
11679
|
+
return this.#oldSizes.get(el) ?? null;
|
|
11680
|
+
}
|
|
11681
|
+
|
|
11682
|
+
/**
|
|
11683
|
+
* Returns the current size of a given element, or undefined if not tracked.
|
|
11684
|
+
*
|
|
11685
|
+
* @param {Element} el - The DOM element to query.
|
|
11686
|
+
* @returns {NodeSizes|null} The new size, or undefined.
|
|
11687
|
+
*/
|
|
11688
|
+
getNewSize(el) {
|
|
11689
|
+
return this.#newSizes.get(el) ?? null;
|
|
11690
|
+
}
|
|
11691
|
+
|
|
11692
|
+
/**
|
|
11693
|
+
* Returns whether the given element was visible in the last scroll update.
|
|
11694
|
+
*
|
|
11695
|
+
* @param {Element} el - The DOM element to check.
|
|
11696
|
+
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
11697
|
+
*/
|
|
11698
|
+
wasVisible(el) {
|
|
11699
|
+
return this.#oldVisibles.get(el) ?? false;
|
|
11700
|
+
}
|
|
11701
|
+
|
|
11702
|
+
/**
|
|
11703
|
+
* Returns whether the given element is currently visible.
|
|
11704
|
+
*
|
|
11705
|
+
* @param {Element} el - The DOM element to check.
|
|
11706
|
+
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
|
|
11707
|
+
*/
|
|
11708
|
+
isVisible(el) {
|
|
11709
|
+
return this.#newVisibles.get(el) ?? false;
|
|
11710
|
+
}
|
|
11711
|
+
|
|
11712
|
+
/**
|
|
11713
|
+
* Returns whether the element was visible in the last time-based visibility check.
|
|
11714
|
+
*
|
|
11715
|
+
* @param {Element} el - The DOM element to check.
|
|
11716
|
+
* @returns {boolean} Visibility state from the previous timed check.
|
|
11717
|
+
*/
|
|
11718
|
+
wasTimedVisible(el) {
|
|
11719
|
+
return this.#oldVisiblesByTime.get(el) ?? false;
|
|
11720
|
+
}
|
|
11721
|
+
|
|
11722
|
+
/**
|
|
11723
|
+
* Returns whether the element is currently visible in the time-based check.
|
|
11724
|
+
*
|
|
11725
|
+
* @param {Element} el - The DOM element to check.
|
|
11726
|
+
* @returns {boolean} Visibility state from the current timed check.
|
|
11727
|
+
*/
|
|
11728
|
+
isTimedVisible(el) {
|
|
11729
|
+
return this.#newVisiblesByTime.get(el) ?? false;
|
|
11730
|
+
}
|
|
11731
|
+
|
|
11732
|
+
/**
|
|
11733
|
+
* Sets the extra scroll boundary margin used when determining if the user is at a "custom" bottom or top.
|
|
11734
|
+
*
|
|
11735
|
+
* @param {number} value - Pixels of additional margin to use.
|
|
11736
|
+
*/
|
|
11737
|
+
setExtraScrollBoundary(value) {
|
|
11738
|
+
if (typeof value !== 'number' || Number.isNaN(value))
|
|
11739
|
+
throw new TypeError('setExtraScrollBoundary(value): value must be a valid number');
|
|
11740
|
+
this.#extraScrollBoundary = value;
|
|
11741
|
+
}
|
|
11742
|
+
|
|
11743
|
+
/**
|
|
11744
|
+
* Returns the current extra scroll boundary setting.
|
|
11745
|
+
*
|
|
11746
|
+
* @returns {number}
|
|
11747
|
+
*/
|
|
11748
|
+
getExtraScrollBoundary() {
|
|
11749
|
+
return this.#extraScrollBoundary;
|
|
11750
|
+
}
|
|
11751
|
+
|
|
11752
|
+
/**
|
|
11753
|
+
* Returns the last known distance (in pixels) from the bottom of the scroll container.
|
|
11754
|
+
*
|
|
11755
|
+
* @returns {number}
|
|
11756
|
+
*/
|
|
11757
|
+
getLastKnownScrollBottomOffset() {
|
|
11758
|
+
return this.#lastKnownScrollBottomOffset;
|
|
11759
|
+
}
|
|
11760
|
+
|
|
11761
|
+
/**
|
|
11762
|
+
* Forces the scroll position to move to the very bottom of the target.
|
|
11763
|
+
*/
|
|
11764
|
+
scrollToBottom() {
|
|
11765
|
+
this.#target.scrollTop = this.#target.scrollHeight;
|
|
11766
|
+
}
|
|
11767
|
+
|
|
11768
|
+
/**
|
|
11769
|
+
* Forces the scroll position to move to the very top of the target.
|
|
11770
|
+
*/
|
|
11771
|
+
scrollToTop() {
|
|
11772
|
+
this.#target.scrollTop = 0;
|
|
11773
|
+
}
|
|
11774
|
+
|
|
11775
|
+
/**
|
|
11776
|
+
* Checks if the user is within the defined extra scroll boundary from the bottom.
|
|
11777
|
+
*
|
|
11778
|
+
* @returns {boolean}
|
|
11779
|
+
*/
|
|
11780
|
+
isUserAtCustomBottom() {
|
|
11781
|
+
return this.#isAtCustomBottom;
|
|
11782
|
+
}
|
|
11783
|
+
|
|
11784
|
+
/**
|
|
11785
|
+
* Checks if the user is within the defined extra scroll boundary from the top.
|
|
11786
|
+
*
|
|
11787
|
+
* @returns {boolean}
|
|
11788
|
+
*/
|
|
11789
|
+
isUserAtCustomTop() {
|
|
11790
|
+
return this.#isAtCustomTop;
|
|
11791
|
+
}
|
|
11792
|
+
|
|
11793
|
+
/**
|
|
11794
|
+
* Returns true if the user is currently scrolled to the bottom of the element.
|
|
11795
|
+
*
|
|
11796
|
+
* @returns {boolean}
|
|
11797
|
+
*/
|
|
11798
|
+
isUserAtBottom() {
|
|
11799
|
+
return this.#isAtBottom;
|
|
11800
|
+
}
|
|
11801
|
+
|
|
11802
|
+
/**
|
|
11803
|
+
* Returns true if the user is currently scrolled to the top of the element.
|
|
11804
|
+
*
|
|
11805
|
+
* @returns {boolean}
|
|
11806
|
+
*/
|
|
11807
|
+
isUserAtTop() {
|
|
11808
|
+
return this.#isAtTop;
|
|
11809
|
+
}
|
|
11810
|
+
|
|
11811
|
+
/**
|
|
11812
|
+
* Returns true if automatic scrolling is currently paused.
|
|
11813
|
+
*
|
|
11814
|
+
* @returns {boolean}
|
|
11815
|
+
*/
|
|
11816
|
+
isScrollPaused() {
|
|
11817
|
+
return this.#scrollPaused;
|
|
11818
|
+
}
|
|
11819
|
+
|
|
11820
|
+
/**
|
|
11821
|
+
* Returns whether the target is the window object.
|
|
11822
|
+
*
|
|
11823
|
+
* @returns {boolean} True if the scroll target is window, false otherwise.
|
|
11824
|
+
*/
|
|
11825
|
+
isWindow() {
|
|
11826
|
+
return this.#useWindow;
|
|
11827
|
+
}
|
|
11828
|
+
|
|
11829
|
+
/**
|
|
11830
|
+
* Returns whether the instance has been destroyed.
|
|
11831
|
+
*
|
|
11832
|
+
* @returns {boolean} True if the instance is destroyed, false otherwise.
|
|
11833
|
+
*/
|
|
11834
|
+
isDestroyed() {
|
|
11835
|
+
return this.#destroyed;
|
|
11836
|
+
}
|
|
11837
|
+
|
|
11838
|
+
/**
|
|
11839
|
+
* Returns whether auto-scroll-to-bottom is enabled.
|
|
11840
|
+
*
|
|
11841
|
+
* @returns {boolean} True if auto-scroll is active, false otherwise.
|
|
11842
|
+
*/
|
|
11843
|
+
getAutoScrollBottom() {
|
|
11844
|
+
return this.#autoScrollBottom;
|
|
11845
|
+
}
|
|
11846
|
+
|
|
11847
|
+
/**
|
|
11848
|
+
* Returns whether MutationObserver is enabled.
|
|
11849
|
+
*
|
|
11850
|
+
* @returns {boolean} True if mutation observation is active, false otherwise.
|
|
11851
|
+
*/
|
|
11852
|
+
getObserveMutations() {
|
|
11853
|
+
return this.#observeMutations;
|
|
11854
|
+
}
|
|
11855
|
+
|
|
11856
|
+
/**
|
|
11857
|
+
* Returns whether layout shift protection is enabled.
|
|
11858
|
+
*
|
|
11859
|
+
* @returns {boolean} True if scroll preservation is active, false otherwise.
|
|
11860
|
+
*/
|
|
11861
|
+
getPreserveScrollOnLayoutShift() {
|
|
11862
|
+
return this.#preserveScrollOnLayoutShift;
|
|
11863
|
+
}
|
|
11864
|
+
|
|
11865
|
+
/**
|
|
11866
|
+
* Returns the debounce delay in milliseconds used for scroll events.
|
|
11867
|
+
*
|
|
11868
|
+
* @returns {number} Debounce delay time.
|
|
11869
|
+
*/
|
|
11870
|
+
getDebounceTime() {
|
|
11871
|
+
return this.#debounceTime;
|
|
11872
|
+
}
|
|
11873
|
+
|
|
11874
|
+
/**
|
|
11875
|
+
* Returns the current number of matching elements observed inside the scroll target.
|
|
11876
|
+
*
|
|
11877
|
+
* @returns {number} Current count of matching elements.
|
|
11878
|
+
*/
|
|
11879
|
+
getElemAmount() {
|
|
11880
|
+
return this.#elemAmount;
|
|
11881
|
+
}
|
|
11882
|
+
|
|
11883
|
+
/**
|
|
11884
|
+
* Returns the previous known count of matching elements from the last update.
|
|
11885
|
+
*
|
|
11886
|
+
* @returns {number} Previous count of matching elements.
|
|
11887
|
+
*/
|
|
11888
|
+
getPrevElemAmount() {
|
|
11889
|
+
return this.#elemOldAmount;
|
|
11890
|
+
}
|
|
11891
|
+
|
|
11892
|
+
/**
|
|
11893
|
+
* Returns the query selector string used to filter observed elements.
|
|
11894
|
+
*
|
|
11895
|
+
* @returns {string} The CSS selector string, or an empty string if none was provided.
|
|
11896
|
+
*/
|
|
11897
|
+
getQuerySelector() {
|
|
11898
|
+
return this.#querySelector;
|
|
11899
|
+
}
|
|
11900
|
+
|
|
11901
|
+
/**
|
|
11902
|
+
* Disconnects all listeners, observers, and clears memory structures.
|
|
11903
|
+
* Once destroyed, this instance should no longer be used.
|
|
11904
|
+
*/
|
|
11905
|
+
destroy() {
|
|
11906
|
+
if (this.#destroyed) return;
|
|
11907
|
+
this.#destroyed = true;
|
|
11908
|
+
|
|
11909
|
+
// Disconnects MutationObserver
|
|
11910
|
+
if (this.#mutationObserver) {
|
|
11911
|
+
this.#mutationObserver.disconnect();
|
|
11912
|
+
this.#mutationObserver = null;
|
|
11913
|
+
}
|
|
11914
|
+
|
|
11915
|
+
// Disconnect ResizeObserver
|
|
11916
|
+
if (this.#resizeObserver) {
|
|
11917
|
+
this.#resizeObserver.disconnect();
|
|
11918
|
+
this.#resizeObserver = null;
|
|
11919
|
+
}
|
|
11920
|
+
|
|
11921
|
+
// Removes scroll listener
|
|
11922
|
+
const target = this.#useWindow ? window : this.#target;
|
|
11923
|
+
if (this.#handler) target.removeEventListener('scroll', this.#handler);
|
|
11924
|
+
|
|
11925
|
+
// Clean the WeakMaps
|
|
11926
|
+
this.#oldSizes = new WeakMap();
|
|
11927
|
+
this.#newSizes = new WeakMap();
|
|
11928
|
+
this.#newVisibles = new WeakMap();
|
|
11929
|
+
this.#oldVisibles = new WeakMap();
|
|
11930
|
+
this.#newVisiblesByTime = new WeakMap();
|
|
11931
|
+
this.#oldVisiblesByTime = new WeakMap();
|
|
11932
|
+
|
|
11933
|
+
// Cleans listeners and filters
|
|
11934
|
+
this.#scrollListeners = {};
|
|
11935
|
+
this.#sizeFilter.clear();
|
|
11936
|
+
this.#loadTags.clear();
|
|
11937
|
+
}
|
|
11938
|
+
}
|
|
11939
|
+
|
|
11940
|
+
/* harmony default export */ const libs_TinySmartScroller = ((/* unused pure expression or super */ null && (TinySmartScroller)));
|
|
11941
|
+
|
|
10330
11942
|
;// ./src/v1/index.mjs
|
|
10331
11943
|
|
|
10332
11944
|
|
|
@@ -10356,6 +11968,8 @@ class TinyDragger {
|
|
|
10356
11968
|
|
|
10357
11969
|
|
|
10358
11970
|
|
|
11971
|
+
|
|
11972
|
+
|
|
10359
11973
|
|
|
10360
11974
|
|
|
10361
11975
|
|