Fixed focus sometimes being lost when clicking on cards at bottom of editor

refs https://github.com/TryGhost/Koenig/pull/964

- editor behaviour has changed to select cards on mousedown, this has the effect of the following click/mouseup event potentially occuring off of the editor canvas if a previously selected card collapses when leaving edit mode
- updated the focus-on-click-below behaviour to skip if the previous mousedown event occurred on a card to avoid unexpected re-focus and card deselection
This commit is contained in:
Kevin Ansfield 2023-10-04 13:22:15 +01:00
parent 506488df11
commit 259321a1a9

View File

@ -13,6 +13,7 @@ export default class GhKoenigEditorReactComponent extends Component {
uploadUrl = `${ghostPaths().apiRoot}/images/upload/`; uploadUrl = `${ghostPaths().apiRoot}/images/upload/`;
editorAPI = null; editorAPI = null;
skipFocusEditor = false;
@tracked titleIsHovered = false; @tracked titleIsHovered = false;
@tracked titleIsFocused = false; @tracked titleIsFocused = false;
@ -38,6 +39,17 @@ export default class GhKoenigEditorReactComponent extends Component {
trackMousedown(event) { trackMousedown(event) {
// triggered when a mousedown is registered on .gh-koenig-editor-pane // triggered when a mousedown is registered on .gh-koenig-editor-pane
this.mousedownY = event.clientY; this.mousedownY = event.clientY;
// mousedown can select a card which can deselect another card meaning the
// mouseup/click event can occur outside of the initially clicked card, in
// which case we don't want to then "re-focus" the editor and cause unexpected
// selection changes
const clickedOnDecorator = (event.target.closest('[data-lexical-decorator]') !== null) || event.target.hasAttribute('data-lexical-decorator');
const clickedOnSlashMenu = (event.target.closest('[data-kg-slash-menu]') !== null) || event.target.hasAttribute('data-kg-slash-menu');
if (clickedOnDecorator || clickedOnSlashMenu) {
this.skipFocusEditor = true;
}
} }
@action @action
@ -126,15 +138,11 @@ export default class GhKoenigEditorReactComponent extends Component {
this.args.registerAPI(API); this.args.registerAPI(API);
} }
// @action // focus the editor when the editor canvas is clicked below the editor content,
// onEditorCreated(koenig) { // otherwise the browser will defocus the editor and the cursor will disappear
// this._setupEditor(koenig);
// this.args.onEditorCreated?.(koenig);
// }
@action @action
focusEditor(event) { focusEditor(event) {
if (event.target.classList.contains('gh-koenig-editor-pane')) { if (!this.skipFocusEditor && event.target.classList.contains('gh-koenig-editor-pane')) {
let editorCanvas = this.editorAPI.editorInstance.getRootElement(); let editorCanvas = this.editorAPI.editorInstance.getRootElement();
let {bottom} = editorCanvas.getBoundingClientRect(); let {bottom} = editorCanvas.getBoundingClientRect();
@ -149,48 +157,12 @@ export default class GhKoenigEditorReactComponent extends Component {
if (this.editorAPI.lastNodeIsDecorator()) { if (this.editorAPI.lastNodeIsDecorator()) {
this.editorAPI.insertParagraphAtBottom(); this.editorAPI.insertParagraphAtBottom();
} }
// Focus the editor // Focus the editor
this.editorAPI.focusEditor({position: 'bottom'}); this.editorAPI.focusEditor({position: 'bottom'});
//scroll to the bottom of the container
// containerRef.current.scrollTop = containerRef.current.scrollHeight;
} }
} }
this.skipFocusEditor = false;
} }
// _setupEditor(koenig) {
// let component = this;
// this.koenigEditor = koenig;
// // focus the title when pressing SHIFT+TAB
// this.koenigEditor.registerKeyCommand({
// str: 'SHIFT+TAB',
// run() {
// component.focusTitle();
// return true;
// }
// });
// }
// _addParaAtTop() {
// if (!this.koenigEditor) {
// return;
// }
// let editor = this.koenigEditor;
// let section = editor.post.toRange().head.section;
// // create a blank paragraph at the top of the editor unless it's already
// // a blank paragraph
// if (section.isListItem || !section.isBlank || section.text !== '') {
// editor.run((postEditor) => {
// let {builder} = postEditor;
// let newPara = builder.createMarkupSection('p');
// let sections = section.isListItem ? section.parent.parent.sections : section.parent.sections;
// postEditor.insertSectionBefore(sections, newPara, section);
// });
// }
// }
} }