Ghost/ghost/admin/lib/koenig-editor/addon/components/koenig-media-selector.js
2021-11-23 16:03:53 +01:00

79 lines
2.5 KiB
JavaScript

import Component from '@glimmer/component';
import {action} from '@ember/object';
import {run} from '@ember/runloop';
const Y_OFFSET = 40;
export default class KoenigMediaSelectorComponent extends Component {
constructor() {
super(...arguments);
// store editor range for later because it might change if focus is lost
this._editorRange = this.args.editorRange;
// store scroll position before anything else renders
const scrollContainer = document.querySelector(this.args.scrollContainerSelector);
this._scrollTop = scrollContainer.scrollTop;
}
willDestroy() {
super.willDestroy(...arguments);
window.removeEventListener('click', this.handleBackgroundClick);
}
@action
didInsertContainer(containerElem) {
this._containerElem = containerElem;
this._positionSelector(this._editorRange);
this.resetScrollPosition();
// any click outside of the selector should close it and clear any /command
// add with 1ms delay so current event loop finishes to avoid instaclose
run.later(() => {
window.addEventListener('click', this.handleBackgroundClick);
});
}
@action
resetScrollPosition() {
const scrollContainer = document.querySelector(this.args.scrollContainerSelector);
scrollContainer.scrollTop = this._scrollTop;
}
@action
insertCard(cardName, payload) {
this.args.replaceWithCardSection(cardName, this._editorRange, payload);
this.args.close();
}
@action
handleBackgroundClick(event) {
if (!this._containerElem.contains(event.target)) {
this.args.editor.run((postEditor) => {
postEditor.deleteRange(this._editorRange.tail.section.toRange());
});
this.args.close();
}
}
@action
handleEscape() {
this.args.close();
this.args.editor.selectRange(this._editorRange.tail);
}
_positionSelector(range) {
let {head: {section}} = range;
if (section && section.renderNode.element) {
let containerRect = this._containerElem.parentNode.getBoundingClientRect();
let selectedElement = section.renderNode.element;
let selectedElementRect = selectedElement.getBoundingClientRect();
let top = selectedElementRect.top - containerRect.top + Y_OFFSET;
this._containerElem.style.top = `${top}px`;
}
}
}