]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/utils/dom.ts
Lexical: Changed table esacpe handling
[bookstack] / resources / js / wysiwyg / utils / dom.ts
1 export function el(tag: string, attrs: Record<string, string | null> = {}, children: (string | HTMLElement)[] = []): HTMLElement {
2     const el = document.createElement(tag);
3     const attrKeys = Object.keys(attrs);
4     for (const attr of attrKeys) {
5         if (attrs[attr] !== null) {
6             el.setAttribute(attr, attrs[attr] as string);
7         }
8     }
9
10     for (const child of children) {
11         if (typeof child === 'string') {
12             el.append(document.createTextNode(child));
13         } else {
14             el.append(child);
15         }
16     }
17
18     return el;
19 }
20
21 export function htmlToDom(html: string): Document {
22     const parser = new DOMParser();
23     return parser.parseFromString(html, 'text/html');
24 }
25
26 export function formatSizeValue(size: number | string, defaultSuffix: string = 'px'): string {
27     if (typeof size === 'number' || /^-?\d+$/.test(size)) {
28         return `${size}${defaultSuffix}`;
29     }
30
31     return size;
32 }
33
34 export function sizeToPixels(size: string): number {
35     if (/^-?\d+$/.test(size)) {
36         return Number(size);
37     }
38
39     if (/^-?\d+\.\d+$/.test(size)) {
40         return Math.round(Number(size));
41     }
42
43     if (/^-?\d+px\s*$/.test(size)) {
44         return Number(size.trim().replace('px', ''));
45     }
46
47     return 0;
48 }
49
50 export type StyleMap = Map<string, string>;
51
52 /**
53  * Creates a map from an element's styles.
54  * Uses direct attribute value string handling since attempting to iterate
55  * over .style will expand out any shorthand properties (like 'padding') making
56  * rather than being representative of the actual properties set.
57  */
58 export function extractStyleMapFromElement(element: HTMLElement): StyleMap {
59     const map: StyleMap = new Map();
60     const styleText= element.getAttribute('style') || '';
61
62     const rules = styleText.split(';');
63     for (const rule of rules) {
64         const [name, value] = rule.split(':');
65         if (!name || !value) {
66             continue;
67         }
68
69         map.set(name.trim().toLowerCase(), value.trim());
70     }
71
72     return map;
73 }
74
75 export function setOrRemoveAttribute(element: HTMLElement, name: string, value: string|null|undefined) {
76     if (value) {
77         element.setAttribute(name, value);
78     } else {
79         element.removeAttribute(name);
80     }
81 }