@oscarpalmer/toretto 0.31.0 → 0.33.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.
@@ -1,6 +1,6 @@
1
1
  import { getAttribute, getAttributes } from "./get.js";
2
2
  import { _isBadAttribute, _isBooleanAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes } from "../internal/attribute.js";
3
- import { setAttribute, setAttributes, setProperties, setProperty } from "./set.js";
3
+ import { setAttribute, setAttributes } from "./set.js";
4
4
  function isBadAttribute(first, second) {
5
5
  return _isBadAttribute(first, second, true);
6
6
  }
@@ -13,4 +13,4 @@ function isEmptyNonBooleanAttribute(first, second) {
13
13
  function isInvalidBooleanAttribute(first, second) {
14
14
  return _isInvalidBooleanAttribute(first, second, true);
15
15
  }
16
- export { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes, setProperties, setProperty };
16
+ export { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes };
@@ -1,14 +1,9 @@
1
- import { updateValue, updateValues } from "../internal/attribute.js";
2
- function setAttribute(element, first, second) {
3
- updateValue(element, first, second);
1
+ import { setElementValue, setElementValues } from "../internal/element-value.js";
2
+ import { updateAttribute } from "../internal/attribute.js";
3
+ function setAttribute(element, first, second, third) {
4
+ setElementValue(element, first, second, third, updateAttribute);
4
5
  }
5
- function setAttributes(element, attributes) {
6
- updateValues(element, attributes);
6
+ function setAttributes(element, attributes, dispatch) {
7
+ setElementValues(element, attributes, null, dispatch, updateAttribute);
7
8
  }
8
- function setProperty(element, first, second) {
9
- updateValue(element, first, second);
10
- }
11
- function setProperties(element, properties) {
12
- updateValues(element, properties);
13
- }
14
- export { setAttribute, setAttributes, setProperties, setProperty };
9
+ export { setAttribute, setAttributes };
package/dist/data.js CHANGED
@@ -24,10 +24,10 @@ function getName(original) {
24
24
  return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original).replace(EXPRESSION_DATA_PREFIX, "")}`;
25
25
  }
26
26
  function setData(element, first, second) {
27
- setElementValues(element, first, second, updateDataAttribute);
27
+ setElementValues(element, first, second, null, updateDataAttribute);
28
28
  }
29
29
  function updateDataAttribute(element, key, value) {
30
- updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, true);
30
+ updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, false, true);
31
31
  }
32
32
  var ATTRIBUTE_DATA_PREFIX = "data-";
33
33
  export { getData, setData };
@@ -1,37 +1,39 @@
1
1
  import { isEventTarget } from "../internal/is.js";
2
2
  function addDelegatedHandler(doc, type, name, passive) {
3
- const count = `${name}${COUNT_SUFFIX}`;
4
- if (doc[count] != null) {
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]?.add(listener);
9
+ target[name].add(listener);
14
10
  addDelegatedHandler(document, type, name, passive);
15
11
  return () => {
16
- removeDelegatedListener(target, type, name, listener, passive);
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
- Object.defineProperty(event, "target", {
24
- configurable: true,
25
- value: items[0]
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
- Object.defineProperty(event, "currentTarget", {
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 removeDelegatedHandler(doc, type, name, passive) {
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 COUNT_SUFFIX = ".count";
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";
@@ -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, type, delegated, listener, extended.passive)) target.removeEventListener(type, listener, extended);
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;
@@ -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 };
@@ -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 = getDistanceBetweenElements(origin, element);
35
- if (distance != null && distance > 0) {
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 && found.element !== origin).map((found) => found.element);
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 (children.includes(to)) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
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
@@ -1,12 +1,12 @@
1
1
  import { isEventTarget, isHTMLOrSVGElement } from "./internal/is.js";
2
- import { isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "./attribute/index.js";
3
2
  import { isChildNode, isInDocument } from "./is.js";
3
+ import { isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "./attribute/index.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 };
@@ -1,17 +1,17 @@
1
- import { isHTMLOrSVGElement } from "./is.js";
2
- import { getString } from "@oscarpalmer/atoms/string";
1
+ import { updateElementValue } from "./element-value.js";
3
2
  import { isPlainObject } from "@oscarpalmer/atoms/is";
4
3
  function badAttributeHandler(name, value) {
5
- if (name == null || value == null) return true;
4
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
6
5
  if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME.test(name)) return true;
7
6
  if (EXPRESSION_SKIP_NAME.test(name) || EXPRESSION_URI_VALUE.test(value) || isValidSourceAttribute(name, value)) return false;
8
7
  return EXPRESSION_DATA_OR_SCRIPT.test(value);
9
8
  }
10
9
  function booleanAttributeHandler(name, value) {
11
- if (name == null || value == null) return true;
12
- if (!booleanAttributesSet.has(name)) return false;
13
- const normalized = value.toLowerCase().trim();
14
- return !(normalized.length === 0 || normalized === name);
10
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
11
+ const normalizedName = name.toLowerCase();
12
+ if (!booleanAttributesSet.has(normalizedName)) return false;
13
+ const normalized = value.toLowerCase();
14
+ return !(normalized.length === 0 || normalized === normalizedName);
15
15
  }
16
16
  function decodeAttribute(value) {
17
17
  textArea ??= document.createElement("textarea");
@@ -32,7 +32,7 @@ function handleAttribute(callback, decode, first, second) {
32
32
  return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
33
33
  }
34
34
  function isAttribute(value) {
35
- return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
35
+ return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
36
36
  }
37
37
  function _isBadAttribute(first, second, decode) {
38
38
  return handleAttribute(badAttributeHandler, decode, first, second);
@@ -46,37 +46,21 @@ function _isEmptyNonBooleanAttribute(first, second, decode) {
46
46
  function _isInvalidBooleanAttribute(first, second, decode) {
47
47
  return handleAttribute(booleanAttributeHandler, decode, first, second);
48
48
  }
49
- function isProperty(value) {
50
- return isPlainObject(value) && typeof value.name === "string";
51
- }
52
49
  function isValidSourceAttribute(name, value) {
53
50
  return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
54
51
  }
55
- function updateAttribute(element, name, value) {
56
- const isBoolean = booleanAttributesSet.has(name.toLowerCase());
57
- if (isBoolean) updateProperty(element, name, value);
58
- if (isBoolean ? value !== true : value == null) element.removeAttribute(name);
59
- else element.setAttribute(name, isBoolean ? "" : getString(value));
60
- }
61
- function updateProperty(element, name, value) {
62
- const actual = name.toLowerCase();
63
- element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
52
+ function updateAttribute(element, name, value, dispatch) {
53
+ const normalizedName = name.toLowerCase();
54
+ const isBoolean = booleanAttributesSet.has(normalizedName);
55
+ const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
56
+ if (name in element) updateProperty(element, normalizedName, next, dispatch);
57
+ updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
64
58
  }
65
- function updateValue(element, first, second) {
66
- if (!isHTMLOrSVGElement(element)) return;
67
- if (isProperty(first)) updateAttribute(element, first.name, first.value);
68
- else if (typeof first === "string") updateAttribute(element, first, second);
69
- }
70
- function updateValues(element, values) {
71
- if (!isHTMLOrSVGElement(element)) return;
72
- const isArray = Array.isArray(values);
73
- const entries = Object.entries(values);
74
- const { length } = entries;
75
- for (let index = 0; index < length; index += 1) {
76
- const entry = entries[index];
77
- if (isArray) updateAttribute(element, entry[1].name, entry[1].value);
78
- else updateAttribute(element, entry[0], entry[1]);
79
- }
59
+ function updateProperty(element, name, value, dispatch) {
60
+ if (Object.is(element[name], value)) return;
61
+ element[name] = value;
62
+ const event = dispatch !== false && elementEvents[element.tagName]?.[name];
63
+ if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
80
64
  }
81
65
  var EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
82
66
  var EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
@@ -113,6 +97,15 @@ const booleanAttributes = Object.freeze([
113
97
  "selected"
114
98
  ]);
115
99
  var booleanAttributesSet = new Set(booleanAttributes);
100
+ var elementEvents = {
101
+ DETAILS: { open: "toggle" },
102
+ INPUT: {
103
+ checked: "change",
104
+ value: "input"
105
+ },
106
+ SELECT: { value: "change" },
107
+ TEXTAREA: { value: "input" }
108
+ };
116
109
  var formElement = document.createElement("form");
117
110
  var textArea;
118
- export { _isBadAttribute, _isBooleanAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes, isProperty, updateValue, updateValues };
111
+ export { _isBadAttribute, _isBooleanAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes, isAttribute, updateAttribute };
@@ -1,19 +1,32 @@
1
1
  import { isHTMLOrSVGElement } from "./is.js";
2
2
  import "../is.js";
3
- import { isNullableOrWhitespace, isPlainObject } from "@oscarpalmer/atoms/is";
4
- function setElementValues(element, first, second, callback) {
3
+ import { isAttribute } from "./attribute.js";
4
+ import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
5
+ function setElementValue(element, first, second, third, callback) {
5
6
  if (!isHTMLOrSVGElement(element)) return;
6
- if (isPlainObject(first)) {
7
- const entries = Object.entries(first);
8
- const { length } = entries;
9
- for (let index = 0; index < length; index += 1) {
10
- const [key, value] = entries[index];
11
- callback(element, key, value);
12
- }
13
- } else if (typeof first === "string") callback(element, first, second);
7
+ if (typeof first === "string") setElementValues(element, first, second, third, callback);
8
+ else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
14
9
  }
15
- function updateElementValue(element, key, value, set, remove, json) {
16
- if (isNullableOrWhitespace(value)) remove.call(element, key);
10
+ function setElementValues(element, first, second, third, callback) {
11
+ if (!isHTMLOrSVGElement(element)) return;
12
+ if (typeof first === "string") {
13
+ callback(element, first, second, third);
14
+ return;
15
+ }
16
+ const isArray = Array.isArray(first);
17
+ if (!isArray && !(typeof first === "object" && first !== null)) return;
18
+ const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
19
+ name,
20
+ value
21
+ }));
22
+ const { length } = entries;
23
+ for (let index = 0; index < length; index += 1) {
24
+ const entry = entries[index];
25
+ if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
26
+ }
27
+ }
28
+ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
29
+ if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
17
30
  else set.call(element, key, json ? JSON.stringify(value) : String(value));
18
31
  }
19
- export { setElementValues, updateElementValue };
32
+ export { setElementValue, setElementValues, updateElementValue };
package/dist/style.js CHANGED
@@ -23,10 +23,10 @@ function getTextDirection(element, computed) {
23
23
  return value === "rtl" ? value : "ltr";
24
24
  }
25
25
  function setStyle(element, property, value) {
26
- setElementValues(element, property, value, updateStyleProperty);
26
+ setElementValues(element, property, value, null, updateStyleProperty);
27
27
  }
28
28
  function setStyles(element, styles) {
29
- setElementValues(element, styles, null, updateStyleProperty);
29
+ setElementValues(element, styles, null, null, updateStyleProperty);
30
30
  }
31
31
  function toggleStyles(element, styles) {
32
32
  function toggle(set) {
@@ -59,7 +59,7 @@ function updateStyleProperty(element, key, value) {
59
59
  this.style[property] = style;
60
60
  }, function(property) {
61
61
  this.style[property] = "";
62
- }, false);
62
+ }, false, false);
63
63
  }
64
64
  var ATTRIBUTE_DIRECTION = "dir";
65
65
  var EXPRESSION_DIRECTION = /^(ltr|rtl)$/i;