Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

162 lines
3.8 KiB

/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
// tslint:disable:prefer-for-of
import { Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2 } from '@angular/core';
import { Types } from './../../utils/types';
const ImageTypes = [
'image/jpeg',
'image/png',
'image/jpg',
'image/gif'
];
@Directive({
selector: '[sqxFileDrop]'
})
export class FileDropDirective {
private dragCounter = 0;
@Input()
public allowedFiles: string[];
@Input()
public onlyImages: boolean;
@Input()
public noDrop: boolean;
@Output('sqxFileDrop')
public drop = new EventEmitter<File[]>();
constructor(
private readonly element: ElementRef,
private readonly renderer: Renderer2
) {
}
@HostListener('paste', ['$event'])
public onPaste(event: ClipboardEvent) {
if (this.noDrop) {
return;
}
const result: File[] = [];
for (let i = 0; i < event.clipboardData.items.length; i++) {
const file = event.clipboardData.items[i].getAsFile();
if (this.isAllowedFile(file)) {
result.push(file!);
}
}
if (result.length > 0) {
this.drop.emit(result);
}
this.stopEvent(event);
}
@HostListener('dragend', ['$event'])
@HostListener('dragleave', ['$event'])
public onDragEnd(event: DragDropEvent) {
const hasFiles = this.hasFiles(event.dataTransfer.types);
if (hasFiles) {
this.dragEnd();
}
}
@HostListener('dragenter', ['$event'])
public onDragEnter(event: DragDropEvent) {
const hasFiles = this.hasFiles(event.dataTransfer.types);
if (hasFiles) {
this.dragStart();
}
}
@HostListener('dragover', ['$event'])
public onDragOver(event: DragDropEvent) {
const hasFiles = this.hasFiles(event.dataTransfer.types);
if (hasFiles) {
this.stopEvent(event);
}
}
@HostListener('drop', ['$event'])
public onDrop(event: DragDropEvent) {
const hasFiles = this.hasFiles(event.dataTransfer.types);
if (hasFiles) {
const result: File[] = [];
for (let i = 0; i < event.dataTransfer.files.length; i++) {
const file = event.dataTransfer.files.item(i);
if (this.isAllowedFile(file)) {
result.push(file!);
}
}
if (result.length > 0) {
this.drop.emit(result);
}
this.dragEnd(0);
this.stopEvent(event);
}
}
private stopEvent(event: Event) {
event.preventDefault();
event.stopPropagation();
}
private dragStart() {
this.dragCounter++;
if (this.dragCounter === 1) {
this.renderer.addClass(this.element.nativeElement, 'drag');
}
}
private dragEnd(number?: number ) {
this.dragCounter = number || this.dragCounter - 1;
if (this.dragCounter === 0) {
this.renderer.removeClass(this.element.nativeElement, 'drag');
}
}
private isAllowedFile(file: File | null) {
return file && (!this.allowedFiles || this.allowedFiles.indexOf(file.type) >= 0) && (!this.onlyImages || ImageTypes.indexOf(file.type) >= 0);
}
private hasFiles(types: any): boolean {
if (!types) {
return false;
}
if (Types.isFunction(types.indexOf)) {
return types.indexOf('Files') !== -1;
} else if (Types.isFunction(types.contains)) {
return types.contains('Files');
} else {
return false;
}
}
}
interface DragDropEvent extends MouseEvent {
readonly dataTransfer: DataTransfer;
}