mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Started loading real content, Improved html loading
Added more styling/layout for buttons and main content area
This commit is contained in:
parent
c2ecbf071f
commit
9ebbf7ce94
@ -5,10 +5,10 @@ export class WysiwygEditor extends Component {
|
|||||||
setup() {
|
setup() {
|
||||||
this.elem = this.$el;
|
this.elem = this.$el;
|
||||||
this.editContainer = this.$refs.editContainer;
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
export function setEditorContentFromHtml(editor: LexicalEditor, html: string) {
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const dom = parser.parseFromString(html, 'text/html');
|
const dom = parser.parseFromString(html, 'text/html');
|
||||||
|
|
||||||
|
console.log(html);
|
||||||
editor.update(() => {
|
editor.update(() => {
|
||||||
const nodes = $generateNodesFromDOM(editor, dom);
|
// Empty existing
|
||||||
const root = $getRoot();
|
const root = $getRoot();
|
||||||
for (const child of root.getChildren()) {
|
for (const child of root.getChildren()) {
|
||||||
child.remove(true);
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,12 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
|
|||||||
|
|
||||||
const editArea = el('div', {
|
const editArea = el('div', {
|
||||||
contenteditable: 'true',
|
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');
|
container.classList.add('editor-container');
|
||||||
|
|
||||||
const editor = createEditor(config);
|
const editor = createEditor(config);
|
||||||
|
@ -51,7 +51,7 @@ export class EditorButton extends EditorUiElement {
|
|||||||
const label = this.getLabel();
|
const label = this.getLabel();
|
||||||
let child: string|HTMLElement = label;
|
let child: string|HTMLElement = label;
|
||||||
if (this.definition.icon) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
.editor-toolbar-main {
|
.editor-toolbar-main {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
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
|
// Buttons
|
||||||
.editor-button {
|
.editor-button {
|
||||||
border: 1px solid #DDD;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
color: #444;
|
color: #444;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.editor-button:hover {
|
.editor-button:hover {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
@ -38,7 +52,6 @@ body.editor-is-fullscreen {
|
|||||||
.editor-button[disabled] {
|
.editor-button[disabled] {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
background-color: #EEE;
|
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
}
|
}
|
||||||
.editor-button-active, .editor-button-active:hover {
|
.editor-button-active, .editor-button-active:hover {
|
||||||
@ -52,7 +65,8 @@ body.editor-is-fullscreen {
|
|||||||
.editor-button-icon svg {
|
.editor-button-icon svg {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
fill: #000;
|
color: inherit;
|
||||||
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers
|
// Containers
|
||||||
|
@ -4,55 +4,14 @@
|
|||||||
option:wysiwyg-editor:text-direction="{{ $locale->htmlDirection() }}"
|
option:wysiwyg-editor:text-direction="{{ $locale->htmlDirection() }}"
|
||||||
option:wysiwyg-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
|
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: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"--}}
|
<textarea refs="wysiwyg-editor@input" id="html-editor" hidden="hidden" name="html" rows="5">{{ old('html') ?? $model->html ?? '' }}</textarea>
|
||||||
{{-- @if($errors->has('html')) class="text-neg" @endif>@if(isset($model) || old('html')){{ old('html') ? old('html') : $model->html }}@endif</textarea>--}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if($errors->has('html'))
|
@if($errors->has('html'))
|
||||||
|
Loading…
Reference in New Issue
Block a user