-
diff --git a/components/upload/nz-upload.component.ts b/components/upload/nz-upload.component.ts
index 568457d7618..b3a6ed4e288 100644
--- a/components/upload/nz-upload.component.ts
+++ b/components/upload/nz-upload.component.ts
@@ -30,6 +30,7 @@ import {
ZipButtonOptions
} from './interface';
import { NzUploadBtnComponent } from './nz-upload-btn.component';
+import { NzUploadListComponent } from './nz-upload-list.component';
@Component({
selector : 'nz-upload',
@@ -40,7 +41,8 @@ import { NzUploadBtnComponent } from './nz-upload-btn.component';
})
export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
private i18n$: Subscription;
- @ViewChild('upload') upload: NzUploadBtnComponent;
+ @ViewChild('uploadComp') uploadComp: NzUploadBtnComponent;
+ @ViewChild('listComp') listComp: NzUploadListComponent;
// tslint:disable-next-line:no-any
locale: any = {};
@@ -112,7 +114,8 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
if (typeof this.nzShowUploadList === 'boolean' && this.nzShowUploadList) {
this.nzShowUploadList = {
showPreviewIcon: true,
- showRemoveIcon : true
+ showRemoveIcon : true,
+ hidePreviewIconInNonImage: false
};
}
// filters
@@ -195,39 +198,16 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
(file.error && file.error.statusText) || this.locale.uploadError;
}
- private genThumb(file: UploadFile): void {
- // tslint:disable-next-line:no-any
- const win = window as any;
- if (
- (this.nzListType !== 'picture' && this.nzListType !== 'picture-card') ||
- typeof document === 'undefined' ||
- typeof win === 'undefined' ||
- !win.FileReader ||
- !win.File ||
- !(file.originFileObj instanceof File) ||
- file.thumbUrl != null
- ) {
- return;
- }
-
- file.thumbUrl = '';
-
- const reader = new FileReader();
- reader.onloadend = () => file.thumbUrl = reader.result as string;
- reader.readAsDataURL(file.originFileObj);
- }
-
private onStart = (file: UploadFile): void => {
if (!this.nzFileList) {
this.nzFileList = [];
}
const targetItem = this.fileToObject(file);
targetItem.status = 'uploading';
- this.nzFileList.push(targetItem);
- this.genThumb(targetItem);
+ this.nzFileList = this.nzFileList.concat(targetItem);
this.nzFileListChange.emit(this.nzFileList);
this.nzChange.emit({ file: targetItem, fileList: this.nzFileList, type: 'start' });
- this.cdr.markForCheck();
+ this.detectChangesList();
}
private onProgress = (e: { percent: number }, file: UploadFile): void => {
@@ -240,7 +220,7 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
fileList: this.nzFileList,
type : 'progress'
});
- this.cdr.detectChanges();
+ this.detectChangesList();
}
private onSuccess = (res: {}, file: UploadFile): void => {
@@ -253,7 +233,7 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
fileList,
type: 'success'
});
- this.cdr.detectChanges();
+ this.detectChangesList();
}
private onError = (err: {}, file: UploadFile): void => {
@@ -267,7 +247,7 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
fileList,
type: 'error'
});
- this.cdr.detectChanges();
+ this.detectChangesList();
}
// #endregion
@@ -288,8 +268,13 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
// #region list
+ private detectChangesList(): void {
+ this.cdr.detectChanges();
+ this.listComp.detectChanges();
+ }
+
onRemove = (file: UploadFile): void => {
- this.upload.abort(file);
+ this.uploadComp.abort(file);
file.status = 'removed';
const fnRes = typeof this.nzRemove === 'function' ?
this.nzRemove(file) : this.nzRemove == null ? true : this.nzRemove;
@@ -342,7 +327,7 @@ export class NzUploadComponent implements OnInit, OnChanges, OnDestroy {
ngOnInit(): void {
this.i18n$ = this.i18n.localeChange.subscribe(() => {
this.locale = this.i18n.getLocaleData('Upload');
- this.cdr.detectChanges();
+ this.detectChangesList();
});
}
diff --git a/components/upload/upload.spec.ts b/components/upload/upload.spec.ts
index 03c33689531..56125412d75 100644
--- a/components/upload/upload.spec.ts
+++ b/components/upload/upload.spec.ts
@@ -293,6 +293,13 @@ describe('upload', () => {
expect(instance._beforeUpload).toBe(false);
});
describe('using observable', () => {
+ it('can return true', () => {
+ spyOn(instance, 'nzChange');
+ instance.beforeUpload = (file: UploadFile, fileList: UploadFile[]): Observable
=> of(true);
+ fixture.detectChanges();
+ pageObject.postSmall();
+ expect(instance.nzChange).toHaveBeenCalled();
+ });
it('can return same file', () => {
let ret = false;
instance.beforeUpload = (file: UploadFile, fileList: UploadFile[]): Observable => {
@@ -565,7 +572,7 @@ describe('upload', () => {
describe('[test boundary]', () => {
it('clean a not exists request', () => {
- instance.comp.upload.reqs.test = null;
+ instance.comp.uploadComp.reqs.test = null;
instance.show = false;
fixture.detectChanges();
expect(true).toBe(true);
@@ -684,6 +691,36 @@ describe('upload', () => {
expect(actions.length).toBe(0);
expect(instance._onRemove).toBe(false);
});
+ it('should be hide preview when is invalid image url', fakeAsync(() => {
+ instance.icons = {
+ showPreviewIcon: true,
+ showRemoveIcon: true,
+ hidePreviewIconInNonImage: false
+ };
+ instance.items = [
+ { url: '1.pdf' }
+ ];
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ const actions = dl.queryAll(By.css('.ant-upload-list-item-actions a'));
+ expect(actions.length).toBe(1);
+ }));
+ it('should be hide preview when is invalid image url', fakeAsync(() => {
+ instance.icons = {
+ showPreviewIcon: true,
+ showRemoveIcon: true,
+ hidePreviewIconInNonImage: true
+ };
+ instance.items = [
+ { url: '1.pdf' }
+ ];
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ const actions = dl.queryAll(By.css('.ant-upload-list-item-actions a'));
+ expect(actions.length).toBe(0);
+ }));
});
describe('[onPreview]', () => {
@@ -699,6 +736,41 @@ describe('upload', () => {
dl.query(By.css('.ant-upload-list-item-actions a')).nativeElement.click();
expect(instance._onPreview).toBe(false);
});
+ it('should support linkProps as object', fakeAsync(() => {
+ instance.items = [
+ {
+ uid: '-1',
+ name: 'foo.png',
+ status: 'done',
+ url: 'http://www.baidu.com/xxx.png',
+ linkProps: {
+ download: 'image'
+ }
+ }
+ ];
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ const el = dl.query(By.css('.ant-upload-list-item-name')).nativeElement as HTMLElement;
+ expect(el.attributes.getNamedItem('download').textContent).toBe('image');
+ }));
+ it('should support linkProps as json stringify', fakeAsync(() => {
+ const linkPropsString = JSON.stringify({ download: 'image' });
+ instance.items = [
+ {
+ uid: '-1',
+ name: 'foo.png',
+ status: 'done',
+ url: 'http://www.baidu.com/xxx.png',
+ linkProps: linkPropsString
+ }
+ ];
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ const el = dl.query(By.css('.ant-upload-list-item-name')).nativeElement as HTMLElement;
+ expect(el.attributes.getNamedItem('download').textContent).toBe('image');
+ }));
});
describe('[onRemove]', () => {
@@ -715,6 +787,61 @@ describe('upload', () => {
expect(instance._onRemove).toBe(false);
});
});
+
+ describe('[isImageUrl]', () => {
+ describe('via image type', () => {
+ it('should be true when file object type value is a valid image', () => {
+ expect(instance.comp.isImageUrl({ type: 'image' } as any)).toBe(true);
+ });
+ });
+ describe('via thumbUrl or url', () => {
+ it('should be false when not found url & thumbUrl', () => {
+ expect(instance.comp.isImageUrl({ } as any)).toBe(false);
+ });
+ describe('via extension', () => {
+ it('with valid image extension', () => {
+ expect(instance.comp.isImageUrl({ url: '1.svg' } as any)).toBe(true);
+ });
+ it('with invalid image extension', () => {
+ expect(instance.comp.isImageUrl({ url: '1.pdf' } as any)).toBe(false);
+ });
+ });
+ describe('when url is base64', () => {
+ it('with valid image base64', () => {
+ expect(instance.comp.isImageUrl({ url: 'data:image/png;base64,1' } as any)).toBe(true);
+ });
+ it('with invalid image base64', () => {
+ expect(instance.comp.isImageUrl({ url: 'data:application/pdf;base64,1' } as any)).toBe(false);
+ });
+ });
+ });
+ });
+
+ describe('[genThumb]', () => {
+ class MockFR {
+ result = '1';
+ onloadend(dataUrl: string): void { }
+ readAsDataURL(): void {
+ this.onloadend('1');
+ }
+ }
+ it('should be generate thumb when is valid image data', () => {
+ spyOn(window as any, 'FileReader').and.returnValue(new MockFR());
+ instance.listType = 'picture';
+ instance.items = [ { originFileObj: new File([''], '1.png', { type: 'image' }), thumbUrl: undefined } ];
+ fixture.detectChanges();
+ expect(instance.items[0].thumbUrl).toBe('1');
+ });
+ it('should be ingore thumb when is invalid image data', () => {
+ const mockFR = new MockFR();
+ mockFR.result = '';
+ spyOn(window as any, 'FileReader').and.returnValue(mockFR);
+ instance.listType = 'picture';
+ instance.items = [ { originFileObj: new File([''], '1.pdf', { type: 'pdf' }), thumbUrl: undefined } ];
+ fixture.detectChanges();
+ expect(instance.items[0].thumbUrl).toBe('');
+ });
+ });
});
describe('btn', () => {
@@ -1140,7 +1267,6 @@ class TestUploadComponent {
[icons]="icons"
[onPreview]="onPreview"
[onRemove]="onRemove">`,
- styleUrls: [ './style/index.less' ],
encapsulation: ViewEncapsulation.None
})
class TestUploadListComponent {