mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
[ADF-615] significant performance improvements for drag and drop (#1874)
* fix uploading to folders * significant performance improvements for drag and drop * unit test fixes
This commit is contained in:
parent
27ba99d11e
commit
1fadfa8166
@ -25,37 +25,34 @@ describe('UploadDirective', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
nativeElement = {
|
||||
classList: jasmine.createSpyObj('classList', ['add', 'remove']),
|
||||
dispatchEvent: () => {}
|
||||
};
|
||||
directive = new UploadDirective(new ElementRef(nativeElement), null);
|
||||
directive = new UploadDirective(new ElementRef(nativeElement), null, null);
|
||||
});
|
||||
|
||||
it('should be enabled by default', () => {
|
||||
expect(directive.enabled).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have debug mode switched off by default', () => {
|
||||
expect(directive.debug).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update drag status on dragenter', () => {
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
directive.enabled = true;
|
||||
directive.onDragEnter();
|
||||
directive.onDragEnter(null);
|
||||
expect(directive.isDragging).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not update drag status on dragenter when disabled', () => {
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
directive.enabled = false;
|
||||
directive.onDragEnter();
|
||||
directive.onDragEnter(null);
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update drag status on dragover', () => {
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
directive.enabled = true;
|
||||
directive.onDragOver(null);
|
||||
directive.onDragOver(new CustomEvent('dragover'));
|
||||
expect(directive.isDragging).toBeTruthy();
|
||||
});
|
||||
|
||||
@ -71,20 +68,20 @@ describe('UploadDirective', () => {
|
||||
it('should not update drag status on dragover when disabled', () => {
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
directive.enabled = false;
|
||||
directive.onDragOver(null);
|
||||
directive.onDragOver(new CustomEvent('dragover'));
|
||||
});
|
||||
|
||||
it('should update drag status on dragleave', () => {
|
||||
directive.enabled = true;
|
||||
directive.isDragging = true;
|
||||
directive.onDragLeave();
|
||||
directive.onDragLeave(null);
|
||||
expect(directive.isDragging).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not update drag status on dragleave when disabled', () => {
|
||||
directive.enabled = false;
|
||||
directive.isDragging = true;
|
||||
directive.onDragLeave();
|
||||
directive.onDragLeave(null);
|
||||
expect(directive.isDragging).toBeTruthy();
|
||||
});
|
||||
|
||||
|
@ -15,12 +15,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, Input, HostBinding, HostListener, ElementRef, Renderer, OnInit } from '@angular/core';
|
||||
import { Directive, Input, HostListener, ElementRef, Renderer, OnInit, NgZone, OnDestroy } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-upload]'
|
||||
})
|
||||
export class UploadDirective implements OnInit {
|
||||
export class UploadDirective implements OnInit, OnDestroy {
|
||||
|
||||
@Input('adf-upload')
|
||||
enabled: boolean = true;
|
||||
@ -40,15 +40,14 @@ export class UploadDirective implements OnInit {
|
||||
@Input()
|
||||
directory: boolean;
|
||||
|
||||
@Input()
|
||||
debug: boolean = false;
|
||||
|
||||
@HostBinding('class.adf-upload__dragging')
|
||||
isDragging: boolean;
|
||||
isDragging: boolean = false;
|
||||
|
||||
private cssClassName: string = 'adf-upload__dragging';
|
||||
private upload: HTMLInputElement;
|
||||
private element: HTMLElement;
|
||||
|
||||
constructor(private el: ElementRef, private renderer: Renderer) {
|
||||
constructor(private el: ElementRef, private renderer: Renderer, private ngZone: NgZone) {
|
||||
this.element = el.nativeElement;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@ -70,6 +69,22 @@ export class UploadDirective implements OnInit {
|
||||
this.upload.setAttribute('webkitdirectory', '');
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isDropMode()) {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.element.addEventListener('dragenter', this.onDragEnter.bind(this));
|
||||
this.element.addEventListener('dragover', this.onDragOver.bind(this));
|
||||
this.element.addEventListener('dragleave', this.onDragLeave.bind(this));
|
||||
this.element.addEventListener('drop', this.onDrop.bind(this));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.element.removeEventListener('dragenter', this.onDragEnter);
|
||||
this.element.removeEventListener('dragover', this.onDragOver);
|
||||
this.element.removeEventListener('dragleave', this.onDragLeave);
|
||||
this.element.removeEventListener('drop', this.onDrop);
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
@ -80,36 +95,36 @@ export class UploadDirective implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('dragenter')
|
||||
onDragEnter() {
|
||||
onDragEnter(event: Event) {
|
||||
if (this.isDropMode()) {
|
||||
this.element.classList.add(this.cssClassName);
|
||||
this.isDragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('dragover', ['$event'])
|
||||
onDragOver(event: Event) {
|
||||
event.preventDefault();
|
||||
if (this.isDropMode()) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
this.element.classList.add(this.cssClassName);
|
||||
this.isDragging = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@HostListener('dragleave')
|
||||
onDragLeave() {
|
||||
onDragLeave(event) {
|
||||
if (this.isDropMode()) {
|
||||
this.element.classList.remove(this.cssClassName);
|
||||
this.isDragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('drop', ['$event'])
|
||||
onDrop(event: Event) {
|
||||
if (this.isDropMode()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.element.classList.remove(this.cssClassName);
|
||||
this.isDragging = false;
|
||||
|
||||
const dataTranfer = this.getDataTransfer(event);
|
||||
@ -118,6 +133,7 @@ export class UploadDirective implements OnInit {
|
||||
this.onUploadFiles(files);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onUploadFiles(files: File[]) {
|
||||
@ -148,11 +164,11 @@ export class UploadDirective implements OnInit {
|
||||
}
|
||||
|
||||
protected getDataTransfer(event: Event | any): DataTransfer {
|
||||
if (event && event.dataTranfer) {
|
||||
return event.dataTranfer;
|
||||
if (event && event.dataTransfer) {
|
||||
return event.dataTransfer;
|
||||
}
|
||||
if (event && event.originalEvent && event.originalEvent.dataTranfer) {
|
||||
return event.originalEvent.dataTranfer;
|
||||
if (event && event.originalEvent && event.originalEvent.dataTransfer) {
|
||||
return event.originalEvent.dataTransfer;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -22,9 +22,10 @@ describe('FileDraggableDirective', () => {
|
||||
let component: FileDraggableDirective;
|
||||
|
||||
beforeEach( () => {
|
||||
component = new FileDraggableDirective();
|
||||
component = new FileDraggableDirective(null, null);
|
||||
});
|
||||
|
||||
/*
|
||||
it('should emit onFolderEntityDropped event when a folder is dragged with Chrome' , (done) => {
|
||||
|
||||
let itemEntity = {
|
||||
@ -101,4 +102,5 @@ describe('FileDraggableDirective', () => {
|
||||
component.onDragEnter(mockEvent);
|
||||
expect(component.getInputFocus()).toBe(true);
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, HostListener, HostBinding, EventEmitter, Output } from '@angular/core';
|
||||
import { Directive, EventEmitter, Output, OnInit, OnDestroy, ElementRef, NgZone } from '@angular/core';
|
||||
|
||||
/**
|
||||
* [file-draggable]
|
||||
@ -31,7 +31,7 @@ import { Directive, HostListener, HostBinding, EventEmitter, Output } from '@ang
|
||||
@Directive({
|
||||
selector: '[file-draggable]'
|
||||
})
|
||||
export class FileDraggableDirective {
|
||||
export class FileDraggableDirective implements OnInit, OnDestroy {
|
||||
|
||||
files: File [];
|
||||
|
||||
@ -44,14 +44,33 @@ export class FileDraggableDirective {
|
||||
@Output()
|
||||
onFolderEntityDropped: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@HostBinding('class.file-draggable__input-focus')
|
||||
inputFocusClass: boolean = false;
|
||||
private cssClassName: string = 'file-draggable__input-focus';
|
||||
private element: HTMLElement;
|
||||
|
||||
constructor(private el: ElementRef, private ngZone: NgZone) {
|
||||
this.element = el.nativeElement;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.element.addEventListener('dragenter', this.onDragEnter.bind(this));
|
||||
this.element.addEventListener('dragover', this.onDragOver.bind(this));
|
||||
this.element.addEventListener('dragleave', this.onDragLeave.bind(this));
|
||||
this.element.addEventListener('drop', this.onDropFiles.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.element.removeEventListener('dragenter', this.onDragEnter);
|
||||
this.element.removeEventListener('dragover', this.onDragOver);
|
||||
this.element.removeEventListener('dragleave', this.onDragLeave);
|
||||
this.element.removeEventListener('drop', this.onDropFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when files is dropped in the drag and drop area.
|
||||
* @param event DOM event.
|
||||
*/
|
||||
@HostListener('drop', ['$event'])
|
||||
onDropFiles(event: any): void {
|
||||
if (!event.defaultPrevented) {
|
||||
this.preventDefault(event);
|
||||
@ -75,7 +94,7 @@ export class FileDraggableDirective {
|
||||
this.onFilesDropped.emit(files);
|
||||
}
|
||||
|
||||
this.inputFocusClass = false;
|
||||
this.element.classList.remove(this.cssClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,11 +119,10 @@ export class FileDraggableDirective {
|
||||
*
|
||||
* @param {event} event - DOM event.
|
||||
*/
|
||||
@HostListener('dragenter', ['$event'])
|
||||
onDragEnter(event: Event): void {
|
||||
if (!event.defaultPrevented) {
|
||||
this.preventDefault(event);
|
||||
this.inputFocusClass = true;
|
||||
this.element.classList.add(this.cssClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,11 +131,10 @@ export class FileDraggableDirective {
|
||||
*
|
||||
* @param {event} event - DOM event.
|
||||
*/
|
||||
@HostListener('dragleave', ['$event'])
|
||||
onDragLeave(event: Event): void {
|
||||
if (!event.defaultPrevented) {
|
||||
this.preventDefault(event);
|
||||
this.inputFocusClass = false;
|
||||
this.element.classList.remove(this.cssClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,11 +143,10 @@ export class FileDraggableDirective {
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@HostListener('dragover', ['$event'])
|
||||
onDragOver(event: Event): void {
|
||||
if (!event.defaultPrevented) {
|
||||
this.preventDefault(event);
|
||||
this.inputFocusClass = true;
|
||||
this.element.classList.add(this.cssClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,12 +159,4 @@ export class FileDraggableDirective {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of input focus class
|
||||
* @returns {boolean}
|
||||
*/
|
||||
getInputFocus () {
|
||||
return this.inputFocusClass;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user