mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 18:01:36 +03:00
352c4af1d7
no issue - ran [es5-getter-ember-codemod](https://github.com/rondale-sc/es5-getter-ember-codemod) - [es5 getters RFC](https://github.com/emberjs/rfcs/blob/master/text/0281-es5-getters.md) - updates the majority of `object.get('property')` with `object.property` with exceptions: - `.get('nested.property')` - it's not possible to determine if this is relying on "safe" path chaining for when `nested` doesn't exist - `.get('config.x')` and `.get('settings.x')` - both our `config` and `settings` services are proxy objects which do not support es5 getters - this PR is not exhaustive, there are still a number of places where `.get('service.foo')` and similar could be replaced but it gets us a long way there in a quick and automated fashion
180 lines
5.0 KiB
JavaScript
180 lines
5.0 KiB
JavaScript
import Component from '@ember/component';
|
|
import {
|
|
IMAGE_EXTENSIONS,
|
|
IMAGE_MIME_TYPES
|
|
} from 'ghost-admin/components/gh-image-uploader';
|
|
import {debounce, run} from '@ember/runloop';
|
|
import {inject as service} from '@ember/service';
|
|
|
|
export default Component.extend({
|
|
ui: service(),
|
|
|
|
classNameBindings: [
|
|
'isDraggedOver:-drag-over',
|
|
'isFullScreen:gh-editor-fullscreen',
|
|
'isPreview:gh-editor-preview'
|
|
],
|
|
|
|
// Internal attributes
|
|
droppedFiles: null,
|
|
headerClass: '',
|
|
headerHeight: 0,
|
|
imageExtensions: IMAGE_EXTENSIONS,
|
|
imageMimeTypes: IMAGE_MIME_TYPES,
|
|
isDraggedOver: false,
|
|
isFullScreen: false,
|
|
isSplitScreen: false,
|
|
uploadedImageUrls: null,
|
|
|
|
// Private
|
|
_dragCounter: 0,
|
|
_onResizeHandler: null,
|
|
_viewActionsWidth: 190,
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
this._onResizeHandler = (evt) => {
|
|
debounce(this, this._setHeaderClass, evt, 100);
|
|
};
|
|
},
|
|
|
|
didInsertElement() {
|
|
this._super(...arguments);
|
|
window.addEventListener('resize', this._onResizeHandler);
|
|
this._setHeaderClass();
|
|
},
|
|
|
|
willDestroyElement() {
|
|
this._super(...arguments);
|
|
window.removeEventListener('resize', this._onResizeHandler);
|
|
},
|
|
|
|
actions: {
|
|
toggleFullScreen(isFullScreen) {
|
|
this.set('isFullScreen', isFullScreen);
|
|
this.ui.set('isFullScreen', isFullScreen);
|
|
run.scheduleOnce('afterRender', this, this._setHeaderClass);
|
|
},
|
|
|
|
togglePreview(isPreview) {
|
|
this.set('isPreview', isPreview);
|
|
},
|
|
|
|
toggleSplitScreen(isSplitScreen) {
|
|
this.set('isSplitScreen', isSplitScreen);
|
|
run.scheduleOnce('afterRender', this, this._setHeaderClass);
|
|
},
|
|
|
|
uploadImages(fileList, resetInput) {
|
|
// convert FileList to an array so that resetting the input doesn't
|
|
// clear the file references before upload actions can be triggered
|
|
let files = Array.from(fileList);
|
|
this.set('droppedFiles', files);
|
|
resetInput();
|
|
},
|
|
|
|
uploadComplete(uploads) {
|
|
this.set('uploadedImageUrls', uploads.mapBy('url'));
|
|
this.set('droppedFiles', null);
|
|
},
|
|
|
|
uploadCancelled() {
|
|
this.set('droppedFiles', null);
|
|
}
|
|
},
|
|
|
|
_setHeaderClass() {
|
|
let editorTitle = this.element.querySelector('.gh-editor-title, .kg-title-input');
|
|
let smallHeaderClass = 'gh-editor-header-small';
|
|
let newHeaderClass = '';
|
|
|
|
this._editorTitleElement = editorTitle;
|
|
|
|
if (this.isSplitScreen) {
|
|
this.set('headerClass', smallHeaderClass);
|
|
return;
|
|
}
|
|
|
|
if (editorTitle) {
|
|
let boundingRect = editorTitle.getBoundingClientRect();
|
|
let maxRight = window.innerWidth - this._viewActionsWidth;
|
|
|
|
if (boundingRect.right >= maxRight) {
|
|
newHeaderClass = smallHeaderClass;
|
|
}
|
|
}
|
|
|
|
if (newHeaderClass !== this.headerClass) {
|
|
// grab height of header so that we can pass it as an offset to other
|
|
// editor components
|
|
run.scheduleOnce('afterRender', this, this._setHeaderHeight);
|
|
}
|
|
|
|
this.set('headerClass', newHeaderClass);
|
|
},
|
|
|
|
_setHeaderHeight() {
|
|
if (this.headerClass && this._editorTitleElement) {
|
|
let height = this._editorTitleElement.offsetHeight;
|
|
return this.set('headerHeight', height);
|
|
}
|
|
|
|
this.set('headerHeight', 0);
|
|
},
|
|
|
|
// dragOver is needed so that drop works
|
|
dragOver(event) {
|
|
if (!event.dataTransfer) {
|
|
return;
|
|
}
|
|
|
|
// this is needed to work around inconsistencies with dropping files
|
|
// from Chrome's downloads bar
|
|
if (navigator.userAgent.indexOf('Chrome') > -1) {
|
|
let eA = event.dataTransfer.effectAllowed;
|
|
event.dataTransfer.dropEffect = (eA === 'move' || eA === 'linkMove') ? 'move' : 'copy';
|
|
}
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
},
|
|
|
|
// dragEnter is needed so that the drag class is correctly removed
|
|
dragEnter(event) {
|
|
if (!event.dataTransfer) {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
// the counter technique prevents flickering of the drag class when
|
|
// dragging across child elements
|
|
this._dragCounter += 1;
|
|
|
|
this.set('isDraggedOver', true);
|
|
},
|
|
|
|
dragLeave(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
this._dragCounter -= 1;
|
|
if (this._dragCounter === 0) {
|
|
this.set('isDraggedOver', false);
|
|
}
|
|
},
|
|
|
|
drop(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
this._dragCounter = 0;
|
|
this.set('isDraggedOver', false);
|
|
|
|
if (event.dataTransfer.files) {
|
|
this.set('droppedFiles', event.dataTransfer.files);
|
|
}
|
|
}
|
|
});
|