Skip to content

Commit

Permalink
feat(root): make nz-root optional
Browse files Browse the repository at this point in the history
  • Loading branch information
trotyl committed Aug 16, 2017
1 parent 32234e4 commit 91a2478
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/components/ng-zorro-antd.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export { NzModalSubject } from './modal/nz-modal-subject.service';
// Tokens (eg. global services' config)
export { NZ_MESSAGE_CONFIG } from './message/nz-message-config';
export { NZ_NOTIFICATION_CONFIG } from './notification/nz-notification-config';
export { NZ_ROOT_CONFIG, NzRootConfig } from './root/nz-root-config';

// ---------------------------------------------------------
// | Root module
Expand Down
32 changes: 32 additions & 0 deletions src/components/root/nz-root-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { InjectionToken } from '@angular/core';

export interface NzRootConfig {
extraFontName: string;
extraFontUrl: string;
}

export const NZ_ROOT_CONFIG = new InjectionToken<NzRootConfig>('NzRootConfig');

export function createNzRootInitializer(document: Document, options?: NzRootConfig) {
return () => {
if (options) {
const style = this._document.createElement('style');
style.innerHTML = `
@font-face {
font-family: '${options.extraFontName}';
src: url('${options.extraFontUrl}.eot'); /* IE9*/
src:
/* IE6-IE8 */
url('${options.extraFontUrl}.eot?#iefix') format('embedded-opentype'),
/* chrome、firefox */
url('${options.extraFontUrl}.woff') format('woff'),
/* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('${options.extraFontUrl}.ttf') format('truetype'),
/* iOS 4.1- */
url('${options.extraFontUrl}.svg#iconfont') format('svg');
}
`;
document.head.appendChild(style);
}
}
}
11 changes: 11 additions & 0 deletions src/components/root/nz-root-style.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
template : ``,
styleUrls : [
'../style/index.less',
'./style/index.less',
],
encapsulation : ViewEncapsulation.None,
})
export class NzRootStyleComponent { }
41 changes: 14 additions & 27 deletions src/components/root/nz-root.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,35 @@ import {
Input,
ViewEncapsulation,
OnInit,
Inject
Inject,
Optional,
} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { NZ_ROOT_CONFIG, NzRootConfig, createNzRootInitializer} from './nz-root-config';

@Component({
selector : '[nz-root],nz-root',
encapsulation: ViewEncapsulation.None,
template : `
selector : '[nz-root],nz-root',
template : `
<ng-content></ng-content>
`,
styleUrls : [
'../style/index.less',
'./style/index.less',
]
})
export class NzRootComponent implements OnInit {

// Extra font definition
@Input() nzExtraFontName: string;
@Input() nzExtraFontUrl: string;

constructor(@Inject(DOCUMENT) private _document: Document) { }
constructor(
@Inject(DOCUMENT) private _document: Document,
// Cannot use type annotation here due to https://github.com/angular/angular-cli/issues/2034
// Should be revisited after AOT being made the only option
@Inject(NZ_ROOT_CONFIG) @Optional() private options: any,
) { }

ngOnInit() {
if (this.nzExtraFontName && this.nzExtraFontUrl) {
const style = this._document.createElement('style');
style.innerHTML = `
@font-face {
font-family: '${this.nzExtraFontName}';
src: url('${this.nzExtraFontUrl}.eot'); /* IE9*/
src:
/* IE6-IE8 */
url('${this.nzExtraFontUrl}.eot?#iefix') format('embedded-opentype'),
/* chrome、firefox */
url('${this.nzExtraFontUrl}.woff') format('woff'),
/* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('${this.nzExtraFontUrl}.ttf') format('truetype'),
/* iOS 4.1- */
url('${this.nzExtraFontUrl}.svg#iconfont') format('svg');
}
`;
this._document.head.appendChild(style);
if (this.nzExtraFontName && this.nzExtraFontUrl && !this.options) {
const options: NzRootConfig = { extraFontName: this.nzExtraFontName, extraFontUrl: this.nzExtraFontUrl };
const initializer = createNzRootInitializer(this._document, options);
}
}
}
45 changes: 45 additions & 0 deletions src/components/root/nz-root.module.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ComponentFactoryResolver, Injector, ComponentRef, ComponentFactory } from '@angular/core';
import { async, inject, TestBed } from '@angular/core/testing';
import { DOCUMENT } from '@angular/common';
import { NzRootModule } from './nz-root.module';
import { NzRootStyleComponent } from './nz-root-style.component';

describe('NzRootModule', () => {
let ngModule: NzRootModule;
let mockDocument: Document;
let mockInjector: Injector;
let mockFactoryResolver: ComponentFactoryResolver;
let mockElement: HTMLDivElement;
let mockComponentFactory: ComponentFactory<NzRootStyleComponent>;
let mockComponentRef: ComponentRef<NzRootStyleComponent>;

beforeEach(() => {
mockDocument = { createElement: () => null } as any;
mockInjector = {} as any;
mockFactoryResolver = { resolveComponentFactory: () => null } as any;
mockElement = {} as any;
mockComponentFactory = { create: () => null } as any;
mockComponentRef = { destroy: () => null } as any;

spyOn(mockDocument, 'createElement').and.returnValue(mockElement);
spyOn(mockComponentRef, 'destroy');
spyOn(mockComponentFactory, 'create').and.returnValue(mockComponentRef);
spyOn(mockFactoryResolver, 'resolveComponentFactory').and.returnValue(mockComponentFactory);
});

beforeEach(() => {
ngModule = new NzRootModule(mockDocument, mockInjector, mockFactoryResolver);
});

it('should create style component when start', () => {
expect(mockDocument.createElement).toHaveBeenCalledWith('div');
expect(mockFactoryResolver.resolveComponentFactory).toHaveBeenCalledWith(NzRootStyleComponent);
expect(mockComponentFactory.create).toHaveBeenCalledWith(mockInjector, null, mockElement);
});

it('should destroy style component when terminate', () => {
ngModule.ngOnDestroy();

expect(mockComponentRef.destroy).toHaveBeenCalled();
})
});
28 changes: 22 additions & 6 deletions src/components/root/nz-root.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import { NgModule } from '@angular/core';
import { NgModule, OnDestroy, ComponentRef, ComponentFactoryResolver, Inject, Optional, Injector, APP_INITIALIZER } from '@angular/core';
import { CommonModule, DOCUMENT } from '@angular/common';
import { NzRootComponent } from './nz-root.component';
import { CommonModule } from '@angular/common';
import { NzRootStyleComponent } from './nz-root-style.component';
import { NZ_ROOT_CONFIG, createNzRootInitializer, NzRootConfig } from './nz-root-config';

@NgModule({
exports : [ NzRootComponent ],
declarations: [ NzRootComponent ],
imports : [ CommonModule ]
exports : [ NzRootComponent ],
declarations : [ NzRootComponent, NzRootStyleComponent ],
imports : [ CommonModule ],
entryComponents : [ NzRootStyleComponent ],
providers : [
{ provide: APP_INITIALIZER, multi: true, useFactory: createNzRootInitializer, deps: [DOCUMENT, [new Optional(), NZ_ROOT_CONFIG]] },
],
})
export class NzRootModule implements OnDestroy {
private styleHostComponent: ComponentRef<NzRootStyleComponent>;

export class NzRootModule {
constructor(@Inject(DOCUMENT) _document: Document, injector: Injector, resolver: ComponentFactoryResolver) {
const componentFactory = resolver.resolveComponentFactory(NzRootStyleComponent);
const div = _document.createElement('div');
this.styleHostComponent = componentFactory.create(injector, null, div);
}

ngOnDestroy() {
this.styleHostComponent.destroy();
}
}

0 comments on commit 91a2478

Please sign in to comment.