mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Range of fixes
- Prevented ui shortcuts running in editor - Added form modal closing on submit - Fixed ability to escape lists via enter on empty last item
This commit is contained in:
parent
ef3de1050f
commit
c8ccb2bac7
@ -25,7 +25,7 @@ export class Shortcuts extends Component {
|
|||||||
|
|
||||||
setupListeners() {
|
setupListeners() {
|
||||||
window.addEventListener('keydown', event => {
|
window.addEventListener('keydown', event => {
|
||||||
if (event.target.closest('input, select, textarea, .cm-editor')) {
|
if (event.target.closest('input, select, textarea, .cm-editor, .editor-container')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,9 +259,21 @@ export class ListItemNode extends ElementNode {
|
|||||||
_: RangeSelection,
|
_: RangeSelection,
|
||||||
restoreSelection = true,
|
restoreSelection = true,
|
||||||
): ListItemNode | ParagraphNode {
|
): ListItemNode | ParagraphNode {
|
||||||
|
|
||||||
|
if (this.getTextContent().trim() === '' && this.isLastChild()) {
|
||||||
|
const list = this.getParentOrThrow<ListNode>();
|
||||||
|
if (!$isListItemNode(list.getParent())) {
|
||||||
|
const paragraph = $createParagraphNode();
|
||||||
|
list.insertAfter(paragraph, restoreSelection);
|
||||||
|
this.remove();
|
||||||
|
return paragraph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const newElement = $createListItemNode(
|
const newElement = $createListItemNode(
|
||||||
this.__checked == null ? undefined : false,
|
this.__checked == null ? undefined : false,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.insertAfter(newElement, restoreSelection);
|
this.insertAfter(newElement, restoreSelection);
|
||||||
|
|
||||||
return newElement;
|
return newElement;
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
## Main Todo
|
## Main Todo
|
||||||
|
|
||||||
- Mac: Shortcut support via command.
|
- Mac: Shortcut support via command.
|
||||||
- Translations
|
|
||||||
- Form closing on submit
|
|
||||||
- Update toolbar overflows to match existing editor, incl. direction dynamic controls
|
- Update toolbar overflows to match existing editor, incl. direction dynamic controls
|
||||||
|
|
||||||
## Secondary Todo
|
## Secondary Todo
|
||||||
@ -17,11 +15,9 @@
|
|||||||
- Color picker for color controls
|
- Color picker for color controls
|
||||||
- Table caption text support
|
- 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)
|
- Support media src conversions (https://github.com/tinymce/tinymce/blob/release/6.6/modules/tinymce/src/plugins/media/main/ts/core/UrlPatterns.ts)
|
||||||
- Check translation coverage
|
- Deep check of translation coverage
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
|
|
||||||
- List selection can get lost on nesting/unnesting
|
- List selection can get lost on nesting/unnesting
|
||||||
- Can't escape lists when bottom element
|
- Content not properly saving on new pages
|
||||||
- Content not properly saving on new pages
|
|
||||||
- BookStack UI (non-editor) shortcuts can trigger in editor (`/` for example)
|
|
@ -100,13 +100,12 @@ export const image: EditorFormDefinition = {
|
|||||||
export function $showLinkForm(link: LinkNode|null, context: EditorUiContext) {
|
export function $showLinkForm(link: LinkNode|null, context: EditorUiContext) {
|
||||||
const linkModal = context.manager.createModal('link');
|
const linkModal = context.manager.createModal('link');
|
||||||
|
|
||||||
let formDefaults = {};
|
|
||||||
if (link) {
|
if (link) {
|
||||||
formDefaults = {
|
const formDefaults: Record<string, string> = {
|
||||||
url: link.getURL(),
|
url: link.getURL(),
|
||||||
text: link.getTextContent(),
|
text: link.getTextContent(),
|
||||||
title: link.getTitle(),
|
title: link.getTitle() || '',
|
||||||
target: link.getTarget(),
|
target: link.getTarget() || '',
|
||||||
}
|
}
|
||||||
|
|
||||||
context.editor.update(() => {
|
context.editor.update(() => {
|
||||||
@ -114,9 +113,16 @@ export function $showLinkForm(link: LinkNode|null, context: EditorUiContext) {
|
|||||||
selection.add(link.getKey());
|
selection.add(link.getKey());
|
||||||
$setSelection(selection);
|
$setSelection(selection);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
linkModal.show(formDefaults);
|
linkModal.show(formDefaults);
|
||||||
|
} else {
|
||||||
|
context.editor.getEditorState().read(() => {
|
||||||
|
const selection = $getSelection();
|
||||||
|
const text = selection?.getTextContent() || '';
|
||||||
|
const formDefaults = {text};
|
||||||
|
linkModal.show(formDefaults);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const link: EditorFormDefinition = {
|
export const link: EditorFormDefinition = {
|
||||||
|
@ -72,6 +72,7 @@ export class EditorFormField extends EditorUiElement {
|
|||||||
export class EditorForm extends EditorContainerUiElement {
|
export class EditorForm extends EditorContainerUiElement {
|
||||||
protected definition: EditorFormDefinition;
|
protected definition: EditorFormDefinition;
|
||||||
protected onCancel: null|(() => void) = null;
|
protected onCancel: null|(() => void) = null;
|
||||||
|
protected onSuccessfulSubmit: null|(() => void) = null;
|
||||||
|
|
||||||
constructor(definition: EditorFormDefinition) {
|
constructor(definition: EditorFormDefinition) {
|
||||||
let children: (EditorFormField|EditorUiElement)[] = definition.fields.map(fieldDefinition => {
|
let children: (EditorFormField|EditorUiElement)[] = definition.fields.map(fieldDefinition => {
|
||||||
@ -98,6 +99,10 @@ export class EditorForm extends EditorContainerUiElement {
|
|||||||
this.onCancel = callback;
|
this.onCancel = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOnSuccessfulSubmit(callback: () => void) {
|
||||||
|
this.onSuccessfulSubmit = callback;
|
||||||
|
}
|
||||||
|
|
||||||
protected getFieldByName(name: string): EditorFormField|null {
|
protected getFieldByName(name: string): EditorFormField|null {
|
||||||
|
|
||||||
const search = (children: EditorUiElement[]): EditorFormField|null => {
|
const search = (children: EditorUiElement[]): EditorFormField|null => {
|
||||||
@ -128,10 +133,13 @@ export class EditorForm extends EditorContainerUiElement {
|
|||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
form.addEventListener('submit', (event) => {
|
form.addEventListener('submit', async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const formData = new FormData(form as HTMLFormElement);
|
const formData = new FormData(form as HTMLFormElement);
|
||||||
this.definition.action(formData, this.getContext());
|
const result = await this.definition.action(formData, this.getContext());
|
||||||
|
if (result && this.onSuccessfulSubmit) {
|
||||||
|
this.onSuccessfulSubmit();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cancelButton.addEventListener('click', (event) => {
|
cancelButton.addEventListener('click', (event) => {
|
||||||
|
@ -28,6 +28,7 @@ export class EditorFormModal extends EditorContainerUiElement {
|
|||||||
const form = this.getForm();
|
const form = this.getForm();
|
||||||
form.setValues(defaultValues);
|
form.setValues(defaultValues);
|
||||||
form.setOnCancel(this.hide.bind(this));
|
form.setOnCancel(this.hide.bind(this));
|
||||||
|
form.setOnSuccessfulSubmit(this.hide.bind(this));
|
||||||
|
|
||||||
this.getContext().manager.setModalActive(this.key, this);
|
this.getContext().manager.setModalActive(this.key, this);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user