@oscarpalmer/toretto 0.30.1 → 0.32.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 +21 -28
- package/dist/event/index.js +1 -1
- package/dist/find/index.js +3 -3
- package/dist/find/relative.js +22 -22
- package/dist/html/index.js +11 -8
- package/dist/html/sanitize.js +29 -14
- package/dist/index.js +2 -2
- package/dist/internal/attribute.js +5 -5
- package/dist/is.js +3 -3
- package/dist/style.js +2 -2
- package/dist/toretto.full.js +125 -264
- package/package.json +6 -6
- 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 +24 -52
- package/src/event/index.ts +1 -7
- package/src/find/index.ts +2 -2
- package/src/find/relative.ts +43 -49
- 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/event/delegation.d.ts +1 -1
- package/types/find/index.d.ts +1 -1
- package/types/find/relative.d.ts +8 -2
- 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,7 @@ 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
|
-
|
|
308
|
+
function noop() {}
|
|
323
309
|
function calculate() {
|
|
324
310
|
return new Promise((resolve) => {
|
|
325
311
|
const values = [];
|
|
@@ -327,53 +313,51 @@ function calculate() {
|
|
|
327
313
|
function step(now) {
|
|
328
314
|
if (last != null) values.push(now - last);
|
|
329
315
|
last = now;
|
|
330
|
-
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(
|
|
316
|
+
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(CALCULATION_TRIM_PART, -CALCULATION_TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM_TOTAL));
|
|
331
317
|
else requestAnimationFrame(step);
|
|
332
318
|
}
|
|
333
319
|
requestAnimationFrame(step);
|
|
334
320
|
});
|
|
335
321
|
}
|
|
336
|
-
function noop() {}
|
|
337
322
|
var CALCULATION_TOTAL = 10;
|
|
338
|
-
var
|
|
339
|
-
|
|
340
|
-
calculate().then((value) => {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const count = `${name}${COUNT_SUFFIX}`;
|
|
346
|
-
if (document$1[count] != null) {
|
|
347
|
-
document$1[count] += 1;
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
document$1[count] = 1;
|
|
351
|
-
document$1.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
323
|
+
var CALCULATION_TRIM_PART = 2;
|
|
324
|
+
var CALCULATION_TRIM_TOTAL = 4;
|
|
325
|
+
calculate().then((value) => {});
|
|
326
|
+
function addDelegatedHandler(doc, type, name, passive) {
|
|
327
|
+
if (DELEGATED.has(name)) return;
|
|
328
|
+
DELEGATED.add(name);
|
|
329
|
+
doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
352
330
|
}
|
|
353
331
|
function addDelegatedListener(target, type, name, listener, passive) {
|
|
354
332
|
target[name] ??= /* @__PURE__ */ new Set();
|
|
355
|
-
target[name]
|
|
333
|
+
target[name].add(listener);
|
|
356
334
|
addDelegatedHandler(document, type, name, passive);
|
|
357
335
|
return () => {
|
|
358
|
-
removeDelegatedListener(target,
|
|
336
|
+
removeDelegatedListener(target, name, listener);
|
|
359
337
|
};
|
|
360
338
|
}
|
|
361
339
|
function delegatedEventHandler(event) {
|
|
362
340
|
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
363
341
|
const items = event.composedPath();
|
|
364
342
|
const { length } = items;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
343
|
+
let target = items[0];
|
|
344
|
+
Object.defineProperties(event, {
|
|
345
|
+
currentTarget: {
|
|
346
|
+
configurable: true,
|
|
347
|
+
get() {
|
|
348
|
+
return target;
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
target: {
|
|
352
|
+
configurable: true,
|
|
353
|
+
value: target
|
|
354
|
+
}
|
|
368
355
|
});
|
|
369
356
|
for (let index = 0; index < length; index += 1) {
|
|
370
357
|
const item = items[index];
|
|
371
358
|
const listeners = item[key];
|
|
372
359
|
if (item.disabled || listeners == null) continue;
|
|
373
|
-
|
|
374
|
-
configurable: true,
|
|
375
|
-
value: item
|
|
376
|
-
});
|
|
360
|
+
target = item;
|
|
377
361
|
for (const listener of listeners) {
|
|
378
362
|
listener.call(item, event);
|
|
379
363
|
if (event.cancelBubble) return;
|
|
@@ -383,23 +367,14 @@ function delegatedEventHandler(event) {
|
|
|
383
367
|
function getDelegatedName(target, type, options) {
|
|
384
368
|
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
369
|
}
|
|
386
|
-
function
|
|
387
|
-
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);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
function removeDelegatedListener(target, type, name, listener, passive) {
|
|
370
|
+
function removeDelegatedListener(target, name, listener) {
|
|
395
371
|
const handlers = target[name];
|
|
396
372
|
if (handlers == null || !handlers.has(listener)) return false;
|
|
397
373
|
handlers.delete(listener);
|
|
398
374
|
if (handlers.size === 0) target[name] = void 0;
|
|
399
|
-
removeDelegatedHandler(document, type, name, passive);
|
|
400
375
|
return true;
|
|
401
376
|
}
|
|
402
|
-
const
|
|
377
|
+
const DELEGATED = /* @__PURE__ */ new Set();
|
|
403
378
|
const EVENT_PREFIX = "@";
|
|
404
379
|
const EVENT_SUFFIX_ACTIVE = ":active";
|
|
405
380
|
const EVENT_SUFFIX_PASSIVE = ":passive";
|
|
@@ -429,7 +404,6 @@ const EVENT_TYPES = new Set([
|
|
|
429
404
|
]);
|
|
430
405
|
const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
431
406
|
const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
|
432
|
-
|
|
433
407
|
function createDispatchOptions(options) {
|
|
434
408
|
return {
|
|
435
409
|
bubbles: getBoolean(options?.bubbles, true),
|
|
@@ -456,11 +430,6 @@ function createEventOptions(options) {
|
|
|
456
430
|
function dispatch(target, type, options) {
|
|
457
431
|
if (isEventTarget(target) && typeof type === "string") target.dispatchEvent(createEvent(type, options));
|
|
458
432
|
}
|
|
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
433
|
function getPosition(event) {
|
|
465
434
|
let x;
|
|
466
435
|
let y;
|
|
@@ -476,18 +445,11 @@ function getPosition(event) {
|
|
|
476
445
|
y
|
|
477
446
|
} : void 0;
|
|
478
447
|
}
|
|
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
448
|
function off(target, type, listener, options) {
|
|
487
449
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return;
|
|
488
450
|
const extended = createEventOptions(options);
|
|
489
451
|
const delegated = getDelegatedName(target, type, extended);
|
|
490
|
-
if (delegated == null || !removeDelegatedListener(target,
|
|
452
|
+
if (delegated == null || !removeDelegatedListener(target, delegated, listener)) target.removeEventListener(type, listener, extended);
|
|
491
453
|
}
|
|
492
454
|
function on(target, type, listener, options) {
|
|
493
455
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
@@ -501,28 +463,6 @@ function on(target, type, listener, options) {
|
|
|
501
463
|
};
|
|
502
464
|
}
|
|
503
465
|
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
|
-
function getDistanceBetweenElements(origin, target) {
|
|
510
|
-
if (origin === target || origin.parentElement === target) return 0;
|
|
511
|
-
const comparison = origin.compareDocumentPosition(target);
|
|
512
|
-
const children = [...origin.parentElement?.children ?? []];
|
|
513
|
-
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
|
-
*/
|
|
526
466
|
function findAncestor(origin, selector) {
|
|
527
467
|
if (!(origin instanceof Element) || selector == null) return null;
|
|
528
468
|
if (typeof selector === "string") {
|
|
@@ -538,29 +478,17 @@ function findAncestor(origin, selector) {
|
|
|
538
478
|
}
|
|
539
479
|
return parent;
|
|
540
480
|
}
|
|
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
481
|
function findRelatives(origin, selector, context) {
|
|
552
482
|
if (!(origin instanceof Element) || typeof selector !== "string") return [];
|
|
553
|
-
if (origin.matches(selector)) return [origin];
|
|
554
483
|
const elements = [...(context instanceof Document || context instanceof Element ? context : document).querySelectorAll(selector)];
|
|
555
484
|
const { length } = elements;
|
|
556
|
-
if (length
|
|
557
|
-
if (length === 1) return [elements[0]];
|
|
485
|
+
if (length < 2) return elements.filter((element) => element !== origin);
|
|
558
486
|
const distances = [];
|
|
559
487
|
let minimum;
|
|
560
488
|
for (let index = 0; index < length; index += 1) {
|
|
561
489
|
const element = elements[index];
|
|
562
|
-
const distance =
|
|
563
|
-
if (distance >
|
|
490
|
+
const distance = getDistance(origin, element);
|
|
491
|
+
if (distance > 0) {
|
|
564
492
|
if (minimum == null || distance < minimum) minimum = distance;
|
|
565
493
|
distances.push({
|
|
566
494
|
distance,
|
|
@@ -568,35 +496,38 @@ function findRelatives(origin, selector, context) {
|
|
|
568
496
|
});
|
|
569
497
|
}
|
|
570
498
|
}
|
|
571
|
-
return
|
|
499
|
+
return distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
500
|
+
}
|
|
501
|
+
function getDistance(origin, target) {
|
|
502
|
+
if (origin === target) return 0;
|
|
503
|
+
if (origin.parentElement === target || target.parentElement === origin) return 1;
|
|
504
|
+
if (origin.parentElement != null && origin.parentElement === target.parentElement) {
|
|
505
|
+
const children = [...origin.parentElement.children];
|
|
506
|
+
return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
507
|
+
}
|
|
508
|
+
const comparison = origin.compareDocumentPosition(target);
|
|
509
|
+
if (comparison & Node.DOCUMENT_POSITION_DISCONNECTED) return -1;
|
|
510
|
+
const preceding = comparison & Node.DOCUMENT_POSITION_PRECEDING;
|
|
511
|
+
return traverse(preceding ? origin : target, preceding ? target : origin) ?? -1;
|
|
572
512
|
}
|
|
573
513
|
function traverse(from, to) {
|
|
574
|
-
let index = [...to.children].indexOf(from);
|
|
575
|
-
if (index > -1) return index + 1;
|
|
576
514
|
let current = from;
|
|
577
515
|
let distance = 0;
|
|
578
516
|
let parent = from.parentElement;
|
|
579
517
|
while (parent != null) {
|
|
580
518
|
if (parent === to) return distance + 1;
|
|
581
|
-
const children = [...parent.children
|
|
582
|
-
if (
|
|
583
|
-
index = children.findIndex((child) => child.contains(to));
|
|
519
|
+
const children = [...parent.children];
|
|
520
|
+
if (to.parentElement === parent) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
521
|
+
const index = children.findIndex((child) => child.contains(to));
|
|
584
522
|
if (index > -1) {
|
|
585
|
-
const traversed = traverse(current, children[index])
|
|
586
|
-
return traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
523
|
+
const traversed = traverse(current, children[index]);
|
|
524
|
+
return traversed == null || traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
587
525
|
}
|
|
588
526
|
current = parent;
|
|
589
527
|
distance += 1;
|
|
590
528
|
parent = parent.parentElement;
|
|
591
529
|
}
|
|
592
530
|
}
|
|
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
531
|
function findElement(selector, context) {
|
|
601
532
|
return findElementOrElements(selector, context, true);
|
|
602
533
|
}
|
|
@@ -631,27 +562,13 @@ function findElementOrElementsFromNodes(array, context, contexts) {
|
|
|
631
562
|
let element;
|
|
632
563
|
if (node instanceof Document) element = node.body;
|
|
633
564
|
else element = node instanceof Element ? node : void 0;
|
|
634
|
-
if (element != null && (context == null || contexts.length === 0 || contexts.some((
|
|
565
|
+
if (element != null && (context == null || contexts.length === 0 || contexts.some((ctx) => ctx === element || ctx.contains(element))) && !result.includes(element)) result.push(element);
|
|
635
566
|
}
|
|
636
567
|
return result;
|
|
637
568
|
}
|
|
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
569
|
function findElements(selector, context) {
|
|
645
570
|
return findElementOrElements(selector, context, false);
|
|
646
571
|
}
|
|
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
572
|
function getElementUnderPointer(skipIgnore) {
|
|
656
573
|
const elements = [...document.querySelectorAll(SUFFIX_HOVER)];
|
|
657
574
|
const { length } = elements;
|
|
@@ -673,12 +590,6 @@ const STYLE_HIDDEN$1 = "hidden";
|
|
|
673
590
|
const STYLE_NONE$1 = "none";
|
|
674
591
|
const SUFFIX_HOVER = ":hover";
|
|
675
592
|
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
593
|
function getFocusable(parent) {
|
|
683
594
|
return getValidElements(parent, FILTERS_FOCUSABLE, false);
|
|
684
595
|
}
|
|
@@ -688,11 +599,6 @@ function getItem(element, tabbable) {
|
|
|
688
599
|
tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
|
|
689
600
|
};
|
|
690
601
|
}
|
|
691
|
-
/**
|
|
692
|
-
* Get a list of tabbable elements within a parent element
|
|
693
|
-
* @param parent Parent element
|
|
694
|
-
* @returns Tabbable elements
|
|
695
|
-
*/
|
|
696
602
|
function getTabbable(parent) {
|
|
697
603
|
return getValidElements(parent, FILTERS_TABBABLE, true);
|
|
698
604
|
}
|
|
@@ -747,11 +653,6 @@ function isDisabledFromFieldset(element) {
|
|
|
747
653
|
function isEditable(element) {
|
|
748
654
|
return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
|
|
749
655
|
}
|
|
750
|
-
/**
|
|
751
|
-
* Is the element focusable?
|
|
752
|
-
* @param element Element to check
|
|
753
|
-
* @returns `true` if focusable, otherwise `false`
|
|
754
|
-
*/
|
|
755
656
|
function isFocusable(element) {
|
|
756
657
|
return element instanceof Element ? isValidElement(element, FILTERS_FOCUSABLE, false) : false;
|
|
757
658
|
}
|
|
@@ -782,11 +683,6 @@ function isNotTabbableRadio(item) {
|
|
|
782
683
|
function isSummarised(item) {
|
|
783
684
|
return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
|
|
784
685
|
}
|
|
785
|
-
/**
|
|
786
|
-
* Is the element tabbable?
|
|
787
|
-
* @param element Element to check
|
|
788
|
-
* @returns `true` if tabbable, otherwise `false`
|
|
789
|
-
*/
|
|
790
686
|
function isTabbable(element) {
|
|
791
687
|
return element instanceof Element ? isValidElement(element, FILTERS_TABBABLE, true) : false;
|
|
792
688
|
}
|
|
@@ -835,33 +731,25 @@ const STYLE_NONE = "none";
|
|
|
835
731
|
const TABINDEX_BASE = 0;
|
|
836
732
|
const TABINDEX_DEFAULT = -1;
|
|
837
733
|
const TYPE_RADIO = "radio";
|
|
838
|
-
|
|
839
734
|
function handleElement(element, depth) {
|
|
840
|
-
if (isClobbered(element)) {
|
|
841
|
-
element.remove();
|
|
842
|
-
return true;
|
|
843
|
-
}
|
|
844
735
|
if (depth === 0) {
|
|
845
|
-
const
|
|
846
|
-
for (const
|
|
736
|
+
const removable = element.querySelectorAll(REMOVE_SELECTOR);
|
|
737
|
+
for (const item of removable) item.remove();
|
|
847
738
|
}
|
|
848
739
|
sanitizeAttributes(element, [...element.attributes]);
|
|
849
|
-
return false;
|
|
850
740
|
}
|
|
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");
|
|
741
|
+
function isClobbered(value) {
|
|
742
|
+
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");
|
|
743
|
+
}
|
|
744
|
+
function removeNode(node) {
|
|
745
|
+
if (typeof node.remove === "function") node.remove();
|
|
858
746
|
}
|
|
859
747
|
function sanitizeAttributes(element, attributes) {
|
|
860
748
|
const { length } = attributes;
|
|
861
749
|
for (let index = 0; index < length; index += 1) {
|
|
862
750
|
const { name, value } = attributes[index];
|
|
863
|
-
if (
|
|
864
|
-
else if (
|
|
751
|
+
if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
|
|
752
|
+
else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute(element, name, true);
|
|
865
753
|
}
|
|
866
754
|
}
|
|
867
755
|
function sanitizeNodes(nodes, depth) {
|
|
@@ -869,22 +757,37 @@ function sanitizeNodes(nodes, depth) {
|
|
|
869
757
|
let { length } = nodes;
|
|
870
758
|
for (let index = 0; index < length; index += 1) {
|
|
871
759
|
const node = actual[index];
|
|
872
|
-
|
|
760
|
+
let remove = isClobbered(node);
|
|
761
|
+
if (!remove) switch (node.nodeType) {
|
|
762
|
+
case Node.ELEMENT_NODE:
|
|
763
|
+
handleElement(node, depth);
|
|
764
|
+
break;
|
|
765
|
+
case Node.COMMENT_NODE:
|
|
766
|
+
remove = COMMENT_HARMFUL.test(node.data);
|
|
767
|
+
break;
|
|
768
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
769
|
+
case Node.PROCESSING_INSTRUCTION_NODE:
|
|
770
|
+
remove = true;
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
if (remove) {
|
|
774
|
+
removeNode(node);
|
|
873
775
|
actual.splice(index, 1);
|
|
874
|
-
length -= 1;
|
|
875
776
|
index -= 1;
|
|
777
|
+
length -= 1;
|
|
876
778
|
continue;
|
|
877
779
|
}
|
|
878
780
|
if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
|
|
879
781
|
}
|
|
880
782
|
return nodes;
|
|
881
783
|
}
|
|
882
|
-
|
|
784
|
+
const COMMENT_HARMFUL = /<[/\w]/g;
|
|
785
|
+
const REMOVE_SELECTOR = "script, toretto-temporary";
|
|
883
786
|
function createHtml(value) {
|
|
884
|
-
const
|
|
885
|
-
|
|
886
|
-
sanitizeNodes([
|
|
887
|
-
return
|
|
787
|
+
const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
|
|
788
|
+
parsed.body.normalize();
|
|
789
|
+
sanitizeNodes([parsed.body], 0);
|
|
790
|
+
return parsed.body.innerHTML;
|
|
888
791
|
}
|
|
889
792
|
function createTemplate(value, options) {
|
|
890
793
|
const template = document.createElement(TEMPLATE_TAG);
|
|
@@ -892,6 +795,9 @@ function createTemplate(value, options) {
|
|
|
892
795
|
if (typeof value === "string" && options.cache) templates[value] = template;
|
|
893
796
|
return template;
|
|
894
797
|
}
|
|
798
|
+
function getHtml(value) {
|
|
799
|
+
return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
|
|
800
|
+
}
|
|
895
801
|
function getNodes(value, options) {
|
|
896
802
|
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
897
803
|
const template = getTemplate(value, options);
|
|
@@ -908,12 +814,11 @@ function getParser() {
|
|
|
908
814
|
}
|
|
909
815
|
function getTemplate(value, options) {
|
|
910
816
|
if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
|
|
911
|
-
if (
|
|
817
|
+
if (value.trim().length === 0) return;
|
|
912
818
|
let template = templates[value];
|
|
913
819
|
if (template != null) return template;
|
|
914
820
|
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
915
|
-
|
|
916
|
-
return template;
|
|
821
|
+
return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
|
|
917
822
|
}
|
|
918
823
|
const html = ((value, options) => {
|
|
919
824
|
return getNodes(value, getOptions(options));
|
|
@@ -932,39 +837,19 @@ html.remove = (template) => {
|
|
|
932
837
|
}
|
|
933
838
|
templates = updated;
|
|
934
839
|
};
|
|
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
840
|
function sanitize(value) {
|
|
942
841
|
return sanitizeNodes(Array.isArray(value) ? value : [value], 0);
|
|
943
842
|
}
|
|
944
843
|
const EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
945
|
-
const
|
|
844
|
+
const PARSE_TYPE_HTML = "text/html";
|
|
946
845
|
const TEMPLATE_TAG = "template";
|
|
846
|
+
const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
|
|
947
847
|
let parser;
|
|
948
848
|
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
849
|
function getStyle(element, property, computed) {
|
|
958
850
|
if (!isHTMLOrSVGElement(element) || typeof property !== "string") return;
|
|
959
851
|
return getStyleValue(element, property, computed === true);
|
|
960
852
|
}
|
|
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
853
|
function getStyles(element, properties, computed) {
|
|
969
854
|
const styles = {};
|
|
970
855
|
if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
|
|
@@ -975,12 +860,6 @@ function getStyles(element, properties, computed) {
|
|
|
975
860
|
}
|
|
976
861
|
return styles;
|
|
977
862
|
}
|
|
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
863
|
function getTextDirection(element, computed) {
|
|
985
864
|
if (!(element instanceof Element)) return;
|
|
986
865
|
const direction = element.getAttribute(ATTRIBUTE_DIRECTION);
|
|
@@ -988,29 +867,12 @@ function getTextDirection(element, computed) {
|
|
|
988
867
|
const value = getStyleValue(element, "direction", computed === true);
|
|
989
868
|
return value === "rtl" ? value : "ltr";
|
|
990
869
|
}
|
|
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
870
|
function setStyle(element, property, value) {
|
|
998
871
|
setElementValues(element, property, value, updateStyleProperty);
|
|
999
872
|
}
|
|
1000
|
-
/**
|
|
1001
|
-
* Set styles on an element
|
|
1002
|
-
* @param element Element to set the styles on
|
|
1003
|
-
* @param styles Styles to set
|
|
1004
|
-
*/
|
|
1005
873
|
function setStyles(element, styles) {
|
|
1006
874
|
setElementValues(element, styles, null, updateStyleProperty);
|
|
1007
875
|
}
|
|
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
876
|
function toggleStyles(element, styles) {
|
|
1015
877
|
function toggle(set) {
|
|
1016
878
|
hasSet = set;
|
|
@@ -1038,13 +900,12 @@ function toggleStyles(element, styles) {
|
|
|
1038
900
|
};
|
|
1039
901
|
}
|
|
1040
902
|
function updateStyleProperty(element, key, value) {
|
|
1041
|
-
updateElementValue(element, key, value, function(property,
|
|
1042
|
-
this.style[property] =
|
|
903
|
+
updateElementValue(element, key, value, function(property, style) {
|
|
904
|
+
this.style[property] = style;
|
|
1043
905
|
}, function(property) {
|
|
1044
906
|
this.style[property] = "";
|
|
1045
907
|
}, false);
|
|
1046
908
|
}
|
|
1047
909
|
const ATTRIBUTE_DIRECTION = "dir";
|
|
1048
910
|
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 };
|
|
911
|
+
export { findElement as $, findElement, findElements as $$, findElements, dispatch, findAncestor, findRelatives, getData, getDistance, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setData, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|