split-with-kerning
Version:
Split a text into words and letters and respect the kerning
129 lines (128 loc) • 3.28 kB
JavaScript
function x(e, t, r) {
if (!e) return 0;
const o = e.charToGlyph(t), i = e.charToGlyph(r);
if (!o || !i) return 0;
let u = e.getKerningValue(o, i);
return u /= e.unitsPerEm, u;
}
function w(e) {
const t = {};
for (const r of e.kerningPairs)
for (const o of r.left)
for (const i of r.right)
t[o + i] = r.value;
return {
unitsPerEm: e.unitsPerEm,
kerningPairs: t
};
}
function C(e, t, r = {}) {
var p;
if (!e)
throw new Error("Element is required");
const { wordSelector: o = ".word", charSelector: i = ".char" } = r, u = Array.from(e.querySelectorAll(o)), d = [];
for (const n of u) {
const c = Array.from(
n.querySelectorAll(i)
);
for (let s = 0; s < c.length; s++) {
const f = c[s];
if (f.textContent) {
const a = t(
f.textContent,
((p = c[s + 1]) == null ? void 0 : p.textContent) ?? ""
);
d.push({
element: f,
margin: `${a}em`
});
}
}
}
if (d.length > 0)
for (const { element: n, margin: c } of d)
n.style.marginInlineEnd = c;
}
function T(e, t, r = {}) {
C(
e,
(o, i) => x(t, o, i),
r
);
}
function y(e, t, r = {}) {
C(
e,
(o, i) => (t.kerningPairs[`${o}${i}`] ?? 0) / t.unitsPerEm,
r
);
}
function N(e, t = "letter") {
const r = e.innerHTML, o = e.getAttribute("aria-label"), i = {
value: e.textContent ?? "",
words: [],
element: e
};
function u(n) {
var f;
const c = document.createDocumentFragment();
let s = [];
t === "none" ? s = [n.textContent ?? ""] : s = ((f = n.textContent) == null ? void 0 : f.split(/(\s+)/)) ?? [];
for (const a of s)
if (!a.trim())
c.appendChild(document.createTextNode(a));
else {
const l = document.createElement("span");
l.ariaHidden = "true", l.className = "word";
const g = {
value: a,
element: l
};
if (t === "word")
l.textContent = a;
else if (t === "none")
l.textContent = a;
else {
g.letters = [];
for (const m of a) {
const h = document.createElement("span");
h.ariaHidden = "true", h.className = "char", h.textContent = m, l.appendChild(h);
const E = {
value: m,
element: h
};
g.letters.push(E);
}
}
i.words.push(g), c.appendChild(l);
}
return c;
}
function d(n) {
if (n.nodeType === Node.TEXT_NODE)
return u(n);
if (n.nodeType === Node.ELEMENT_NODE) {
const c = n.cloneNode(!1);
for (const s of n.childNodes)
c.appendChild(d(s));
return c;
}
return document.createDocumentFragment();
}
const p = document.createDocumentFragment();
for (const n of [...e.childNodes])
p.appendChild(d(n));
return e.ariaLabel = e.textContent ?? "", e.innerHTML = "", e.appendChild(p), {
reset: () => {
e.innerHTML = r, o ? e.setAttribute("aria-label", o) : e.removeAttribute("aria-label");
},
splitted: i
};
}
export {
y as applyKerningFromExport,
T as applyKerningFromFont,
w as convertOptimizedToKerningPairs,
x as getKerningValue,
N as splitText
};