@oscarpalmer/toretto 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/event/delegation.js +19 -26
- package/dist/event/index.js +1 -1
- package/dist/find/index.js +2 -2
- package/dist/find/relative.js +18 -17
- package/dist/index.js +2 -2
- package/dist/toretto.full.js +42 -47
- package/package.json +3 -3
- package/src/event/delegation.ts +23 -51
- package/src/event/index.ts +1 -7
- package/src/find/index.ts +1 -1
- package/src/find/relative.ts +35 -37
- package/types/event/delegation.d.ts +1 -1
- package/types/find/index.d.ts +1 -1
- package/types/find/relative.d.ts +8 -2
package/dist/event/delegation.js
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
import { isEventTarget } from "../internal/is.js";
|
|
2
2
|
function addDelegatedHandler(doc, type, name, passive) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
doc[count] += 1;
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
doc[count] = 1;
|
|
3
|
+
if (DELEGATED.has(name)) return;
|
|
4
|
+
DELEGATED.add(name);
|
|
9
5
|
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
10
6
|
}
|
|
11
7
|
function addDelegatedListener(target, type, name, listener, passive) {
|
|
12
8
|
target[name] ??= /* @__PURE__ */ new Set();
|
|
13
|
-
target[name]
|
|
9
|
+
target[name].add(listener);
|
|
14
10
|
addDelegatedHandler(document, type, name, passive);
|
|
15
11
|
return () => {
|
|
16
|
-
removeDelegatedListener(target,
|
|
12
|
+
removeDelegatedListener(target, name, listener);
|
|
17
13
|
};
|
|
18
14
|
}
|
|
19
15
|
function delegatedEventHandler(event) {
|
|
20
16
|
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
21
17
|
const items = event.composedPath();
|
|
22
18
|
const { length } = items;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
let target = items[0];
|
|
20
|
+
Object.defineProperties(event, {
|
|
21
|
+
currentTarget: {
|
|
22
|
+
configurable: true,
|
|
23
|
+
get() {
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
target: {
|
|
28
|
+
configurable: true,
|
|
29
|
+
value: target
|
|
30
|
+
}
|
|
26
31
|
});
|
|
27
32
|
for (let index = 0; index < length; index += 1) {
|
|
28
33
|
const item = items[index];
|
|
29
34
|
const listeners = item[key];
|
|
30
35
|
if (item.disabled || listeners == null) continue;
|
|
31
|
-
|
|
32
|
-
configurable: true,
|
|
33
|
-
value: item
|
|
34
|
-
});
|
|
36
|
+
target = item;
|
|
35
37
|
for (const listener of listeners) {
|
|
36
38
|
listener.call(item, event);
|
|
37
39
|
if (event.cancelBubble) return;
|
|
@@ -41,23 +43,14 @@ function delegatedEventHandler(event) {
|
|
|
41
43
|
function getDelegatedName(target, type, options) {
|
|
42
44
|
if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
43
45
|
}
|
|
44
|
-
function
|
|
45
|
-
const count = `${name}${COUNT_SUFFIX}`;
|
|
46
|
-
doc[count] -= 1;
|
|
47
|
-
if (doc[count] < 1) {
|
|
48
|
-
doc[count] = void 0;
|
|
49
|
-
doc.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function removeDelegatedListener(target, type, name, listener, passive) {
|
|
46
|
+
function removeDelegatedListener(target, name, listener) {
|
|
53
47
|
const handlers = target[name];
|
|
54
48
|
if (handlers == null || !handlers.has(listener)) return false;
|
|
55
49
|
handlers.delete(listener);
|
|
56
50
|
if (handlers.size === 0) target[name] = void 0;
|
|
57
|
-
removeDelegatedHandler(document, type, name, passive);
|
|
58
51
|
return true;
|
|
59
52
|
}
|
|
60
|
-
var
|
|
53
|
+
var DELEGATED = /* @__PURE__ */ new Set();
|
|
61
54
|
var EVENT_PREFIX = "@";
|
|
62
55
|
var EVENT_SUFFIX_ACTIVE = ":active";
|
|
63
56
|
var EVENT_SUFFIX_PASSIVE = ":passive";
|
package/dist/event/index.js
CHANGED
|
@@ -48,7 +48,7 @@ function off(target, type, listener, options) {
|
|
|
48
48
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return;
|
|
49
49
|
const extended = createEventOptions(options);
|
|
50
50
|
const delegated = getDelegatedName(target, type, extended);
|
|
51
|
-
if (delegated == null || !removeDelegatedListener(target,
|
|
51
|
+
if (delegated == null || !removeDelegatedListener(target, delegated, listener)) target.removeEventListener(type, listener, extended);
|
|
52
52
|
}
|
|
53
53
|
function on(target, type, listener, options) {
|
|
54
54
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
package/dist/find/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { findAncestor, findRelatives } from "./relative.js";
|
|
1
|
+
import { findAncestor, findRelatives, getDistance } from "./relative.js";
|
|
2
2
|
function findElement(selector, context) {
|
|
3
3
|
return findElementOrElements(selector, context, true);
|
|
4
4
|
}
|
|
@@ -61,4 +61,4 @@ var STYLE_HIDDEN = "hidden";
|
|
|
61
61
|
var STYLE_NONE = "none";
|
|
62
62
|
var SUFFIX_HOVER = ":hover";
|
|
63
63
|
var TAG_HEAD = "HEAD";
|
|
64
|
-
export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getElementUnderPointer };
|
|
64
|
+
export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getDistance, getElementUnderPointer };
|
package/dist/find/relative.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
function getDistanceBetweenElements(origin, target) {
|
|
2
|
-
if (origin === target) return 0;
|
|
3
|
-
if (origin.parentElement === target) return 1;
|
|
4
|
-
const children = [...origin.parentElement?.children ?? []];
|
|
5
|
-
if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
6
|
-
const comparison = origin.compareDocumentPosition(target);
|
|
7
|
-
const beforeOrInside = Boolean(comparison & 2 || comparison & 8);
|
|
8
|
-
if (beforeOrInside || Boolean(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
|
|
9
|
-
}
|
|
10
1
|
function findAncestor(origin, selector) {
|
|
11
2
|
if (!(origin instanceof Element) || selector == null) return null;
|
|
12
3
|
if (typeof selector === "string") {
|
|
@@ -31,8 +22,8 @@ function findRelatives(origin, selector, context) {
|
|
|
31
22
|
let minimum;
|
|
32
23
|
for (let index = 0; index < length; index += 1) {
|
|
33
24
|
const element = elements[index];
|
|
34
|
-
const distance =
|
|
35
|
-
if (distance
|
|
25
|
+
const distance = getDistance(origin, element);
|
|
26
|
+
if (distance > 0) {
|
|
36
27
|
if (minimum == null || distance < minimum) minimum = distance;
|
|
37
28
|
distances.push({
|
|
38
29
|
distance,
|
|
@@ -40,19 +31,29 @@ function findRelatives(origin, selector, context) {
|
|
|
40
31
|
});
|
|
41
32
|
}
|
|
42
33
|
}
|
|
43
|
-
return distances.filter((found) => found.distance === minimum
|
|
34
|
+
return distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
35
|
+
}
|
|
36
|
+
function getDistance(origin, target) {
|
|
37
|
+
if (origin === target) return 0;
|
|
38
|
+
if (origin.parentElement === target || target.parentElement === origin) return 1;
|
|
39
|
+
if (origin.parentElement != null && origin.parentElement === target.parentElement) {
|
|
40
|
+
const children = [...origin.parentElement.children];
|
|
41
|
+
return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
42
|
+
}
|
|
43
|
+
const comparison = origin.compareDocumentPosition(target);
|
|
44
|
+
if (comparison & Node.DOCUMENT_POSITION_DISCONNECTED) return -1;
|
|
45
|
+
const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
|
|
46
|
+
return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
|
|
44
47
|
}
|
|
45
48
|
function traverse(from, to) {
|
|
46
|
-
let index = [...to.children].indexOf(from);
|
|
47
|
-
if (index > -1) return 1;
|
|
48
49
|
let current = from;
|
|
49
50
|
let distance = 0;
|
|
50
51
|
let parent = from.parentElement;
|
|
51
52
|
while (parent != null) {
|
|
52
53
|
if (parent === to) return distance + 1;
|
|
53
54
|
const children = [...parent.children];
|
|
54
|
-
if (
|
|
55
|
-
index = children.findIndex((child) => child.contains(to));
|
|
55
|
+
if (to.parentElement === parent) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
56
|
+
const index = children.findIndex((child) => child.contains(to));
|
|
56
57
|
if (index > -1) {
|
|
57
58
|
const traversed = traverse(current, children[index]);
|
|
58
59
|
return traversed == null || traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
@@ -62,4 +63,4 @@ function traverse(from, to) {
|
|
|
62
63
|
parent = parent.parentElement;
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
export { findAncestor, findRelatives };
|
|
66
|
+
export { findAncestor, findRelatives, getDistance };
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,10 @@ import { isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInval
|
|
|
3
3
|
import { isChildNode, isInDocument } from "./is.js";
|
|
4
4
|
import { getData, setData } from "./data.js";
|
|
5
5
|
import { dispatch, getPosition, off, on } from "./event/index.js";
|
|
6
|
-
import { findAncestor, findRelatives } from "./find/relative.js";
|
|
6
|
+
import { findAncestor, findRelatives, getDistance } from "./find/relative.js";
|
|
7
7
|
import { $ as findElement, $$ as findElements, getElementUnderPointer } from "./find/index.js";
|
|
8
8
|
import { getFocusable, getTabbable, isFocusable, isTabbable } from "./focusable.js";
|
|
9
9
|
import { html, sanitize } from "./html/index.js";
|
|
10
10
|
import touch_default from "./touch.js";
|
|
11
11
|
import { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles } from "./style.js";
|
|
12
|
-
export { findElement as $, findElement, findElements as $$, findElements, dispatch, findAncestor, findRelatives, getData, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setData, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|
|
12
|
+
export { findElement as $, findElement, findElements as $$, findElements, dispatch, findAncestor, findRelatives, getData, getDistance, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setData, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|
package/dist/toretto.full.js
CHANGED
|
@@ -305,6 +305,7 @@ function updateDataAttribute(element, key, value) {
|
|
|
305
305
|
updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, true);
|
|
306
306
|
}
|
|
307
307
|
const ATTRIBUTE_DATA_PREFIX = "data-";
|
|
308
|
+
function noop() {}
|
|
308
309
|
function calculate() {
|
|
309
310
|
return new Promise((resolve) => {
|
|
310
311
|
const values = [];
|
|
@@ -312,49 +313,51 @@ function calculate() {
|
|
|
312
313
|
function step(now) {
|
|
313
314
|
if (last != null) values.push(now - last);
|
|
314
315
|
last = now;
|
|
315
|
-
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(
|
|
316
|
+
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(CALCULATION_TRIM_PART, -CALCULATION_TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM_TOTAL));
|
|
316
317
|
else requestAnimationFrame(step);
|
|
317
318
|
}
|
|
318
319
|
requestAnimationFrame(step);
|
|
319
320
|
});
|
|
320
321
|
}
|
|
321
|
-
function noop() {}
|
|
322
322
|
var CALCULATION_TOTAL = 10;
|
|
323
|
-
var
|
|
323
|
+
var CALCULATION_TRIM_PART = 2;
|
|
324
|
+
var CALCULATION_TRIM_TOTAL = 4;
|
|
324
325
|
calculate().then((value) => {});
|
|
325
326
|
function addDelegatedHandler(doc, type, name, passive) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
doc[count] += 1;
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
doc[count] = 1;
|
|
327
|
+
if (DELEGATED.has(name)) return;
|
|
328
|
+
DELEGATED.add(name);
|
|
332
329
|
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
333
330
|
}
|
|
334
331
|
function addDelegatedListener(target, type, name, listener, passive) {
|
|
335
332
|
target[name] ??= /* @__PURE__ */ new Set();
|
|
336
|
-
target[name]
|
|
333
|
+
target[name].add(listener);
|
|
337
334
|
addDelegatedHandler(document, type, name, passive);
|
|
338
335
|
return () => {
|
|
339
|
-
removeDelegatedListener(target,
|
|
336
|
+
removeDelegatedListener(target, name, listener);
|
|
340
337
|
};
|
|
341
338
|
}
|
|
342
339
|
function delegatedEventHandler(event) {
|
|
343
340
|
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
344
341
|
const items = event.composedPath();
|
|
345
342
|
const { length } = items;
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
343
|
+
let target = items[0];
|
|
344
|
+
Object.defineProperties(event, {
|
|
345
|
+
currentTarget: {
|
|
346
|
+
configurable: true,
|
|
347
|
+
get() {
|
|
348
|
+
return target;
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
target: {
|
|
352
|
+
configurable: true,
|
|
353
|
+
value: target
|
|
354
|
+
}
|
|
349
355
|
});
|
|
350
356
|
for (let index = 0; index < length; index += 1) {
|
|
351
357
|
const item = items[index];
|
|
352
358
|
const listeners = item[key];
|
|
353
359
|
if (item.disabled || listeners == null) continue;
|
|
354
|
-
|
|
355
|
-
configurable: true,
|
|
356
|
-
value: item
|
|
357
|
-
});
|
|
360
|
+
target = item;
|
|
358
361
|
for (const listener of listeners) {
|
|
359
362
|
listener.call(item, event);
|
|
360
363
|
if (event.cancelBubble) return;
|
|
@@ -364,23 +367,14 @@ function delegatedEventHandler(event) {
|
|
|
364
367
|
function getDelegatedName(target, type, options) {
|
|
365
368
|
if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
366
369
|
}
|
|
367
|
-
function
|
|
368
|
-
const count = `${name}${COUNT_SUFFIX}`;
|
|
369
|
-
doc[count] -= 1;
|
|
370
|
-
if (doc[count] < 1) {
|
|
371
|
-
doc[count] = void 0;
|
|
372
|
-
doc.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
function removeDelegatedListener(target, type, name, listener, passive) {
|
|
370
|
+
function removeDelegatedListener(target, name, listener) {
|
|
376
371
|
const handlers = target[name];
|
|
377
372
|
if (handlers == null || !handlers.has(listener)) return false;
|
|
378
373
|
handlers.delete(listener);
|
|
379
374
|
if (handlers.size === 0) target[name] = void 0;
|
|
380
|
-
removeDelegatedHandler(document, type, name, passive);
|
|
381
375
|
return true;
|
|
382
376
|
}
|
|
383
|
-
const
|
|
377
|
+
const DELEGATED = /* @__PURE__ */ new Set();
|
|
384
378
|
const EVENT_PREFIX = "@";
|
|
385
379
|
const EVENT_SUFFIX_ACTIVE = ":active";
|
|
386
380
|
const EVENT_SUFFIX_PASSIVE = ":passive";
|
|
@@ -455,7 +449,7 @@ function off(target, type, listener, options) {
|
|
|
455
449
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return;
|
|
456
450
|
const extended = createEventOptions(options);
|
|
457
451
|
const delegated = getDelegatedName(target, type, extended);
|
|
458
|
-
if (delegated == null || !removeDelegatedListener(target,
|
|
452
|
+
if (delegated == null || !removeDelegatedListener(target, delegated, listener)) target.removeEventListener(type, listener, extended);
|
|
459
453
|
}
|
|
460
454
|
function on(target, type, listener, options) {
|
|
461
455
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
@@ -469,15 +463,6 @@ function on(target, type, listener, options) {
|
|
|
469
463
|
};
|
|
470
464
|
}
|
|
471
465
|
const PROPERTY_DETAIL = "detail";
|
|
472
|
-
function getDistanceBetweenElements(origin, target) {
|
|
473
|
-
if (origin === target) return 0;
|
|
474
|
-
if (origin.parentElement === target) return 1;
|
|
475
|
-
const children = [...origin.parentElement?.children ?? []];
|
|
476
|
-
if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
477
|
-
const comparison = origin.compareDocumentPosition(target);
|
|
478
|
-
const beforeOrInside = Boolean(comparison & 2 || comparison & 8);
|
|
479
|
-
if (beforeOrInside || Boolean(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
|
|
480
|
-
}
|
|
481
466
|
function findAncestor(origin, selector) {
|
|
482
467
|
if (!(origin instanceof Element) || selector == null) return null;
|
|
483
468
|
if (typeof selector === "string") {
|
|
@@ -502,8 +487,8 @@ function findRelatives(origin, selector, context) {
|
|
|
502
487
|
let minimum;
|
|
503
488
|
for (let index = 0; index < length; index += 1) {
|
|
504
489
|
const element = elements[index];
|
|
505
|
-
const distance =
|
|
506
|
-
if (distance
|
|
490
|
+
const distance = getDistance(origin, element);
|
|
491
|
+
if (distance > 0) {
|
|
507
492
|
if (minimum == null || distance < minimum) minimum = distance;
|
|
508
493
|
distances.push({
|
|
509
494
|
distance,
|
|
@@ -511,19 +496,29 @@ function findRelatives(origin, selector, context) {
|
|
|
511
496
|
});
|
|
512
497
|
}
|
|
513
498
|
}
|
|
514
|
-
return distances.filter((found) => found.distance === minimum
|
|
499
|
+
return distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
500
|
+
}
|
|
501
|
+
function getDistance(origin, target) {
|
|
502
|
+
if (origin === target) return 0;
|
|
503
|
+
if (origin.parentElement === target || target.parentElement === origin) return 1;
|
|
504
|
+
if (origin.parentElement != null && origin.parentElement === target.parentElement) {
|
|
505
|
+
const children = [...origin.parentElement.children];
|
|
506
|
+
return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
507
|
+
}
|
|
508
|
+
const comparison = origin.compareDocumentPosition(target);
|
|
509
|
+
if (comparison & Node.DOCUMENT_POSITION_DISCONNECTED) return -1;
|
|
510
|
+
const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
|
|
511
|
+
return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
|
|
515
512
|
}
|
|
516
513
|
function traverse(from, to) {
|
|
517
|
-
let index = [...to.children].indexOf(from);
|
|
518
|
-
if (index > -1) return 1;
|
|
519
514
|
let current = from;
|
|
520
515
|
let distance = 0;
|
|
521
516
|
let parent = from.parentElement;
|
|
522
517
|
while (parent != null) {
|
|
523
518
|
if (parent === to) return distance + 1;
|
|
524
519
|
const children = [...parent.children];
|
|
525
|
-
if (
|
|
526
|
-
index = children.findIndex((child) => child.contains(to));
|
|
520
|
+
if (to.parentElement === parent) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
521
|
+
const index = children.findIndex((child) => child.contains(to));
|
|
527
522
|
if (index > -1) {
|
|
528
523
|
const traversed = traverse(current, children[index]);
|
|
529
524
|
return traversed == null || traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
@@ -913,4 +908,4 @@ function updateStyleProperty(element, key, value) {
|
|
|
913
908
|
}
|
|
914
909
|
const ATTRIBUTE_DIRECTION = "dir";
|
|
915
910
|
const EXPRESSION_DIRECTION = /^(ltr|rtl)$/i;
|
|
916
|
-
export { findElement as $, findElement, findElements as $$, findElements, dispatch, findAncestor, findRelatives, getData, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setData, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|
|
911
|
+
export { findElement as $, findElement, findElements as $$, findElements, dispatch, findAncestor, findRelatives, getData, getDistance, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setData, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@oscarpalmer/atoms": "^0.
|
|
7
|
+
"@oscarpalmer/atoms": "^0.117"
|
|
8
8
|
},
|
|
9
9
|
"description": "A collection of badass DOM utilities.",
|
|
10
10
|
"devDependencies": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"jsdom": "^27.3",
|
|
14
14
|
"oxfmt": "^0.19",
|
|
15
15
|
"oxlint": "^1.34",
|
|
16
|
-
"rolldown": "1.0.0-beta.
|
|
16
|
+
"rolldown": "1.0.0-beta.56",
|
|
17
17
|
"tslib": "^2.8",
|
|
18
18
|
"typescript": "^5.9",
|
|
19
19
|
"vite": "8.0.0-beta.2",
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
},
|
|
94
94
|
"type": "module",
|
|
95
95
|
"types": "types/index.d.ts",
|
|
96
|
-
"version": "0.
|
|
96
|
+
"version": "0.32.0"
|
|
97
97
|
}
|
package/src/event/delegation.ts
CHANGED
|
@@ -3,31 +3,17 @@ import type {CustomEventListener, RemovableEventListener} from '../models';
|
|
|
3
3
|
|
|
4
4
|
//
|
|
5
5
|
|
|
6
|
-
type DocumentWithListenerCounts = Document &
|
|
7
|
-
Partial<{
|
|
8
|
-
[key: string]: number;
|
|
9
|
-
}>;
|
|
10
|
-
|
|
11
6
|
export type EventTargetWithListeners = EventTarget &
|
|
12
7
|
Partial<{
|
|
13
8
|
[key: string]: Set<EventListener | CustomEventListener>;
|
|
14
9
|
}>;
|
|
15
10
|
|
|
16
|
-
function addDelegatedHandler(
|
|
17
|
-
|
|
18
|
-
type: string,
|
|
19
|
-
name: string,
|
|
20
|
-
passive: boolean,
|
|
21
|
-
): void {
|
|
22
|
-
const count = `${name}${COUNT_SUFFIX}`;
|
|
23
|
-
|
|
24
|
-
if (doc[count] != null) {
|
|
25
|
-
(doc[count] as number) += 1;
|
|
26
|
-
|
|
11
|
+
function addDelegatedHandler(doc: Document, type: string, name: string, passive: boolean): void {
|
|
12
|
+
if (DELEGATED.has(name)) {
|
|
27
13
|
return;
|
|
28
14
|
}
|
|
29
15
|
|
|
30
|
-
|
|
16
|
+
DELEGATED.add(name);
|
|
31
17
|
|
|
32
18
|
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, {
|
|
33
19
|
passive,
|
|
@@ -43,12 +29,12 @@ export function addDelegatedListener(
|
|
|
43
29
|
): RemovableEventListener {
|
|
44
30
|
target[name] ??= new Set();
|
|
45
31
|
|
|
46
|
-
target[name]
|
|
32
|
+
target[name].add(listener);
|
|
47
33
|
|
|
48
|
-
addDelegatedHandler(document
|
|
34
|
+
addDelegatedHandler(document, type, name, passive);
|
|
49
35
|
|
|
50
36
|
return () => {
|
|
51
|
-
removeDelegatedListener(target,
|
|
37
|
+
removeDelegatedListener(target, name, listener);
|
|
52
38
|
};
|
|
53
39
|
}
|
|
54
40
|
|
|
@@ -58,9 +44,19 @@ function delegatedEventHandler(this: boolean, event: Event): void {
|
|
|
58
44
|
const items = event.composedPath();
|
|
59
45
|
const {length} = items;
|
|
60
46
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
let target = items[0];
|
|
48
|
+
|
|
49
|
+
Object.defineProperties(event, {
|
|
50
|
+
currentTarget: {
|
|
51
|
+
configurable: true,
|
|
52
|
+
get() {
|
|
53
|
+
return target;
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
target: {
|
|
57
|
+
configurable: true,
|
|
58
|
+
value: target,
|
|
59
|
+
},
|
|
64
60
|
});
|
|
65
61
|
|
|
66
62
|
for (let index = 0; index < length; index += 1) {
|
|
@@ -71,10 +67,7 @@ function delegatedEventHandler(this: boolean, event: Event): void {
|
|
|
71
67
|
continue;
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
configurable: true,
|
|
76
|
-
value: item,
|
|
77
|
-
});
|
|
70
|
+
target = item;
|
|
78
71
|
|
|
79
72
|
for (const listener of listeners) {
|
|
80
73
|
(listener as EventListener).call(item, event);
|
|
@@ -102,29 +95,10 @@ export function getDelegatedName(
|
|
|
102
95
|
}
|
|
103
96
|
}
|
|
104
97
|
|
|
105
|
-
function removeDelegatedHandler(
|
|
106
|
-
doc: DocumentWithListenerCounts,
|
|
107
|
-
type: string,
|
|
108
|
-
name: string,
|
|
109
|
-
passive: boolean,
|
|
110
|
-
): void {
|
|
111
|
-
const count = `${name}${COUNT_SUFFIX}`;
|
|
112
|
-
|
|
113
|
-
(doc[count] as number) -= 1;
|
|
114
|
-
|
|
115
|
-
if ((doc[count] as number) < 1) {
|
|
116
|
-
doc[count] = undefined;
|
|
117
|
-
|
|
118
|
-
doc.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
98
|
export function removeDelegatedListener(
|
|
123
99
|
target: EventTargetWithListeners,
|
|
124
|
-
type: string,
|
|
125
100
|
name: string,
|
|
126
101
|
listener: EventListener | CustomEventListener,
|
|
127
|
-
passive: boolean,
|
|
128
102
|
): boolean {
|
|
129
103
|
const handlers = target[name];
|
|
130
104
|
|
|
@@ -138,14 +112,12 @@ export function removeDelegatedListener(
|
|
|
138
112
|
target[name] = undefined;
|
|
139
113
|
}
|
|
140
114
|
|
|
141
|
-
removeDelegatedHandler(document as DocumentWithListenerCounts, type, name, passive);
|
|
142
|
-
|
|
143
115
|
return true;
|
|
144
116
|
}
|
|
145
117
|
|
|
146
118
|
//
|
|
147
119
|
|
|
148
|
-
const
|
|
120
|
+
const DELEGATED = new Set<string>();
|
|
149
121
|
|
|
150
122
|
const EVENT_PREFIX = '@';
|
|
151
123
|
|
|
@@ -178,6 +150,6 @@ const EVENT_TYPES: Set<string> = new Set([
|
|
|
178
150
|
'touchstart',
|
|
179
151
|
]);
|
|
180
152
|
|
|
181
|
-
const HANDLER_ACTIVE
|
|
153
|
+
const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
182
154
|
|
|
183
|
-
const HANDLER_PASSIVE
|
|
155
|
+
const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
package/src/event/index.ts
CHANGED
|
@@ -151,13 +151,7 @@ export function off(
|
|
|
151
151
|
|
|
152
152
|
if (
|
|
153
153
|
delegated == null ||
|
|
154
|
-
!removeDelegatedListener(
|
|
155
|
-
target as EventTargetWithListeners,
|
|
156
|
-
type,
|
|
157
|
-
delegated,
|
|
158
|
-
listener,
|
|
159
|
-
extended.passive,
|
|
160
|
-
)
|
|
154
|
+
!removeDelegatedListener(target as EventTargetWithListeners, delegated, listener)
|
|
161
155
|
) {
|
|
162
156
|
target.removeEventListener(type, listener as EventListener, extended);
|
|
163
157
|
}
|
package/src/find/index.ts
CHANGED
package/src/find/relative.ts
CHANGED
|
@@ -1,30 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* - Get the distance between two elements _(i.e., the amount of nodes of between them)_
|
|
3
|
-
* - If the distance cannot be calculated, `-1` is returned
|
|
4
|
-
*/
|
|
5
|
-
function getDistanceBetweenElements(origin: Element, target: Element): number | undefined {
|
|
6
|
-
if (origin === target) {
|
|
7
|
-
return 0;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (origin.parentElement === target) {
|
|
11
|
-
return 1;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const children = [...(origin.parentElement?.children ?? [])];
|
|
15
|
-
|
|
16
|
-
if (children.includes(target)) {
|
|
17
|
-
return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const comparison = origin.compareDocumentPosition(target);
|
|
21
|
-
const beforeOrInside = Boolean(comparison & 2 || comparison & 8);
|
|
22
|
-
|
|
23
|
-
if (beforeOrInside || Boolean(comparison & 4 || comparison & 16)) {
|
|
24
|
-
return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
1
|
/**
|
|
29
2
|
* Find the closest ancestor element that matches the selector _(string or callback)_
|
|
30
3
|
*
|
|
@@ -74,8 +47,7 @@ export function findAncestor(
|
|
|
74
47
|
/**
|
|
75
48
|
* Finds the closest elements to the origin element that matches the selector
|
|
76
49
|
*
|
|
77
|
-
*
|
|
78
|
-
* - _(If you only want to traverse up, use {@link findAncestor})_
|
|
50
|
+
* Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
|
|
79
51
|
* @param origin Element to start from
|
|
80
52
|
* @param selector Selector to match
|
|
81
53
|
* @param context Context to search within
|
|
@@ -109,9 +81,9 @@ export function findRelatives(
|
|
|
109
81
|
|
|
110
82
|
for (let index = 0; index < length; index += 1) {
|
|
111
83
|
const element = elements[index];
|
|
112
|
-
const distance =
|
|
84
|
+
const distance = getDistance(origin, element);
|
|
113
85
|
|
|
114
|
-
if (distance
|
|
86
|
+
if (distance > 0) {
|
|
115
87
|
if (minimum == null || distance < minimum) {
|
|
116
88
|
minimum = distance;
|
|
117
89
|
}
|
|
@@ -124,17 +96,43 @@ export function findRelatives(
|
|
|
124
96
|
}
|
|
125
97
|
|
|
126
98
|
return distances
|
|
127
|
-
.filter(found => found.distance === minimum
|
|
99
|
+
.filter(found => found.distance === minimum)
|
|
128
100
|
.map(found => found.element);
|
|
129
101
|
}
|
|
130
102
|
|
|
131
|
-
|
|
132
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Get the distance between two elements _(i.e., the amount of nodes of between them)_
|
|
105
|
+
* @param origin Origin element
|
|
106
|
+
* @param target Target element
|
|
107
|
+
* @returns Distance between elements, or `-1` if distance cannot be calculated
|
|
108
|
+
*/
|
|
109
|
+
export function getDistance(origin: Element, target: Element): number {
|
|
110
|
+
if (origin === target) {
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
133
113
|
|
|
134
|
-
if (
|
|
114
|
+
if (origin.parentElement === target || target.parentElement === origin) {
|
|
135
115
|
return 1;
|
|
136
116
|
}
|
|
137
117
|
|
|
118
|
+
if (origin.parentElement != null && origin.parentElement === target.parentElement) {
|
|
119
|
+
const children = [...origin.parentElement.children];
|
|
120
|
+
|
|
121
|
+
return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const comparison = origin.compareDocumentPosition(target);
|
|
125
|
+
|
|
126
|
+
if (comparison & Node.DOCUMENT_POSITION_DISCONNECTED) {
|
|
127
|
+
return -1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
|
|
131
|
+
|
|
132
|
+
return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function traverse(from: Element, to: Element): number | undefined {
|
|
138
136
|
let current = from;
|
|
139
137
|
let distance = 0;
|
|
140
138
|
let parent: Element | null = from.parentElement;
|
|
@@ -146,11 +144,11 @@ function traverse(from: Element, to: Element): number | undefined {
|
|
|
146
144
|
|
|
147
145
|
const children = [...parent.children];
|
|
148
146
|
|
|
149
|
-
if (
|
|
147
|
+
if (to.parentElement === parent) {
|
|
150
148
|
return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
index = children.findIndex(child => child.contains(to));
|
|
151
|
+
const index = children.findIndex(child => child.contains(to));
|
|
154
152
|
|
|
155
153
|
if (index > -1) {
|
|
156
154
|
const traversed = traverse(current, children[index]);
|
|
@@ -4,4 +4,4 @@ export type EventTargetWithListeners = EventTarget & Partial<{
|
|
|
4
4
|
}>;
|
|
5
5
|
export declare function addDelegatedListener(target: EventTargetWithListeners, type: string, name: string, listener: EventListener | CustomEventListener, passive: boolean): RemovableEventListener;
|
|
6
6
|
export declare function getDelegatedName(target: EventTarget, type: string, options: AddEventListenerOptions): string | undefined;
|
|
7
|
-
export declare function removeDelegatedListener(target: EventTargetWithListeners,
|
|
7
|
+
export declare function removeDelegatedListener(target: EventTargetWithListeners, name: string, listener: EventListener | CustomEventListener): boolean;
|
package/types/find/index.d.ts
CHANGED
|
@@ -23,4 +23,4 @@ export declare function findElements(selector: Selector, context?: Selector | nu
|
|
|
23
23
|
*/
|
|
24
24
|
export declare function getElementUnderPointer(skipIgnore?: boolean): Element | null;
|
|
25
25
|
export { findElement as $, findElements as $$ };
|
|
26
|
-
export { findAncestor, findRelatives } from './relative';
|
|
26
|
+
export { findAncestor, findRelatives, getDistance } from './relative';
|
package/types/find/relative.d.ts
CHANGED
|
@@ -11,11 +11,17 @@ export declare function findAncestor(origin: Element, selector: string | ((eleme
|
|
|
11
11
|
/**
|
|
12
12
|
* Finds the closest elements to the origin element that matches the selector
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* - _(If you only want to traverse up, use {@link findAncestor})_
|
|
14
|
+
* Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
|
|
16
15
|
* @param origin Element to start from
|
|
17
16
|
* @param selector Selector to match
|
|
18
17
|
* @param context Context to search within
|
|
19
18
|
* @returns Found elements
|
|
20
19
|
*/
|
|
21
20
|
export declare function findRelatives(origin: Element, selector: string, context?: Document | Element): Element[];
|
|
21
|
+
/**
|
|
22
|
+
* Get the distance between two elements _(i.e., the amount of nodes of between them)_
|
|
23
|
+
* @param origin Origin element
|
|
24
|
+
* @param target Target element
|
|
25
|
+
* @returns Distance between elements, or `-1` if distance cannot be calculated
|
|
26
|
+
*/
|
|
27
|
+
export declare function getDistance(origin: Element, target: Element): number;
|