1 import {sizeToPixels} from "../../../utils/dom";
2 import {SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
3 import {elem} from "../../../../services/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 interface NodeHasAlignment {
11 readonly __alignment: CommonBlockAlignment;
12 setAlignment(alignment: CommonBlockAlignment): void;
13 getAlignment(): CommonBlockAlignment;
16 export interface NodeHasId {
17 readonly __id: string;
18 setId(id: string): void;
22 export interface NodeHasInset {
23 readonly __inset: number;
24 setInset(inset: number): void;
28 export interface NodeHasDirection {
29 readonly __dir: EditorNodeDirection;
30 setDirection(direction: EditorNodeDirection): void;
31 getDirection(): EditorNodeDirection;
34 export interface CommonBlockInterface extends NodeHasId, NodeHasAlignment, NodeHasInset, NodeHasDirection {}
36 export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment {
37 const textAlignStyle: string = element.style.textAlign || '';
38 if (validAlignments.includes(textAlignStyle as CommonBlockAlignment)) {
39 return textAlignStyle as CommonBlockAlignment;
42 if (element.classList.contains('align-left')) {
44 } else if (element.classList.contains('align-right')) {
46 } else if (element.classList.contains('align-center')) {
48 } else if (element.classList.contains('align-justify')) {
55 export function extractInsetFromElement(element: HTMLElement): number {
56 const elemPadding: string = element.style.paddingLeft || '0';
57 return sizeToPixels(elemPadding);
60 export function extractDirectionFromElement(element: HTMLElement): EditorNodeDirection {
61 const elemDir = (element.dir || '').toLowerCase();
62 if (elemDir === 'rtl' || elemDir === 'ltr') {
69 export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void {
71 node.setId(element.id);
74 node.setAlignment(extractAlignmentFromElement(element));
75 node.setInset(extractInsetFromElement(element));
76 node.setDirection(extractDirectionFromElement(element));
79 export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean {
80 return nodeA.__id !== nodeB.__id ||
81 nodeA.__alignment !== nodeB.__alignment ||
82 nodeA.__inset !== nodeB.__inset ||
83 nodeA.__dir !== nodeB.__dir;
86 export function applyCommonPropertyChanges(prevNode: CommonBlockInterface, currentNode: CommonBlockInterface, element: HTMLElement): void {
87 if (prevNode.__id !== currentNode.__id) {
88 element.setAttribute('id', currentNode.__id);
91 if (prevNode.__alignment !== currentNode.__alignment) {
92 for (const alignment of validAlignments) {
93 element.classList.remove('align-' + alignment);
96 if (currentNode.__alignment) {
97 element.classList.add('align-' + currentNode.__alignment);
101 if (prevNode.__inset !== currentNode.__inset) {
102 if (currentNode.__inset) {
103 element.style.paddingLeft = `${currentNode.__inset}px`;
105 element.style.removeProperty('paddingLeft');
109 if (prevNode.__dir !== currentNode.__dir) {
110 if (currentNode.__dir) {
111 element.dir = currentNode.__dir;
113 element.removeAttribute('dir');
118 export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void {
120 element.setAttribute('id', node.__id);
123 if (node.__alignment) {
124 element.classList.add('align-' + node.__alignment);
128 element.style.paddingLeft = `${node.__inset}px`;
132 element.dir = node.__dir;
136 export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void {
137 node.setId(serializedNode.id);
138 node.setAlignment(serializedNode.alignment);
139 node.setInset(serializedNode.inset);
140 node.setDirection(serializedNode.direction);
143 export interface NodeHasSize {
144 setHeight(height: number): void;
145 setWidth(width: number): void;