Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lexical based editor #5058

Open
wants to merge 42 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5a4f595
Editors: Added lexical editor for testing
ssddanbrown May 27, 2024
6e852d2
Lexical: Played with commands, extracted & improved callout node
ssddanbrown May 27, 2024
49546cd
Lexical: Switched to ts for new editor build
ssddanbrown May 27, 2024
0f8bd86
Lexical: Added custom id-supporting paragraph blocks
ssddanbrown May 28, 2024
b24d60e
Lexical: Started UI fundementals with basic button
ssddanbrown May 28, 2024
483d9bf
Lexical: Added a range of format buttons
ssddanbrown May 28, 2024
dc1a40e
Lexical: Added ui container type
ssddanbrown May 29, 2024
57259ae
Lexical: Added format previews to format buttons
ssddanbrown May 30, 2024
ae98745
Lexical: Started on form UI
ssddanbrown May 30, 2024
7c504a1
Lexical: Created core modal functionality
ssddanbrown Jun 1, 2024
a74e041
Lexical: Started build of image node and decoration UI
ssddanbrown Jun 3, 2024
ba871ec
Lexical: Started image resize controls, Defined thorough decorator model
ssddanbrown Jun 5, 2024
e959c46
Lexical: Made image resize handles functional
ssddanbrown Jun 5, 2024
0722960
Lexical: Added selection to state for aligned reading
ssddanbrown Jun 5, 2024
5c34363
Added base node/button for details/summary
ssddanbrown Jun 6, 2024
e889bc6
Lexical: Added view/edit source code button/form/action
ssddanbrown Jun 12, 2024
a475cf6
Lexical: Added clear formatting button
ssddanbrown Jun 12, 2024
9e43e03
Lexical: Added color picker controls
ssddanbrown Jun 12, 2024
e2409a5
Lexical: Added basic list button/support
ssddanbrown Jun 19, 2024
13d970c
Lexical: Added button icon system
ssddanbrown Jun 19, 2024
f47f7dd
Lexical: Added base table support and started resize handling
ssddanbrown Jun 21, 2024
ac01c62
Lexical: Added table creator UI
ssddanbrown Jun 21, 2024
a07092b
Lexical: Updated lexical, added undo state tracking, format styles
ssddanbrown Jun 23, 2024
5546b8f
Lexical: Added more icons, made reflective text/bg color buttons
ssddanbrown Jun 23, 2024
3af22ce
Lexical: Created custom table node with col width handling
ssddanbrown Jun 24, 2024
5993663
Lexical: Extracted mouse drag tracking to new helper
ssddanbrown Jun 25, 2024
b1130cb
Lexical: Linked up table resize handler (unfinished)
ssddanbrown Jun 26, 2024
72a0e08
Lexical: Completed initial table cell resize handle logic
ssddanbrown Jun 26, 2024
4e2820d
Lexical: Added horizontal rule node
ssddanbrown Jun 27, 2024
f10ec32
Lexical: Added overflow container
ssddanbrown Jun 27, 2024
517c578
Lexical: Reorganised some logic into manager
ssddanbrown Jun 30, 2024
c9a03c5
Lexical: Added base context toolbar logic
ssddanbrown Jun 30, 2024
b1c4890
Lexical: Added context toolbar placement, added link toolbar
ssddanbrown Jun 30, 2024
c2ecbf0
Lexical: Added tracked container, added fullscreen action
ssddanbrown Jul 1, 2024
9ebbf7c
Lexical: Started loading real content, Improved html loading
ssddanbrown Jul 1, 2024
97f570a
Lexical: Started code block node implementation
ssddanbrown Jul 2, 2024
d0a5a5e
Lexical: Linked code block to editor, added button
ssddanbrown Jul 2, 2024
feca1f0
Lexical: Started diagram support
ssddanbrown Jul 3, 2024
a8f1160
JS: Converted come common services to typescript
ssddanbrown Jul 3, 2024
04c7e68
Lexical: Linked up saving logic of editor via interface
ssddanbrown Jul 4, 2024
2c96af9
Lexical: Worked on toolbar styling, got format submenu working
ssddanbrown Jul 4, 2024
51d8044
Lexical: Added initial form/modal styles
ssddanbrown Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions dev/build/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const entryPoints = {
code: path.join(__dirname, '../../resources/js/code/index.mjs'),
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
markdown: path.join(__dirname, '../../resources/js/markdown/index.mjs'),
wysiwyg: path.join(__dirname, '../../resources/js/wysiwyg/index.ts'),
};

// Locate our output directory
Expand All @@ -31,6 +32,13 @@ esbuild.build({
format: 'esm',
minify: isProd,
logLevel: 'info',
loader: {
'.svg': 'text',
},
absWorkingDir: path.join(__dirname, '../..'),
alias: {
'@icons': './resources/icons',
},
banner: {
js: '// See the "/licenses" URI for full package license details',
css: '/* See the "/licenses" URI for full package license details */',
Expand Down
304 changes: 216 additions & 88 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"build:css:watch": "sass ./resources/sass:./public/dist --watch --embed-sources",
"build:css:production": "sass ./resources/sass:./public/dist -s compressed",
"build:js:dev": "node dev/build/esbuild.js",
"build:js:watch": "chokidar --initial \"./resources/**/*.js\" \"./resources/**/*.mjs\" -c \"npm run build:js:dev\"",
"build:js:watch": "chokidar --initial \"./resources/**/*.js\" \"./resources/**/*.mjs\" \"./resources/**/*.ts\" -c \"npm run build:js:dev\"",
"build:js:production": "node dev/build/esbuild.js production",
"build": "npm-run-all --parallel build:*:dev",
"production": "npm-run-all --parallel build:*:production",
Expand All @@ -14,7 +14,8 @@
"livereload": "livereload ./public/dist/",
"permissions": "chown -R $USER:$USER bootstrap/cache storage public/uploads",
"lint": "eslint \"resources/**/*.js\" \"resources/**/*.mjs\"",
"fix": "eslint --fix \"resources/**/*.js\" \"resources/**/*.mjs\""
"fix": "eslint --fix \"resources/**/*.js\" \"resources/**/*.mjs\"",
"ts:lint": "tsc --noEmit"
},
"devDependencies": {
"@lezer/generator": "^1.5.1",
Expand All @@ -25,7 +26,8 @@
"eslint-plugin-import": "^2.29.0",
"livereload": "^0.9.3",
"npm-run-all": "^4.1.5",
"sass": "^1.69.5"
"sass": "^1.69.5",
"typescript": "^5.4.5"
},
"dependencies": {
"@codemirror/commands": "^6.3.2",
Expand All @@ -41,11 +43,20 @@
"@codemirror/state": "^6.3.3",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.22.2",
"@lexical/history": "^0.16.0",
"@lexical/html": "^0.16.0",
"@lexical/link": "^0.16.0",
"@lexical/list": "^0.16.0",
"@lexical/rich-text": "^0.16.0",
"@lexical/selection": "^0.16.0",
"@lexical/table": "^0.16.0",
"@lexical/utils": "^0.16.0",
"@lezer/highlight": "^1.2.0",
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
"codemirror": "^6.0.1",
"idb-keyval": "^6.2.1",
"lexical": "^0.16.0",
"markdown-it": "^14.1.0",
"markdown-it-task-lists": "^2.1.1",
"snabbdom": "^3.5.1",
Expand All @@ -59,7 +70,8 @@
},
"extends": "airbnb-base",
"ignorePatterns": [
"resources/**/*-stub.js"
"resources/**/*-stub.js",
"resources/**/*.ts"
],
"overrides": [],
"parserOptions": {
Expand Down
2 changes: 1 addition & 1 deletion resources/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/align-center.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/align-justify.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/align-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/align-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/bold.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/code-block.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/code.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/details.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/format-clear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/fullscreen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/help.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/highlighter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/horizontal-rule.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/indent-decrease.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/indent-increase.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/italic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/list-bullet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/list-check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/list-numbered.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/more-horizontal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/redo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/source-view.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/editor/strikethrough.svg
1 change: 1 addition & 0 deletions resources/icons/editor/subscript.svg
1 change: 1 addition & 0 deletions resources/icons/editor/superscript.svg
1 change: 1 addition & 0 deletions resources/icons/editor/table.svg
1 change: 1 addition & 0 deletions resources/icons/editor/text-color.svg
1 change: 1 addition & 0 deletions resources/icons/editor/underlined.svg
1 change: 1 addition & 0 deletions resources/icons/editor/undo.svg
1 change: 1 addition & 0 deletions resources/icons/editor/unlink.svg
9 changes: 4 additions & 5 deletions resources/js/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as events from './services/events';
import * as httpInstance from './services/http';
import Translations from './services/translations';

import * as components from './services/components';
import * as componentMap from './components';
import {ComponentStore} from './services/components.ts';

// Url retrieval function
window.baseUrl = function baseUrl(path) {
Expand Down Expand Up @@ -32,6 +31,6 @@ window.trans_choice = translator.getPlural.bind(translator);
window.trans_plural = translator.parsePlural.bind(translator);

// Load & initialise components
components.register(componentMap);
window.$components = components;
components.init();
window.$components = new ComponentStore();
window.$components.register(componentMap);
window.$components.init();
1 change: 1 addition & 0 deletions resources/js/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ export {TriLayout} from './tri-layout';
export {UserSelect} from './user-select';
export {WebhookEvents} from './webhook-events';
export {WysiwygEditor} from './wysiwyg-editor';
export {WysiwygEditorTinymce} from './wysiwyg-editor-tinymce';
export {WysiwygInput} from './wysiwyg-input';
4 changes: 2 additions & 2 deletions resources/js/components/markdown-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ export class MarkdownEditor extends Component {
/**
* Get the content of this editor.
* Used by the parent page editor component.
* @return {{html: String, markdown: String}}
* @return {Promise<{html: String, markdown: String}>}
*/
getContent() {
async getContent() {
return this.editor.actions.getContent();
}

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/page-comment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component} from './component';
import {getLoading, htmlToDom} from '../services/dom';
import {buildForInput} from '../wysiwyg/config';
import {buildForInput} from '../wysiwyg-tinymce/config';

export class PageComment extends Component {

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/page-comments.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component} from './component';
import {getLoading, htmlToDom} from '../services/dom';
import {buildForInput} from '../wysiwyg/config';
import {buildForInput} from '../wysiwyg-tinymce/config';

export class PageComments extends Component {

Expand Down
8 changes: 5 additions & 3 deletions resources/js/components/page-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class PageEditor extends Component {
async saveDraft() {
const data = {name: this.titleElem.value.trim()};

const editorContent = this.getEditorComponent().getContent();
const editorContent = await this.getEditorComponent().getContent();
Object.assign(data, editorContent);

let didSave = false;
Expand Down Expand Up @@ -235,10 +235,12 @@ export class PageEditor extends Component {
}

/**
* @return MarkdownEditor|WysiwygEditor
* @return {MarkdownEditor|WysiwygEditor|WysiwygEditorTinymce}
*/
getEditorComponent() {
return window.$components.first('markdown-editor') || window.$components.first('wysiwyg-editor');
return window.$components.first('markdown-editor')
|| window.$components.first('wysiwyg-editor')
|| window.$components.first('wysiwyg-editor-tinymce');
}

}
48 changes: 48 additions & 0 deletions resources/js/components/wysiwyg-editor-tinymce.js
Original file line number Diff line number Diff line change
@@ -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 {Promise<{html: String}>}
*/
async getContent() {
return {
html: this.editor.getContent(),
};
}

}
Loading