Lexical: Added direction support to extra blocks

Also removed duplicated dir functionality that remained in core.
This commit is contained in:
Dan Brown 2024-09-22 12:07:24 +01:00
parent e6edd9340e
commit 2add15bd72
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 40 additions and 28 deletions

View File

@ -135,10 +135,6 @@ export class ParagraphNode extends ElementNode {
const formatType = this.getFormatType();
element.style.textAlign = formatType;
const direction = this.getDirection();
if (direction) {
element.dir = direction;
}
const indent = this.getIndent();
if (indent > 0) {
// padding-inline-start is not widely supported in email HTML, but
@ -156,7 +152,6 @@ export class ParagraphNode extends ElementNode {
const node = $createParagraphNode();
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
node.setDirection(serializedNode.direction);
node.setTextFormat(serializedNode.textFormat);
return node;
}

View File

@ -158,11 +158,6 @@ export class QuoteNode extends ElementNode {
const formatType = this.getFormatType();
element.style.textAlign = formatType;
const direction = this.getDirection();
if (direction) {
element.dir = direction;
}
}
return {
@ -174,7 +169,6 @@ export class QuoteNode extends ElementNode {
const node = $createQuoteNode();
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
node.setDirection(serializedNode.direction);
return node;
}
@ -324,11 +318,6 @@ export class HeadingNode extends ElementNode {
const formatType = this.getFormatType();
element.style.textAlign = formatType;
const direction = this.getDirection();
if (direction) {
element.dir = direction;
}
}
return {
@ -340,7 +329,6 @@ export class HeadingNode extends ElementNode {
const node = $createHeadingNode(serializedNode.tag);
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
node.setDirection(serializedNode.direction);
return node;
}

View File

@ -63,7 +63,7 @@ export function extractInsetFromElement(element: HTMLElement): number {
return sizeToPixels(elemPadding);
}
function extractDirectionFromElement(element: HTMLElement): EditorNodeDirection {
export function extractDirectionFromElement(element: HTMLElement): EditorNodeDirection {
const elemDir = (element.dir || '').toLowerCase();
if (elemDir === 'rtl' || elemDir === 'ltr') {
return elemDir;

View File

@ -1,12 +1,12 @@
import {
DOMConversionFn,
DOMConversionMap,
DOMConversionMap, EditorConfig,
LexicalNode,
Spread
} from "lexical";
import {EditorConfig} from "lexical/LexicalEditor";
import {$isListItemNode, ListItemNode, ListNode, ListType, SerializedListNode} from "@lexical/list";
import {$createCustomListItemNode} from "./custom-list-item";
import {extractDirectionFromElement} from "./_common";
export type SerializedCustomListNode = Spread<{
@ -33,6 +33,7 @@ export class CustomListNode extends ListNode {
static clone(node: CustomListNode) {
const newNode = new CustomListNode(node.__listType, node.__start, node.__key);
newNode.__id = node.__id;
newNode.__dir = node.__dir;
return newNode;
}
@ -42,9 +43,18 @@ export class CustomListNode extends ListNode {
dom.setAttribute('id', this.__id);
}
if (this.__dir) {
dom.setAttribute('dir', this.__dir);
}
return dom;
}
updateDOM(prevNode: ListNode, dom: HTMLElement, config: EditorConfig): boolean {
return super.updateDOM(prevNode, dom, config) ||
prevNode.__dir !== this.__dir;
}
exportJSON(): SerializedCustomListNode {
return {
...super.exportJSON(),
@ -57,6 +67,7 @@ export class CustomListNode extends ListNode {
static importJSON(serializedNode: SerializedCustomListNode): CustomListNode {
const node = $createCustomListNode(serializedNode.listType);
node.setId(serializedNode.id);
node.setDirection(serializedNode.direction);
return node;
}
@ -69,6 +80,10 @@ export class CustomListNode extends ListNode {
(baseResult.node as CustomListNode).setId(element.id);
}
if (element.dir && baseResult?.node) {
(baseResult.node as CustomListNode).setDirection(extractDirectionFromElement(element));
}
if (baseResult) {
baseResult.after = $normalizeChildren;
}

View File

@ -5,10 +5,11 @@ import {
LexicalEditor,
LexicalNode,
SerializedElementNode, Spread,
EditorConfig,
} from 'lexical';
import type {EditorConfig} from "lexical/LexicalEditor";
import {el} from "../utils/dom";
import {extractDirectionFromElement} from "./_common";
export type SerializedDetailsNode = Spread<{
id: string;
@ -34,6 +35,7 @@ export class DetailsNode extends ElementNode {
static clone(node: DetailsNode): DetailsNode {
const newNode = new DetailsNode(node.__key);
newNode.__id = node.__id;
newNode.__dir = node.__dir;
return newNode;
}
@ -43,11 +45,16 @@ export class DetailsNode extends ElementNode {
el.setAttribute('id', this.__id);
}
if (this.__dir) {
el.setAttribute('dir', this.__dir);
}
return el;
}
updateDOM(prevNode: DetailsNode, dom: HTMLElement) {
return prevNode.__id !== this.__id;
return prevNode.__id !== this.__id
|| prevNode.__dir !== this.__dir;
}
static importDOM(): DOMConversionMap|null {
@ -60,6 +67,10 @@ export class DetailsNode extends ElementNode {
node.setId(element.id);
}
if (element.dir) {
node.setDirection(extractDirectionFromElement(element));
}
return {node};
},
priority: 3,
@ -80,6 +91,7 @@ export class DetailsNode extends ElementNode {
static importJSON(serializedNode: SerializedDetailsNode): DetailsNode {
const node = $createDetailsNode();
node.setId(serializedNode.id);
node.setDirection(serializedNode.direction);
return node;
}

View File

@ -2,16 +2,14 @@
## In progress
- RTL/LTR support
- Basic implementation added
- Test across main range of content blocks
- Test that HTML is being set as expected
- Test editor defaults when between RTL/LTR modes
//
## Main Todo
- Mac: Shortcut support via command.
- Translations
- Form closing on submit
- Update toolbar overflows to match existing editor, incl. direction dynamic controls
## Secondary Todo
@ -19,7 +17,11 @@
- Color picker for color controls
- Table caption text support
- Support media src conversions (https://github.com/tinymce/tinymce/blob/release/6.6/modules/tinymce/src/plugins/media/main/ts/core/UrlPatterns.ts)
- Check translation coverage
## Bugs
- List selection can get lost on nesting/unnesting
- List selection can get lost on nesting/unnesting
- Can't escape lists when bottom element
- Content not properly saving on new pages
- BookStack UI (non-editor) shortcuts can trigger in editor (`/` for example)