• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / ba7e05e2-37c0-44c6-8725-6f617aa0d43e

pending completion
ba7e05e2-37c0-44c6-8725-6f617aa0d43e

Pull #2756

circleci

huanhuanwa
test(color-picker): add test #INFR-8673
Pull Request #2756: feat(color-picker): add popoverRef param when panel open and close #INFR-8673

187 of 6315 branches covered (2.96%)

Branch coverage included in aggregate %.

2 of 2 new or added lines in 1 file covered. (100.0%)

2645 of 13660 relevant lines covered (19.36%)

83.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.12
/src/upload/file-drop.directive.ts
1
import { isEmpty } from 'ngx-tethys/util';
2
import { fromEvent, Subject } from 'rxjs';
3
import { filter, takeUntil, tap } from 'rxjs/operators';
4

5
import {
6
    Directive,
7
    ElementRef,
8
    EventEmitter,
9
    HostBinding,
10
    Inject,
11
    Input,
1✔
12
    NgZone,
13
    OnDestroy,
×
14
    OnInit,
15
    Output,
16
    Renderer2
×
17
} from '@angular/core';
×
18

×
19
import { FileSelectBaseDirective } from './file-select-base';
×
20
import { THY_UPLOAD_DEFAULT_OPTIONS, ThyUploadConfig } from './upload.config';
×
21

×
22
/**
×
23
 * @name thyFileDrop
×
24
 */
25
@Directive({
26
    selector: '[thyFileDrop]',
×
27
    standalone: true
×
28
})
29
export class ThyFileDropDirective extends FileSelectBaseDirective implements OnInit, OnDestroy {
×
30
    @HostBinding('class.drop-over')
×
31
    @HostBinding('class.thy-drop-over')
32
    isDragOver = false;
×
33
    private dragOverCustomClass: string;
×
34

×
35
    @Input() set thyFileDropClassName(value: string) {
×
36
        this.dragOverCustomClass = value;
×
37
    }
×
38

39
    @Output() thyOnDrop = new EventEmitter();
40

41
    private ngUnsubscribe$ = new Subject<void>();
42

×
43
    constructor(
44
        public elementRef: ElementRef,
45
        public renderer: Renderer2,
×
46
        public ngZone: NgZone,
47
        @Inject(THY_UPLOAD_DEFAULT_OPTIONS) public defaultConfig: ThyUploadConfig
×
48
    ) {
49
        super(elementRef, defaultConfig);
50
    }
×
51

×
52
    public ngOnInit(): void {
×
53
        this.ngZone.runOutsideAngular(() => {
×
54
            fromEvent(this.elementRef.nativeElement, 'dragenter')
55
                .pipe(
56
                    takeUntil(this.ngUnsubscribe$),
57
                    tap((event: DragEvent) => {
×
58
                        event.preventDefault();
59
                    }),
×
60
                    filter(event => event.dataTransfer.items && event.dataTransfer.items.length > 0)
61
                )
62
                .subscribe((event: DragEvent) => {
×
63
                    if (this.checkRejectFolderAndHtmlElement(event)) {
×
64
                        const files = this.filterFilesOrItems(Array.from(event.dataTransfer.items));
×
65
                        if (!isEmpty(files)) {
×
66
                            this.ngZone.run(() => {
×
67
                                this.isDragOver = true;
68
                                this.toggleDropOverClassName();
69
                            });
×
70
                        }
×
71
                    }
72
                });
73

74
            fromEvent(this.elementRef.nativeElement, 'dragover')
75
                .pipe(takeUntil(this.ngUnsubscribe$))
76
                .subscribe((event: any) => {
77
                    event.preventDefault();
×
78
                });
×
79

×
80
            fromEvent(this.elementRef.nativeElement, 'dragleave')
×
81
                .pipe(takeUntil(this.ngUnsubscribe$))
×
82
                .subscribe((event: any) => {
×
83
                    this.ngZone.run(() => {
×
84
                        if (!this.elementRef.nativeElement.contains(event.fromElement)) {
85
                            this.resetDragOver();
86
                            this.toggleDropOverClassName();
87
                        }
×
88
                    });
89
                });
90

91
            fromEvent(this.elementRef.nativeElement, 'drop')
×
92
                .pipe(
93
                    takeUntil(this.ngUnsubscribe$),
×
94
                    tap((event: DragEvent) => {
95
                        event.preventDefault();
×
96
                    })
×
97
                )
98
                .subscribe((event: DragEvent) => {
×
99
                    this.ngZone.run(() => {
100
                        if (this.checkRejectFolderAndHtmlElement(event)) {
101
                            const files = this.filterFilesOrItems(event.dataTransfer ? Array.from(event.dataTransfer.files) : []);
×
102
                            if (!isEmpty(files)) {
×
103
                                this.selectFiles(event, Array.from(event.dataTransfer.files), this.thyOnDrop);
×
104
                            }
105
                        }
106
                        this.resetDragOver();
107
                        this.toggleDropOverClassName();
×
108
                    });
109
                });
110
        });
111
    }
×
112

×
113
    private checkRejectFolderAndHtmlElement(event: DragEvent) {
×
114
        // 排除文件夹和HTML元素拖拽
115
        const items: DataTransferItemList | DataTransferItem[] = event.dataTransfer ? event.dataTransfer.items : [];
116
        let res = true;
×
117
        for (let index = 0; index < items.length; index++) {
118
            const item = items[index];
119
            const entry = this.getAsEntry(item);
120
            if (item.kind !== 'file' || (entry && !entry.isFile)) {
121
                res = false;
×
122
                // console.error(`file extensions not support drag upload, kind: ${item.kind}, type: ${item.type}`);
123
            }
124
        }
×
125
        return res;
126
    }
127

×
128
    private getAsEntry(item: DataTransferItem): FileSystemEntry {
×
129
        let entry: FileSystemEntry;
130
        if (item['getAsEntry']) {
1✔
131
            // https://wiki.whatwg.org/wiki/DragAndDropEntries
132
            entry = item['getAsEntry']();
133
        } else if (item.webkitGetAsEntry) {
134
            entry = item.webkitGetAsEntry();
135
        }
136
        return entry;
1✔
137
    }
138

139
    private filterFilesOrItems(items: Array<DataTransferItem | File>): Array<DataTransferItem | File> {
140
        if (this.acceptType && this.acceptType != '*/*') {
141
            return items.filter(item => {
142
                return this.acceptType.includes(item.type);
1✔
143
            });
144
        } else {
145
            return Array.from(items);
146
        }
147
    }
148

149
    private toggleDropOverClassName() {
150
        if (this.dragOverCustomClass) {
151
            if (this.isDragOver) {
152
                this.renderer.addClass(this.elementRef.nativeElement, this.dragOverCustomClass);
153
            } else {
154
                this.renderer.removeClass(this.elementRef.nativeElement, this.dragOverCustomClass);
155
            }
156
        }
157
    }
158

159
    private setDragOverState(isDragOver: boolean) {
160
        this.isDragOver = isDragOver;
161
    }
162

163
    private resetDragOver() {
164
        this.setDragOverState(false);
165
    }
166

167
    public ngOnDestroy(): void {
168
        this.ngUnsubscribe$.next();
169
        this.ngUnsubscribe$.complete();
170
    }
171
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc