diff --git a/src/lib/directives/ng2-fittext.directive.ts b/src/lib/directives/ng2-fittext.directive.ts index 24ee24e..331783c 100644 --- a/src/lib/directives/ng2-fittext.directive.ts +++ b/src/lib/directives/ng2-fittext.directive.ts @@ -29,13 +29,13 @@ export class Ng2FittextDirective @Input('modelToWatch') modelToWatch: any; - @Output() fontSizeChanged: EventEmitter = new EventEmitter(); + @Output() fontSizeChanged: EventEmitter = new EventEmitter(); private fontSize = 1000; private speed = 1.05; private done = false; - constructor(public el: ElementRef, public renderer: Renderer2) {} + constructor(public el: ElementRef, public renderer: Renderer2) {} setFontSize(fontSize: number): void { if (this.isVisible() && !this.isDone()) { @@ -62,10 +62,19 @@ export class Ng2FittextDirective return Math.floor(fontSize / speed); } - checkOverflow(parent: any, children: any): boolean { - const overflowX = children.scrollWidth - parent.clientWidth; - const overflowY = children.clientHeight - parent.clientHeight; - return overflowX > 1 || overflowY > 1; + checkOverflow(parent: HTMLElement, children: HTMLElement): boolean { + return ( + this.hasXAxisOverflow(parent, children) || + this.hasYAxisOverflow(parent, children) + ); + } + + hasXAxisOverflow(parent: HTMLElement, children: HTMLElement): boolean { + return children.scrollWidth - parent.clientWidth > 0; + } + + hasYAxisOverflow(parent: HTMLElement, children: HTMLElement): boolean { + return children.clientHeight - parent.clientHeight > 0; } @HostListener('window:resize', ['$event']) @@ -100,13 +109,7 @@ export class Ng2FittextDirective ngAfterViewInit() { if (this.isVisible() && !this.isDone()) { if (this.fittext) { - const overflow = this.container - ? this.checkOverflow(this.container, this.el.nativeElement) - : this.checkOverflow( - this.el.nativeElement.parentElement, - this.el.nativeElement - ); - if (overflow) { + if (this.hasOverflow()) { if (this.fontSize > this.minFontSize) { // iterate only until font size is bigger than minimal value this.setFontSize(this.calculateFontSize(this.fontSize, this.speed)); @@ -156,4 +159,13 @@ export class Ng2FittextDirective isVisible(): boolean { return this.getStartFontSizeFromHeight() > 0; } + + hasOverflow(): boolean { + return this.container + ? this.checkOverflow(this.container, this.el.nativeElement) + : this.checkOverflow( + this.el.nativeElement.parentElement, + this.el.nativeElement + ); + } } diff --git a/src/lib/directives/specs/ng2-fittext.directive.spec.ts b/src/lib/directives/specs/ng2-fittext.directive.spec.ts index 32c2ce7..f1f26ba 100644 --- a/src/lib/directives/specs/ng2-fittext.directive.spec.ts +++ b/src/lib/directives/specs/ng2-fittext.directive.spec.ts @@ -101,18 +101,22 @@ describe('Class: Ng2FittextDirective', () => { }); describe('Method: checkOverflow', () => { - let parentElementMock: any; - let childrenElementMock: any; + let parentElementMock: HTMLElement; + let childrenElementMock: HTMLElement; + let hasXAxisOverflowSpy: jasmine.Spy; + let hasYAxisOverflowSpy: jasmine.Spy; beforeEach(() => { - parentElementMock = { - clientWidth: 0, - clientHeight: 0, - }; - childrenElementMock = { - scrollWidth: 0, - clientHeight: 0, - }; + parentElementMock = {} as HTMLElement; + childrenElementMock = {} as HTMLElement; + hasXAxisOverflowSpy = spyOn( + ng2FittextDirective, + 'hasXAxisOverflow' + ).and.returnValue(false); + hasYAxisOverflowSpy = spyOn( + ng2FittextDirective, + 'hasYAxisOverflow' + ).and.returnValue(false); }); it('Should return false if no overflow is present', () => { @@ -125,7 +129,7 @@ describe('Class: Ng2FittextDirective', () => { }); it('Should return true if x axis has overflow', () => { - childrenElementMock.scrollWidth = 2; + hasXAxisOverflowSpy.and.returnValue(true); expect( ng2FittextDirective.checkOverflow( parentElementMock, @@ -135,7 +139,7 @@ describe('Class: Ng2FittextDirective', () => { }); it('Should return true if y axis has overflow', () => { - childrenElementMock.clientHeight = 2; + hasYAxisOverflowSpy.and.returnValue(true); expect( ng2FittextDirective.checkOverflow( parentElementMock, @@ -194,4 +198,113 @@ describe('Class: Ng2FittextDirective', () => { expect(ng2FittextDirective.isVisible()).toBe(false); }); }); + + describe('Method: hasXAxisOverflow', () => { + let parentElementMock: HTMLElement; + let childrenElementMock: HTMLElement; + + beforeEach(() => { + parentElementMock = { + clientWidth: 0, + } as HTMLElement; + childrenElementMock = { + scrollWidth: 0, + } as HTMLElement; + }); + + it('Should return false if no overflow is present on the x axis', () => { + expect( + ng2FittextDirective.hasXAxisOverflow( + parentElementMock, + childrenElementMock + ) + ).toBe(false); + }); + + it('Should return true if overflow is present on the x axis', () => { + childrenElementMock = { + scrollWidth: 2, + } as HTMLElement; + expect( + ng2FittextDirective.hasXAxisOverflow( + parentElementMock, + childrenElementMock + ) + ).toBe(true); + }); + }); + + describe('Method: hasYAxisOverflow', () => { + let parentElementMock: HTMLElement; + let childrenElementMock: HTMLElement; + + beforeEach(() => { + parentElementMock = { + clientHeight: 0, + } as HTMLElement; + childrenElementMock = { + clientHeight: 0, + } as HTMLElement; + }); + + it('Should return false if no overflow is present on the x axis', () => { + expect( + ng2FittextDirective.hasYAxisOverflow( + parentElementMock, + childrenElementMock + ) + ).toBe(false); + }); + + it('Should return true if overflow is present on the x axis', () => { + childrenElementMock = { + clientHeight: 2, + } as HTMLElement; + expect( + ng2FittextDirective.hasYAxisOverflow( + parentElementMock, + childrenElementMock + ) + ).toBe(true); + }); + }); + + describe('Method: hasOverflow', () => { + let containerMock: any; + let parentElementMock: any; + + beforeEach(() => { + containerMock = { + isContainer: true, + }; + parentElementMock = { + isParentElement: true, + }; + ng2FittextDirective.container = { ...containerMock }; + ng2FittextDirective.el.nativeElement = { + parentElement: { ...parentElementMock }, + } as HTMLElement; + }); + + it('Should calculate the overflow using the container if is present', () => { + spyOn(ng2FittextDirective, 'checkOverflow').and.callFake( + (parentElement: any, childrenElement: any) => { + expect(parentElement).toEqual(containerMock); + return true; + } + ); + expect(ng2FittextDirective.hasOverflow()).toBe(true); + }); + + it('Should calculate the overflow using the parent element if the container is not present', () => { + delete ng2FittextDirective.container; + spyOn(ng2FittextDirective, 'checkOverflow').and.callFake( + (parentElement: any, childrenElement: any) => { + expect(parentElement).toEqual(parentElementMock); + return true; + } + ); + expect(ng2FittextDirective.hasOverflow()).toBe(true); + }); + }); });