@oscarpalmer/toretto 0.30.0 → 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.
@@ -9,10 +9,7 @@ function getSupport() {
9
9
  if (typeof navigator.msMaxTouchPoints === "number" && navigator.msMaxTouchPoints > 0) return true;
10
10
  return false;
11
11
  }
12
- /**
13
- * Does the device support touch events?
14
- */
15
- const supportsTouch = (() => {
12
+ var touch_default = (() => {
16
13
  let support = getSupport();
17
14
  const instance = Object.create({
18
15
  get() {
@@ -28,15 +25,13 @@ const supportsTouch = (() => {
28
25
  } });
29
26
  return instance;
30
27
  })();
31
- var touch_default = supportsTouch;
32
-
33
28
  function isPlainObject(value) {
34
29
  if (value === null || typeof value !== "object") return false;
35
30
  if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
36
31
  const prototype = Object.getPrototypeOf(value);
37
32
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
38
33
  }
39
- var TYPED_ARRAYS = new Set([
34
+ new Set([
40
35
  Int8Array,
41
36
  Uint8Array,
42
37
  Uint8ClampedArray,
@@ -49,7 +44,6 @@ var TYPED_ARRAYS = new Set([
49
44
  BigInt64Array,
50
45
  BigUint64Array
51
46
  ]);
52
-
53
47
  function compact(array, strict) {
54
48
  if (!Array.isArray(array)) return [];
55
49
  const { length } = array;
@@ -61,7 +55,6 @@ function compact(array, strict) {
61
55
  }
62
56
  return compacted;
63
57
  }
64
-
65
58
  function getString(value) {
66
59
  if (typeof value === "string") return value;
67
60
  if (value == null) return "";
@@ -77,12 +70,10 @@ function words(value) {
77
70
  return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
78
71
  }
79
72
  var EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
80
-
81
73
  function isNullableOrWhitespace(value) {
82
74
  return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
83
75
  }
84
76
  var EXPRESSION_WHITESPACE$1 = /^\s*$/;
85
-
86
77
  function camelCase(value) {
87
78
  return toCase(value, "", true, false);
88
79
  }
@@ -117,7 +108,6 @@ function toCase(value, delimiter, capitalizeAny, capitalizeFirst) {
117
108
  }
118
109
  var EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
119
110
  var EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
120
-
121
111
  function parse(value, reviver) {
122
112
  try {
123
113
  return JSON.parse(value, reviver);
@@ -125,24 +115,12 @@ function parse(value, reviver) {
125
115
  return;
126
116
  }
127
117
  }
128
-
129
- /**
130
- * Is the value an event target?
131
- * @param value Value to check
132
- * @returns `true` if it's an event target, otherwise `false`
133
- */
134
118
  function isEventTarget(value) {
135
119
  return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
136
120
  }
137
- /**
138
- * Is the value an HTML or SVG element?
139
- * @param value Value to check
140
- * @returns `true` if it's an HTML or SVG element, otherwise `false`
141
- */
142
121
  function isHTMLOrSVGElement(value) {
143
122
  return value instanceof HTMLElement || value instanceof SVGElement;
144
123
  }
145
-
146
124
  function badAttributeHandler(name, value) {
147
125
  if (name == null || value == null) return true;
148
126
  if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME.test(name)) return true;
@@ -176,21 +154,39 @@ function handleAttribute(callback, decode, first, second) {
176
154
  function isAttribute(value) {
177
155
  return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
178
156
  }
179
- function isBadAttribute$1(first, second, decode) {
157
+ function _isBadAttribute(first, second, decode) {
180
158
  return handleAttribute(badAttributeHandler, decode, first, second);
181
159
  }
182
- function isBooleanAttribute$1(first, decode) {
160
+ function _isBooleanAttribute(first, decode) {
183
161
  return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
184
162
  }
185
- function isEmptyNonBooleanAttribute$1(first, second, decode) {
163
+ function _isEmptyNonBooleanAttribute(first, second, decode) {
186
164
  return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
187
165
  }
188
- function isInvalidBooleanAttribute$1(first, second, decode) {
166
+ function _isInvalidBooleanAttribute(first, second, decode) {
189
167
  return handleAttribute(booleanAttributeHandler, decode, first, second);
190
168
  }
169
+ function isProperty(value) {
170
+ return isPlainObject(value) && typeof value.name === "string";
171
+ }
191
172
  function isValidSourceAttribute(name, value) {
192
173
  return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
193
174
  }
175
+ function updateAttribute(element, name, value) {
176
+ const isBoolean = booleanAttributesSet.has(name.toLowerCase());
177
+ if (isBoolean) updateProperty(element, name, value);
178
+ if (isBoolean ? value !== true : value == null) element.removeAttribute(name);
179
+ else element.setAttribute(name, isBoolean ? "" : getString(value));
180
+ }
181
+ function updateProperty(element, name, value) {
182
+ const actual = name.toLowerCase();
183
+ element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
184
+ }
185
+ function updateValue(element, first, second) {
186
+ if (!isHTMLOrSVGElement(element)) return;
187
+ if (isProperty(first)) updateAttribute(element, first.name, first.value);
188
+ else if (typeof first === "string") updateAttribute(element, first, second);
189
+ }
194
190
  const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
195
191
  const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
196
192
  const EXPRESSION_EVENT_NAME = /^on/i;
@@ -199,9 +195,6 @@ const EXPRESSION_SOURCE_NAME = /^src$/i;
199
195
  const EXPRESSION_SOURCE_VALUE = /^data:/i;
200
196
  const EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
201
197
  const EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
202
- /**
203
- * List of boolean attributes
204
- */
205
198
  const booleanAttributes = Object.freeze([
206
199
  "async",
207
200
  "autofocus",
@@ -231,7 +224,6 @@ const booleanAttributes = Object.freeze([
231
224
  const booleanAttributesSet = new Set(booleanAttributes);
232
225
  const formElement = document.createElement("form");
233
226
  let textArea;
234
-
235
227
  function getBoolean(value, defaultValue) {
236
228
  return typeof value === "boolean" ? value : defaultValue ?? false;
237
229
  }
@@ -240,32 +232,28 @@ function getStyleValue(element, property, computed) {
240
232
  return computed ? getComputedStyle(element)[name] : element.style[name];
241
233
  }
242
234
  const EXPRESSION_DATA_PREFIX = /^data-/i;
243
-
235
+ function setAttribute(element, first, second) {
236
+ updateValue(element, first, second);
237
+ }
244
238
  function isBadAttribute(first, second) {
245
- return isBadAttribute$1(first, second, true);
239
+ return _isBadAttribute(first, second, true);
246
240
  }
247
241
  function isBooleanAttribute(first) {
248
- return isBooleanAttribute$1(first, true);
242
+ return _isBooleanAttribute(first, true);
249
243
  }
250
244
  function isEmptyNonBooleanAttribute(first, second) {
251
- return isEmptyNonBooleanAttribute$1(first, second, true);
245
+ return _isEmptyNonBooleanAttribute(first, second, true);
252
246
  }
253
247
  function isInvalidBooleanAttribute(first, second) {
254
- return isInvalidBooleanAttribute$1(first, second, true);
255
- }
256
-
257
- /**
258
- * Is the value a child node?
259
- * @param value Value to check
260
- * @returns `true` if it's a child node, otherwise `false`
261
- */
248
+ return _isInvalidBooleanAttribute(first, second, true);
249
+ }
262
250
  function isChildNode(value) {
263
251
  return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
264
252
  }
265
- function isInDocument(node, document$1) {
253
+ function isInDocument(node, doc) {
266
254
  if (!(node instanceof Node)) return false;
267
- if (!(document$1 instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
268
- return node.ownerDocument == null ? node === document$1 : node.ownerDocument === document$1 && document$1.contains(node);
255
+ if (!(doc instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
256
+ return node.ownerDocument == null ? node === doc : node.ownerDocument === doc && doc.contains(node);
269
257
  }
270
258
  const CHILD_NODE_TYPES = new Set([
271
259
  Node.ELEMENT_NODE,
@@ -274,7 +262,6 @@ const CHILD_NODE_TYPES = new Set([
274
262
  Node.COMMENT_NODE,
275
263
  Node.DOCUMENT_TYPE_NODE
276
264
  ]);
277
-
278
265
  function setElementValues(element, first, second, callback) {
279
266
  if (!isHTMLOrSVGElement(element)) return;
280
267
  if (isPlainObject(first)) {
@@ -290,7 +277,6 @@ function updateElementValue(element, key, value, set, remove, json) {
290
277
  if (isNullableOrWhitespace(value)) remove.call(element, key);
291
278
  else set.call(element, key, json ? JSON.stringify(value) : String(value));
292
279
  }
293
-
294
280
  function getData(element, keys, parseValues) {
295
281
  if (!isHTMLOrSVGElement(element)) return;
296
282
  const shouldParse = parseValues !== false;
@@ -319,7 +305,6 @@ function updateDataAttribute(element, key, value) {
319
305
  updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, true);
320
306
  }
321
307
  const ATTRIBUTE_DATA_PREFIX = "data-";
322
-
323
308
  function calculate() {
324
309
  return new Promise((resolve) => {
325
310
  const values = [];
@@ -336,19 +321,15 @@ function calculate() {
336
321
  function noop() {}
337
322
  var CALCULATION_TOTAL = 10;
338
323
  var CALCULATION_TRIM = 4;
339
- let milliseconds = 1e3 / 60;
340
- calculate().then((value) => {
341
- milliseconds = value;
342
- });
343
-
344
- function addDelegatedHandler(document$1, type, name, passive) {
324
+ calculate().then((value) => {});
325
+ function addDelegatedHandler(doc, type, name, passive) {
345
326
  const count = `${name}${COUNT_SUFFIX}`;
346
- if (document$1[count] != null) {
347
- document$1[count] += 1;
327
+ if (doc[count] != null) {
328
+ doc[count] += 1;
348
329
  return;
349
330
  }
350
- document$1[count] = 1;
351
- document$1.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
331
+ doc[count] = 1;
332
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
352
333
  }
353
334
  function addDelegatedListener(target, type, name, listener, passive) {
354
335
  target[name] ??= /* @__PURE__ */ new Set();
@@ -383,12 +364,12 @@ function delegatedEventHandler(event) {
383
364
  function getDelegatedName(target, type, options) {
384
365
  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}`;
385
366
  }
386
- function removeDelegatedHandler(document$1, type, name, passive) {
367
+ function removeDelegatedHandler(doc, type, name, passive) {
387
368
  const count = `${name}${COUNT_SUFFIX}`;
388
- document$1[count] -= 1;
389
- if (document$1[count] < 1) {
390
- document$1[count] = void 0;
391
- document$1.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
369
+ doc[count] -= 1;
370
+ if (doc[count] < 1) {
371
+ doc[count] = void 0;
372
+ doc.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
392
373
  }
393
374
  }
394
375
  function removeDelegatedListener(target, type, name, listener, passive) {
@@ -429,7 +410,6 @@ const EVENT_TYPES = new Set([
429
410
  ]);
430
411
  const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
431
412
  const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
432
-
433
413
  function createDispatchOptions(options) {
434
414
  return {
435
415
  bubbles: getBoolean(options?.bubbles, true),
@@ -456,11 +436,6 @@ function createEventOptions(options) {
456
436
  function dispatch(target, type, options) {
457
437
  if (isEventTarget(target) && typeof type === "string") target.dispatchEvent(createEvent(type, options));
458
438
  }
459
- /**
460
- * Get the X- and Y-coordinates from a pointer event
461
- * @param event Pointer event
462
- * @returns X- and Y-coordinates
463
- */
464
439
  function getPosition(event) {
465
440
  let x;
466
441
  let y;
@@ -476,13 +451,6 @@ function getPosition(event) {
476
451
  y
477
452
  } : void 0;
478
453
  }
479
- /**
480
- * Remove an event listener
481
- * @param target Event target
482
- * @param type Type of event
483
- * @param listener Event listener
484
- * @param options Options for event
485
- */
486
454
  function off(target, type, listener, options) {
487
455
  if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return;
488
456
  const extended = createEventOptions(options);
@@ -501,28 +469,15 @@ function on(target, type, listener, options) {
501
469
  };
502
470
  }
503
471
  const PROPERTY_DETAIL = "detail";
504
-
505
- /**
506
- * - Get the distance between two elements _(i.e., the amount of nodes of between them)_
507
- * - If the distance cannot be calculated, `-1` is returned
508
- */
509
472
  function getDistanceBetweenElements(origin, target) {
510
- if (origin === target || origin.parentElement === target) return 0;
511
- const comparison = origin.compareDocumentPosition(target);
473
+ if (origin === target) return 0;
474
+ if (origin.parentElement === target) return 1;
512
475
  const children = [...origin.parentElement?.children ?? []];
513
476
  if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
514
- const beforeOrInside = !!(comparison & 2 || comparison & 8);
515
- if (beforeOrInside || !!(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
516
- }
517
- /**
518
- * Find the closest ancestor element that matches the selector _(string or callback)_
519
- *
520
- * - If no match is found, `null` is returned
521
- * - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
522
- * @param origin Element to start from
523
- * @param selector Selector to match
524
- * @returns Found ancestor or `null`
525
- */
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
+ }
526
481
  function findAncestor(origin, selector) {
527
482
  if (!(origin instanceof Element) || selector == null) return null;
528
483
  if (typeof selector === "string") {
@@ -538,29 +493,17 @@ function findAncestor(origin, selector) {
538
493
  }
539
494
  return parent;
540
495
  }
541
- /**
542
- * Finds the closest elements to the origin element that matches the selector
543
- *
544
- * - Traverses up, down, and sideways in the _DOM_-tree
545
- * - _(If you only want to traverse up, use {@link findAncestor})_
546
- * @param origin Element to start from
547
- * @param selector Selector to match
548
- * @param context Context to search within
549
- * @returns Found elements
550
- */
551
496
  function findRelatives(origin, selector, context) {
552
497
  if (!(origin instanceof Element) || typeof selector !== "string") return [];
553
- if (origin.matches(selector)) return [origin];
554
498
  const elements = [...(context instanceof Document || context instanceof Element ? context : document).querySelectorAll(selector)];
555
499
  const { length } = elements;
556
- if (length === 0) return [];
557
- if (length === 1) return [elements[0]];
500
+ if (length < 2) return elements.filter((element) => element !== origin);
558
501
  const distances = [];
559
502
  let minimum;
560
503
  for (let index = 0; index < length; index += 1) {
561
504
  const element = elements[index];
562
- const distance = getDistanceBetweenElements(origin, element) ?? -1;
563
- if (distance > -1) {
505
+ const distance = getDistanceBetweenElements(origin, element);
506
+ if (distance != null && distance > 0) {
564
507
  if (minimum == null || distance < minimum) minimum = distance;
565
508
  distances.push({
566
509
  distance,
@@ -568,35 +511,28 @@ function findRelatives(origin, selector, context) {
568
511
  });
569
512
  }
570
513
  }
571
- return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
514
+ return distances.filter((found) => found.distance === minimum && found.element !== origin).map((found) => found.element);
572
515
  }
573
516
  function traverse(from, to) {
574
517
  let index = [...to.children].indexOf(from);
575
- if (index > -1) return index + 1;
518
+ if (index > -1) return 1;
576
519
  let current = from;
577
520
  let distance = 0;
578
521
  let parent = from.parentElement;
579
522
  while (parent != null) {
580
523
  if (parent === to) return distance + 1;
581
- const children = [...parent.children ?? []];
524
+ const children = [...parent.children];
582
525
  if (children.includes(to)) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
583
526
  index = children.findIndex((child) => child.contains(to));
584
527
  if (index > -1) {
585
- const traversed = traverse(current, children[index]) ?? -1;
586
- return traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
528
+ const traversed = traverse(current, children[index]);
529
+ return traversed == null || traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
587
530
  }
588
531
  current = parent;
589
532
  distance += 1;
590
533
  parent = parent.parentElement;
591
534
  }
592
535
  }
593
-
594
- /**
595
- * Find the first element that matches the selector
596
- * @param selector Selector to find element for
597
- * @param context Context to search within _(defaults to `document`)_
598
- * @returns Found element or `null`
599
- */
600
536
  function findElement(selector, context) {
601
537
  return findElementOrElements(selector, context, true);
602
538
  }
@@ -631,27 +567,13 @@ function findElementOrElementsFromNodes(array, context, contexts) {
631
567
  let element;
632
568
  if (node instanceof Document) element = node.body;
633
569
  else element = node instanceof Element ? node : void 0;
634
- 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);
570
+ if (element != null && (context == null || contexts.length === 0 || contexts.some((ctx) => ctx === element || ctx.contains(element))) && !result.includes(element)) result.push(element);
635
571
  }
636
572
  return result;
637
573
  }
638
- /**
639
- * Find elements that match the selector
640
- * @param selector Selector to find elements for
641
- * @param context Context to search within _(defaults to `document`)_
642
- * @returns Found elements
643
- */
644
574
  function findElements(selector, context) {
645
575
  return findElementOrElements(selector, context, false);
646
576
  }
647
- /**
648
- * Get the most specific element under the pointer
649
- *
650
- * - Ignores elements with `pointer-events: none` and `visibility: hidden`
651
- * - _(If `skipIgnore` is `true`, no elements are ignored)_
652
- * @param skipIgnore Skip ignored elements?
653
- * @returns Found element or `null`
654
- */
655
577
  function getElementUnderPointer(skipIgnore) {
656
578
  const elements = [...document.querySelectorAll(SUFFIX_HOVER)];
657
579
  const { length } = elements;
@@ -673,12 +595,6 @@ const STYLE_HIDDEN$1 = "hidden";
673
595
  const STYLE_NONE$1 = "none";
674
596
  const SUFFIX_HOVER = ":hover";
675
597
  const TAG_HEAD = "HEAD";
676
-
677
- /**
678
- * Get a list of focusable elements within a parent element
679
- * @param parent Parent element
680
- * @returns Focusable elements
681
- */
682
598
  function getFocusable(parent) {
683
599
  return getValidElements(parent, FILTERS_FOCUSABLE, false);
684
600
  }
@@ -688,11 +604,6 @@ function getItem(element, tabbable) {
688
604
  tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
689
605
  };
690
606
  }
691
- /**
692
- * Get a list of tabbable elements within a parent element
693
- * @param parent Parent element
694
- * @returns Tabbable elements
695
- */
696
607
  function getTabbable(parent) {
697
608
  return getValidElements(parent, FILTERS_TABBABLE, true);
698
609
  }
@@ -747,11 +658,6 @@ function isDisabledFromFieldset(element) {
747
658
  function isEditable(element) {
748
659
  return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
749
660
  }
750
- /**
751
- * Is the element focusable?
752
- * @param element Element to check
753
- * @returns `true` if focusable, otherwise `false`
754
- */
755
661
  function isFocusable(element) {
756
662
  return element instanceof Element ? isValidElement(element, FILTERS_FOCUSABLE, false) : false;
757
663
  }
@@ -782,11 +688,6 @@ function isNotTabbableRadio(item) {
782
688
  function isSummarised(item) {
783
689
  return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
784
690
  }
785
- /**
786
- * Is the element tabbable?
787
- * @param element Element to check
788
- * @returns `true` if tabbable, otherwise `false`
789
- */
790
691
  function isTabbable(element) {
791
692
  return element instanceof Element ? isValidElement(element, FILTERS_TABBABLE, true) : false;
792
693
  }
@@ -835,33 +736,25 @@ const STYLE_NONE = "none";
835
736
  const TABINDEX_BASE = 0;
836
737
  const TABINDEX_DEFAULT = -1;
837
738
  const TYPE_RADIO = "radio";
838
-
839
739
  function handleElement(element, depth) {
840
- if (isClobbered(element)) {
841
- element.remove();
842
- return true;
843
- }
844
740
  if (depth === 0) {
845
- const scripts = element.querySelectorAll("script");
846
- for (const script of scripts) script.remove();
741
+ const removable = element.querySelectorAll(REMOVE_SELECTOR);
742
+ for (const item of removable) item.remove();
847
743
  }
848
744
  sanitizeAttributes(element, [...element.attributes]);
849
- return false;
850
745
  }
851
- /**
852
- * Is the element clobbered?
853
- *
854
- * Thanks, DOMPurify _(https://github.com/cure53/DOMPurify)_
855
- */
856
- function isClobbered(element) {
857
- 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");
746
+ function isClobbered(value) {
747
+ 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");
748
+ }
749
+ function removeNode(node) {
750
+ if (typeof node.remove === "function") node.remove();
858
751
  }
859
752
  function sanitizeAttributes(element, attributes) {
860
753
  const { length } = attributes;
861
754
  for (let index = 0; index < length; index += 1) {
862
755
  const { name, value } = attributes[index];
863
- if (isBadAttribute$1(name, value, false) || isEmptyNonBooleanAttribute$1(name, value, false)) element.removeAttribute(name);
864
- else if (isInvalidBooleanAttribute$1(name, value, false)) element.setAttribute(name, "");
756
+ if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
757
+ else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
865
758
  }
866
759
  }
867
760
  function sanitizeNodes(nodes, depth) {
@@ -869,22 +762,37 @@ function sanitizeNodes(nodes, depth) {
869
762
  let { length } = nodes;
870
763
  for (let index = 0; index < length; index += 1) {
871
764
  const node = actual[index];
872
- if (node instanceof Element && handleElement(node, depth)) {
765
+ let remove = isClobbered(node);
766
+ if (!remove) switch (node.nodeType) {
767
+ case Node.ELEMENT_NODE:
768
+ handleElement(node, depth);
769
+ break;
770
+ case Node.COMMENT_NODE:
771
+ remove = COMMENT_HARMFUL.test(node.data);
772
+ break;
773
+ case Node.DOCUMENT_TYPE_NODE:
774
+ case Node.PROCESSING_INSTRUCTION_NODE:
775
+ remove = true;
776
+ break;
777
+ }
778
+ if (remove) {
779
+ removeNode(node);
873
780
  actual.splice(index, 1);
874
- length -= 1;
875
781
  index -= 1;
782
+ length -= 1;
876
783
  continue;
877
784
  }
878
785
  if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
879
786
  }
880
787
  return nodes;
881
788
  }
882
-
789
+ const COMMENT_HARMFUL = /<[/\w]/g;
790
+ const REMOVE_SELECTOR = "script, toretto-temporary";
883
791
  function createHtml(value) {
884
- const html$1 = getParser().parseFromString(typeof value === "string" ? value : value.innerHTML, HTML_PARSE_TYPE);
885
- html$1.body.normalize();
886
- sanitizeNodes([html$1.body], 0);
887
- return html$1.body.innerHTML;
792
+ const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
793
+ parsed.body.normalize();
794
+ sanitizeNodes([parsed.body], 0);
795
+ return parsed.body.innerHTML;
888
796
  }
889
797
  function createTemplate(value, options) {
890
798
  const template = document.createElement(TEMPLATE_TAG);
@@ -892,6 +800,9 @@ function createTemplate(value, options) {
892
800
  if (typeof value === "string" && options.cache) templates[value] = template;
893
801
  return template;
894
802
  }
803
+ function getHtml(value) {
804
+ return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
805
+ }
895
806
  function getNodes(value, options) {
896
807
  if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
897
808
  const template = getTemplate(value, options);
@@ -908,12 +819,11 @@ function getParser() {
908
819
  }
909
820
  function getTemplate(value, options) {
910
821
  if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
911
- if (typeof value !== "string" || value.trim().length === 0) return;
822
+ if (value.trim().length === 0) return;
912
823
  let template = templates[value];
913
824
  if (template != null) return template;
914
825
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
915
- template = element instanceof HTMLTemplateElement ? element : createTemplate(value, options);
916
- return template;
826
+ return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
917
827
  }
918
828
  const html = ((value, options) => {
919
829
  return getNodes(value, getOptions(options));
@@ -932,39 +842,19 @@ html.remove = (template) => {
932
842
  }
933
843
  templates = updated;
934
844
  };
935
- /**
936
- * Sanitize one or more nodes, recursively
937
- * @param value Node or nodes to sanitize
938
- * @param options Sanitization options
939
- * @returns Sanitized nodes
940
- */
941
845
  function sanitize(value) {
942
846
  return sanitizeNodes(Array.isArray(value) ? value : [value], 0);
943
847
  }
944
848
  const EXPRESSION_ID = /^[a-z][\w-]*$/i;
945
- const HTML_PARSE_TYPE = "text/html";
849
+ const PARSE_TYPE_HTML = "text/html";
946
850
  const TEMPLATE_TAG = "template";
851
+ const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
947
852
  let parser;
948
853
  let templates = {};
949
-
950
- /**
951
- * Get a style from an element
952
- * @param element Element to get the style from
953
- * @param property Style name
954
- * @param computed Get the computed style? _(defaults to `false`)_
955
- * @returns Style value
956
- */
957
854
  function getStyle(element, property, computed) {
958
855
  if (!isHTMLOrSVGElement(element) || typeof property !== "string") return;
959
856
  return getStyleValue(element, property, computed === true);
960
857
  }
961
- /**
962
- * Get styles from an element
963
- * @param element Element to get the styles from
964
- * @param properties Styles to get
965
- * @param computed Get the computed styles? _(defaults to `false`)_
966
- * @returns Style values
967
- */
968
858
  function getStyles(element, properties, computed) {
969
859
  const styles = {};
970
860
  if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
@@ -975,12 +865,6 @@ function getStyles(element, properties, computed) {
975
865
  }
976
866
  return styles;
977
867
  }
978
- /**
979
- * Get the text direction of an element
980
- * @param element Element to get the text direction from
981
- * @param computed Get the computed text direction? _(defaults to `false`)_
982
- * @returns Text direction
983
- */
984
868
  function getTextDirection(element, computed) {
985
869
  if (!(element instanceof Element)) return;
986
870
  const direction = element.getAttribute(ATTRIBUTE_DIRECTION);
@@ -988,29 +872,12 @@ function getTextDirection(element, computed) {
988
872
  const value = getStyleValue(element, "direction", computed === true);
989
873
  return value === "rtl" ? value : "ltr";
990
874
  }
991
- /**
992
- * Set a style on an element
993
- * @param element Element to set the style on
994
- * @param property Style name
995
- * @param value Style value
996
- */
997
875
  function setStyle(element, property, value) {
998
876
  setElementValues(element, property, value, updateStyleProperty);
999
877
  }
1000
- /**
1001
- * Set styles on an element
1002
- * @param element Element to set the styles on
1003
- * @param styles Styles to set
1004
- */
1005
878
  function setStyles(element, styles) {
1006
879
  setElementValues(element, styles, null, updateStyleProperty);
1007
880
  }
1008
- /**
1009
- * Toggle styles for an element
1010
- * @param element Element to style
1011
- * @param styles Styles to be set or removed
1012
- * @returns Style toggler
1013
- */
1014
881
  function toggleStyles(element, styles) {
1015
882
  function toggle(set) {
1016
883
  hasSet = set;
@@ -1038,13 +905,12 @@ function toggleStyles(element, styles) {
1038
905
  };
1039
906
  }
1040
907
  function updateStyleProperty(element, key, value) {
1041
- updateElementValue(element, key, value, function(property, value$1) {
1042
- this.style[property] = value$1;
908
+ updateElementValue(element, key, value, function(property, style) {
909
+ this.style[property] = style;
1043
910
  }, function(property) {
1044
911
  this.style[property] = "";
1045
912
  }, false);
1046
913
  }
1047
914
  const ATTRIBUTE_DIRECTION = "dir";
1048
915
  const EXPRESSION_DIRECTION = /^(ltr|rtl)$/i;
1049
-
1050
- 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 };
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 };