mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Added direction support to extra blocks
Also removed duplicated dir functionality that remained in core.
This commit is contained in:
parent
e6edd9340e
commit
2add15bd72
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
Loading…
Reference in New Issue
Block a user