@amimpact/willy-utils 4.4.0 → 4.5.1
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/README.md +0 -12
- package/package.json +21 -37
- package/src/cookie.ts +49 -0
- package/src/date.ts +304 -0
- package/src/form.ts +78 -0
- package/{dist/includes/tinyduration.js → src/includes/tinyduration.ts} +81 -41
- package/src/index.ts +61 -0
- package/src/misc.ts +285 -0
- package/{dist/selectors.js → src/selectors.ts} +14 -19
- package/{dist/url.js → src/url.ts} +42 -35
- package/.eslintrc +0 -3
- package/.prettierrc +0 -5
- package/dist/cookie.d.ts +0 -15
- package/dist/cookie.js +0 -44
- package/dist/date.d.ts +0 -138
- package/dist/date.js +0 -154
- package/dist/form.d.ts +0 -9
- package/dist/form.js +0 -87
- package/dist/includes/tinyduration.d.ts +0 -20
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -39
- package/dist/misc.d.ts +0 -94
- package/dist/misc.js +0 -235
- package/dist/selectors.d.ts +0 -24
- package/dist/url.d.ts +0 -24
- package/tsconfig.json +0 -20
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* https://github.com/MelleB/tinyduration
|
|
3
|
+
* v 3.2.0
|
|
4
|
+
*/
|
|
5
|
+
interface DurationValues {
|
|
6
|
+
years?: number;
|
|
7
|
+
months?: number;
|
|
8
|
+
weeks?: number;
|
|
9
|
+
days?: number;
|
|
10
|
+
hours?: number;
|
|
11
|
+
minutes?: number;
|
|
12
|
+
seconds?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type Duration = {
|
|
16
|
+
negative?: boolean;
|
|
17
|
+
} & DurationValues;
|
|
18
|
+
|
|
19
|
+
const units: Array<{ unit: keyof DurationValues; symbol: string }> = [
|
|
5
20
|
{ unit: 'years', symbol: 'Y' },
|
|
6
21
|
{ unit: 'months', symbol: 'M' },
|
|
7
22
|
{ unit: 'weeks', symbol: 'W' },
|
|
@@ -10,95 +25,121 @@ var units = [
|
|
|
10
25
|
{ unit: 'minutes', symbol: 'M' },
|
|
11
26
|
{ unit: 'seconds', symbol: 'S' },
|
|
12
27
|
];
|
|
28
|
+
|
|
13
29
|
// Construction of the duration regex
|
|
14
30
|
// NOTE: IE11 kan niet overweg met groups in een regex
|
|
15
31
|
// const r = (name: string, unit: string): string =>
|
|
16
32
|
// `((?<${name}>-?\\d*[\\.,]?\\d+)${unit})?`;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const r = (name: string, unit: string): string => `((\\d*[\\.,]?\\d+)${unit})?`;
|
|
34
|
+
|
|
35
|
+
const durationRegex = new RegExp(
|
|
36
|
+
[
|
|
37
|
+
'P',
|
|
38
|
+
r('years', 'Y'),
|
|
39
|
+
r('months', 'M'),
|
|
40
|
+
r('weeks', 'W'),
|
|
41
|
+
r('days', 'D'),
|
|
42
|
+
'(T',
|
|
43
|
+
r('hours', 'H'),
|
|
44
|
+
r('minutes', 'M'),
|
|
45
|
+
r('seconds', 'S'),
|
|
46
|
+
')?', // end optional time
|
|
47
|
+
].join(''),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
function parseNum(s: string): number | undefined {
|
|
31
51
|
if (s === '' || s === undefined || s === null) {
|
|
32
52
|
return undefined;
|
|
33
53
|
}
|
|
54
|
+
|
|
34
55
|
return parseFloat(s.replace(',', '.'));
|
|
35
56
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
57
|
+
|
|
58
|
+
export const InvalidDurationError = new Error('Invalid duration');
|
|
59
|
+
|
|
60
|
+
export function parse(durationStr: string): Duration {
|
|
61
|
+
const match = durationRegex.exec(durationStr);
|
|
62
|
+
|
|
39
63
|
if (!match) {
|
|
40
|
-
throw
|
|
64
|
+
throw InvalidDurationError;
|
|
41
65
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
66
|
+
|
|
67
|
+
let empty = true;
|
|
68
|
+
const values: DurationValues = {};
|
|
69
|
+
for (const { unit, symbol } of units) {
|
|
46
70
|
// NOTE: IE11 kan niet overweg met groups in een regex
|
|
47
71
|
// if (match.groups[unit]) {
|
|
48
72
|
// empty = false;
|
|
49
73
|
// values[unit] = parseNum(match.groups[unit]);
|
|
50
74
|
// }
|
|
75
|
+
|
|
51
76
|
// Bovenstaande manier met named groups geeft een fout in IE11
|
|
52
77
|
// Dus maar zelf een extra loop typen en checken hoe de object opgebouwd moet worden
|
|
53
78
|
// Eerste match overslaan
|
|
54
|
-
for (
|
|
55
|
-
|
|
79
|
+
for (let index = 1; index < match.length - 1; index++) {
|
|
80
|
+
const str = match[index];
|
|
81
|
+
|
|
56
82
|
if (str) {
|
|
57
|
-
|
|
83
|
+
const strippedSymbol = str.charAt(str.length - 1);
|
|
84
|
+
|
|
58
85
|
if (strippedSymbol === symbol) {
|
|
59
86
|
empty = false;
|
|
87
|
+
|
|
60
88
|
// 2 x een symbool 'M', deze even handmatig checken
|
|
61
|
-
|
|
89
|
+
let u = unit;
|
|
62
90
|
if (symbol === 'M') {
|
|
63
91
|
u = index === 3 ? 'months' : 'minutes';
|
|
64
92
|
}
|
|
93
|
+
|
|
65
94
|
values[u] = parseNum(str.substring(0, str.length - 1));
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
97
|
}
|
|
69
98
|
}
|
|
99
|
+
|
|
70
100
|
if (empty) {
|
|
71
|
-
throw
|
|
101
|
+
throw InvalidDurationError;
|
|
72
102
|
}
|
|
73
|
-
|
|
103
|
+
|
|
104
|
+
const duration: Duration = values;
|
|
74
105
|
// if (match.groups.negative) {
|
|
75
106
|
// duration.negative = true;
|
|
76
107
|
// }
|
|
108
|
+
|
|
77
109
|
return duration;
|
|
78
110
|
}
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
|
|
112
|
+
const s = (
|
|
113
|
+
number: number | undefined,
|
|
114
|
+
component: string,
|
|
115
|
+
): string | undefined => {
|
|
81
116
|
if (!number) {
|
|
82
117
|
return undefined;
|
|
83
118
|
}
|
|
84
|
-
|
|
85
|
-
|
|
119
|
+
|
|
120
|
+
let numberAsString = number.toString();
|
|
121
|
+
const exponentIndex = numberAsString.indexOf('e');
|
|
86
122
|
if (exponentIndex > -1) {
|
|
87
|
-
|
|
123
|
+
const magnitude = parseInt(numberAsString.slice(exponentIndex + 2), 10);
|
|
88
124
|
numberAsString = number.toFixed(magnitude + exponentIndex - 2);
|
|
89
125
|
}
|
|
126
|
+
|
|
90
127
|
return numberAsString + component;
|
|
91
128
|
};
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
|
|
130
|
+
export function serialize(duration: Duration): string {
|
|
131
|
+
if (
|
|
132
|
+
!duration.years &&
|
|
94
133
|
!duration.months &&
|
|
95
134
|
!duration.weeks &&
|
|
96
135
|
!duration.days &&
|
|
97
136
|
!duration.hours &&
|
|
98
137
|
!duration.minutes &&
|
|
99
|
-
!duration.seconds
|
|
138
|
+
!duration.seconds
|
|
139
|
+
) {
|
|
100
140
|
return 'PT0S';
|
|
101
141
|
}
|
|
142
|
+
|
|
102
143
|
return [
|
|
103
144
|
// duration.negative && '-',
|
|
104
145
|
'P',
|
|
@@ -114,4 +155,3 @@ function serialize(duration) {
|
|
|
114
155
|
.filter(Boolean)
|
|
115
156
|
.join('');
|
|
116
157
|
}
|
|
117
|
-
exports.serialize = serialize;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createCookie, readCookie, eraseCookie } from './cookie';
|
|
2
|
+
import {
|
|
3
|
+
formatCraftDate,
|
|
4
|
+
formatDateFromNow,
|
|
5
|
+
formatNewDate,
|
|
6
|
+
formatUTCDate,
|
|
7
|
+
parseISODuration,
|
|
8
|
+
} from './date';
|
|
9
|
+
import { convertObjectToFormData } from './form';
|
|
10
|
+
import {
|
|
11
|
+
bytesToSize,
|
|
12
|
+
capitalize,
|
|
13
|
+
checkForScrollbars,
|
|
14
|
+
convertHexToRGBA,
|
|
15
|
+
downloadFile,
|
|
16
|
+
getNestedSet,
|
|
17
|
+
getUrlsFromString,
|
|
18
|
+
isEmpty,
|
|
19
|
+
isHoverableDevice,
|
|
20
|
+
isPlainObject,
|
|
21
|
+
isTouchDevice,
|
|
22
|
+
isValidUrl,
|
|
23
|
+
observeResize,
|
|
24
|
+
wrap,
|
|
25
|
+
} from './misc';
|
|
26
|
+
import { $, $$, getParents } from './selectors';
|
|
27
|
+
import { isCraftActionUrl, isInternalLink, isExternalUrl, isAsset, slugify } from './url';
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
$,
|
|
31
|
+
$$,
|
|
32
|
+
bytesToSize,
|
|
33
|
+
capitalize,
|
|
34
|
+
checkForScrollbars,
|
|
35
|
+
convertHexToRGBA,
|
|
36
|
+
createCookie,
|
|
37
|
+
downloadFile,
|
|
38
|
+
eraseCookie,
|
|
39
|
+
formatCraftDate,
|
|
40
|
+
convertObjectToFormData,
|
|
41
|
+
formatDateFromNow,
|
|
42
|
+
formatNewDate,
|
|
43
|
+
formatUTCDate,
|
|
44
|
+
getNestedSet,
|
|
45
|
+
getParents,
|
|
46
|
+
getUrlsFromString,
|
|
47
|
+
isAsset,
|
|
48
|
+
isCraftActionUrl,
|
|
49
|
+
isEmpty,
|
|
50
|
+
isExternalUrl,
|
|
51
|
+
isHoverableDevice,
|
|
52
|
+
isInternalLink,
|
|
53
|
+
isPlainObject,
|
|
54
|
+
isTouchDevice,
|
|
55
|
+
isValidUrl,
|
|
56
|
+
observeResize,
|
|
57
|
+
parseISODuration,
|
|
58
|
+
readCookie,
|
|
59
|
+
slugify,
|
|
60
|
+
wrap,
|
|
61
|
+
};
|
package/src/misc.ts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Navigator {
|
|
3
|
+
msSaveBlob?: (blob: any, defaultName?: string) => boolean;
|
|
4
|
+
msSaveOrOpenBlob: (blob: any, defaultName?: string) => boolean;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Toon mooier bestandsformaat
|
|
10
|
+
* @param {string | number} bytes
|
|
11
|
+
*/
|
|
12
|
+
export const bytesToSize = (bytes: number) => {
|
|
13
|
+
if (typeof bytes === 'string') {
|
|
14
|
+
bytes = parseInt(bytes);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
18
|
+
if (bytes === 0) return '0 Byte';
|
|
19
|
+
|
|
20
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
21
|
+
return Math.round(bytes / Math.pow(1024, i)) + ' ' + sizes[i];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Eerste letter van een string een hoofdletter maken
|
|
26
|
+
* @param {string} str
|
|
27
|
+
*/
|
|
28
|
+
export const capitalize = (str: string) => {
|
|
29
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check of een HTML element horizontale of verticale scrollbars heeft
|
|
34
|
+
* als dat zo is, dan wordt een class op het element gezet.
|
|
35
|
+
*
|
|
36
|
+
* @param {HTMLElement} el
|
|
37
|
+
* @param {String} dir // vertical of horizontal
|
|
38
|
+
*/
|
|
39
|
+
export const checkForScrollbars = (el: HTMLElement, dir: String = 'vertical') => {
|
|
40
|
+
if (!el) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const direction = dir === 'vertical' ? 'scrollTop' : 'scrollLeft';
|
|
45
|
+
|
|
46
|
+
let hasScrollbar = !!el[direction];
|
|
47
|
+
|
|
48
|
+
if (!hasScrollbar) {
|
|
49
|
+
el[direction] = 1;
|
|
50
|
+
hasScrollbar = !!el[direction];
|
|
51
|
+
el[direction] = 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (hasScrollbar) {
|
|
55
|
+
el.classList.add(`has-${dir}-scrollbar`);
|
|
56
|
+
} else {
|
|
57
|
+
el.classList.remove(`has-${dir}-scrollbar`);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Hex kleurcode converten naar rgba
|
|
63
|
+
*
|
|
64
|
+
* @param {string} hexCode
|
|
65
|
+
* @param {number} opacity
|
|
66
|
+
*/
|
|
67
|
+
export const convertHexToRGBA = (hexCode: string, opacity = 1) => {
|
|
68
|
+
let hex = hexCode.replace('#', '');
|
|
69
|
+
|
|
70
|
+
if (hex.length === 3) {
|
|
71
|
+
hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
75
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
76
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
77
|
+
|
|
78
|
+
/* Backward compatibility for whole number based opacity values. */
|
|
79
|
+
if (opacity > 1 && opacity <= 100) {
|
|
80
|
+
opacity = opacity / 100;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return `rgba(${r},${g},${b},${opacity})`;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Downloaden van een bestand
|
|
88
|
+
*
|
|
89
|
+
* @param {any} data
|
|
90
|
+
* @param {string} fileName
|
|
91
|
+
*/
|
|
92
|
+
export const downloadFile = (data: any, fileName: string) => {
|
|
93
|
+
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
|
94
|
+
window.navigator.msSaveOrOpenBlob(new Blob([data]), fileName);
|
|
95
|
+
} else {
|
|
96
|
+
let fileURL;
|
|
97
|
+
if (isValidUrl(data)) {
|
|
98
|
+
fileURL = data;
|
|
99
|
+
} else {
|
|
100
|
+
fileURL = window.URL.createObjectURL(new Blob([data]));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const fileLink = document.createElement('a');
|
|
104
|
+
fileLink.href = fileURL;
|
|
105
|
+
fileLink.setAttribute('download', fileName);
|
|
106
|
+
document.body.appendChild(fileLink);
|
|
107
|
+
fileLink.click();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Flat structure array ombouwen naar een array met children
|
|
113
|
+
* @param {array} entries
|
|
114
|
+
* @param {number} level
|
|
115
|
+
* @param {number | string} left
|
|
116
|
+
* @param {number | string} right
|
|
117
|
+
*/
|
|
118
|
+
export const getNestedSet = (entries: any[] = [], level: number = 1, left: any, right: any) => {
|
|
119
|
+
return entries
|
|
120
|
+
.filter((item) => {
|
|
121
|
+
return (
|
|
122
|
+
parseFloat(item.level) === level &&
|
|
123
|
+
((typeof left === 'undefined' && typeof right === 'undefined') ||
|
|
124
|
+
(parseFloat(item.lft) > left && parseFloat(item.rgt) < right))
|
|
125
|
+
);
|
|
126
|
+
})
|
|
127
|
+
.map((item) => {
|
|
128
|
+
const returnItem = item;
|
|
129
|
+
|
|
130
|
+
returnItem['children'] = getNestedSet(
|
|
131
|
+
entries,
|
|
132
|
+
parseFloat(item.level) + 1,
|
|
133
|
+
parseFloat(item.lft),
|
|
134
|
+
parseFloat(item.rgt),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return returnItem;
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Urls uit een string halen
|
|
143
|
+
* @param {string} content - html
|
|
144
|
+
*/
|
|
145
|
+
export const getUrlsFromString = (content: string) => {
|
|
146
|
+
const regex =
|
|
147
|
+
/(https?|ftp|file):\/\/([-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)/gi;
|
|
148
|
+
|
|
149
|
+
const m = content.match(regex);
|
|
150
|
+
|
|
151
|
+
return m || null;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Bepalen of een waarde leeg is
|
|
156
|
+
*
|
|
157
|
+
* @param {any} value
|
|
158
|
+
* @returns {boolean}
|
|
159
|
+
*/
|
|
160
|
+
export const isEmpty = (value): boolean => {
|
|
161
|
+
if (Array.isArray(value)) {
|
|
162
|
+
return !value.length;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (isPlainObject(value)) {
|
|
166
|
+
return !Object.keys(value).length;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (Number.isNaN(value)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return !value;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Bepalen of jouw device hover ondersteunt
|
|
178
|
+
*
|
|
179
|
+
* @returns {boolean}
|
|
180
|
+
*/
|
|
181
|
+
export const isHoverableDevice = (): boolean => {
|
|
182
|
+
return window.matchMedia('(hover: hover) and (pointer: fine)').matches;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Bekijken of een waarde een object is
|
|
187
|
+
* https://github.com/reduxjs/redux/blob/master/src/utils/isPlainObject.ts
|
|
188
|
+
*
|
|
189
|
+
* @param {any} value - Waarde welke je wilt checken of het een object is
|
|
190
|
+
* @returns {boolean}
|
|
191
|
+
*/
|
|
192
|
+
export const isPlainObject = (value: any): boolean => {
|
|
193
|
+
if (typeof value !== 'object' || value === null) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let proto = value;
|
|
198
|
+
|
|
199
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
200
|
+
proto = Object.getPrototypeOf(proto);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return Object.getPrototypeOf(value) === proto;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Bepalen of je gebruikt maakt van een touchscreen
|
|
208
|
+
* https://gist.github.com/esedic/39a16a7521d42ae205203e3d40dc19f5
|
|
209
|
+
*
|
|
210
|
+
* @returns {boolean}
|
|
211
|
+
*/
|
|
212
|
+
export const isTouchDevice = (): boolean => {
|
|
213
|
+
let result = false;
|
|
214
|
+
|
|
215
|
+
if (window.PointerEvent && 'maxTouchPoints' in navigator) {
|
|
216
|
+
// if Pointer Events are supported, just check maxTouchPoints
|
|
217
|
+
if (navigator.maxTouchPoints > 0) {
|
|
218
|
+
result = true;
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
// no Pointer Events...
|
|
222
|
+
if (window.matchMedia && window.matchMedia('(any-pointer:coarse)').matches) {
|
|
223
|
+
// check for any-pointer:coarse which mostly means touchscreen
|
|
224
|
+
result = true;
|
|
225
|
+
} else if (window.TouchEvent || 'ontouchstart' in window) {
|
|
226
|
+
// last resort - check for exposed touch events API / event handler
|
|
227
|
+
result = true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return result;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Bekijken of een waarde url is
|
|
236
|
+
*
|
|
237
|
+
* @param {any} urlString - Waarde welke je wilt checken of het een url is
|
|
238
|
+
* @returns {boolean}
|
|
239
|
+
*/
|
|
240
|
+
export const isValidUrl = (urlString: any) => {
|
|
241
|
+
if (typeof urlString !== 'string') {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const urlPattern = new RegExp(
|
|
246
|
+
'^(https?:\\/\\/)?' + // validate protocol
|
|
247
|
+
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
|
|
248
|
+
'((\\d{1,3}\\.){3}\\d{1,3}))' + // validate OR ip (v4) address
|
|
249
|
+
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path
|
|
250
|
+
'(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
|
|
251
|
+
'(\\#[-a-z\\d_]*)?$',
|
|
252
|
+
'i',
|
|
253
|
+
); // validate fragment locator
|
|
254
|
+
return !!urlPattern.test(urlString);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Resize observer; checkt of een HTML element zijn dimensies veranderen
|
|
259
|
+
* en zodra dat gebeurt wordt de callback functie gecalled.
|
|
260
|
+
*
|
|
261
|
+
* @param {HTMLElement} el
|
|
262
|
+
* @param {Function} callback
|
|
263
|
+
*/
|
|
264
|
+
export const observeResize = (element: HTMLElement, callback: Function) => {
|
|
265
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
266
|
+
callback(element);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
if (element) {
|
|
270
|
+
resizeObserver.observe(element);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Wrap een element in een nieuw element
|
|
276
|
+
*
|
|
277
|
+
* @param {HTMLElement} el
|
|
278
|
+
* @param {HTMLElement} wrapper
|
|
279
|
+
*/
|
|
280
|
+
export const wrap = (el: HTMLElement, wrapper: HTMLElement) => {
|
|
281
|
+
if (el.parentNode) {
|
|
282
|
+
el.parentNode.insertBefore(wrapper, el);
|
|
283
|
+
wrapper.appendChild(el);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getParents = exports.$$ = exports.$ = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Selecteer eerste item wat je tegenkomt
|
|
6
3
|
*
|
|
@@ -8,11 +5,9 @@ exports.getParents = exports.$$ = exports.$ = void 0;
|
|
|
8
5
|
* @param {*} [containerElement=document] - Element waarin hij moet selecteren
|
|
9
6
|
* @returns {(HTMLElement|null)}
|
|
10
7
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
exports.$ = $;
|
|
8
|
+
export const $ = (selector: string, containerElement: any = document): HTMLElement | null =>
|
|
9
|
+
containerElement.querySelector(selector);
|
|
10
|
+
|
|
16
11
|
/**
|
|
17
12
|
* Selecteer alle items
|
|
18
13
|
*
|
|
@@ -20,11 +15,9 @@ exports.$ = $;
|
|
|
20
15
|
* @param {*} [containerElement=document] - Element waarin hij moet selecteren
|
|
21
16
|
* @returns {HTMLElement[]}
|
|
22
17
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
exports.$$ = $$;
|
|
18
|
+
export const $$ = (selector: string, containerElement: any = document): HTMLElement[] =>
|
|
19
|
+
Array.prototype.slice.apply(containerElement.querySelectorAll(selector));
|
|
20
|
+
|
|
28
21
|
/**
|
|
29
22
|
* Haal parents van een element op
|
|
30
23
|
*
|
|
@@ -32,20 +25,22 @@ exports.$$ = $$;
|
|
|
32
25
|
* @param {string} [parentSelector] - Een selector waar hij aan moet voldoen.
|
|
33
26
|
* Als deze niet wordt meegegeven dan geeft hij alle parents terug
|
|
34
27
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
export const getParents = (el: HTMLElement, parentSelector: string = '') => {
|
|
29
|
+
const parents: HTMLElement[] = [];
|
|
30
|
+
let p = el.parentElement;
|
|
31
|
+
|
|
39
32
|
// Tot de body omhoog bubbelen
|
|
40
33
|
while (p && p.tagName !== 'BODY') {
|
|
41
|
-
|
|
34
|
+
const o = p;
|
|
35
|
+
|
|
42
36
|
// Als er geen selector is meegegeven, dan het element toevoegen
|
|
43
37
|
// Of als er een selector is meegegeven en hij matcht, dan het element toevoegen
|
|
44
38
|
if (parentSelector === '' || o.matches(parentSelector)) {
|
|
45
39
|
parents.push(o);
|
|
46
40
|
}
|
|
41
|
+
|
|
47
42
|
p = o.parentElement;
|
|
48
43
|
}
|
|
44
|
+
|
|
49
45
|
return parents;
|
|
50
46
|
};
|
|
51
|
-
exports.getParents = getParents;
|