Also removed duplicated dir functionality that remained in core.
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
const node = $createParagraphNode();
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
- node.setDirection(serializedNode.direction);
node.setTextFormat(serializedNode.textFormat);
return node;
}
const formatType = this.getFormatType();
element.style.textAlign = formatType;
-
- const direction = this.getDirection();
- if (direction) {
- element.dir = direction;
- }
}
return {
const node = $createQuoteNode();
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
- node.setDirection(serializedNode.direction);
return node;
}
const formatType = this.getFormatType();
element.style.textAlign = formatType;
-
- const direction = this.getDirection();
- if (direction) {
- element.dir = direction;
- }
}
return {
const node = $createHeadingNode(serializedNode.tag);
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
- node.setDirection(serializedNode.direction);
return node;
}
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;
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<{
static clone(node: CustomListNode) {
const newNode = new CustomListNode(node.__listType, node.__start, node.__key);
newNode.__id = node.__id;
+ newNode.__dir = node.__dir;
return newNode;
}
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(),
static importJSON(serializedNode: SerializedCustomListNode): CustomListNode {
const node = $createCustomListNode(serializedNode.listType);
node.setId(serializedNode.id);
+ node.setDirection(serializedNode.direction);
return node;
}
(baseResult.node as CustomListNode).setId(element.id);
}
+ if (element.dir && baseResult?.node) {
+ (baseResult.node as CustomListNode).setDirection(extractDirectionFromElement(element));
+ }
+
if (baseResult) {
baseResult.after = $normalizeChildren;
}
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;
static clone(node: DetailsNode): DetailsNode {
const newNode = new DetailsNode(node.__key);
newNode.__id = node.__id;
+ newNode.__dir = node.__dir;
return newNode;
}
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 {
node.setId(element.id);
}
+ if (element.dir) {
+ node.setDirection(extractDirectionFromElement(element));
+ }
+
return {node};
},
priority: 3,
static importJSON(serializedNode: SerializedDetailsNode): DetailsNode {
const node = $createDetailsNode();
node.setId(serializedNode.id);
+ node.setDirection(serializedNode.direction);
return node;
}
## 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
- 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
\ No newline at end of file
+- 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)
\ No newline at end of file