Tracking de l'application VApp (IHM du jeu)
This commit is contained in:
494
VApp/node_modules/vuetify/lib/util/helpers.mjs
generated
vendored
Normal file
494
VApp/node_modules/vuetify/lib/util/helpers.mjs
generated
vendored
Normal file
@ -0,0 +1,494 @@
|
||||
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
||||
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
||||
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
||||
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
|
||||
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
||||
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
||||
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
||||
// Utilities
|
||||
import { capitalize, Comment, computed, Fragment, isVNode, reactive, toRefs, unref, watchEffect } from 'vue';
|
||||
import { IN_BROWSER } from "./globals.mjs"; // Types
|
||||
export function getNestedValue(obj, path, fallback) {
|
||||
const last = path.length - 1;
|
||||
if (last < 0) return obj === undefined ? fallback : obj;
|
||||
for (let i = 0; i < last; i++) {
|
||||
if (obj == null) {
|
||||
return fallback;
|
||||
}
|
||||
obj = obj[path[i]];
|
||||
}
|
||||
if (obj == null) return fallback;
|
||||
return obj[path[last]] === undefined ? fallback : obj[path[last]];
|
||||
}
|
||||
export function deepEqual(a, b) {
|
||||
if (a === b) return true;
|
||||
if (a instanceof Date && b instanceof Date && a.getTime() !== b.getTime()) {
|
||||
// If the values are Date, compare them as timestamps
|
||||
return false;
|
||||
}
|
||||
if (a !== Object(a) || b !== Object(b)) {
|
||||
// If the values aren't objects, they were already checked for equality
|
||||
return false;
|
||||
}
|
||||
const props = Object.keys(a);
|
||||
if (props.length !== Object.keys(b).length) {
|
||||
// Different number of props, don't bother to check
|
||||
return false;
|
||||
}
|
||||
return props.every(p => deepEqual(a[p], b[p]));
|
||||
}
|
||||
export function getObjectValueByPath(obj, path, fallback) {
|
||||
// credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
|
||||
if (obj == null || !path || typeof path !== 'string') return fallback;
|
||||
if (obj[path] !== undefined) return obj[path];
|
||||
path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
|
||||
path = path.replace(/^\./, ''); // strip a leading dot
|
||||
return getNestedValue(obj, path.split('.'), fallback);
|
||||
}
|
||||
export function getPropertyFromItem(item, property, fallback) {
|
||||
if (property === true) return item === undefined ? fallback : item;
|
||||
if (property == null || typeof property === 'boolean') return fallback;
|
||||
if (item !== Object(item)) {
|
||||
if (typeof property !== 'function') return fallback;
|
||||
const value = property(item, fallback);
|
||||
return typeof value === 'undefined' ? fallback : value;
|
||||
}
|
||||
if (typeof property === 'string') return getObjectValueByPath(item, property, fallback);
|
||||
if (Array.isArray(property)) return getNestedValue(item, property, fallback);
|
||||
if (typeof property !== 'function') return fallback;
|
||||
const value = property(item, fallback);
|
||||
return typeof value === 'undefined' ? fallback : value;
|
||||
}
|
||||
export function createRange(length) {
|
||||
let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
||||
return Array.from({
|
||||
length
|
||||
}, (v, k) => start + k);
|
||||
}
|
||||
export function getZIndex(el) {
|
||||
if (!el || el.nodeType !== Node.ELEMENT_NODE) return 0;
|
||||
const index = +window.getComputedStyle(el).getPropertyValue('z-index');
|
||||
if (!index) return getZIndex(el.parentNode);
|
||||
return index;
|
||||
}
|
||||
export function convertToUnit(str) {
|
||||
let unit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'px';
|
||||
if (str == null || str === '') {
|
||||
return undefined;
|
||||
} else if (isNaN(+str)) {
|
||||
return String(str);
|
||||
} else if (!isFinite(+str)) {
|
||||
return undefined;
|
||||
} else {
|
||||
return `${Number(str)}${unit}`;
|
||||
}
|
||||
}
|
||||
export function isObject(obj) {
|
||||
return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
|
||||
}
|
||||
export function refElement(obj) {
|
||||
if (obj && '$el' in obj) {
|
||||
const el = obj.$el;
|
||||
if (el?.nodeType === Node.TEXT_NODE) {
|
||||
// Multi-root component, use the first element
|
||||
return el.nextElementSibling;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// KeyboardEvent.keyCode aliases
|
||||
export const keyCodes = Object.freeze({
|
||||
enter: 13,
|
||||
tab: 9,
|
||||
delete: 46,
|
||||
esc: 27,
|
||||
space: 32,
|
||||
up: 38,
|
||||
down: 40,
|
||||
left: 37,
|
||||
right: 39,
|
||||
end: 35,
|
||||
home: 36,
|
||||
del: 46,
|
||||
backspace: 8,
|
||||
insert: 45,
|
||||
pageup: 33,
|
||||
pagedown: 34,
|
||||
shift: 16
|
||||
});
|
||||
export const keyValues = Object.freeze({
|
||||
enter: 'Enter',
|
||||
tab: 'Tab',
|
||||
delete: 'Delete',
|
||||
esc: 'Escape',
|
||||
space: 'Space',
|
||||
up: 'ArrowUp',
|
||||
down: 'ArrowDown',
|
||||
left: 'ArrowLeft',
|
||||
right: 'ArrowRight',
|
||||
end: 'End',
|
||||
home: 'Home',
|
||||
del: 'Delete',
|
||||
backspace: 'Backspace',
|
||||
insert: 'Insert',
|
||||
pageup: 'PageUp',
|
||||
pagedown: 'PageDown',
|
||||
shift: 'Shift'
|
||||
});
|
||||
export function keys(o) {
|
||||
return Object.keys(o);
|
||||
}
|
||||
export function has(obj, key) {
|
||||
return key.every(k => obj.hasOwnProperty(k));
|
||||
}
|
||||
// Array of keys
|
||||
export function pick(obj, paths) {
|
||||
const found = {};
|
||||
const keys = new Set(Object.keys(obj));
|
||||
for (const path of paths) {
|
||||
if (keys.has(path)) {
|
||||
found[path] = obj[path];
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// Array of keys
|
||||
|
||||
// Array of keys or RegExp to test keys against
|
||||
|
||||
export function pickWithRest(obj, paths, exclude) {
|
||||
const found = Object.create(null);
|
||||
const rest = Object.create(null);
|
||||
for (const key in obj) {
|
||||
if (paths.some(path => path instanceof RegExp ? path.test(key) : path === key) && !exclude?.some(path => path === key)) {
|
||||
found[key] = obj[key];
|
||||
} else {
|
||||
rest[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return [found, rest];
|
||||
}
|
||||
export function omit(obj, exclude) {
|
||||
const clone = {
|
||||
...obj
|
||||
};
|
||||
exclude.forEach(prop => delete clone[prop]);
|
||||
return clone;
|
||||
}
|
||||
export function only(obj, include) {
|
||||
const clone = {};
|
||||
include.forEach(prop => clone[prop] = obj[prop]);
|
||||
return clone;
|
||||
}
|
||||
const onRE = /^on[^a-z]/;
|
||||
export const isOn = key => onRE.test(key);
|
||||
const bubblingEvents = ['onAfterscriptexecute', 'onAnimationcancel', 'onAnimationend', 'onAnimationiteration', 'onAnimationstart', 'onAuxclick', 'onBeforeinput', 'onBeforescriptexecute', 'onChange', 'onClick', 'onCompositionend', 'onCompositionstart', 'onCompositionupdate', 'onContextmenu', 'onCopy', 'onCut', 'onDblclick', 'onFocusin', 'onFocusout', 'onFullscreenchange', 'onFullscreenerror', 'onGesturechange', 'onGestureend', 'onGesturestart', 'onGotpointercapture', 'onInput', 'onKeydown', 'onKeypress', 'onKeyup', 'onLostpointercapture', 'onMousedown', 'onMousemove', 'onMouseout', 'onMouseover', 'onMouseup', 'onMousewheel', 'onPaste', 'onPointercancel', 'onPointerdown', 'onPointerenter', 'onPointerleave', 'onPointermove', 'onPointerout', 'onPointerover', 'onPointerup', 'onReset', 'onSelect', 'onSubmit', 'onTouchcancel', 'onTouchend', 'onTouchmove', 'onTouchstart', 'onTransitioncancel', 'onTransitionend', 'onTransitionrun', 'onTransitionstart', 'onWheel'];
|
||||
const compositionIgnoreKeys = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft', 'Enter', 'Escape', 'Tab', ' '];
|
||||
export function isComposingIgnoreKey(e) {
|
||||
return e.isComposing && compositionIgnoreKeys.includes(e.key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter attributes that should be applied to
|
||||
* the root element of an input component. Remaining
|
||||
* attributes should be passed to the <input> element inside.
|
||||
*/
|
||||
export function filterInputAttrs(attrs) {
|
||||
const [events, props] = pickWithRest(attrs, [onRE]);
|
||||
const inputEvents = omit(events, bubblingEvents);
|
||||
const [rootAttrs, inputAttrs] = pickWithRest(props, ['class', 'style', 'id', /^data-/]);
|
||||
Object.assign(rootAttrs, events);
|
||||
Object.assign(inputAttrs, inputEvents);
|
||||
return [rootAttrs, inputAttrs];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set difference of B and A, i.e. the set of elements in B but not in A
|
||||
*/
|
||||
export function arrayDiff(a, b) {
|
||||
const diff = [];
|
||||
for (let i = 0; i < b.length; i++) {
|
||||
if (!a.includes(b[i])) diff.push(b[i]);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
export function wrapInArray(v) {
|
||||
return v == null ? [] : Array.isArray(v) ? v : [v];
|
||||
}
|
||||
export function defaultFilter(value, search, item) {
|
||||
return value != null && search != null && typeof value !== 'boolean' && value.toString().toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) !== -1;
|
||||
}
|
||||
export function debounce(fn, delay) {
|
||||
let timeoutId = 0;
|
||||
const wrap = function () {
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => fn(...args), unref(delay));
|
||||
};
|
||||
wrap.clear = () => {
|
||||
clearTimeout(timeoutId);
|
||||
};
|
||||
wrap.immediate = fn;
|
||||
return wrap;
|
||||
}
|
||||
export function throttle(fn, limit) {
|
||||
let throttling = false;
|
||||
return function () {
|
||||
if (!throttling) {
|
||||
throttling = true;
|
||||
setTimeout(() => throttling = false, limit);
|
||||
return fn(...arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
export function clamp(value) {
|
||||
let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
||||
let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
export function getDecimals(value) {
|
||||
const trimmedStr = value.toString().trim();
|
||||
return trimmedStr.includes('.') ? trimmedStr.length - trimmedStr.indexOf('.') - 1 : 0;
|
||||
}
|
||||
export function padEnd(str, length) {
|
||||
let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
|
||||
return str + char.repeat(Math.max(0, length - str.length));
|
||||
}
|
||||
export function padStart(str, length) {
|
||||
let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
|
||||
return char.repeat(Math.max(0, length - str.length)) + str;
|
||||
}
|
||||
export function chunk(str) {
|
||||
let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
||||
const chunked = [];
|
||||
let index = 0;
|
||||
while (index < str.length) {
|
||||
chunked.push(str.substr(index, size));
|
||||
index += size;
|
||||
}
|
||||
return chunked;
|
||||
}
|
||||
export function chunkArray(array) {
|
||||
let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
||||
return Array.from({
|
||||
length: Math.ceil(array.length / size)
|
||||
}, (v, i) => array.slice(i * size, i * size + size));
|
||||
}
|
||||
export function humanReadableFileSize(bytes) {
|
||||
let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
|
||||
if (bytes < base) {
|
||||
return `${bytes} B`;
|
||||
}
|
||||
const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G'];
|
||||
let unit = -1;
|
||||
while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
|
||||
bytes /= base;
|
||||
++unit;
|
||||
}
|
||||
return `${bytes.toFixed(1)} ${prefix[unit]}B`;
|
||||
}
|
||||
export function mergeDeep() {
|
||||
let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
let arrayFn = arguments.length > 2 ? arguments[2] : undefined;
|
||||
const out = {};
|
||||
for (const key in source) {
|
||||
out[key] = source[key];
|
||||
}
|
||||
for (const key in target) {
|
||||
const sourceProperty = source[key];
|
||||
const targetProperty = target[key];
|
||||
|
||||
// Only continue deep merging if
|
||||
// both properties are objects
|
||||
if (isObject(sourceProperty) && isObject(targetProperty)) {
|
||||
out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn);
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(sourceProperty) && Array.isArray(targetProperty) && arrayFn) {
|
||||
out[key] = arrayFn(sourceProperty, targetProperty);
|
||||
continue;
|
||||
}
|
||||
out[key] = targetProperty;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
export function flattenFragments(nodes) {
|
||||
return nodes.map(node => {
|
||||
if (node.type === Fragment) {
|
||||
return flattenFragments(node.children);
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}).flat();
|
||||
}
|
||||
export function toKebabCase() {
|
||||
let str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||
if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str);
|
||||
const kebab = str.replace(/[^a-z]/gi, '-').replace(/\B([A-Z])/g, '-$1').toLowerCase();
|
||||
toKebabCase.cache.set(str, kebab);
|
||||
return kebab;
|
||||
}
|
||||
toKebabCase.cache = new Map();
|
||||
export function findChildrenWithProvide(key, vnode) {
|
||||
if (!vnode || typeof vnode !== 'object') return [];
|
||||
if (Array.isArray(vnode)) {
|
||||
return vnode.map(child => findChildrenWithProvide(key, child)).flat(1);
|
||||
} else if (Array.isArray(vnode.children)) {
|
||||
return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1);
|
||||
} else if (vnode.component) {
|
||||
if (Object.getOwnPropertySymbols(vnode.component.provides).includes(key)) {
|
||||
return [vnode.component];
|
||||
} else if (vnode.component.subTree) {
|
||||
return findChildrenWithProvide(key, vnode.component.subTree).flat(1);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
var _arr = /*#__PURE__*/new WeakMap();
|
||||
var _pointer = /*#__PURE__*/new WeakMap();
|
||||
export class CircularBuffer {
|
||||
constructor(size) {
|
||||
_classPrivateFieldInitSpec(this, _arr, {
|
||||
writable: true,
|
||||
value: []
|
||||
});
|
||||
_classPrivateFieldInitSpec(this, _pointer, {
|
||||
writable: true,
|
||||
value: 0
|
||||
});
|
||||
this.size = size;
|
||||
}
|
||||
push(val) {
|
||||
_classPrivateFieldGet(this, _arr)[_classPrivateFieldGet(this, _pointer)] = val;
|
||||
_classPrivateFieldSet(this, _pointer, (_classPrivateFieldGet(this, _pointer) + 1) % this.size);
|
||||
}
|
||||
values() {
|
||||
return _classPrivateFieldGet(this, _arr).slice(_classPrivateFieldGet(this, _pointer)).concat(_classPrivateFieldGet(this, _arr).slice(0, _classPrivateFieldGet(this, _pointer)));
|
||||
}
|
||||
}
|
||||
export function getEventCoordinates(e) {
|
||||
if ('touches' in e) {
|
||||
return {
|
||||
clientX: e.touches[0].clientX,
|
||||
clientY: e.touches[0].clientY
|
||||
};
|
||||
}
|
||||
return {
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY
|
||||
};
|
||||
}
|
||||
|
||||
// Only allow a single return type
|
||||
|
||||
/**
|
||||
* Convert a computed ref to a record of refs.
|
||||
* The getter function must always return an object with the same keys.
|
||||
*/
|
||||
|
||||
export function destructComputed(getter) {
|
||||
const refs = reactive({});
|
||||
const base = computed(getter);
|
||||
watchEffect(() => {
|
||||
for (const key in base.value) {
|
||||
refs[key] = base.value[key];
|
||||
}
|
||||
}, {
|
||||
flush: 'sync'
|
||||
});
|
||||
return toRefs(refs);
|
||||
}
|
||||
|
||||
/** Array.includes but value can be any type */
|
||||
export function includes(arr, val) {
|
||||
return arr.includes(val);
|
||||
}
|
||||
export function eventName(propName) {
|
||||
return propName[2].toLowerCase() + propName.slice(3);
|
||||
}
|
||||
export const EventProp = () => [Function, Array];
|
||||
export function hasEvent(props, name) {
|
||||
name = 'on' + capitalize(name);
|
||||
return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
|
||||
}
|
||||
export function callEvent(handler) {
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
if (Array.isArray(handler)) {
|
||||
for (const h of handler) {
|
||||
h(...args);
|
||||
}
|
||||
} else if (typeof handler === 'function') {
|
||||
handler(...args);
|
||||
}
|
||||
}
|
||||
export function focusableChildren(el) {
|
||||
let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
||||
const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
|
||||
return [...el.querySelectorAll(targets)];
|
||||
}
|
||||
export function getNextElement(elements, location, condition) {
|
||||
let _el;
|
||||
let idx = elements.indexOf(document.activeElement);
|
||||
const inc = location === 'next' ? 1 : -1;
|
||||
do {
|
||||
idx += inc;
|
||||
_el = elements[idx];
|
||||
} while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0);
|
||||
return _el;
|
||||
}
|
||||
export function focusChild(el, location) {
|
||||
const focusable = focusableChildren(el);
|
||||
if (!location) {
|
||||
if (el === document.activeElement || !el.contains(document.activeElement)) {
|
||||
focusable[0]?.focus();
|
||||
}
|
||||
} else if (location === 'first') {
|
||||
focusable[0]?.focus();
|
||||
} else if (location === 'last') {
|
||||
focusable.at(-1)?.focus();
|
||||
} else if (typeof location === 'number') {
|
||||
focusable[location]?.focus();
|
||||
} else {
|
||||
const _el = getNextElement(focusable, location);
|
||||
if (_el) _el.focus();else focusChild(el, location === 'next' ? 'first' : 'last');
|
||||
}
|
||||
}
|
||||
export function isEmpty(val) {
|
||||
return val === null || val === undefined || typeof val === 'string' && val.trim() === '';
|
||||
}
|
||||
export function noop() {}
|
||||
|
||||
/** Returns null if the selector is not supported or we can't check */
|
||||
export function matchesSelector(el, selector) {
|
||||
const supportsSelector = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports(`selector(${selector})`);
|
||||
if (!supportsSelector) return null;
|
||||
try {
|
||||
return !!el && el.matches(selector);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
export function ensureValidVNode(vnodes) {
|
||||
return vnodes.some(child => {
|
||||
if (!isVNode(child)) return true;
|
||||
if (child.type === Comment) return false;
|
||||
return child.type !== Fragment || ensureValidVNode(child.children);
|
||||
}) ? vnodes : null;
|
||||
}
|
||||
export function defer(timeout, cb) {
|
||||
if (!IN_BROWSER || timeout === 0) {
|
||||
cb();
|
||||
return () => {};
|
||||
}
|
||||
const timeoutId = window.setTimeout(cb, timeout);
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
}
|
||||
//# sourceMappingURL=helpers.mjs.map
|
Reference in New Issue
Block a user