From a5d631db027d593e9032dd99b336cb8ae6e7da38 Mon Sep 17 00:00:00 2001 From: Wilson Zeng Date: Sun, 19 Aug 2018 20:17:12 +0800 Subject: [PATCH] feat(module:modal): smart to determine whether to add padding-right (#1877) close #1422 --- components/modal/nz-modal.component.ts | 16 ++++++++++++--- components/modal/nz-modal.spec.ts | 28 +++++++++++++++++++------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index 503792c466d..ce3fcaa8dee 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -414,13 +414,23 @@ export class NzModalComponent extends NzModalRef impleme const openModals = this.modalControl.openModals; if (openModals.length + plusNum > 0) { - this.renderer.setStyle(this.document.body, 'padding-right', `${this.nzMeasureScrollbarService.scrollBarWidth}px`); - this.renderer.setStyle(this.document.body, 'overflow', 'hidden'); - } else { + if (this.hasBodyScrollBar()) { // Adding padding-right only when body's scrollbar is able to shown up + this.renderer.setStyle(this.document.body, 'padding-right', `${this.nzMeasureScrollbarService.scrollBarWidth}px`); + this.renderer.setStyle(this.document.body, 'overflow', 'hidden'); + } + } else { // NOTE: we need to always remove the padding due to the scroll bar may be disappear by window resizing before modal closed this.renderer.removeStyle(this.document.body, 'padding-right'); this.renderer.removeStyle(this.document.body, 'overflow'); } } + + /** + * Check whether the body element is able to has the scroll bar (if the body content height exceeds the window's height) + * Exceptional Cases: users can show the scroll bar by their own permanently (eg. overflow: scroll) + */ + private hasBodyScrollBar(): boolean { + return this.document.body.scrollHeight > (window.innerHeight || this.document.documentElement.clientHeight); + } } //////////// diff --git a/components/modal/nz-modal.spec.ts b/components/modal/nz-modal.spec.ts index 4f8f3462714..156d89db8d8 100644 --- a/components/modal/nz-modal.spec.ts +++ b/components/modal/nz-modal.spec.ts @@ -1,7 +1,7 @@ /* TODO: Sort out and rewrite for more standardized */ -import { Component, DebugElement, ElementRef, EventEmitter, Input, NgModule } from '@angular/core'; -import { async, fakeAsync, flush, flushMicrotasks, inject, tick, ComponentFixture, ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing'; +import { Component, ElementRef, EventEmitter, Input } from '@angular/core'; +import { async, fakeAsync, flush, inject, tick, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; @@ -15,12 +15,10 @@ import { NzI18nService } from '../i18n/nz-i18n.service'; import { CssUnitPipe } from './css-unit.pipe'; import { NzModalControlService } from './nz-modal-control.service'; import { NzModalRef } from './nz-modal-ref.class'; -import { MODAL_ANIMATE_DURATION, NzModalComponent } from './nz-modal.component'; +import { NzModalComponent } from './nz-modal.component'; import { NzModalModule } from './nz-modal.module'; import { NzModalService } from './nz-modal.service'; -const WAIT_ANIMATE_TIME = MODAL_ANIMATE_DURATION + 50; - describe('modal testing (legacy)', () => { let instance; let fixture: ComponentFixture<{}>; @@ -473,6 +471,24 @@ describe('NzModal', () => { modalRef.triggerCancel(); expect(spyCancel).toHaveBeenCalled(); }); + + it('should add/remove padding-left depends on current scrollbar (just functions mockup)', () => { + const modalRef = modalService.create(); + const modalInstance = modalRef.getInstance(); + spyOnProperty(window, 'innerHeight').and.returnValue(null); // Disable innerHeight to test another branch + // tslint:disable-next-line:no-string-literal + spyOnProperty(modalInstance['document'].body, 'scrollHeight').and.returnValue(200); + // tslint:disable-next-line:no-string-literal + spyOnProperty(modalInstance['document'].documentElement, 'clientHeight').and.returnValue(100); + // tslint:disable-next-line:no-string-literal + expect(modalInstance['hasBodyScrollBar']()).toBeTruthy(); + + // tslint:disable-next-line:no-string-literal + const spySetStyle = spyOn(modalInstance['renderer'], 'setStyle'); + // tslint:disable-next-line:no-string-literal + modalInstance['changeBodyOverflow'](1); + expect(spySetStyle).toHaveBeenCalled(); + }); }); }); @@ -658,8 +674,6 @@ class TestCssUnitPipeComponent { } }) export class ModalByServiceComponent { nonServiceModalVisible = false; - - constructor(modalControlService: NzModalControlService) {} } // -------------------------------------------