@oscarpalmer/toretto 0.41.0 → 0.42.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.
Files changed (55) hide show
  1. package/dist/attribute/{get.d.mts → get.attribute.d.mts} +3 -2
  2. package/dist/attribute/{get.mjs → get.attribute.mjs} +4 -3
  3. package/dist/attribute/index.d.mts +3 -16
  4. package/dist/attribute/index.mjs +4 -7
  5. package/dist/attribute/{set.d.mts → set.attribute.d.mts} +4 -4
  6. package/dist/attribute/{set.mjs → set.attribute.mjs} +2 -2
  7. package/dist/create.d.mts +25 -0
  8. package/dist/create.mjs +17 -0
  9. package/dist/data.mjs +7 -7
  10. package/dist/event/delegation.mjs +8 -1
  11. package/dist/html/index.d.mts +23 -26
  12. package/dist/html/index.mjs +85 -18
  13. package/dist/html/sanitize.mjs +6 -5
  14. package/dist/index.d.mts +113 -52
  15. package/dist/index.mjs +510 -361
  16. package/dist/internal/attribute.d.mts +4 -3
  17. package/dist/internal/attribute.mjs +13 -23
  18. package/dist/internal/element-value.d.mts +2 -2
  19. package/dist/internal/element-value.mjs +4 -2
  20. package/dist/internal/get-value.mjs +1 -1
  21. package/dist/internal/property.d.mts +4 -0
  22. package/dist/internal/property.mjs +21 -0
  23. package/dist/property/get.property.d.mts +20 -0
  24. package/dist/property/get.property.mjs +35 -0
  25. package/dist/property/index.d.mts +3 -0
  26. package/dist/property/index.mjs +3 -0
  27. package/dist/property/set.property.d.mts +32 -0
  28. package/dist/property/set.property.mjs +34 -0
  29. package/dist/style.d.mts +12 -7
  30. package/dist/style.mjs +14 -18
  31. package/package.json +12 -5
  32. package/src/attribute/{get.ts → get.attribute.ts} +14 -3
  33. package/src/attribute/index.ts +10 -22
  34. package/src/attribute/{set.ts → set.attribute.ts} +9 -5
  35. package/src/create.ts +81 -0
  36. package/src/data.ts +16 -8
  37. package/src/event/delegation.ts +24 -3
  38. package/src/event/index.ts +9 -3
  39. package/src/find/index.ts +11 -3
  40. package/src/find/relative.ts +4 -0
  41. package/src/focusable.ts +10 -2
  42. package/src/html/index.ts +166 -58
  43. package/src/html/sanitize.ts +14 -11
  44. package/src/index.ts +2 -1
  45. package/src/internal/attribute.ts +23 -42
  46. package/src/internal/element-value.ts +11 -4
  47. package/src/internal/get-value.ts +8 -0
  48. package/src/internal/is.ts +4 -0
  49. package/src/internal/property.ts +42 -0
  50. package/src/is.ts +10 -2
  51. package/src/property/get.property.ts +73 -0
  52. package/src/property/index.ts +2 -0
  53. package/src/property/set.property.ts +102 -0
  54. package/src/style.ts +52 -27
  55. package/src/touch.ts +14 -2
package/dist/index.mjs CHANGED
@@ -108,203 +108,6 @@ function isNullableOrWhitespace(value) {
108
108
  }
109
109
  const EXPRESSION_WHITESPACE$1 = /^\s*$/;
110
110
  //#endregion
111
- //#region src/internal/is.ts
112
- /**
113
- * Is the value an event target?
114
- * @param value Value to check
115
- * @returns `true` if it's an event target, otherwise `false`
116
- */
117
- function isEventTarget(value) {
118
- return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
119
- }
120
- /**
121
- * Is the value an HTML or SVG element?
122
- * @param value Value to check
123
- * @returns `true` if it's an HTML or SVG element, otherwise `false`
124
- */
125
- function isHTMLOrSVGElement(value) {
126
- return value instanceof HTMLElement || value instanceof SVGElement;
127
- }
128
- //#endregion
129
- //#region src/is.ts
130
- /**
131
- * Is the value a child node?
132
- * @param value Value to check
133
- * @returns `true` if it's a child node, otherwise `false`
134
- */
135
- function isChildNode(value) {
136
- return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
137
- }
138
- function isInDocument(node, doc) {
139
- if (!(node instanceof Node)) return false;
140
- if (!(doc instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
141
- return node.ownerDocument == null ? node === doc : node.ownerDocument === doc && doc.contains(node);
142
- }
143
- const CHILD_NODE_TYPES = new Set([
144
- Node.ELEMENT_NODE,
145
- Node.TEXT_NODE,
146
- Node.PROCESSING_INSTRUCTION_NODE,
147
- Node.COMMENT_NODE,
148
- Node.DOCUMENT_TYPE_NODE
149
- ]);
150
- //#endregion
151
- //#region src/internal/element-value.ts
152
- function setElementValue(element, first, second, third, callback) {
153
- if (!isHTMLOrSVGElement(element)) return;
154
- if (typeof first === "string") setElementValues(element, first, second, third, callback);
155
- else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
156
- }
157
- function setElementValues(element, first, second, third, callback) {
158
- if (!isHTMLOrSVGElement(element)) return;
159
- if (typeof first === "string") {
160
- callback(element, first, second, third);
161
- return;
162
- }
163
- const isArray = Array.isArray(first);
164
- if (!isArray && !(typeof first === "object" && first !== null)) return;
165
- const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
166
- name,
167
- value
168
- }));
169
- const { length } = entries;
170
- for (let index = 0; index < length; index += 1) {
171
- const entry = entries[index];
172
- if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
173
- }
174
- }
175
- function updateElementValue(element, key, value, set, remove, isBoolean, json) {
176
- if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
177
- else set.call(element, key, json ? JSON.stringify(value) : String(value));
178
- }
179
- //#endregion
180
- //#region src/internal/attribute.ts
181
- function badAttributeHandler(name, value) {
182
- if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
183
- if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME.test(name)) return true;
184
- if (EXPRESSION_SKIP_NAME.test(name) || EXPRESSION_URI_VALUE.test(value) || isValidSourceAttribute(name, value)) return false;
185
- return EXPRESSION_DATA_OR_SCRIPT.test(value);
186
- }
187
- function booleanAttributeHandler(name, value) {
188
- if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
189
- const normalizedName = name.toLowerCase();
190
- if (!booleanAttributesSet.has(normalizedName)) return false;
191
- const normalized = value.toLowerCase();
192
- return !(normalized.length === 0 || normalized === normalizedName);
193
- }
194
- function decodeAttribute(value) {
195
- textArea ??= document.createElement("textarea");
196
- textArea.innerHTML = value;
197
- return decodeURIComponent(textArea.value);
198
- }
199
- function handleAttribute(callback, decode, first, second) {
200
- let name;
201
- let value;
202
- if (isAttribute(first)) {
203
- name = first.name;
204
- value = String(first.value);
205
- } else if (typeof first === "string" && typeof second === "string") {
206
- name = first;
207
- value = second;
208
- }
209
- if (decode && value != null) value = decodeAttribute(value);
210
- return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
211
- }
212
- function isAttribute(value) {
213
- return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
214
- }
215
- function _isBadAttribute(first, second, decode) {
216
- return handleAttribute(badAttributeHandler, decode, first, second);
217
- }
218
- function _isBooleanAttribute(first, decode) {
219
- return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
220
- }
221
- function _isEmptyNonBooleanAttribute(first, second, decode) {
222
- return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
223
- }
224
- function _isInvalidBooleanAttribute(first, second, decode) {
225
- return handleAttribute(booleanAttributeHandler, decode, first, second);
226
- }
227
- function isValidSourceAttribute(name, value) {
228
- return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
229
- }
230
- function updateAttribute(element, name, value, dispatch) {
231
- const normalizedName = name.toLowerCase();
232
- const isBoolean = booleanAttributesSet.has(normalizedName);
233
- const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
234
- if (name in element) updateProperty(element, normalizedName, next, dispatch);
235
- updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
236
- }
237
- function updateProperty(element, name, value, dispatch) {
238
- if (Object.is(element[name], value)) return;
239
- element[name] = value;
240
- const event = dispatch !== false && elementEvents[element.tagName]?.[name];
241
- if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
242
- }
243
- const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
244
- const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
245
- const EXPRESSION_EVENT_NAME = /^on/i;
246
- const EXPRESSION_SKIP_NAME = /^(aria-[-\w]+|data-[-\w.\u00B7-\uFFFF]+)$/i;
247
- const EXPRESSION_SOURCE_NAME = /^src$/i;
248
- const EXPRESSION_SOURCE_VALUE = /^data:/i;
249
- const EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
250
- const EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
251
- /**
252
- * List of boolean attributes
253
- */
254
- const booleanAttributes = Object.freeze([
255
- "async",
256
- "autofocus",
257
- "autoplay",
258
- "checked",
259
- "controls",
260
- "default",
261
- "defer",
262
- "disabled",
263
- "formnovalidate",
264
- "hidden",
265
- "inert",
266
- "ismap",
267
- "itemscope",
268
- "loop",
269
- "multiple",
270
- "muted",
271
- "nomodule",
272
- "novalidate",
273
- "open",
274
- "playsinline",
275
- "readonly",
276
- "required",
277
- "reversed",
278
- "selected"
279
- ]);
280
- const booleanAttributesSet = new Set(booleanAttributes);
281
- const elementEvents = {
282
- DETAILS: { open: "toggle" },
283
- INPUT: {
284
- checked: "change",
285
- value: "input"
286
- },
287
- SELECT: { value: "change" },
288
- TEXTAREA: { value: "input" }
289
- };
290
- const formElement = document.createElement("form");
291
- let textArea;
292
- //#endregion
293
- //#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
294
- /**
295
- * Parse a JSON string into its proper value _(or `undefined` if it fails)_
296
- * @param value JSON string to parse
297
- * @param reviver Reviver function to transform the parsed values
298
- * @returns Parsed value or `undefined` if parsing fails
299
- */
300
- function parse(value, reviver) {
301
- try {
302
- return JSON.parse(value, reviver);
303
- } catch {
304
- return;
305
- }
306
- }
307
- //#endregion
308
111
  //#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
309
112
  /**
310
113
  * Clamp a number between a minimum and maximum value
@@ -349,7 +152,7 @@ var SizedMap = class extends Map {
349
152
  * Is the Map full?
350
153
  */
351
154
  get full() {
352
- return this.size >= this.#maximumSize;
155
+ return super.size >= this.#maximumSize;
353
156
  }
354
157
  get maximum() {
355
158
  return this.#maximumSize;
@@ -368,17 +171,23 @@ var SizedMap = class extends Map {
368
171
  * @inheritdoc
369
172
  */
370
173
  get(key) {
371
- const value = super.get(key);
372
- if (value !== void 0 || this.has(key)) this.set(key, value);
373
- return value;
174
+ if (super.has(key)) {
175
+ const value = super.get(key);
176
+ this.#setValue(key, value, true);
177
+ return value;
178
+ }
374
179
  }
375
180
  /**
376
181
  * @inheritdoc
377
182
  */
378
183
  set(key, value) {
379
- if (this.has(key)) this.delete(key);
380
- else if (this.size >= this.#maximumSize) this.delete(this.keys().next().value);
381
- return super.set(key, value);
184
+ return this.#setValue(key, value, super.has(key));
185
+ }
186
+ #setValue(key, value, has) {
187
+ if (has) super.delete(key);
188
+ else if (super.size >= this.#maximumSize) super.delete(super.keys().next().value);
189
+ super.set(key, value);
190
+ return this;
382
191
  }
383
192
  };
384
193
  //#endregion
@@ -534,27 +343,232 @@ function toCaseCallback(value) {
534
343
  }
535
344
  cased.push(join(partResult, delimiters[type]));
536
345
  }
537
- return join(cased, delimiters[type]);
346
+ return join(cased, delimiters[type]);
347
+ }
348
+ const CASE_CAMEL = "camel";
349
+ const CASE_KEBAB = "kebab";
350
+ const CASE_PASCAL = "pascal";
351
+ const CASE_SNAKE = "snake";
352
+ const DELIMTER_EMPTY = "";
353
+ const DELIMITER_HYPHEN = "-";
354
+ const DELIMITER_UNDERSCORE = "_";
355
+ const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
356
+ const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
357
+ const REPLACEMENT_CAMEL_CASE = "$1-$2";
358
+ const S = "s";
359
+ const caseMemoizers = {};
360
+ const delimiters = {
361
+ [CASE_CAMEL]: DELIMTER_EMPTY,
362
+ [CASE_KEBAB]: DELIMITER_HYPHEN,
363
+ [CASE_PASCAL]: DELIMTER_EMPTY,
364
+ [CASE_SNAKE]: DELIMITER_UNDERSCORE
365
+ };
366
+ let memoizedCapitalize;
367
+ //#endregion
368
+ //#region src/internal/is.ts
369
+ /**
370
+ * Is the value an event target?
371
+ * @param value Value to check
372
+ * @returns `true` if it's an event target, otherwise `false`
373
+ */
374
+ function isEventTarget(value) {
375
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
376
+ }
377
+ /**
378
+ * Is the value an HTML or SVG element?
379
+ * @param value Value to check
380
+ * @returns `true` if it's an HTML or SVG element, otherwise `false`
381
+ */
382
+ function isHTMLOrSVGElement(value) {
383
+ return value instanceof HTMLElement || value instanceof SVGElement;
384
+ }
385
+ //#endregion
386
+ //#region src/is.ts
387
+ /**
388
+ * Is the value a child node?
389
+ * @param value Value to check
390
+ * @returns `true` if it's a child node, otherwise `false`
391
+ */
392
+ function isChildNode(value) {
393
+ return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
394
+ }
395
+ function isInDocument(node, doc) {
396
+ if (!(node instanceof Node)) return false;
397
+ if (!(doc instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
398
+ return node.ownerDocument == null ? node === doc : node.ownerDocument === doc && doc.contains(node);
399
+ }
400
+ const CHILD_NODE_TYPES = new Set([
401
+ Node.ELEMENT_NODE,
402
+ Node.TEXT_NODE,
403
+ Node.PROCESSING_INSTRUCTION_NODE,
404
+ Node.COMMENT_NODE,
405
+ Node.DOCUMENT_TYPE_NODE
406
+ ]);
407
+ //#endregion
408
+ //#region src/internal/element-value.ts
409
+ function setElementValue(element, first, second, third, callback) {
410
+ if (!isHTMLOrSVGElement(element)) return;
411
+ if (typeof first === "string") setElementValues(element, first, second, third, callback);
412
+ else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
413
+ }
414
+ function setElementValues(element, first, second, third, callback) {
415
+ if (!isHTMLOrSVGElement(element)) return;
416
+ const dispatch = third !== false;
417
+ if (typeof first === "string") {
418
+ callback(element, kebabCase(first), second, dispatch);
419
+ return;
420
+ }
421
+ const isArray = Array.isArray(first);
422
+ if (!isArray && !(typeof first === "object" && first !== null)) return;
423
+ const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
424
+ name,
425
+ value
426
+ }));
427
+ const { length } = entries;
428
+ for (let index = 0; index < length; index += 1) {
429
+ const entry = entries[index];
430
+ if (typeof entry === "object" && typeof entry?.name === "string") callback(element, kebabCase(entry.name), entry.value, dispatch);
431
+ }
432
+ }
433
+ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
434
+ if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
435
+ else set.call(element, key, json ? JSON.stringify(value) : String(value));
436
+ }
437
+ //#endregion
438
+ //#region src/internal/property.ts
439
+ function updateProperty(element, name, value, dispatch) {
440
+ let property = name;
441
+ if (!(property in element)) property = camelCase(name);
442
+ if (!(property in element) || Object.is(element[property], value)) return;
443
+ element[property] = value;
444
+ const event = dispatch && elementEvents[element.tagName]?.[property];
445
+ if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
446
+ }
447
+ const elementEvents = {
448
+ DETAILS: { open: "toggle" },
449
+ INPUT: {
450
+ checked: "change",
451
+ value: "input"
452
+ },
453
+ SELECT: { value: "change" },
454
+ TEXTAREA: { value: "input" }
455
+ };
456
+ //#endregion
457
+ //#region src/internal/attribute.ts
458
+ function badAttributeHandler(name, value) {
459
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
460
+ if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME.test(name)) return true;
461
+ if (EXPRESSION_SKIP_NAME.test(name) || EXPRESSION_URI_VALUE.test(value) || isValidSourceAttribute(name, value)) return false;
462
+ return EXPRESSION_DATA_OR_SCRIPT.test(value);
463
+ }
464
+ function booleanAttributeHandler(name, value) {
465
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
466
+ const normalizedName = name.toLowerCase();
467
+ if (!booleanAttributesSet.has(normalizedName)) return false;
468
+ const normalized = value.toLowerCase();
469
+ return !(normalized.length === 0 || normalized === normalizedName);
470
+ }
471
+ function decodeAttribute(value) {
472
+ textArea ??= document.createElement("textarea");
473
+ textArea.innerHTML = value;
474
+ return decodeURIComponent(textArea.value);
475
+ }
476
+ function handleAttribute(callback, decode, first, second) {
477
+ let name;
478
+ let value;
479
+ if (isAttribute(first)) {
480
+ name = first.name;
481
+ value = String(first.value);
482
+ } else if (typeof first === "string" && typeof second === "string") {
483
+ name = first;
484
+ value = second;
485
+ }
486
+ if (name != null) name = kebabCase(name);
487
+ if (decode && value != null) value = decodeAttribute(value);
488
+ return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
489
+ }
490
+ function isAttribute(value) {
491
+ return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
492
+ }
493
+ function _isBadAttribute(first, second, decode) {
494
+ return handleAttribute(badAttributeHandler, decode, first, second);
495
+ }
496
+ function _isBooleanAttribute(first, decode) {
497
+ return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
498
+ }
499
+ function _isInvalidBooleanAttribute(first, second, decode) {
500
+ return handleAttribute(booleanAttributeHandler, decode, first, second);
501
+ }
502
+ function isValidSourceAttribute(name, value) {
503
+ return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
504
+ }
505
+ function updateAttribute(element, name, value, dispatch) {
506
+ const lowerCaseName = name.toLowerCase();
507
+ const isBoolean = booleanAttributesSet.has(lowerCaseName);
508
+ const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
509
+ if (isBoolean || dispatchedAttributes.has(name)) updateProperty(element, name, next, dispatch);
510
+ updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
511
+ }
512
+ const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
513
+ const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
514
+ const EXPRESSION_EVENT_NAME = /^on/i;
515
+ const EXPRESSION_SKIP_NAME = /^(aria-[-\w]+|data-[-\w.\u00B7-\uFFFF]+)$/i;
516
+ const EXPRESSION_SOURCE_NAME = /^src$/i;
517
+ const EXPRESSION_SOURCE_VALUE = /^data:/i;
518
+ const EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
519
+ const EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
520
+ /**
521
+ * List of boolean attributes
522
+ */
523
+ const booleanAttributes = Object.freeze([
524
+ "async",
525
+ "autofocus",
526
+ "autoplay",
527
+ "checked",
528
+ "controls",
529
+ "default",
530
+ "defer",
531
+ "disabled",
532
+ "formnovalidate",
533
+ "hidden",
534
+ "inert",
535
+ "ismap",
536
+ "itemscope",
537
+ "loop",
538
+ "multiple",
539
+ "muted",
540
+ "nomodule",
541
+ "novalidate",
542
+ "open",
543
+ "playsinline",
544
+ "readonly",
545
+ "required",
546
+ "reversed",
547
+ "selected"
548
+ ]);
549
+ const booleanAttributesSet = new Set(booleanAttributes);
550
+ const dispatchedAttributes = new Set([
551
+ "checked",
552
+ "open",
553
+ "value"
554
+ ]);
555
+ const formElement = document.createElement("form");
556
+ let textArea;
557
+ //#endregion
558
+ //#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
559
+ /**
560
+ * Parse a JSON string into its proper value _(or `undefined` if it fails)_
561
+ * @param value JSON string to parse
562
+ * @param reviver Reviver function to transform the parsed values
563
+ * @returns Parsed value or `undefined` if parsing fails
564
+ */
565
+ function parse(value, reviver) {
566
+ try {
567
+ return JSON.parse(value, reviver);
568
+ } catch {
569
+ return;
570
+ }
538
571
  }
539
- const CASE_CAMEL = "camel";
540
- const CASE_KEBAB = "kebab";
541
- const CASE_PASCAL = "pascal";
542
- const CASE_SNAKE = "snake";
543
- const DELIMTER_EMPTY = "";
544
- const DELIMITER_HYPHEN = "-";
545
- const DELIMITER_UNDERSCORE = "_";
546
- const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
547
- const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
548
- const REPLACEMENT_CAMEL_CASE = "$1-$2";
549
- const S = "s";
550
- const caseMemoizers = {};
551
- const delimiters = {
552
- [CASE_CAMEL]: DELIMTER_EMPTY,
553
- [CASE_KEBAB]: DELIMITER_HYPHEN,
554
- [CASE_PASCAL]: DELIMTER_EMPTY,
555
- [CASE_SNAKE]: DELIMITER_UNDERSCORE
556
- };
557
- let memoizedCapitalize;
558
572
  //#endregion
559
573
  //#region src/internal/get-value.ts
560
574
  function getBoolean(value, defaultValue) {
@@ -572,9 +586,9 @@ function getStyleValue(element, property, computed) {
572
586
  }
573
587
  const EXPRESSION_DATA_PREFIX = /^data-/i;
574
588
  //#endregion
575
- //#region src/attribute/get.ts
589
+ //#region src/attribute/get.attribute.ts
576
590
  function getAttribute(element, name, parseValues) {
577
- if (isHTMLOrSVGElement(element) && typeof name === "string") return getAttributeValue(element, name, parseValues !== false);
591
+ if (isHTMLOrSVGElement(element) && typeof name === "string") return getAttributeValue(element, kebabCase(name), parseValues !== false);
578
592
  }
579
593
  /**
580
594
  * Get specific attributes from an element
@@ -590,12 +604,12 @@ function getAttributes(element, names, parseData) {
590
604
  const { length } = names;
591
605
  for (let index = 0; index < length; index += 1) {
592
606
  const name = names[index];
593
- if (typeof name === "string") attributes[name] = getAttributeValue(element, name, shouldParse);
607
+ if (typeof name === "string") attributes[name] = getAttributeValue(element, kebabCase(name), shouldParse);
594
608
  }
595
609
  return attributes;
596
610
  }
597
611
  //#endregion
598
- //#region src/attribute/set.ts
612
+ //#region src/attribute/set.attribute.ts
599
613
  function setAttribute(element, first, second, third) {
600
614
  setElementValue(element, first, second, third, updateAttribute);
601
615
  }
@@ -610,34 +624,197 @@ function isBadAttribute(first, second) {
610
624
  function isBooleanAttribute(first) {
611
625
  return _isBooleanAttribute(first, true);
612
626
  }
613
- function isEmptyNonBooleanAttribute(first, second) {
614
- return _isEmptyNonBooleanAttribute(first, second, true);
615
- }
616
627
  function isInvalidBooleanAttribute(first, second) {
617
628
  return _isInvalidBooleanAttribute(first, second, true);
618
629
  }
619
630
  //#endregion
631
+ //#region src/style.ts
632
+ /**
633
+ * Get a style from an element
634
+ * @param element Element to get the style from
635
+ * @param property Style name
636
+ * @param computed Get the computed style? _(defaults to `false`)_
637
+ * @returns Style value
638
+ */
639
+ function getStyle(element, property, computed) {
640
+ if (isHTMLOrSVGElement(element) && typeof property === "string") return getStyleValue(element, property, computed === true);
641
+ }
642
+ /**
643
+ * Get styles from an element
644
+ * @param element Element to get the styles from
645
+ * @param properties Styles to get
646
+ * @param computed Get the computed styles? _(defaults to `false`)_
647
+ * @returns Style values
648
+ */
649
+ function getStyles(element, properties, computed) {
650
+ const styles = {};
651
+ if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
652
+ const { length } = properties;
653
+ for (let index = 0; index < length; index += 1) {
654
+ const property = properties[index];
655
+ if (typeof property === "string") styles[property] = getStyleValue(element, property, computed === true);
656
+ }
657
+ return styles;
658
+ }
659
+ function getTextDirection(node) {
660
+ let target;
661
+ if (isHTMLOrSVGElement(node)) target = node;
662
+ else target = node instanceof Node ? node.ownerDocument?.documentElement ?? document.documentElement : document.documentElement;
663
+ let { direction } = target.style;
664
+ if (direction === "") direction = getStyleValue(target, PROPETY_DIRECTION, true);
665
+ return direction === DIRECTION_RTL ? DIRECTION_RTL : DIRECTION_LTR;
666
+ }
667
+ /**
668
+ * Set a style on an element
669
+ * @param element Element to set the style on
670
+ * @param property Style name
671
+ * @param value Style value
672
+ */
673
+ function setStyle(element, property, value) {
674
+ setElementValues(element, property, value, null, updateStyleProperty);
675
+ }
676
+ /**
677
+ * Set styles on an element
678
+ * @param element Element to set the styles on
679
+ * @param styles Styles to set
680
+ */
681
+ function setStyles(element, styles) {
682
+ setElementValues(element, styles, null, null, updateStyleProperty);
683
+ }
684
+ /**
685
+ * Toggle styles for an element
686
+ * @param element Element to style
687
+ * @param styles Styles to be set or removed
688
+ * @returns Style toggler
689
+ */
690
+ function toggleStyles(element, styles) {
691
+ function toggle(set) {
692
+ hasSet = set;
693
+ let next;
694
+ if (set) {
695
+ values = getStyles(element, keys);
696
+ next = styles;
697
+ } else {
698
+ next = { ...values };
699
+ values = {};
700
+ for (let index = 0; index < length; index += 1) values[keys[index]] = void 0;
701
+ }
702
+ setStyles(element, next);
703
+ }
704
+ const keys = Object.keys(styles);
705
+ const { length } = keys;
706
+ let hasSet = false;
707
+ let values = {};
708
+ return {
709
+ set() {
710
+ if (!hasSet) toggle(true);
711
+ },
712
+ remove() {
713
+ if (hasSet) toggle(false);
714
+ }
715
+ };
716
+ }
717
+ function updateStyleProperty(element, key, value) {
718
+ updateElementValue(element, key, value, function(property, style) {
719
+ this.style[property] = String(style);
720
+ }, function(property) {
721
+ this.style[property] = "";
722
+ }, false, false);
723
+ }
724
+ const DIRECTION_LTR = "ltr";
725
+ const DIRECTION_RTL = "rtl";
726
+ const PROPETY_DIRECTION = "direction";
727
+ //#endregion
728
+ //#region src/property/get.property.ts
729
+ /**
730
+ * Get the values of one or more properties on an element
731
+ * @param target Target element
732
+ * @param properties Properties to get
733
+ * @returns Property values
734
+ */
735
+ function getProperties(target, properties) {
736
+ const values = {};
737
+ if (!isHTMLOrSVGElement(target) || !Array.isArray(properties)) return values;
738
+ const { length } = properties;
739
+ for (let index = 0; index < length; index += 1) {
740
+ const property = properties[index];
741
+ if (typeof property === "string") values[property] = getPropertyValue(target, property);
742
+ }
743
+ return values;
744
+ }
745
+ /**
746
+ * Get the value of a property on an element
747
+ * @param target Target element
748
+ * @param property Property to get
749
+ * @returns Property value
750
+ */
751
+ function getProperty(target, property) {
752
+ if (isHTMLOrSVGElement(target) && typeof property === "string") return getPropertyValue(target, property);
753
+ }
754
+ function getPropertyValue(element, property) {
755
+ let actual = property;
756
+ if (!(actual in element)) actual = camelCase(actual);
757
+ if (actual in element) return element[actual];
758
+ }
759
+ //#endregion
760
+ //#region src/property/set.property.ts
761
+ /**
762
+ * Set the values of one or more properties on an element
763
+ *
764
+ * Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
765
+ * @param target Target element
766
+ * @param properties Properties to set
767
+ * @param dispatch Dispatch events for properties? _(defaults to `true`)_
768
+ */
769
+ function setProperties(target, properties, dispatch) {
770
+ if (!isHTMLOrSVGElement(target) || !isPlainObject(properties)) return;
771
+ const shouldDispatch = dispatch !== false;
772
+ const keys = Object.keys(properties);
773
+ const { length } = keys;
774
+ for (let index = 0; index < length; index += 1) {
775
+ const key = keys[index];
776
+ if (booleanAttributesSet.has(key.toLowerCase()) || dispatchedAttributes.has(key)) setAttribute(target, key, properties[key], shouldDispatch);
777
+ else updateProperty(target, key, properties[key], shouldDispatch);
778
+ }
779
+ }
780
+ function setProperty(target, property, value, dispatch) {
781
+ if (!isHTMLOrSVGElement(target) || typeof property !== "string") return;
782
+ if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(target, property, value, dispatch !== false);
783
+ else updateProperty(target, property, value, dispatch !== false);
784
+ }
785
+ //#endregion
786
+ //#region src/create.ts
787
+ function createElement(tag, properties, attributes, styles) {
788
+ if (typeof tag !== "string") throw new TypeError(MESSAGE);
789
+ const element = document.createElement(tag);
790
+ if (properties != null) setProperties(element, properties);
791
+ if (attributes != null) setAttributes(element, attributes);
792
+ if (styles != null) setStyles(element, styles);
793
+ return element;
794
+ }
795
+ const MESSAGE = "Tag name must be a string";
796
+ //#endregion
620
797
  //#region src/data.ts
621
798
  function getData(element, keys, parseValues) {
622
799
  if (!isHTMLOrSVGElement(element)) return;
623
- const shouldParse = parseValues !== false;
800
+ const noParse = parseValues === false;
624
801
  if (typeof keys === "string") {
625
- const value = element.dataset[keys];
802
+ const value = element.dataset[camelCase(keys)];
626
803
  if (value === void 0) return;
627
- return shouldParse ? parse(value) : value;
804
+ return noParse ? value : parse(value);
628
805
  }
629
806
  const { length } = keys;
630
807
  const data = {};
631
808
  for (let index = 0; index < length; index += 1) {
632
809
  const key = keys[index];
633
- const value = element.dataset[key];
810
+ const value = element.dataset[camelCase(key)];
634
811
  if (value == null) data[key] = void 0;
635
- else data[key] = shouldParse ? parse(value) : value;
812
+ else data[key] = noParse ? value : parse(value);
636
813
  }
637
814
  return data;
638
815
  }
639
816
  function getName(original) {
640
- return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original).replace(EXPRESSION_DATA_PREFIX, "")}`;
817
+ return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original.replace(EXPRESSION_DATA_PREFIX, ""))}`;
641
818
  }
642
819
  function setData(element, first, second) {
643
820
  setElementValues(element, first, second, null, updateDataAttribute);
@@ -671,7 +848,14 @@ function delegatedEventHandler(event) {
671
848
  const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
672
849
  const items = event.composedPath();
673
850
  const { length } = items;
851
+ let cancelled = false;
674
852
  let target = items[0];
853
+ const originalStopPropagation = event.stopPropagation;
854
+ event.stopPropagation = function() {
855
+ cancelled = true;
856
+ originalStopPropagation.call(event);
857
+ };
858
+ event.stopImmediatePropagation = event.stopPropagation.bind(event);
675
859
  Object.defineProperties(event, {
676
860
  currentTarget: {
677
861
  configurable: true,
@@ -691,7 +875,7 @@ function delegatedEventHandler(event) {
691
875
  target = item;
692
876
  for (const listener of listeners) {
693
877
  listener.call(item, event);
694
- if (event.cancelBubble) return;
878
+ if (cancelled) return;
695
879
  }
696
880
  }
697
881
  }
@@ -1125,8 +1309,9 @@ const TYPE_RADIO = "radio";
1125
1309
  //#region src/html/sanitize.ts
1126
1310
  function handleElement(element, depth) {
1127
1311
  if (depth === 0) {
1128
- const removable = element.querySelectorAll(REMOVE_SELECTOR);
1129
- for (const item of removable) item.remove();
1312
+ const removable = [...element.querySelectorAll(REMOVE_SELECTOR)];
1313
+ const { length } = removable;
1314
+ for (let index = 0; index < length; index += 1) removable[index].remove();
1130
1315
  }
1131
1316
  sanitizeAttributes(element, [...element.attributes]);
1132
1317
  }
@@ -1145,7 +1330,7 @@ function sanitizeAttributes(element, attributes) {
1145
1330
  const { length } = attributes;
1146
1331
  for (let index = 0; index < length; index += 1) {
1147
1332
  const { name, value } = attributes[index];
1148
- if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
1333
+ if (_isBadAttribute(name, value, false)) element.removeAttribute(name);
1149
1334
  else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
1150
1335
  }
1151
1336
  }
@@ -1191,16 +1376,22 @@ function createHtml(value) {
1191
1376
  function createTemplate(value, options) {
1192
1377
  const template = document.createElement(TEMPLATE_TAG);
1193
1378
  template.innerHTML = createHtml(value);
1194
- if (typeof value === "string" && options.cache) templates[value] = template;
1379
+ if (typeof value === "string" && options.cache) templates.set(value, template);
1195
1380
  return template;
1196
1381
  }
1382
+ function getComment(index) {
1383
+ return COMMENT_TEMPLATE.replace(COMMENT_INDEX, String(index));
1384
+ }
1197
1385
  function getHtml(value) {
1198
1386
  return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
1199
1387
  }
1200
- function getNodes(value, options) {
1388
+ function getNodes(value, options, nodes) {
1201
1389
  if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
1202
1390
  const template = getTemplate(value, options);
1203
- return template == null ? [] : [...template.content.cloneNode(true).childNodes];
1391
+ if (template == null) return [];
1392
+ const cloned = [...template.content.cloneNode(true).childNodes];
1393
+ if (nodes != null) replaceComments(cloned, nodes);
1394
+ return cloned;
1204
1395
  }
1205
1396
  function getOptions(input) {
1206
1397
  const options = isPlainObject(input) ? input : {};
@@ -1211,31 +1402,86 @@ function getParser() {
1211
1402
  parser ??= new DOMParser();
1212
1403
  return parser;
1213
1404
  }
1405
+ function getTagged(strings, values) {
1406
+ const tagged = {
1407
+ nodes: [],
1408
+ template: ""
1409
+ };
1410
+ const stringsLength = strings.length;
1411
+ let nodeIndex = 0;
1412
+ for (let stringIndex = 0; stringIndex < stringsLength; stringIndex += 1) {
1413
+ const value = values[stringIndex];
1414
+ tagged.template += strings[stringIndex];
1415
+ if (value instanceof Node) {
1416
+ tagged.nodes.push(value);
1417
+ tagged.template += getComment(nodeIndex);
1418
+ nodeIndex += 1;
1419
+ } else if (hasNodes(value)) {
1420
+ const items = [...value];
1421
+ const itemsLength = items.length;
1422
+ for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
1423
+ const item = items[itemIndex];
1424
+ if (item instanceof Node) {
1425
+ tagged.nodes.push(item);
1426
+ tagged.template += getComment(nodeIndex);
1427
+ nodeIndex += 1;
1428
+ } else tagged.template += getString(item);
1429
+ }
1430
+ } else if (Array.isArray(value)) {
1431
+ const valueLength = value.length;
1432
+ for (let valueIndex = 0; valueIndex < valueLength; valueIndex += 1) tagged.template += getString(value[valueIndex]);
1433
+ } else tagged.template += getString(value);
1434
+ }
1435
+ return tagged;
1436
+ }
1214
1437
  function getTemplate(value, options) {
1215
1438
  if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
1216
1439
  if (value.trim().length === 0) return;
1217
- let template = templates[value];
1440
+ let template = templates.get(value);
1218
1441
  if (template != null) return template;
1219
1442
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
1220
1443
  return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
1221
1444
  }
1222
- const html = ((value, options) => {
1223
- return getNodes(value, getOptions(options));
1224
- });
1445
+ function hasNodes(value) {
1446
+ if (value instanceof HTMLCollection || value instanceof NodeList) return true;
1447
+ return Array.isArray(value) && value.some((item) => item instanceof Node);
1448
+ }
1449
+ function html(first, ...second) {
1450
+ if (isTagged(first)) {
1451
+ const tagged = getTagged(first, second);
1452
+ return getNodes(tagged.template, getOptions(), tagged.nodes);
1453
+ }
1454
+ return getNodes(first, getOptions(second[0]));
1455
+ }
1456
+ /**
1457
+ * Clear cache of template elements
1458
+ */
1225
1459
  html.clear = () => {
1226
- templates = {};
1460
+ templates.clear();
1227
1461
  };
1462
+ /**
1463
+ * Remove cached template element for an HTML string or id
1464
+ * @param template HTML string or id for a template element
1465
+ */
1228
1466
  html.remove = (template) => {
1229
- if (typeof template !== "string" || templates[template] == null) return;
1230
- const keys = Object.keys(templates);
1231
- const { length } = keys;
1232
- const updated = {};
1233
- for (let index = 0; index < length; index += 1) {
1234
- const key = keys[index];
1235
- if (key !== template) updated[key] = templates[key];
1236
- }
1237
- templates = updated;
1467
+ templates.delete(template);
1238
1468
  };
1469
+ function isTagged(value) {
1470
+ return Array.isArray(value) && Array.isArray(value.raw);
1471
+ }
1472
+ function replaceComments(origin, replacements) {
1473
+ const nodes = [...origin];
1474
+ const { length } = nodes;
1475
+ for (let nodeIndex = 0; nodeIndex < length; nodeIndex += 1) {
1476
+ const node = nodes[nodeIndex];
1477
+ if (node instanceof Comment) {
1478
+ const [, index] = EXPRESSION_COMMENT.exec(node.textContent) ?? [];
1479
+ if (index != null) node.replaceWith(replacements[Number(index)]);
1480
+ continue;
1481
+ }
1482
+ if (node.hasChildNodes()) replaceComments(node.childNodes, replacements);
1483
+ }
1484
+ }
1239
1485
  /**
1240
1486
  * Sanitize one or more nodes, recursively
1241
1487
  * @param value Node or nodes to sanitize
@@ -1245,112 +1491,15 @@ html.remove = (template) => {
1245
1491
  function sanitize(value) {
1246
1492
  return sanitizeNodes(Array.isArray(value) ? value : [value], 0);
1247
1493
  }
1494
+ const COMMENT_INDEX = "<index>";
1495
+ const COMMENT_TEMPLATE = `<!--toretto.node:${COMMENT_INDEX}-->`;
1496
+ const EXPRESSION_COMMENT = /^toretto\.node:(\d+)$/;
1248
1497
  const EXPRESSION_ID = /^[a-z][\w-]*$/i;
1249
1498
  const PARSE_TYPE_HTML = "text/html";
1250
1499
  const TEMPLATE_TAG = "template";
1251
1500
  const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
1501
+ const templates = new SizedMap(128);
1252
1502
  let parser;
1253
- let templates = {};
1254
- //#endregion
1255
- //#region src/style.ts
1256
- /**
1257
- * Get a style from an element
1258
- * @param element Element to get the style from
1259
- * @param property Style name
1260
- * @param computed Get the computed style? _(defaults to `false`)_
1261
- * @returns Style value
1262
- */
1263
- function getStyle(element, property, computed) {
1264
- if (!isHTMLOrSVGElement(element) || typeof property !== "string") return;
1265
- return getStyleValue(element, property, computed === true);
1266
- }
1267
- /**
1268
- * Get styles from an element
1269
- * @param element Element to get the styles from
1270
- * @param properties Styles to get
1271
- * @param computed Get the computed styles? _(defaults to `false`)_
1272
- * @returns Style values
1273
- */
1274
- function getStyles(element, properties, computed) {
1275
- const styles = {};
1276
- if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
1277
- const { length } = properties;
1278
- for (let index = 0; index < length; index += 1) {
1279
- const property = properties[index];
1280
- if (typeof property === "string") styles[property] = getStyleValue(element, property, computed === true);
1281
- }
1282
- return styles;
1283
- }
1284
- /**
1285
- * Get the text direction of an element
1286
- * @param element Element to get the text direction from
1287
- * @param computed Get the computed text direction? _(defaults to `false`)_
1288
- * @returns Text direction
1289
- */
1290
- function getTextDirection(element, computed) {
1291
- if (!(element instanceof Element)) return;
1292
- const direction = element.getAttribute(ATTRIBUTE_DIRECTION);
1293
- if (direction != null && EXPRESSION_DIRECTION.test(direction)) return direction.toLowerCase();
1294
- const value = getStyleValue(element, "direction", computed === true);
1295
- return value === "rtl" ? value : "ltr";
1296
- }
1297
- /**
1298
- * Set a style on an element
1299
- * @param element Element to set the style on
1300
- * @param property Style name
1301
- * @param value Style value
1302
- */
1303
- function setStyle(element, property, value) {
1304
- setElementValues(element, property, value, null, updateStyleProperty);
1305
- }
1306
- /**
1307
- * Set styles on an element
1308
- * @param element Element to set the styles on
1309
- * @param styles Styles to set
1310
- */
1311
- function setStyles(element, styles) {
1312
- setElementValues(element, styles, null, null, updateStyleProperty);
1313
- }
1314
- /**
1315
- * Toggle styles for an element
1316
- * @param element Element to style
1317
- * @param styles Styles to be set or removed
1318
- * @returns Style toggler
1319
- */
1320
- function toggleStyles(element, styles) {
1321
- function toggle(set) {
1322
- hasSet = set;
1323
- let next;
1324
- if (set) {
1325
- values = getStyles(element, keys);
1326
- next = styles;
1327
- } else {
1328
- next = { ...values };
1329
- values = {};
1330
- for (const key of keys) values[key] = void 0;
1331
- }
1332
- setStyles(element, next);
1333
- }
1334
- const keys = Object.keys(styles);
1335
- let hasSet = false;
1336
- let values = {};
1337
- return {
1338
- set() {
1339
- if (!hasSet) toggle(true);
1340
- },
1341
- remove() {
1342
- if (hasSet) toggle(false);
1343
- }
1344
- };
1345
- }
1346
- function updateStyleProperty(element, key, value) {
1347
- updateElementValue(element, key, value, function(property, style) {
1348
- this.style[property] = style;
1349
- }, function(property) {
1350
- this.style[property] = "";
1351
- }, false, false);
1352
- }
1353
- const ATTRIBUTE_DIRECTION = "dir";
1354
- const EXPRESSION_DIRECTION = /^(ltr|rtl)$/i;
1503
+ window.templates = templates;
1355
1504
  //#endregion
1356
- export { findElement as $, findElement, findElements as $$, findElements, booleanAttributes, dispatch, findAncestor, findRelatives, getAttribute, getAttributes, getData, getDistance, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAttribute, setAttributes, setData, setStyle, setStyles, supportsTouch, toggleStyles };
1505
+ export { findElement as $, findElement, findElements as $$, findElements, booleanAttributes, createElement, dispatch, findAncestor, findRelatives, getAttribute, getAttributes, getData, getDistance, getElementUnderPointer, getFocusable, getPosition, getProperties, getProperty, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAttribute, setAttributes, setData, setProperties, setProperty, setStyle, setStyles, supportsTouch, toggleStyles };