1 import {LexicalNode, Spread} from "lexical";
2 import type {SerializedElementNode} from "lexical/nodes/LexicalElementNode";
3 import {el, sizeToPixels} from "../utils/dom";
5 export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | '';
6 const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify'];
8 type EditorNodeDirection = 'ltr' | 'rtl' | null;
10 export type SerializedCommonBlockNode = Spread<{
12 alignment: CommonBlockAlignment;
14 }, SerializedElementNode>
16 export interface NodeHasAlignment {
17 readonly __alignment: CommonBlockAlignment;
18 setAlignment(alignment: CommonBlockAlignment): void;
19 getAlignment(): CommonBlockAlignment;
22 export interface NodeHasId {
23 readonly __id: string;
24 setId(id: string): void;
28 export interface NodeHasInset {
29 readonly __inset: number;
30 setInset(inset: number): void;
34 export interface NodeHasDirection {
35 readonly __dir: EditorNodeDirection;
36 setDirection(direction: EditorNodeDirection): void;
37 getDirection(): EditorNodeDirection;
40 interface CommonBlockInterface extends NodeHasId, NodeHasAlignment, NodeHasInset, NodeHasDirection {}
42 export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment {
43 const textAlignStyle: string = element.style.textAlign || '';
44 if (validAlignments.includes(textAlignStyle as CommonBlockAlignment)) {
45 return textAlignStyle as CommonBlockAlignment;
48 if (element.classList.contains('align-left')) {
50 } else if (element.classList.contains('align-right')) {
52 } else if (element.classList.contains('align-center')) {
54 } else if (element.classList.contains('align-justify')) {
61 export function extractInsetFromElement(element: HTMLElement): number {
62 const elemPadding: string = element.style.paddingLeft || '0';
63 return sizeToPixels(elemPadding);
66 export function extractDirectionFromElement(element: HTMLElement): EditorNodeDirection {
67 const elemDir = (element.dir || '').toLowerCase();
68 if (elemDir === 'rtl' || elemDir === 'ltr') {
75 export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void {
77 node.setId(element.id);
80 node.setAlignment(extractAlignmentFromElement(element));
81 node.setInset(extractInsetFromElement(element));
82 node.setDirection(extractDirectionFromElement(element));
85 export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean {
86 return nodeA.__id !== nodeB.__id ||
87 nodeA.__alignment !== nodeB.__alignment ||
88 nodeA.__inset !== nodeB.__inset ||
89 nodeA.__dir !== nodeB.__dir;
92 export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void {
94 element.setAttribute('id', node.__id);
97 if (node.__alignment) {
98 element.classList.add('align-' + node.__alignment);
102 element.style.paddingLeft = `${node.__inset}px`;
106 element.dir = node.__dir;
110 export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void {
111 node.setId(serializedNode.id);
112 node.setAlignment(serializedNode.alignment);
113 node.setInset(serializedNode.inset);
114 node.setDirection(serializedNode.direction);
117 export interface NodeHasSize {
118 setHeight(height: number): void;
119 setWidth(width: number): void;