-
Notifications
You must be signed in to change notification settings - Fork 465
/
utils.js
118 lines (97 loc) · 2.83 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
export const domReady = new Promise((resolve) => {
const checkState = () => {
if (document.readyState !== 'loading') resolve();
};
document.addEventListener('readystatechange', checkState);
checkState();
});
const range = document.createRange();
range.selectNode(document.documentElement);
export const strToEl = (str) => {
const frag = range.createContextualFragment(String(str));
return frag.children[0];
};
const entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
};
export const escapeHTML = (str) => {
return String(str).replace(/[&<>"'/]/g, (s) => entityMap[s]);
};
export const escapeHtmlTag = (strings, ...values) => {
values = values.map((s) => escapeHTML(s));
return strings.reduce((str, val, i) => str + val + (values[i] || ''), '');
};
export const readFileAsText = (file) => {
return new Response(file).text();
};
export const round = (num, places) => {
const mult = 10 ** places;
return Math.floor(Math.round(num * mult)) / mult;
};
export const humanSize = (bytes) => {
return bytes < 1024 ? `${bytes} bytes` : `${round(bytes / 1024, 2)}k`;
};
const transitionClassFunc = ({ removeClass = false } = {}) => {
return (el, className = 'active', transitionClass = 'transition') => {
if (removeClass) {
if (!el.classList.contains(className)) return Promise.resolve();
} else if (el.classList.contains(className)) return Promise.resolve();
const transitionEnd = new Promise((resolve) => {
const listener = (event) => {
if (event.target !== el) return;
el.removeEventListener('transitionend', listener);
el.classList.remove(transitionClass);
resolve();
};
el.classList.add(transitionClass);
requestAnimationFrame(() => {
el.addEventListener('transitionend', listener);
el.classList[removeClass ? 'remove' : 'add'](className);
});
});
const transitionTimeout = new Promise((resolve) => {
setTimeout(resolve, 1000);
});
return Promise.race([transitionEnd, transitionTimeout]);
};
};
export const transitionToClass = transitionClassFunc();
export const transitionFromClass = transitionClassFunc({ removeClass: true });
export const trackFocusMethod = () => {
let focusMethod = 'mouse';
document.body.addEventListener(
'focus',
(event) => {
event.target.classList.add(
focusMethod === 'key' ? 'key-focused' : 'mouse-focused'
);
},
true
);
document.body.addEventListener(
'blur',
(event) => {
event.target.classList.remove('key-focused', 'mouse-focused');
},
true
);
document.body.addEventListener(
'keydown',
() => {
focusMethod = 'key';
},
true
);
document.body.addEventListener(
'mousedown',
() => {
focusMethod = 'mouse';
},
true
);
};