]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/utils/dom.ts
Updated version and assets for release v25.05.1
[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')
56  * rather than being representative of the actual properties set.
57  */
58 export function extractStyleMapFromElement(element: HTMLElement): StyleMap {
59     const styleText= element.getAttribute('style') || '';
60     return styleStringToStyleMap(styleText);
61 }
62
63 /**
64  * Convert string-formatted styles into a StyleMap.
65  */
66 export function styleStringToStyleMap(styleText: string): StyleMap {
67     const map: StyleMap = new Map();
68
69     const rules = styleText.split(';');
70     for (const rule of rules) {
71         const [name, value] = rule.split(':');
72         if (!name || !value) {
73             continue;
74         }
75
76         map.set(name.trim().toLowerCase(), value.trim());
77     }
78
79     return map;
80 }
81
82 /**
83  * Convert a StyleMap into inline string style text.
84  */
85 export function styleMapToStyleString(map: StyleMap): string {
86     const parts = [];
87     for (const [style, value] of map.entries()) {
88         parts.push(`${style}:${value}`);
89     }
90     return parts.join(';');
91 }
92
93 export function setOrRemoveAttribute(element: HTMLElement, name: string, value: string|null|undefined) {
94     if (value) {
95         element.setAttribute(name, value);
96     } else {
97         element.removeAttribute(name);
98     }
99 }