]> BookStack Code Mirror - bookstack/commitdiff
Lexical: Started loading real content, Improved html loading
authorDan Brown <redacted>
Mon, 1 Jul 2024 14:10:22 +0000 (15:10 +0100)
committerDan Brown <redacted>
Mon, 1 Jul 2024 14:10:22 +0000 (15:10 +0100)
Added more styling/layout for buttons and main content area

resources/js/components/wysiwyg-editor.js
resources/js/wysiwyg/actions.ts
resources/js/wysiwyg/index.ts
resources/js/wysiwyg/ui/framework/buttons.ts
resources/sass/_editor.scss
resources/views/pages/parts/wysiwyg-editor.blade.php

index bdcdd5c51a0911e5b1f0d2f8a0941f55b2b5cf7a..2f0e660b19fc778644a6554a76c9db1c0bbaad58 100644 (file)
@@ -5,10 +5,10 @@ export class WysiwygEditor extends Component {
     setup() {
         this.elem = this.$el;
         this.editContainer = this.$refs.editContainer;
     setup() {
         this.elem = this.$el;
         this.editContainer = this.$refs.editContainer;
-        this.editContent = this.$refs.editContent;
+        this.input = this.$refs.input;
 
         window.importVersioned('wysiwyg').then(wysiwyg => {
 
         window.importVersioned('wysiwyg').then(wysiwyg => {
-            const editorContent = this.editContent.textContent;
+            const editorContent = this.input.value;
             wysiwyg.createPageEditorInstance(this.editContainer, editorContent);
         });
     }
             wysiwyg.createPageEditorInstance(this.editContainer, editorContent);
         });
     }
index bca31e51b7a9b300cee0dc48f74db59f36fd4e5e..3a32b82d8614785e149652da5a9d24b2595e3bc1 100644 (file)
@@ -1,17 +1,32 @@
-import {$getRoot, LexicalEditor} from "lexical";
+import {$createParagraphNode, $getRoot, $isTextNode, LexicalEditor} from "lexical";
 import {$generateHtmlFromNodes, $generateNodesFromDOM} from "@lexical/html";
 import {$generateHtmlFromNodes, $generateNodesFromDOM} from "@lexical/html";
+import {$createCustomParagraphNode} from "./nodes/custom-paragraph";
 
 
 export function setEditorContentFromHtml(editor: LexicalEditor, html: string) {
     const parser = new DOMParser();
     const dom = parser.parseFromString(html, 'text/html');
 
 
 
 export function setEditorContentFromHtml(editor: LexicalEditor, html: string) {
     const parser = new DOMParser();
     const dom = parser.parseFromString(html, 'text/html');
 
+    console.log(html);
     editor.update(() => {
     editor.update(() => {
-        const nodes = $generateNodesFromDOM(editor, dom);
+        // Empty existing
         const root = $getRoot();
         for (const child of root.getChildren()) {
             child.remove(true);
         }
         const root = $getRoot();
         for (const child of root.getChildren()) {
             child.remove(true);
         }
+
+        const nodes = $generateNodesFromDOM(editor, dom);
+
+        // Wrap top-level text nodes
+        for (let i = 0; i < nodes.length; i++) {
+            const node = nodes[i];
+            if ($isTextNode(node)) {
+                const paragraph = $createCustomParagraphNode();
+                paragraph.append(node);
+                nodes[i] = paragraph;
+            }
+        }
+
         root.append(...nodes);
     });
 }
         root.append(...nodes);
     });
 }
index 3ca01835f288d2625052469bed831752236197d0..b0ff896c76eb3e0eb239202a4feb242008a82021 100644 (file)
@@ -29,8 +29,12 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
 
     const editArea = el('div', {
         contenteditable: 'true',
 
     const editArea = el('div', {
         contenteditable: 'true',
+        class: 'editor-content-area page-content',
     });
     });
-    container.append(editArea);
+    const editWrap = el('div', {
+        class: 'editor-content-wrap',
+    }, [editArea]);
+    container.append(editWrap);
     container.classList.add('editor-container');
 
     const editor = createEditor(config);
     container.classList.add('editor-container');
 
     const editor = createEditor(config);
index f74201ff74cdedd1fb106e9ca380735e12fccb7d..4418be6237c2853d73d58d52e5241447d9242238 100644 (file)
@@ -51,7 +51,7 @@ export class EditorButton extends EditorUiElement {
         const label = this.getLabel();
         let child: string|HTMLElement = label;
         if (this.definition.icon) {
         const label = this.getLabel();
         let child: string|HTMLElement = label;
         if (this.definition.icon) {
-            child = el('span', {class: 'editor-button-icon'});
+            child = el('div', {class: 'editor-button-icon'});
             child.innerHTML = this.definition.icon;
         }
 
             child.innerHTML = this.definition.icon;
         }
 
index 79cbc73e89d396c86a08466d415db616168966b4..7530382630bd309e744e50019f726250118a5322 100644 (file)
@@ -14,6 +14,9 @@
 .editor-toolbar-main {
   display: flex;
   flex-wrap: wrap;
 .editor-toolbar-main {
   display: flex;
   flex-wrap: wrap;
+  justify-content: center;
+  border-top: 1px solid #DDD;
+  border-bottom: 1px solid #DDD;
 }
 
 body.editor-is-fullscreen {
 }
 
 body.editor-is-fullscreen {
@@ -22,13 +25,24 @@ body.editor-is-fullscreen {
     z-index: 20;
   }
 }
     z-index: 20;
   }
 }
+.editor-content-area {
+  &:focus {
+    outline: 0;
+  }
+}
+.editor-content-wrap {
+  overflow-y: scroll;
+}
 
 // Buttons
 .editor-button {
 
 // Buttons
 .editor-button {
-  border: 1px solid #DDD;
   font-size: 12px;
   padding: 4px 6px;
   color: #444;
   font-size: 12px;
   padding: 4px 6px;
   color: #444;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 .editor-button:hover {
   background-color: #EEE;
 }
 .editor-button:hover {
   background-color: #EEE;
@@ -38,7 +52,6 @@ body.editor-is-fullscreen {
 .editor-button[disabled] {
   pointer-events: none;
   cursor: not-allowed;
 .editor-button[disabled] {
   pointer-events: none;
   cursor: not-allowed;
-  background-color: #EEE;
   opacity: .6;
 }
 .editor-button-active, .editor-button-active:hover {
   opacity: .6;
 }
 .editor-button-active, .editor-button-active:hover {
@@ -52,7 +65,8 @@ body.editor-is-fullscreen {
 .editor-button-icon svg {
   width: 24px;
   height: 24px;
 .editor-button-icon svg {
   width: 24px;
   height: 24px;
-  fill: #000;
+  color: inherit;
+  fill: currentColor;
 }
 
 // Containers
 }
 
 // Containers
index 8fc0dc55a55d70aaf6579650126b3fb749f1ad06..ee5a2e19b11dd1b527253aea6a9311be889cb5dd 100644 (file)
@@ -4,55 +4,14 @@
      option:wysiwyg-editor:text-direction="{{ $locale->htmlDirection() }}"
      option:wysiwyg-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
      option:wysiwyg-editor:server-upload-limit-text="{{ trans('errors.server_upload_limit') }}"
      option:wysiwyg-editor:text-direction="{{ $locale->htmlDirection() }}"
      option:wysiwyg-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
      option:wysiwyg-editor:server-upload-limit-text="{{ trans('errors.server_upload_limit') }}"
-     class="">
+     class="flex-container-column flex-fill">
 
 
-    <div class="editor-container" refs="wysiwyg-editor@edit-container">
+    <div class="editor-container flex-container-column flex-fill" refs="wysiwyg-editor@edit-container">
     </div>
 
     </div>
 
-    <script type="text/html" refs="wysiwyg-editor@edit-content">
-        <p id="Content!">Some <strong>content</strong> here</p>
-        <p>Content with image in, before text. <img src="https://bookstack.local/bookstack/uploads/images/gallery/2022-03/scaled-1680-/cats-image-2400x1000-2.jpg" width="200" alt="Sleepy meow"> After text.</p>
-        <p>This has a <a href="https://example.com" target="_blank" title="Link to example">link</a> in it</p>
-        <h2>List below this h2 header</h2>
-        <ul>
-            <li>Hello</li>
-        </ul>
-
-        <details>
-            <summary>Collapsible details/summary block</summary>
-            <p>Inner text here</p>
-            <h4>Inner Header</h4>
-            <p>More text <strong>with bold in</strong> it</p>
-        </details>
-
-        <p class="callout info">
-            Hello there, this is an info callout
-        </p>
-
-        <h3>Table</h3>
-
-        <table>
-            <thead>
-            <tr>
-                <th>Cell A</th>
-                <th>Cell B</th>
-                <th>Cell C</th>
-            </tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td>Cell D</td>
-                <td>Cell E</td>
-                <td>Cell F</td>
-            </tr>
-            </tbody>
-        </table>
-    </script>
-
     <div id="lexical-debug" style="white-space: pre-wrap; font-size: 12px; height: 200px; overflow-y: scroll; background-color: #000; padding: 1rem; border-radius: 4px; color: #FFF;"></div>
 
     <div id="lexical-debug" style="white-space: pre-wrap; font-size: 12px; height: 200px; overflow-y: scroll; background-color: #000; padding: 1rem; border-radius: 4px; color: #FFF;"></div>
 
-{{--    <textarea id="html-editor"  name="html" rows="5"--}}
-{{--          @if($errors->has('html')) class="text-neg" @endif>@if(isset($model) || old('html')){{ old('html') ? old('html') : $model->html }}@endif</textarea>--}}
+    <textarea refs="wysiwyg-editor@input" id="html-editor" hidden="hidden"  name="html" rows="5">{{ old('html') ?? $model->html ?? '' }}</textarea>
 </div>
 
 @if($errors->has('html'))
 </div>
 
 @if($errors->has('html'))