diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts
index 9f832b69e..534663a54 100644
--- a/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts
+++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts
@@ -82,7 +82,7 @@ describe('HTMLCopyAndPaste tests', () => {
pastedHTML: ` 123
done
todo
done
todo
todo
Hello\tworld
Hello\tworld
', + 'Hello\tworld
Hello\tworld
', ); }); diff --git a/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTextNode.test.ts b/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTextNode.test.ts index 57e1dcb3b..b1ea099ac 100644 --- a/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTextNode.test.ts +++ b/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTextNode.test.ts @@ -8,7 +8,7 @@ import { $createParagraphNode, - $createTextNode, + $createTextNode, $getEditor, $getNodeByKey, $getRoot, $getSelection, @@ -41,6 +41,9 @@ import { $setCompositionKey, getEditorStateTextContent, } from '../../../LexicalUtils'; +import {Text} from "@codemirror/state"; +import {$generateHtmlFromNodes} from "@lexical/html"; +import {formatBold} from "@lexical/selection/__tests__/utils"; const editorConfig = Object.freeze({ namespace: '', @@ -792,6 +795,58 @@ describe('LexicalTextNode tests', () => { ); }); + describe('exportDOM()', () => { + + test('simple text exports as a text node', async () => { + await update(() => { + const paragraph = $getRoot().getFirstChildhello
'); + }); + }); + + test('simple text wrapped in span if leading or ending spacing', async () => { + + const textByExpectedHtml = { + 'hello ': 'hello
', + ' hello': 'hello
', + ' hello ': 'hello
', + } + + await update(() => { + const paragraph = $getRoot().getFirstChildhello
hello world
', + 'hello world
', ); }); }); diff --git a/resources/js/wysiwyg/lexical/html/__tests__/unit/LexicalHtml.test.ts b/resources/js/wysiwyg/lexical/html/__tests__/unit/LexicalHtml.test.ts index 3dbe5da8b..947e591b4 100644 --- a/resources/js/wysiwyg/lexical/html/__tests__/unit/LexicalHtml.test.ts +++ b/resources/js/wysiwyg/lexical/html/__tests__/unit/LexicalHtml.test.ts @@ -102,7 +102,7 @@ describe('HTML', () => { html = $generateHtmlFromNodes(editor, selection); }); - expect(html).toBe('World'); + expect(html).toBe('World'); }); test(`[Lexical -> HTML]: Default selection (undefined) should serialize entire editor state`, () => { @@ -145,7 +145,7 @@ describe('HTML', () => { }); expect(html).toBe( - 'Hello
World
', + 'Hello
World
', ); }); @@ -175,7 +175,7 @@ describe('HTML', () => { }); expect(html).toBe( - 'Hello world!
', + 'Hello world!
', ); }); @@ -205,7 +205,7 @@ describe('HTML', () => { }); expect(html).toBe( - 'Hello world!
', + 'Hello world!
', ); }); }); diff --git a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts index abc509629..6848e5532 100644 --- a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts +++ b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts @@ -115,7 +115,7 @@ describe('LexicalTableNode tests', () => { // Make sure paragraph is inserted inside empty cells const emptyCell = 'Hello there | General Kenobi! |
Lexical is nice | ${emptyCell}
Hello there | General Kenobi! |
Lexical is nice | ${emptyCell}
Get schwifty!
Get schwifty!
Get schwifty!
Get schwifty!
Get schwifty!
Get schwifty!
Get schwifty!
Get schwifty!
Hello
world
', + 'Hello
world
', initialHtml: 'Helloworld
', splitOffset: 1, splitPath: [0], @@ -46,7 +46,7 @@ describe('LexicalUtils#splitNode', () => { { _: 'split paragraph before the first text node', expectedHtml: - 'Helloworld
', + 'Helloworld
', initialHtml: 'Helloworld
', splitOffset: 0, splitPath: [0], @@ -54,7 +54,7 @@ describe('LexicalUtils#splitNode', () => { { _: 'split paragraph after the last text node', expectedHtml: - 'Helloworld
Helloworld
Helloworld
', splitOffset: 2, // Any offset that is higher than children size splitPath: [0], @@ -62,8 +62,8 @@ describe('LexicalUtils#splitNode', () => { { _: 'split list items between two text nodes', expectedHtml: - 'Hello
world
', + 'Hello
world
', initialHtml: 'Helloworld
', selectionOffset: 5, // Selection on text node after "Hello" world selectionPath: [0, 0], @@ -55,13 +55,13 @@ describe('LexicalUtils#insertNodeToNearestRoot', () => { _: 'insert into nested list items', expectedHtml: 'Hello world
' + + 'Hello world
' + 'Hello world
', @@ -94,7 +94,7 @@ describe('LexicalUtils#insertNodeToNearestRoot', () => { expectedHtml: 'Hello world
', + 'Hello world
', initialHtml: 'Hello world
', selectionOffset: 0, // Selection on text node after "Hello" world selectionPath: [0, 0], @@ -104,8 +104,8 @@ describe('LexicalUtils#insertNodeToNearestRoot', () => { expectedHtml: 'Before
' + - 'After
', + 'Before
' + + 'After
', initialHtml: 'Before
' + @@ -116,9 +116,9 @@ describe('LexicalUtils#insertNodeToNearestRoot', () => { { _: 'insert with selection on root child', expectedHtml: - 'Before
' + + 'Before
' + 'After
', + 'After
', initialHtml: 'Before
After
', selectionOffset: 1, selectionPath: [], @@ -126,7 +126,7 @@ describe('LexicalUtils#insertNodeToNearestRoot', () => { { _: 'insert with selection on root end', expectedHtml: - 'Before
' + + 'Before
' + 'Before
', selectionOffset: 1, diff --git a/resources/js/wysiwyg/todo.md b/resources/js/wysiwyg/todo.md index 31e3533b1..bcd4851e8 100644 --- a/resources/js/wysiwyg/todo.md +++ b/resources/js/wysiwyg/todo.md @@ -7,7 +7,6 @@ ## Main Todo - Mac: Shortcut support via command. -- Update toolbar overflows to match existing editor, incl. direction dynamic controls ## Secondary Todo @@ -16,9 +15,9 @@ - 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) - Deep check of translation coverage +- About button & view +- Mobile display and handling ## Bugs -- Editor theme classes remain on items after export -- List selection can get lost on nesting/unnesting -- Content not properly saving on new pages \ No newline at end of file +- List selection can get lost on nesting/unnesting \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/framework/manager.ts b/resources/js/wysiwyg/ui/framework/manager.ts index 732530375..7c0975da7 100644 --- a/resources/js/wysiwyg/ui/framework/manager.ts +++ b/resources/js/wysiwyg/ui/framework/manager.ts @@ -163,6 +163,10 @@ export class EditorUIManager { }); } + getDefaultDirection(): 'rtl' | 'ltr' { + return this.getContext().options.textDirection === 'rtl' ? 'rtl' : 'ltr'; + } + protected updateContextToolbars(update: EditorUiStateUpdate): void { for (let i = this.activeContextToolbars.length - 1; i >= 0; i--) { const toolbar = this.activeContextToolbars[i]; diff --git a/resources/js/wysiwyg/ui/index.ts b/resources/js/wysiwyg/ui/index.ts index 8bfdb8965..3811f44b9 100644 --- a/resources/js/wysiwyg/ui/index.ts +++ b/resources/js/wysiwyg/ui/index.ts @@ -32,7 +32,7 @@ export function buildEditorUI(container: HTMLElement, element: HTMLElement, scro manager.setContext(context); // Create primary toolbar - manager.setToolbar(getMainEditorFullToolbar()); + manager.setToolbar(getMainEditorFullToolbar(context)); // Register modals for (const key of Object.keys(modals)) { diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts index b064a2a9f..35146e5a4 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/toolbars.ts @@ -1,5 +1,5 @@ import {EditorButton} from "./framework/buttons"; -import {EditorContainerUiElement, EditorSimpleClassContainer, EditorUiElement} from "./framework/core"; +import {EditorContainerUiElement, EditorSimpleClassContainer, EditorUiContext, EditorUiElement} from "./framework/core"; import {EditorFormatMenu} from "./framework/blocks/format-menu"; import {FormatPreviewButton} from "./framework/blocks/format-preview-button"; import {EditorDropdownButton} from "./framework/blocks/dropdown-button"; @@ -80,7 +80,10 @@ import {el} from "../utils/dom"; import {EditorButtonWithMenu} from "./framework/blocks/button-with-menu"; import {EditorSeparator} from "./framework/blocks/separator"; -export function getMainEditorFullToolbar(): EditorContainerUiElement { +export function getMainEditorFullToolbar(context: EditorUiContext): EditorContainerUiElement { + + const inRtlMode = context.manager.getDefaultDirection() === 'rtl'; + return new EditorSimpleClassContainer('editor-toolbar-main', [ // History state @@ -124,17 +127,17 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement { ]), // Alignment - new EditorOverflowContainer(6, [ // TODO - Dynamic + new EditorOverflowContainer(6, [ new EditorButton(alignLeft), new EditorButton(alignCenter), new EditorButton(alignRight), new EditorButton(alignJustify), - new EditorButton(directionLTR), // TODO - Dynamic - new EditorButton(directionRTL), // TODO - Dynamic - ]), + inRtlMode ? new EditorButton(directionLTR) : null, + inRtlMode ? new EditorButton(directionRTL) : null, + ].filter(x => x !== null)), // Lists - new EditorOverflowContainer(5, [ + new EditorOverflowContainer(3, [ new EditorButton(bulletList), new EditorButton(numberList), new EditorButton(taskList), diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss index 91aef9920..b33cb4d05 100644 --- a/resources/sass/_editor.scss +++ b/resources/sass/_editor.scss @@ -27,6 +27,7 @@ body.editor-is-fullscreen { } .editor-content-area { min-height: 100%; + padding-block: 1rem; &:focus { outline: 0; } @@ -136,7 +137,6 @@ body.editor-is-fullscreen { background-color: #FFF; box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.15); z-index: 99; - min-width: 120px; display: flex; flex-direction: row; } diff --git a/resources/sass/_pages.scss b/resources/sass/_pages.scss index 6e6f7bb7e..426f7961c 100755 --- a/resources/sass/_pages.scss +++ b/resources/sass/_pages.scss @@ -35,12 +35,15 @@ } @include larger-than($xxl) { + .page-editor-wysiwyg2024 .page-edit-toolbar, + .page-editor-wysiwyg2024 .page-editor-page-area, .page-editor-wysiwyg .page-edit-toolbar, .page-editor-wysiwyg .page-editor-page-area { max-width: 1140px; } - .page-editor-wysiwyg .floating-toolbox { + .page-editor-wysiwyg .floating-toolbox, + .page-editor-wysiwyg2024 .floating-toolbox { position: absolute; } }