-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathformat.js
80 lines (67 loc) · 2.46 KB
/
format.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
import {format as isoformat} from "isoformat";
import {html} from "htl";
// Note: use formatAuto (or any other localized format) to present values to the
// user; stringify is only intended for machine values.
export function stringify(x) {
return x == null ? "" : `${x}`;
}
export const formatLocaleAuto = localize(locale => {
const formatNumber = formatLocaleNumber(locale);
return value => value == null ? ""
: typeof value === "number" ? formatNumber(value)
: value instanceof Date ? formatDate(value)
: `${value}`;
});
export const formatLocaleNumber = localize(locale => {
return value => value === 0 ? "0" : value.toLocaleString(locale); // handle negative zero
});
export function formatObjects(format, circular = true) {
return value => value === null ? gray("null")
: value === undefined ? gray("undefined")
: Number.isNaN(value) ? gray(NaN)
: circular && Array.isArray(value) ? formatArray(value)
: circular && isTypedArray(value) ? formatArray(value)
: value instanceof Date ? formatDate(value)
: circular && value instanceof Node ? value
: circular && typeof value === "object" ? formatObject(value)
: format(value);
}
function isTypedArray(_) {
return _?.prototype?.__proto__?.constructor?.name == "TypedArray";
}
function formatObject(o) {
const subformat = formatObjects(formatAuto, false);
return `{${Object.entries(o).map(([key, value]) => `${key}: ${subformat(value)}`).join(", ")}}`;
}
function formatArray(value) {
const subformat = formatObjects(formatAuto, false);
const l = value.length;
value = Array.from({length: Math.min(30, l)}, (_, i) => subformat(value[i]));
return `[${value.join(", ")}${l > 30 ? "…" : "" }]`;
}
export const formatAuto = formatLocaleAuto();
export const formatNumber = formatLocaleNumber();
export function formatTrim(value) {
const s = value.toString();
const n = s.length;
let i0 = -1, i1;
out: for (let i = 1; i < n; ++i) {
switch (s[i]) {
case ".": i0 = i1 = i; break;
case "0": if (i0 === 0) i0 = i; i1 = i; break;
default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;
}
}
return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
}
export function formatDate(date) {
return isoformat(date, "Invalid Date");
}
// Memoize the last-returned locale.
export function localize(f) {
let key = localize, value;
return (locale = "en") => locale === key ? value : (value = f(key = locale));
}
function gray(label) {
return html`<span class=gray>${label}`;
}