mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 02:41:50 +03:00
c33a0c23bc
refs https://github.com/TryGhost/Ghost/issues/9724 - mobiledoc-kit's `key.isPrintable()` returns true for <kbd>Enter</kbd> but in this instance we don't want to capture newlines as printable chars - swapped insertion of `event.key` for `key.toString()` for better handling of named keys that output characters (eg. when `event.key` === `Enter` which prints `\n`)
145 lines
4.0 KiB
JavaScript
145 lines
4.0 KiB
JavaScript
import Component from '@ember/component';
|
|
import Key from 'mobiledoc-kit/utils/key';
|
|
import layout from '../templates/components/koenig-caption-input';
|
|
import {computed} from '@ember/object';
|
|
import {kgStyle} from 'ember-cli-ghost-spirit/helpers/kg-style';
|
|
import {run} from '@ember/runloop';
|
|
|
|
export default Component.extend({
|
|
tagName: 'figcaption',
|
|
classNameBindings: ['figCaptionClass'],
|
|
layout,
|
|
|
|
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._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();
|
|
}
|
|
},
|
|
|
|
_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.blur();
|
|
},
|
|
|
|
_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;
|
|
}
|
|
});
|