mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
060d791a63
no issue The `settings` service has been a source of confusion when writing with modern Ember patterns because it's use of the deprecated `ProxyMixin` forced all property access/setting to go via `.get()` and `.set()` whereas the rest of the system has mostly (there are a few other uses of ProxyObjects remaining) eliminated the use of the non-native get/set methods. - removed use of `ProxyMixin` in the `settings` service by grabbing the attributes off the setting model after fetching and using `Object.defineProperty()` to add native getters/setters that pass through to the model's getters/setters. Ember's autotracking automatically works across the native getters/setters so we can then use the service as if it was any other native object - updated all code to use `settings.{attrName}` directly for getting/setting instead of `.get()` and `.set()` - removed use of observer in the `customViews` service because it was being set up before the native properties had been added on the settings service meaning autotracking wasn't able to set up properly
168 lines
5.4 KiB
JavaScript
168 lines
5.4 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
|
import {action} from '@ember/object';
|
|
import {inject as service} from '@ember/service';
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
export default class GhKoenigEditorReactComponent extends Component {
|
|
@service settings;
|
|
|
|
containerElement = null;
|
|
titleElement = null;
|
|
// koenigEditor = null;
|
|
mousedownY = 0;
|
|
uploadUrl = `${ghostPaths().apiRoot}/images/upload/`;
|
|
|
|
@tracked titleIsHovered = false;
|
|
@tracked titleIsFocused = false;
|
|
|
|
get title() {
|
|
return this.args.title === '(Untitled)' ? '' : this.args.title;
|
|
}
|
|
|
|
get accentColor() {
|
|
const color = this.settings.accentColor;
|
|
if (color && color[0] === '#') {
|
|
return color.slice(1);
|
|
}
|
|
return color;
|
|
}
|
|
|
|
@action
|
|
registerElement(element) {
|
|
this.containerElement = element;
|
|
}
|
|
|
|
@action
|
|
trackMousedown(event) {
|
|
// triggered when a mousedown is registered on .gh-koenig-editor-pane
|
|
this.mousedownY = event.clientY;
|
|
}
|
|
|
|
// Title actions -----------------------------------------------------------
|
|
|
|
@action
|
|
registerTitleElement(element) {
|
|
this.titleElement = element;
|
|
|
|
// this is needed because focus event handler won't be fired if input has focus when rendering
|
|
if (this.titleElement === document.activeElement) {
|
|
this.titleIsFocused = true;
|
|
}
|
|
}
|
|
|
|
@action
|
|
updateTitle(event) {
|
|
this.args.onTitleChange?.(event.target.value);
|
|
}
|
|
|
|
@action
|
|
focusTitle() {
|
|
this.titleElement.focus();
|
|
}
|
|
|
|
// @action
|
|
// onTitleKeydown(event) {
|
|
// let value = event.target.value;
|
|
// let selectionStart = event.target.selectionStart;
|
|
|
|
// // enter will always focus the editor
|
|
// // down arrow will only focus the editor when the cursor is at the
|
|
// // end of the input to preserve the default OS behaviour
|
|
// if (
|
|
// event.key === 'Enter' ||
|
|
// event.key === 'Tab' ||
|
|
// ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && (!value || selectionStart === value.length))
|
|
// ) {
|
|
// event.preventDefault();
|
|
|
|
// // on Enter we also want to create a blank para if necessary
|
|
// if (event.key === 'Enter') {
|
|
// this._addParaAtTop();
|
|
// }
|
|
|
|
// this.koenigEditor.focus();
|
|
// }
|
|
// }
|
|
|
|
// Body actions ------------------------------------------------------------
|
|
|
|
// @action
|
|
// onEditorCreated(koenig) {
|
|
// this._setupEditor(koenig);
|
|
// this.args.onEditorCreated?.(koenig);
|
|
// }
|
|
|
|
// @action
|
|
// focusEditor(event) {
|
|
// if (event.target.classList.contains('gh-koenig-editor-pane')) {
|
|
// let editorCanvas = this.koenigEditor.element;
|
|
// let {bottom} = editorCanvas.getBoundingClientRect();
|
|
|
|
// // if a mousedown and subsequent mouseup occurs below the editor
|
|
// // canvas, focus the editor and put the cursor at the end of the
|
|
// // document
|
|
// if (this.mousedownY > bottom && event.clientY > bottom) {
|
|
// let {post} = this.koenigEditor;
|
|
// let range = post.toRange();
|
|
// let {tailSection} = range;
|
|
|
|
// event.preventDefault();
|
|
// this.koenigEditor.focus();
|
|
|
|
// // we should always have a visible cursor when focusing
|
|
// // at the bottom so create an empty paragraph if last
|
|
// // section is a card
|
|
// if (tailSection.isCardSection) {
|
|
// this.koenigEditor.run((postEditor) => {
|
|
// let newSection = postEditor.builder.createMarkupSection('p');
|
|
// postEditor.insertSectionAtEnd(newSection);
|
|
// tailSection = newSection;
|
|
// });
|
|
// }
|
|
|
|
// this.koenigEditor.selectRange(tailSection.tailPosition());
|
|
|
|
// // ensure we're scrolled to the bottom
|
|
// this.containerElement.scrollTop = this.containerElement.scrollHeight;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// _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);
|
|
// });
|
|
// }
|
|
// }
|
|
}
|