@oscarpalmer/toretto 0.30.1 → 0.31.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,16 +1,16 @@
1
1
  import { getAttribute, getAttributes } from "./get.js";
2
- import { booleanAttributes, isBadAttribute as isBadAttribute$1, isBooleanAttribute as isBooleanAttribute$1, isEmptyNonBooleanAttribute as isEmptyNonBooleanAttribute$1, isInvalidBooleanAttribute as isInvalidBooleanAttribute$1 } from "../internal/attribute.js";
2
+ import { _isBadAttribute, _isBooleanAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes } from "../internal/attribute.js";
3
3
  import { setAttribute, setAttributes, setProperties, setProperty } from "./set.js";
4
4
  function isBadAttribute(first, second) {
5
- return isBadAttribute$1(first, second, true);
5
+ return _isBadAttribute(first, second, true);
6
6
  }
7
7
  function isBooleanAttribute(first) {
8
- return isBooleanAttribute$1(first, true);
8
+ return _isBooleanAttribute(first, true);
9
9
  }
10
10
  function isEmptyNonBooleanAttribute(first, second) {
11
- return isEmptyNonBooleanAttribute$1(first, second, true);
11
+ return _isEmptyNonBooleanAttribute(first, second, true);
12
12
  }
13
13
  function isInvalidBooleanAttribute(first, second) {
14
- return isInvalidBooleanAttribute$1(first, second, true);
14
+ return _isInvalidBooleanAttribute(first, second, true);
15
15
  }
16
16
  export { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes, setProperties, setProperty };
@@ -1,12 +1,12 @@
1
1
  import { isEventTarget } from "../internal/is.js";
2
- function addDelegatedHandler(document$1, type, name, passive) {
2
+ function addDelegatedHandler(doc, type, name, passive) {
3
3
  const count = `${name}${COUNT_SUFFIX}`;
4
- if (document$1[count] != null) {
5
- document$1[count] += 1;
4
+ if (doc[count] != null) {
5
+ doc[count] += 1;
6
6
  return;
7
7
  }
8
- document$1[count] = 1;
9
- document$1.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
8
+ doc[count] = 1;
9
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
10
10
  }
11
11
  function addDelegatedListener(target, type, name, listener, passive) {
12
12
  target[name] ??= /* @__PURE__ */ new Set();
@@ -41,12 +41,12 @@ function delegatedEventHandler(event) {
41
41
  function getDelegatedName(target, type, options) {
42
42
  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
43
  }
44
- function removeDelegatedHandler(document$1, type, name, passive) {
44
+ function removeDelegatedHandler(doc, type, name, passive) {
45
45
  const count = `${name}${COUNT_SUFFIX}`;
46
- document$1[count] -= 1;
47
- if (document$1[count] < 1) {
48
- document$1[count] = void 0;
49
- document$1.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
46
+ doc[count] -= 1;
47
+ if (doc[count] < 1) {
48
+ doc[count] = void 0;
49
+ doc.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
50
50
  }
51
51
  }
52
52
  function removeDelegatedListener(target, type, name, listener, passive) {
@@ -33,7 +33,7 @@ function findElementOrElementsFromNodes(array, context, contexts) {
33
33
  let element;
34
34
  if (node instanceof Document) element = node.body;
35
35
  else element = node instanceof Element ? node : void 0;
36
- if (element != null && (context == null || contexts.length === 0 || contexts.some((context$1) => context$1 === element || context$1.contains(element))) && !result.includes(element)) result.push(element);
36
+ if (element != null && (context == null || contexts.length === 0 || contexts.some((ctx) => ctx === element || ctx.contains(element))) && !result.includes(element)) result.push(element);
37
37
  }
38
38
  return result;
39
39
  }
@@ -1,10 +1,11 @@
1
1
  function getDistanceBetweenElements(origin, target) {
2
- if (origin === target || origin.parentElement === target) return 0;
3
- const comparison = origin.compareDocumentPosition(target);
2
+ if (origin === target) return 0;
3
+ if (origin.parentElement === target) return 1;
4
4
  const children = [...origin.parentElement?.children ?? []];
5
5
  if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
6
- const beforeOrInside = !!(comparison & 2 || comparison & 8);
7
- if (beforeOrInside || !!(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
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;
8
9
  }
9
10
  function findAncestor(origin, selector) {
10
11
  if (!(origin instanceof Element) || selector == null) return null;
@@ -23,17 +24,15 @@ function findAncestor(origin, selector) {
23
24
  }
24
25
  function findRelatives(origin, selector, context) {
25
26
  if (!(origin instanceof Element) || typeof selector !== "string") return [];
26
- if (origin.matches(selector)) return [origin];
27
27
  const elements = [...(context instanceof Document || context instanceof Element ? context : document).querySelectorAll(selector)];
28
28
  const { length } = elements;
29
- if (length === 0) return [];
30
- if (length === 1) return [elements[0]];
29
+ if (length < 2) return elements.filter((element) => element !== origin);
31
30
  const distances = [];
32
31
  let minimum;
33
32
  for (let index = 0; index < length; index += 1) {
34
33
  const element = elements[index];
35
- const distance = getDistanceBetweenElements(origin, element) ?? -1;
36
- if (distance > -1) {
34
+ const distance = getDistanceBetweenElements(origin, element);
35
+ if (distance != null && distance > 0) {
37
36
  if (minimum == null || distance < minimum) minimum = distance;
38
37
  distances.push({
39
38
  distance,
@@ -41,22 +40,22 @@ function findRelatives(origin, selector, context) {
41
40
  });
42
41
  }
43
42
  }
44
- return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
43
+ return distances.filter((found) => found.distance === minimum && found.element !== origin).map((found) => found.element);
45
44
  }
46
45
  function traverse(from, to) {
47
46
  let index = [...to.children].indexOf(from);
48
- if (index > -1) return index + 1;
47
+ if (index > -1) return 1;
49
48
  let current = from;
50
49
  let distance = 0;
51
50
  let parent = from.parentElement;
52
51
  while (parent != null) {
53
52
  if (parent === to) return distance + 1;
54
- const children = [...parent.children ?? []];
53
+ const children = [...parent.children];
55
54
  if (children.includes(to)) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
56
55
  index = children.findIndex((child) => child.contains(to));
57
56
  if (index > -1) {
58
- const traversed = traverse(current, children[index]) ?? -1;
59
- return traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
57
+ const traversed = traverse(current, children[index]);
58
+ return traversed == null || traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
60
59
  }
61
60
  current = parent;
62
61
  distance += 1;
@@ -1,10 +1,10 @@
1
1
  import { sanitizeNodes } from "./sanitize.js";
2
2
  import { isPlainObject } from "@oscarpalmer/atoms/is";
3
3
  function createHtml(value) {
4
- const html$1 = getParser().parseFromString(typeof value === "string" ? value : value.innerHTML, HTML_PARSE_TYPE);
5
- html$1.body.normalize();
6
- sanitizeNodes([html$1.body], 0);
7
- return html$1.body.innerHTML;
4
+ const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
5
+ parsed.body.normalize();
6
+ sanitizeNodes([parsed.body], 0);
7
+ return parsed.body.innerHTML;
8
8
  }
9
9
  function createTemplate(value, options) {
10
10
  const template = document.createElement(TEMPLATE_TAG);
@@ -12,6 +12,9 @@ function createTemplate(value, options) {
12
12
  if (typeof value === "string" && options.cache) templates[value] = template;
13
13
  return template;
14
14
  }
15
+ function getHtml(value) {
16
+ return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
17
+ }
15
18
  function getNodes(value, options) {
16
19
  if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
17
20
  const template = getTemplate(value, options);
@@ -28,12 +31,11 @@ function getParser() {
28
31
  }
29
32
  function getTemplate(value, options) {
30
33
  if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
31
- if (typeof value !== "string" || value.trim().length === 0) return;
34
+ if (value.trim().length === 0) return;
32
35
  let template = templates[value];
33
36
  if (template != null) return template;
34
37
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
35
- template = element instanceof HTMLTemplateElement ? element : createTemplate(value, options);
36
- return template;
38
+ return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
37
39
  }
38
40
  var html = ((value, options) => {
39
41
  return getNodes(value, getOptions(options));
@@ -56,8 +58,9 @@ function sanitize(value) {
56
58
  return sanitizeNodes(Array.isArray(value) ? value : [value], 0);
57
59
  }
58
60
  var EXPRESSION_ID = /^[a-z][\w-]*$/i;
59
- var HTML_PARSE_TYPE = "text/html";
61
+ var PARSE_TYPE_HTML = "text/html";
60
62
  var TEMPLATE_TAG = "template";
63
+ var TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
61
64
  var parser;
62
65
  var templates = {};
63
66
  export { html, sanitize };
@@ -1,25 +1,24 @@
1
- import { isBadAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "../internal/attribute.js";
1
+ import { _isBadAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute } from "../internal/attribute.js";
2
+ import { setAttribute } from "../attribute/set.js";
2
3
  function handleElement(element, depth) {
3
- if (isClobbered(element)) {
4
- element.remove();
5
- return true;
6
- }
7
4
  if (depth === 0) {
8
- const scripts = element.querySelectorAll("script");
9
- for (const script of scripts) script.remove();
5
+ const removable = element.querySelectorAll(REMOVE_SELECTOR);
6
+ for (const item of removable) item.remove();
10
7
  }
11
8
  sanitizeAttributes(element, [...element.attributes]);
12
- return false;
13
9
  }
14
- function isClobbered(element) {
15
- return element instanceof HTMLFormElement && (typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function");
10
+ function isClobbered(value) {
11
+ return value instanceof HTMLFormElement && (typeof value.nodeName !== "string" || typeof value.textContent !== "string" || typeof value.removeChild !== "function" || !(value.attributes instanceof NamedNodeMap) || typeof value.removeAttribute !== "function" || typeof value.setAttribute !== "function" || typeof value.namespaceURI !== "string" || typeof value.insertBefore !== "function" || typeof value.hasChildNodes !== "function");
12
+ }
13
+ function removeNode(node) {
14
+ if (typeof node.remove === "function") node.remove();
16
15
  }
17
16
  function sanitizeAttributes(element, attributes) {
18
17
  const { length } = attributes;
19
18
  for (let index = 0; index < length; index += 1) {
20
19
  const { name, value } = attributes[index];
21
- if (isBadAttribute(name, value, false) || isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
22
- else if (isInvalidBooleanAttribute(name, value, false)) element.setAttribute(name, "");
20
+ if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
21
+ else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
23
22
  }
24
23
  }
25
24
  function sanitizeNodes(nodes, depth) {
@@ -27,14 +26,30 @@ function sanitizeNodes(nodes, depth) {
27
26
  let { length } = nodes;
28
27
  for (let index = 0; index < length; index += 1) {
29
28
  const node = actual[index];
30
- if (node instanceof Element && handleElement(node, depth)) {
29
+ let remove = isClobbered(node);
30
+ if (!remove) switch (node.nodeType) {
31
+ case Node.ELEMENT_NODE:
32
+ handleElement(node, depth);
33
+ break;
34
+ case Node.COMMENT_NODE:
35
+ remove = COMMENT_HARMFUL.test(node.data);
36
+ break;
37
+ case Node.DOCUMENT_TYPE_NODE:
38
+ case Node.PROCESSING_INSTRUCTION_NODE:
39
+ remove = true;
40
+ break;
41
+ }
42
+ if (remove) {
43
+ removeNode(node);
31
44
  actual.splice(index, 1);
32
- length -= 1;
33
45
  index -= 1;
46
+ length -= 1;
34
47
  continue;
35
48
  }
36
49
  if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
37
50
  }
38
51
  return nodes;
39
52
  }
53
+ var COMMENT_HARMFUL = /<[/\w]/g;
54
+ var REMOVE_SELECTOR = "script, toretto-temporary";
40
55
  export { sanitizeAttributes, sanitizeNodes };
@@ -34,16 +34,16 @@ function handleAttribute(callback, decode, first, second) {
34
34
  function isAttribute(value) {
35
35
  return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
36
36
  }
37
- function isBadAttribute(first, second, decode) {
37
+ function _isBadAttribute(first, second, decode) {
38
38
  return handleAttribute(badAttributeHandler, decode, first, second);
39
39
  }
40
- function isBooleanAttribute(first, decode) {
40
+ function _isBooleanAttribute(first, decode) {
41
41
  return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
42
42
  }
43
- function isEmptyNonBooleanAttribute(first, second, decode) {
43
+ function _isEmptyNonBooleanAttribute(first, second, decode) {
44
44
  return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
45
45
  }
46
- function isInvalidBooleanAttribute(first, second, decode) {
46
+ function _isInvalidBooleanAttribute(first, second, decode) {
47
47
  return handleAttribute(booleanAttributeHandler, decode, first, second);
48
48
  }
49
49
  function isProperty(value) {
@@ -115,4 +115,4 @@ const booleanAttributes = Object.freeze([
115
115
  var booleanAttributesSet = new Set(booleanAttributes);
116
116
  var formElement = document.createElement("form");
117
117
  var textArea;
118
- export { booleanAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, isProperty, updateValue, updateValues };
118
+ export { _isBadAttribute, _isBooleanAttribute, _isEmptyNonBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes, isProperty, updateValue, updateValues };
package/dist/is.js CHANGED
@@ -2,10 +2,10 @@ import { isEventTarget, isHTMLOrSVGElement } from "./internal/is.js";
2
2
  function isChildNode(value) {
3
3
  return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
4
4
  }
5
- function isInDocument(node, document) {
5
+ function isInDocument(node, doc) {
6
6
  if (!(node instanceof Node)) return false;
7
- if (!(document instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
8
- return node.ownerDocument == null ? node === document : node.ownerDocument === document && document.contains(node);
7
+ if (!(doc instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
8
+ return node.ownerDocument == null ? node === doc : node.ownerDocument === doc && doc.contains(node);
9
9
  }
10
10
  var CHILD_NODE_TYPES = new Set([
11
11
  Node.ELEMENT_NODE,
package/dist/style.js CHANGED
@@ -55,8 +55,8 @@ function toggleStyles(element, styles) {
55
55
  };
56
56
  }
57
57
  function updateStyleProperty(element, key, value) {
58
- updateElementValue(element, key, value, function(property, value$1) {
59
- this.style[property] = value$1;
58
+ updateElementValue(element, key, value, function(property, style) {
59
+ this.style[property] = style;
60
60
  }, function(property) {
61
61
  this.style[property] = "";
62
62
  }, false);