mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
927a977257
no issue - forced card deselection+reselection so that keys such as `Enter` and `Backspace` work as expected when the card is shown as selected
161 lines
4.4 KiB
JavaScript
161 lines
4.4 KiB
JavaScript
import Component from '@ember/component';
|
|
import Key from 'mobiledoc-kit/utils/key';
|
|
import {computed} from '@ember/object';
|
|
import {kgStyle} from '../helpers/kg-style';
|
|
import {run} from '@ember/runloop';
|
|
import {inject as service} from '@ember/service';
|
|
|
|
export default Component.extend({
|
|
koenigUi: service(),
|
|
|
|
tagName: 'figcaption',
|
|
classNameBindings: ['figCaptionClass'],
|
|
|
|
caption: '',
|
|
captureInput: false,
|
|
placeholder: '',
|
|
|
|
_keypressHandler: null,
|
|
_keydownHandler: null,
|
|
|
|
update() {},
|
|
addParagraphAfterCard() {},
|
|
moveCursorToNextSection() {},
|
|
moveCursorToPrevSection() {},
|
|
|
|
figCaptionClass: computed(function () {
|
|
return `${kgStyle(['figcaption'])} w-100 relative`;
|
|
}),
|
|
|
|
didReceiveAttrs() {
|
|
this._super(...arguments);
|
|
|
|
if (this.captureInput && !this._keypressHandler) {
|
|
this._attachHandlers();
|
|
}
|
|
|
|
if (!this.captureInput && this._keypressHandler) {
|
|
this._detachHandlers();
|
|
}
|
|
},
|
|
|
|
willDestroyElement() {
|
|
this._super(...arguments);
|
|
this.koenigUi.captionLostFocus(this);
|
|
this._detachHandlers();
|
|
},
|
|
|
|
actions: {
|
|
registerEditor(editor) {
|
|
let commands = {
|
|
ENTER: run.bind(this, this._enter),
|
|
ESC: run.bind(this, this._escape),
|
|
UP: run.bind(this, this._upOrLeft),
|
|
LEFT: run.bind(this, this._upOrLeft),
|
|
DOWN: run.bind(this, this._rightOrDown),
|
|
RIGHT: run.bind(this, this._rightOrDown)
|
|
};
|
|
|
|
Object.keys(commands).forEach((str) => {
|
|
editor.registerKeyCommand({
|
|
str,
|
|
run() {
|
|
return commands[str](editor, str);
|
|
}
|
|
});
|
|
});
|
|
|
|
this.editor = editor;
|
|
},
|
|
|
|
handleEnter() {
|
|
this.addParagraphAfterCard();
|
|
}
|
|
},
|
|
|
|
// events ------------------------------------------------------------------
|
|
|
|
focusIn() {
|
|
this.koenigUi.captionGainedFocus(this);
|
|
},
|
|
|
|
focusOut() {
|
|
this.koenigUi.captionLostFocus(this);
|
|
},
|
|
|
|
// private -----------------------------------------------------------------
|
|
|
|
_attachHandlers() {
|
|
if (!this._keypressHandler) {
|
|
this._keypressHandler = run.bind(this, this._handleKeypress);
|
|
window.addEventListener('keypress', this._keypressHandler);
|
|
}
|
|
},
|
|
|
|
_detachHandlers() {
|
|
window.removeEventListener('keypress', this._keypressHandler);
|
|
this._keypressHandler = null;
|
|
this._keydownHandler = null;
|
|
},
|
|
|
|
// only fires if the card is selected, moves focus to the caption input so
|
|
// that it's possible to start typing without explicitly focusing the input
|
|
_handleKeypress(event) {
|
|
let key = new Key(event);
|
|
let {editor} = this;
|
|
|
|
if (event.target.matches('[data-kg="editor"]') && editor && !editor._hasFocus() && key.isPrintableKey() && !key.isEnter()) {
|
|
editor.focus();
|
|
editor.run((postEditor) => {
|
|
postEditor.insertText(editor.post.tailPosition(), key.toString());
|
|
});
|
|
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
|
|
/* key commands ----------------------------------------------------------*/
|
|
|
|
_enter() {
|
|
this.send('handleEnter');
|
|
},
|
|
|
|
_escape(editor) {
|
|
editor.element.blur();
|
|
this.deselectCard();
|
|
this.selectCard();
|
|
},
|
|
|
|
_upOrLeft(editor, key) {
|
|
let {isCollapsed, head} = editor.range;
|
|
|
|
if (isCollapsed && head.isEqual(head.section.headPosition())) {
|
|
return this.moveCursorToPrevSection();
|
|
}
|
|
|
|
// we're simulating a text input so up/down move the cursor to the
|
|
// beginning/end of the input
|
|
if (isCollapsed && key === 'UP') {
|
|
return editor.selectRange(head.section.headPosition().toRange());
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
_rightOrDown(editor, key) {
|
|
let {isCollapsed, tail} = editor.range;
|
|
|
|
if (isCollapsed && tail.isEqual(tail.section.tailPosition())) {
|
|
return this.moveCursorToNextSection();
|
|
}
|
|
|
|
// we're simulating a text input so up/down move the cursor to the
|
|
// beginning/end of the input
|
|
if (isCollapsed && key === 'DOWN') {
|
|
return editor.selectRange(tail.section.tailPosition().toRange());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
});
|