generated from shgysk8zer0/npm-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstringify.js
More file actions
148 lines (126 loc) · 4.32 KB
/
stringify.js
File metadata and controls
148 lines (126 loc) · 4.32 KB
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// import { styleSheetToLink } from './parsers/css.js';
import { createCallback } from '@aegisjsproject/callback-registry/callbackRegistry.js';
import { registerSignal, registerController } from '@aegisjsproject/callback-registry/callbackRegistry.js';
import { stringifyAttr, createAttribute } from './dom.js';
import { registerBlob } from './blob-registry.js';
const toData = ([name, val]) => ['data-' + name.replaceAll(/[A-Z]/g, c => `-${c.toLowerCase()}`), val];
export const attr = attrs => Object.entries(attrs).map(([attr, val]) => {
switch(typeof val) {
case 'string':
return createAttribute(attr, val);
case 'number':
case 'bigint':
return Number.isNaN(val) ? undefined : createAttribute(attr, val.toString());
case 'boolean':
return val ? createAttribute(attr) : undefined;
case 'undefined':
return undefined;
case 'function':
return createCallback(val);
case 'object':
if (val === null) {
return undefined;
} else if (val instanceof URL) {
return createAttribute(attr, val.href);
} else if (val instanceof Date) {
return createAttribute(attr, val.toISOString());
} else {
return createAttribute(attr, val.toString());
}
case 'symbol':
return createAttribute(attr, val.description);
default:
return createAttribute(attr, val.toString());
}
}).filter(attr => attr instanceof Attr)
.map(stringifyAttr)
.join(' ');
export function data(dataObj) {
return attr(Object.fromEntries(Object.entries(dataObj).map(toData)));
}
export const DATE_FORMAT = {
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
};
export const formatDate = (date, {
weekday = DATE_FORMAT.weekday,
month = DATE_FORMAT.month,
day = DATE_FORMAT.day,
year = DATE_FORMAT.year,
hour = DATE_FORMAT.hour,
minute = DATE_FORMAT.minute,
} = DATE_FORMAT) => date.toLocaleString(navigator.language, {
weekday, month, day, year, hour, minute,
});
const formatArray = 'Intl' in globalThis && Intl.ListFormat instanceof Function
? arr => new Intl.ListFormat().format(arr.map(stringify))
: arr => arr.join(', ');
const formatNumber = 'Intl' in globalThis && Intl.NumberFormat instanceof Function
? num => new Intl.NumberFormat().format(num)
: num => num.toString();
export const stringify = thing => {
switch(typeof thing) {
case 'string':
return thing;
case 'boolean':
return thing ? 'true' : 'false';
case 'symbol':
return thing.description;
case 'number':
case 'bigint':
return formatNumber(thing);
case 'undefined':
return '';
case 'function':
return createCallback(thing);
case 'object':
if (thing === null) {
return '';
} else if (Array.isArray(thing)) {
return formatArray(thing);
} else if (thing instanceof HTMLTemplateElement) {
const el = document.createElement('div');
el.append(thing.content.cloneNode(true));
return el.innerHTML;
} else if (thing instanceof Element) {
return thing.outerHTML;
} else if (thing instanceof DocumentFragment) {
const el = document.createElement('div');
el.append(thing.cloneNode(true));
return el.innerHTML;
} else if (thing instanceof CSSStyleSheet) {
document.adoptedStyleSheets = [...document.adoptedStyleSheets, thing];
break;
} else if (thing instanceof Blob) {
return registerBlob(thing);
} else if(thing instanceof Date) {
return formatDate(thing);
} else if (thing instanceof DOMTokenList) {
return [...thing].join(' ');
} else if (thing instanceof NodeList || thing instanceof HTMLCollection || thing instanceof HTMLFormControlsCollection) {
return [...thing].map(el => el.outerHTML).join('\n');
} else if (thing instanceof MediaList) {
return thing.mediaText;
} else if (thing instanceof Attr) {
return stringifyAttr(thing);
} else if (thing instanceof NamedNodeMap) {
return Array.from(thing, stringifyAttr).join(' ');
} else if ('TrustedType' in globalThis && thing instanceof globalThis.TrustedType) {
return thing;
} else if ('Iterator' in globalThis && thing instanceof globalThis.Iterator) {
return stringify([...thing]);
} else if (thing instanceof AbortSignal) {
return registerSignal(thing);
} else if (thing instanceof AbortController) {
return registerController(thing);
} else {
return thing.toString();
}
default:
return thing.toString();
}
};