@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.
- package/dist/attribute/index.js +5 -5
- package/dist/event/delegation.js +10 -10
- package/dist/find/index.js +1 -1
- package/dist/find/relative.js +13 -14
- package/dist/html/index.js +11 -8
- package/dist/html/sanitize.js +29 -14
- package/dist/internal/attribute.js +5 -5
- package/dist/is.js +3 -3
- package/dist/style.js +2 -2
- package/dist/toretto.full.js +102 -236
- package/package.json +4 -4
- package/src/attribute/get.ts +4 -12
- package/src/attribute/index.ts +5 -5
- package/src/attribute/set.ts +13 -13
- package/src/data.ts +7 -16
- package/src/event/delegation.ts +10 -10
- package/src/find/index.ts +1 -1
- package/src/find/relative.ts +19 -23
- package/src/html/index.ts +13 -12
- package/src/html/sanitize.ts +58 -31
- package/src/internal/attribute.ts +9 -9
- package/src/internal/element-value.ts +3 -4
- package/src/internal/get-value.ts +5 -8
- package/src/internal/is.ts +1 -3
- package/src/is.ts +4 -4
- package/src/models.ts +0 -5
- package/src/style.ts +12 -15
- package/types/attribute/get.d.ts +3 -3
- package/types/attribute/set.d.ts +9 -9
- package/types/data.d.ts +4 -5
- package/types/internal/attribute.d.ts +7 -7
- package/types/internal/element-value.d.ts +2 -3
- package/types/internal/get-value.d.ts +2 -3
- package/types/internal/is.d.ts +1 -2
- package/types/models.d.ts +0 -4
- package/types/style.d.ts +7 -7
package/dist/toretto.full.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
157
|
+
function _isBadAttribute(first, second, decode) {
|
|
180
158
|
return handleAttribute(badAttributeHandler, decode, first, second);
|
|
181
159
|
}
|
|
182
|
-
function
|
|
160
|
+
function _isBooleanAttribute(first, decode) {
|
|
183
161
|
return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
|
|
184
162
|
}
|
|
185
|
-
function
|
|
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
|
|
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
|
|
239
|
+
return _isBadAttribute(first, second, true);
|
|
246
240
|
}
|
|
247
241
|
function isBooleanAttribute(first) {
|
|
248
|
-
return
|
|
242
|
+
return _isBooleanAttribute(first, true);
|
|
249
243
|
}
|
|
250
244
|
function isEmptyNonBooleanAttribute(first, second) {
|
|
251
|
-
return
|
|
245
|
+
return _isEmptyNonBooleanAttribute(first, second, true);
|
|
252
246
|
}
|
|
253
247
|
function isInvalidBooleanAttribute(first, second) {
|
|
254
|
-
return
|
|
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,
|
|
253
|
+
function isInDocument(node, doc) {
|
|
266
254
|
if (!(node instanceof Node)) return false;
|
|
267
|
-
if (!(
|
|
268
|
-
return node.ownerDocument == null ? 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
|
-
|
|
340
|
-
|
|
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 (
|
|
347
|
-
|
|
327
|
+
if (doc[count] != null) {
|
|
328
|
+
doc[count] += 1;
|
|
348
329
|
return;
|
|
349
330
|
}
|
|
350
|
-
|
|
351
|
-
|
|
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(
|
|
367
|
+
function removeDelegatedHandler(doc, type, name, passive) {
|
|
387
368
|
const count = `${name}${COUNT_SUFFIX}`;
|
|
388
|
-
|
|
389
|
-
if (
|
|
390
|
-
|
|
391
|
-
|
|
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
|
|
511
|
-
|
|
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
|
|
515
|
-
|
|
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
|
|
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)
|
|
563
|
-
if (distance >
|
|
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
|
|
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
|
|
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])
|
|
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((
|
|
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
|
|
846
|
-
for (const
|
|
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
|
-
|
|
853
|
-
|
|
854
|
-
|
|
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 (
|
|
864
|
-
else if (
|
|
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
|
-
|
|
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
|
|
885
|
-
|
|
886
|
-
sanitizeNodes([
|
|
887
|
-
return
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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,
|
|
1042
|
-
this.style[property] =
|
|
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 };
|