Editors: Added lexical editor for testing
Started basic playground for testing lexical as a new WYSIWYG editor. Moved out tinymce to be under wysiwyg-tinymce instead so lexical is the default, but TinyMce code remains.
This commit is contained in:
parent
6019d2ee14
commit
5a4f595341
|
@ -14,6 +14,7 @@ const entryPoints = {
|
||||||
code: path.join(__dirname, '../../resources/js/code/index.mjs'),
|
code: path.join(__dirname, '../../resources/js/code/index.mjs'),
|
||||||
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
|
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
|
||||||
markdown: path.join(__dirname, '../../resources/js/markdown/index.mjs'),
|
markdown: path.join(__dirname, '../../resources/js/markdown/index.mjs'),
|
||||||
|
wysiwyg: path.join(__dirname, '../../resources/js/wysiwyg/index.mjs'),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Locate our output directory
|
// Locate our output directory
|
||||||
|
|
|
@ -18,11 +18,16 @@
|
||||||
"@codemirror/state": "^6.3.3",
|
"@codemirror/state": "^6.3.3",
|
||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@codemirror/view": "^6.22.2",
|
"@codemirror/view": "^6.22.2",
|
||||||
|
"@lexical/history": "^0.15.0",
|
||||||
|
"@lexical/html": "^0.15.0",
|
||||||
|
"@lexical/rich-text": "^0.15.0",
|
||||||
|
"@lexical/utils": "^0.15.0",
|
||||||
"@lezer/highlight": "^1.2.0",
|
"@lezer/highlight": "^1.2.0",
|
||||||
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
|
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
|
||||||
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
|
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
|
"lexical": "^0.15.0",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"markdown-it-task-lists": "^2.1.1",
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
"snabbdom": "^3.5.1",
|
"snabbdom": "^3.5.1",
|
||||||
|
@ -691,6 +696,85 @@
|
||||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@lexical/clipboard": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-binCltK7KiURQJFogvueYfmDNEKynN/lmZrCLFp2xBjEIajqw4WtOVLJZ33engdqNlvj0JqrxrWxbKG+yvUwrg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/html": "0.15.0",
|
||||||
|
"@lexical/list": "0.15.0",
|
||||||
|
"@lexical/selection": "0.15.0",
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/history": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-r+pzR2k/51AL6l8UfXeVe/GWPIeWY1kEOuKx9nsYB9tmAkTF66tTFz33DJIMWBVtAHWN7Dcdv0/yy6q8R6CAUQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/html": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-x/sfGvibwo8b5Vso4ppqNyS/fVve6Rn+TmvP/0eWOaa0I3aOQ57ulfcK6p/GTe+ZaEi8vW64oZPdi8XDgwSRaA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/selection": "0.15.0",
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/list": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-JuF4k7uo4rZFOSZGrmkxo1+sUrwTKNBhhJAiCgtM+6TO90jppxzCFNKur81yPzF1+g4GWLC9gbjzKb52QPb6cQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/rich-text": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-76tXh/eeEOHl91HpFEXCc/tUiLrsa9RcSyvCzRZahk5zqYvQPXma/AUfRzuSMf2kLwDEoauKAVqNFQcbPhqwpQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/clipboard": "0.15.0",
|
||||||
|
"@lexical/selection": "0.15.0",
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/selection": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-S+AQC6eJiQYSa5zOPuecN85prCT0Bcb8miOdJaE17Zh+vgdUH5gk9I0tEBeG5T7tkSpq6lFiEqs2FZSfaHflbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/table": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-3IRBg8IoIHetqKozRQbJQ2aPyG0ziXZ+lc8TOIAGs6METW/wxntaV+rTNrODanKAgvk2iJTIyfFkYjsqS9+VFg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/utils": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lexical/utils": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-/6954LDmTcVFgexhy5WOZDa4TxNQOEZNrf8z7TRAFiAQkihcME/GRoq1en5cbXoVNF8jv5AvNyyc7x0MByRJ6A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@lexical/list": "0.15.0",
|
||||||
|
"@lexical/selection": "0.15.0",
|
||||||
|
"@lexical/table": "0.15.0",
|
||||||
|
"lexical": "0.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@lezer/common": {
|
"node_modules/@lezer/common": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
|
||||||
|
@ -2709,6 +2793,11 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lexical": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lexical/-/lexical-0.15.0.tgz",
|
||||||
|
"integrity": "sha512-/7HrPAmtgsc1F+qpv5bFwoQZ6CbH/w3mPPL2AW5P75/QYrqKz4bhvJrc2jozIX0GxtuT/YUYT7w+1sZMtUWbOg=="
|
||||||
|
},
|
||||||
"node_modules/linkify-it": {
|
"node_modules/linkify-it": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||||
|
|
|
@ -41,11 +41,16 @@
|
||||||
"@codemirror/state": "^6.3.3",
|
"@codemirror/state": "^6.3.3",
|
||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@codemirror/view": "^6.22.2",
|
"@codemirror/view": "^6.22.2",
|
||||||
|
"@lexical/history": "^0.15.0",
|
||||||
|
"@lexical/html": "^0.15.0",
|
||||||
|
"@lexical/rich-text": "^0.15.0",
|
||||||
|
"@lexical/utils": "^0.15.0",
|
||||||
"@lezer/highlight": "^1.2.0",
|
"@lezer/highlight": "^1.2.0",
|
||||||
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
|
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
|
||||||
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
|
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
|
"lexical": "^0.15.0",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"markdown-it-task-lists": "^2.1.1",
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
"snabbdom": "^3.5.1",
|
"snabbdom": "^3.5.1",
|
||||||
|
|
|
@ -58,4 +58,5 @@ export {TriLayout} from './tri-layout';
|
||||||
export {UserSelect} from './user-select';
|
export {UserSelect} from './user-select';
|
||||||
export {WebhookEvents} from './webhook-events';
|
export {WebhookEvents} from './webhook-events';
|
||||||
export {WysiwygEditor} from './wysiwyg-editor';
|
export {WysiwygEditor} from './wysiwyg-editor';
|
||||||
|
export {WysiwygEditorTinymce} from './wysiwyg-editor-tinymce';
|
||||||
export {WysiwygInput} from './wysiwyg-input';
|
export {WysiwygInput} from './wysiwyg-input';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Component} from './component';
|
import {Component} from './component';
|
||||||
import {getLoading, htmlToDom} from '../services/dom';
|
import {getLoading, htmlToDom} from '../services/dom';
|
||||||
import {buildForInput} from '../wysiwyg/config';
|
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||||
|
|
||||||
export class PageComment extends Component {
|
export class PageComment extends Component {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Component} from './component';
|
import {Component} from './component';
|
||||||
import {getLoading, htmlToDom} from '../services/dom';
|
import {getLoading, htmlToDom} from '../services/dom';
|
||||||
import {buildForInput} from '../wysiwyg/config';
|
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||||
|
|
||||||
export class PageComments extends Component {
|
export class PageComments extends Component {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import {buildForEditor as buildEditorConfig} from '../wysiwyg-tinymce/config';
|
||||||
|
import {Component} from './component';
|
||||||
|
|
||||||
|
export class WysiwygEditorTinymce extends Component {
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
this.elem = this.$el;
|
||||||
|
|
||||||
|
this.tinyMceConfig = buildEditorConfig({
|
||||||
|
language: this.$opts.language,
|
||||||
|
containerElement: this.elem,
|
||||||
|
darkMode: document.documentElement.classList.contains('dark-mode'),
|
||||||
|
textDirection: this.$opts.textDirection,
|
||||||
|
drawioUrl: this.getDrawIoUrl(),
|
||||||
|
pageId: Number(this.$opts.pageId),
|
||||||
|
translations: {
|
||||||
|
imageUploadErrorText: this.$opts.imageUploadErrorText,
|
||||||
|
serverUploadLimitText: this.$opts.serverUploadLimitText,
|
||||||
|
},
|
||||||
|
translationMap: window.editor_translations,
|
||||||
|
});
|
||||||
|
|
||||||
|
window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
|
||||||
|
window.tinymce.init(this.tinyMceConfig).then(editors => {
|
||||||
|
this.editor = editors[0];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDrawIoUrl() {
|
||||||
|
const drawioUrlElem = document.querySelector('[drawio-url]');
|
||||||
|
if (drawioUrlElem) {
|
||||||
|
return drawioUrlElem.getAttribute('drawio-url');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of this editor.
|
||||||
|
* Used by the parent page editor component.
|
||||||
|
* @return {{html: String}}
|
||||||
|
*/
|
||||||
|
getContent() {
|
||||||
|
return {
|
||||||
|
html: this.editor.getContent(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,28 +1,13 @@
|
||||||
import {buildForEditor as buildEditorConfig} from '../wysiwyg/config';
|
|
||||||
import {Component} from './component';
|
import {Component} from './component';
|
||||||
|
|
||||||
export class WysiwygEditor extends Component {
|
export class WysiwygEditor extends Component {
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
this.elem = this.$el;
|
this.elem = this.$el;
|
||||||
|
this.editArea = this.$refs.editArea;
|
||||||
|
|
||||||
this.tinyMceConfig = buildEditorConfig({
|
window.importVersioned('wysiwyg').then(wysiwyg => {
|
||||||
language: this.$opts.language,
|
wysiwyg.createPageEditorInstance(this.editArea);
|
||||||
containerElement: this.elem,
|
|
||||||
darkMode: document.documentElement.classList.contains('dark-mode'),
|
|
||||||
textDirection: this.$opts.textDirection,
|
|
||||||
drawioUrl: this.getDrawIoUrl(),
|
|
||||||
pageId: Number(this.$opts.pageId),
|
|
||||||
translations: {
|
|
||||||
imageUploadErrorText: this.$opts.imageUploadErrorText,
|
|
||||||
serverUploadLimitText: this.$opts.serverUploadLimitText,
|
|
||||||
},
|
|
||||||
translationMap: window.editor_translations,
|
|
||||||
});
|
|
||||||
|
|
||||||
window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
|
|
||||||
window.tinymce.init(this.tinyMceConfig).then(editors => {
|
|
||||||
this.editor = editors[0];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Component} from './component';
|
import {Component} from './component';
|
||||||
import {buildForInput} from '../wysiwyg/config';
|
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||||
|
|
||||||
export class WysiwygInput extends Component {
|
export class WysiwygInput extends Component {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
import {$getRoot, createEditor, ElementNode} from 'lexical';
|
||||||
|
import {createEmptyHistoryState, registerHistory} from '@lexical/history';
|
||||||
|
import {HeadingNode, QuoteNode, registerRichText} from '@lexical/rich-text';
|
||||||
|
import {mergeRegister} from '@lexical/utils';
|
||||||
|
import {$generateNodesFromDOM} from '@lexical/html';
|
||||||
|
|
||||||
|
class CalloutParagraph extends ElementNode {
|
||||||
|
__category = 'info';
|
||||||
|
|
||||||
|
static getType() {
|
||||||
|
return 'callout';
|
||||||
|
}
|
||||||
|
|
||||||
|
static clone(node) {
|
||||||
|
return new CalloutParagraph(node.__category, node.__key);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(category, key) {
|
||||||
|
super(key);
|
||||||
|
this.__category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDOM(_config, _editor) {
|
||||||
|
const dom = document.createElement('p');
|
||||||
|
dom.classList.add('callout', this.__category || '');
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDOM(prevNode, dom) {
|
||||||
|
// Returning false tells Lexical that this node does not need its
|
||||||
|
// DOM element replacing with a new copy from createDOM.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static importDOM() {
|
||||||
|
return {
|
||||||
|
p: node => {
|
||||||
|
if (node.classList.contains('callout')) {
|
||||||
|
return {
|
||||||
|
conversion: element => {
|
||||||
|
let category = 'info';
|
||||||
|
const categories = ['info', 'success', 'warning', 'danger'];
|
||||||
|
|
||||||
|
for (const c of categories) {
|
||||||
|
if (element.classList.contains(c)) {
|
||||||
|
category = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
node: new CalloutParagraph(category),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority: 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportJSON() {
|
||||||
|
return {
|
||||||
|
...super.exportJSON(),
|
||||||
|
type: 'callout',
|
||||||
|
version: 1,
|
||||||
|
category: this.__category,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - Extract callout to own file
|
||||||
|
// TODO - Add helper functions
|
||||||
|
// https://lexical.dev/docs/concepts/nodes#creating-custom-nodes
|
||||||
|
|
||||||
|
export function createPageEditorInstance(editArea) {
|
||||||
|
console.log('creating editor', editArea);
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
namespace: 'BookStackPageEditor',
|
||||||
|
nodes: [HeadingNode, QuoteNode, CalloutParagraph],
|
||||||
|
onError: console.error,
|
||||||
|
};
|
||||||
|
|
||||||
|
const startingHtml = editArea.innerHTML;
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const dom = parser.parseFromString(startingHtml, 'text/html');
|
||||||
|
|
||||||
|
const editor = createEditor(config);
|
||||||
|
editor.setRootElement(editArea);
|
||||||
|
|
||||||
|
mergeRegister(
|
||||||
|
registerRichText(editor),
|
||||||
|
registerHistory(editor, createEmptyHistoryState(), 300),
|
||||||
|
);
|
||||||
|
|
||||||
|
editor.update(() => {
|
||||||
|
const startingNodes = $generateNodesFromDOM(editor, dom);
|
||||||
|
const root = $getRoot();
|
||||||
|
root.append(...startingNodes);
|
||||||
|
});
|
||||||
|
|
||||||
|
const debugView = document.getElementById('lexical-debug');
|
||||||
|
editor.registerUpdateListener(({editorState}) => {
|
||||||
|
console.log('editorState', editorState.toJSON());
|
||||||
|
debugView.textContent = JSON.stringify(editorState.toJSON(), null, 2);
|
||||||
|
});
|
||||||
|
}
|
|
@ -33,11 +33,15 @@
|
||||||
{{--Editors--}}
|
{{--Editors--}}
|
||||||
<div class="edit-area flex-fill flex">
|
<div class="edit-area flex-fill flex">
|
||||||
|
|
||||||
{{--WYSIWYG Editor--}}
|
|
||||||
@if($editor === 'wysiwyg')
|
@if($editor === 'wysiwyg')
|
||||||
@include('pages.parts.wysiwyg-editor', ['model' => $model])
|
@include('pages.parts.wysiwyg-editor', ['model' => $model])
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
{{--WYSIWYG Editor (TinyMCE - Deprecated)--}}
|
||||||
|
@if($editor === 'wysiwyg-tinymce')
|
||||||
|
@include('pages.parts.wysiwyg-editor-tinymce', ['model' => $model])
|
||||||
|
@endif
|
||||||
|
|
||||||
{{--Markdown Editor--}}
|
{{--Markdown Editor--}}
|
||||||
@if($editor === 'markdown')
|
@if($editor === 'markdown')
|
||||||
@include('pages.parts.markdown-editor', ['model' => $model])
|
@include('pages.parts.markdown-editor', ['model' => $model])
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
@push('head')
|
||||||
|
<script src="{{ versioned_asset('libs/tinymce/tinymce.min.js') }}" nonce="{{ $cspNonce }}"></script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
<div component="wysiwyg-editor-tinymce"
|
||||||
|
option:wysiwyg-editor-tinymce:language="{{ $locale->htmlLang() }}"
|
||||||
|
option:wysiwyg-editor-tinymce:page-id="{{ $model->id ?? 0 }}"
|
||||||
|
option:wysiwyg-editor-tinymce:text-direction="{{ $locale->htmlDirection() }}"
|
||||||
|
option:wysiwyg-editor-tinymce:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
|
||||||
|
option:wysiwyg-editor-tinymce:server-upload-limit-text="{{ trans('errors.server_upload_limit') }}"
|
||||||
|
class="flex-fill flex">
|
||||||
|
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($errors->has('html'))
|
||||||
|
<div class="text-neg text-small">{{ $errors->first('html') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@include('form.editor-translations')
|
|
@ -1,21 +1,31 @@
|
||||||
@push('head')
|
|
||||||
<script src="{{ versioned_asset('libs/tinymce/tinymce.min.js') }}" nonce="{{ $cspNonce }}"></script>
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
<div component="wysiwyg-editor"
|
<div component="wysiwyg-editor"
|
||||||
option:wysiwyg-editor:language="{{ $locale->htmlLang() }}"
|
option:wysiwyg-editor:language="{{ $locale->htmlLang() }}"
|
||||||
option:wysiwyg-editor:page-id="{{ $model->id ?? 0 }}"
|
option:wysiwyg-editor:page-id="{{ $model->id ?? 0 }}"
|
||||||
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="flex-fill flex">
|
class="">
|
||||||
|
|
||||||
<textarea id="html-editor" name="html" rows="5"
|
<div refs="wysiwyg-editor@edit-area" contenteditable="true">
|
||||||
@if($errors->has('html')) class="text-neg" @endif>@if(isset($model) || old('html')){{ old('html') ? old('html') : $model->html }}@endif</textarea>
|
<p>Some content here</p>
|
||||||
|
<h2>List below this h2 header</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Hello</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p class="callout danger">
|
||||||
|
Hello there, this is an info callout
|
||||||
|
</p>
|
||||||
|
</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>--}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if($errors->has('html'))
|
@if($errors->has('html'))
|
||||||
<div class="text-neg text-small">{{ $errors->first('html') }}</div>
|
<div class="text-neg text-small">{{ $errors->first('html') }}</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@include('form.editor-translations')
|
{{--TODO - @include('form.editor-translations')--}}
|
Loading…
Reference in New Issue