mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(content): add dimension read/write methods
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
import {Component, ElementRef, Optional, NgZone, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {App} from '../app/app';
|
||||
import {Ion} from '../ion';
|
||||
import {Config} from '../../config/config';
|
||||
import {Keyboard} from '../../util/keyboard';
|
||||
import {nativeRaf, nativeTimeout, transitionEnd} from '../../util/dom';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {ScrollView} from '../../util/scroll-view';
|
||||
import {Tabs} from '../tabs/tabs';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
|
||||
|
||||
/**
|
||||
* @name Content
|
||||
@@ -57,9 +59,14 @@ import {ScrollView} from '../../util/scroll-view';
|
||||
}
|
||||
})
|
||||
export class Content extends Ion {
|
||||
private _paddingTop: number = 0;
|
||||
private _paddingBottom: number = 0;
|
||||
private _scrollPadding: number = 0;
|
||||
private _computedTop: number;
|
||||
private _computedBottom: number;
|
||||
private _paddingTop: number;
|
||||
private _paddingBottom: number;
|
||||
private _scrollPadding: number;
|
||||
private _headerHeight: number;
|
||||
private _footerHeight: number;
|
||||
private _tabbarOnTop: boolean = null;
|
||||
private _inputPolling: boolean = false;
|
||||
private _scroll: ScrollView;
|
||||
private _scLsn: Function;
|
||||
@@ -72,7 +79,8 @@ export class Content extends Ion {
|
||||
private _app: App,
|
||||
private _keyboard: Keyboard,
|
||||
private _zone: NgZone,
|
||||
@Optional() viewCtrl: ViewController
|
||||
@Optional() viewCtrl: ViewController,
|
||||
@Optional() private _tabs: Tabs
|
||||
) {
|
||||
super(_elementRef);
|
||||
this._sbPadding = _config.getBoolean('statusbarPadding', false);
|
||||
@@ -308,6 +316,7 @@ export class Content extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
*/
|
||||
addCssClass(className: string) {
|
||||
this.getNativeElement().classList.add(className);
|
||||
@@ -315,6 +324,7 @@ export class Content extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
*/
|
||||
removeCssClass(className: string) {
|
||||
this.getNativeElement().classList.remove(className);
|
||||
@@ -322,6 +332,7 @@ export class Content extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
*/
|
||||
setScrollElementStyle(prop: string, val: any) {
|
||||
this._scrollEle.style[prop] = val;
|
||||
@@ -368,6 +379,7 @@ export class Content extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
* Adds padding to the bottom of the scroll element when the keyboard is open
|
||||
* so content below the keyboard can be scrolled into view.
|
||||
*/
|
||||
@@ -382,16 +394,7 @@ export class Content extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
setContentPadding(paddingTop: number, paddingBottom: number) {
|
||||
this._paddingTop = paddingTop;
|
||||
this._paddingBottom = paddingBottom;
|
||||
this._scrollEle.style.paddingTop = (paddingTop > 0 ? paddingTop + 'px' : '');
|
||||
this._scrollEle.style.paddingBottom = (paddingBottom > 0 ? paddingBottom + 'px' : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
*/
|
||||
clearScrollPaddingFocusOut() {
|
||||
if (!this._inputPolling) {
|
||||
@@ -406,4 +409,97 @@ export class Content extends Ion {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM READ
|
||||
*/
|
||||
readDimensions() {
|
||||
this._computedTop = 0 ;
|
||||
this._computedBottom = 0;
|
||||
this._paddingTop = 0;
|
||||
this._paddingBottom = 0;
|
||||
this._headerHeight = 0;
|
||||
this._footerHeight = 0;
|
||||
|
||||
let ele: HTMLElement = this._elementRef.nativeElement;
|
||||
let parentEle: HTMLElement = ele.parentElement;
|
||||
let computedStyle: any;
|
||||
|
||||
for (var i = 0; i < parentEle.children.length; i++) {
|
||||
ele = <HTMLElement>parentEle.children[i];
|
||||
|
||||
if (ele.tagName === 'ION-CONTENT') {
|
||||
computedStyle = getComputedStyle(ele);
|
||||
this._computedTop = parsePxUnit(computedStyle.paddingTop);
|
||||
this._paddingTop += this._computedTop;
|
||||
|
||||
this._computedBottom = parsePxUnit(computedStyle.paddingBottom);
|
||||
this._paddingBottom += this._computedBottom;
|
||||
|
||||
} else if (ele.tagName === 'ION-HEADER') {
|
||||
this._headerHeight = ele.clientHeight;
|
||||
this._paddingTop += this._headerHeight;
|
||||
|
||||
} else if (ele.tagName === 'ION-FOOTER') {
|
||||
this._footerHeight = ele.clientHeight;
|
||||
this._paddingBottom += this._footerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
ele = parentEle;
|
||||
let tabbarEle: HTMLElement;
|
||||
let tabbarOnTop: boolean;
|
||||
|
||||
while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
|
||||
|
||||
if (ele.tagName === 'ION-TABS') {
|
||||
tabbarEle = <HTMLElement>ele.firstElementChild;
|
||||
tabbarOnTop = ele.getAttribute('tabbarplacement') === 'top';
|
||||
|
||||
if (tabbarOnTop) {
|
||||
this._paddingTop += tabbarEle.clientHeight;
|
||||
|
||||
} else {
|
||||
this._paddingBottom += tabbarEle.clientHeight;
|
||||
}
|
||||
|
||||
if (this._tabbarOnTop === null) {
|
||||
// this is the first tabbar found, remember it's position
|
||||
this._tabbarOnTop = tabbarOnTop;
|
||||
}
|
||||
}
|
||||
|
||||
ele = ele.parentElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DOM WRITE
|
||||
*/
|
||||
writeDimensions() {
|
||||
// only add inline padding styles if the computed padding value, which would
|
||||
// have come from the app's css, is different than the new padding value
|
||||
if (this._paddingTop !== this._computedTop) {
|
||||
this._scrollEle.style.paddingTop = (this._paddingTop > 0 ? this._paddingTop + 'px' : '');
|
||||
}
|
||||
|
||||
if (this._paddingBottom !== this._computedBottom) {
|
||||
this._scrollEle.style.paddingBottom = (this._paddingBottom > 0 ? this._paddingBottom + 'px' : '');
|
||||
}
|
||||
|
||||
if (this._tabbarOnTop && this._tabs) {
|
||||
if (this._tabbarOnTop) {
|
||||
this._tabs.setTabbarPosition(this._headerHeight, -1);
|
||||
|
||||
} else {
|
||||
this._tabs.setTabbarPosition(-1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function parsePxUnit(val: string): number {
|
||||
return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
|
||||
}
|
||||
|
||||
@@ -8,25 +8,31 @@ import {Navbar} from '../navbar/navbar';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-header'
|
||||
})
|
||||
export class Header {
|
||||
|
||||
constructor(@Optional() viewCtr: ViewController) {
|
||||
viewCtr && viewCtr.setHeader(this);
|
||||
constructor(@Optional() viewCtrl: ViewController) {
|
||||
viewCtrl && viewCtrl.setHeader(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-footer'
|
||||
})
|
||||
export class Footer {
|
||||
|
||||
constructor(@Optional() viewCtr: ViewController) {
|
||||
viewCtr && viewCtr.setFooter(this);
|
||||
constructor(@Optional() viewCtrl: ViewController) {
|
||||
viewCtrl && viewCtrl.setFooter(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,11 +11,6 @@ import {ViewController} from '../components/nav/view-controller';
|
||||
*/
|
||||
export class PageTransition extends Transition {
|
||||
enteringPage: Animation;
|
||||
paddingTop = 0;
|
||||
paddingBottom = 0;
|
||||
headerHeight = 0;
|
||||
footerHeight = 0;
|
||||
tabbarOnTop: boolean = null;
|
||||
|
||||
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
|
||||
super(enteringView, leavingView, opts);
|
||||
@@ -25,97 +20,26 @@ export class PageTransition extends Transition {
|
||||
this.add(this.enteringPage);
|
||||
|
||||
this.before.addDomReadFn(this.readDimensions.bind(this));
|
||||
this.before.addDomWriteFn(this.writeContentPadding.bind(this));
|
||||
this.before.addDomWriteFn(this.writeDimensions.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM READ
|
||||
*/
|
||||
readDimensions() {
|
||||
let pageElementRef = this.enteringView.pageRef();
|
||||
if (!pageElementRef) return;
|
||||
|
||||
let pageEle = <HTMLElement>pageElementRef.nativeElement;
|
||||
if (pageEle.tagName !== 'ION-PAGE') {
|
||||
pageEle = <HTMLElement>pageEle.querySelector('ion-page');
|
||||
if (!pageEle) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let ele: HTMLElement;
|
||||
let computedStyle: any;
|
||||
|
||||
for (var i = 0; i < pageEle.children.length; i++) {
|
||||
ele = <HTMLElement>pageEle.children[i];
|
||||
|
||||
if (ele.tagName === 'ION-CONTENT') {
|
||||
computedStyle = getComputedStyle(ele);
|
||||
this.paddingTop += parsePxUnit(computedStyle.paddingTop);
|
||||
this.paddingBottom += parsePxUnit(computedStyle.paddingBottom);
|
||||
|
||||
} else if (ele.tagName === 'ION-HEADER') {
|
||||
this.headerHeight = ele.clientHeight;
|
||||
this.paddingTop += this.headerHeight;
|
||||
|
||||
} else if (ele.tagName === 'ION-FOOTER') {
|
||||
this.footerHeight = ele.clientHeight;
|
||||
this.paddingBottom += this.footerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
ele = pageEle;
|
||||
let tabbarEle: HTMLElement;
|
||||
let tabbarOnTop: boolean;
|
||||
|
||||
while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
|
||||
|
||||
if (ele.tagName === 'ION-TABS') {
|
||||
tabbarEle = <HTMLElement>ele.firstElementChild;
|
||||
tabbarOnTop = ele.getAttribute('tabbarplacement') === 'top';
|
||||
|
||||
if (tabbarOnTop) {
|
||||
this.paddingTop += tabbarEle.clientHeight;
|
||||
|
||||
} else {
|
||||
this.paddingBottom += tabbarEle.clientHeight;
|
||||
}
|
||||
|
||||
if (this.tabbarOnTop === null) {
|
||||
// this is the first tabbar found, remember it's position
|
||||
this.tabbarOnTop = tabbarOnTop;
|
||||
}
|
||||
}
|
||||
|
||||
ele = ele.parentElement;
|
||||
let content = <Content>this.enteringView.getContent();
|
||||
if (content && content instanceof Content) {
|
||||
content.readDimensions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM WRITE
|
||||
*/
|
||||
writeContentPadding() {
|
||||
if (this.paddingTop || this.paddingBottom) {
|
||||
let content = <Content>this.enteringView.getContent();
|
||||
|
||||
if (content && content instanceof Content) {
|
||||
content.setContentPadding(this.paddingTop, this.paddingBottom);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tabbarOnTop !== null) {
|
||||
let tab = this.enteringView.getNav();
|
||||
if (tab && tab.parent) {
|
||||
let tabs = <Tabs>tab.parent;
|
||||
if (tabs instanceof Tabs) {
|
||||
if (this.tabbarOnTop) {
|
||||
tabs.setTabbarPosition(this.headerHeight, -1);
|
||||
|
||||
} else {
|
||||
tabs.setTabbarPosition(-1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
writeDimensions() {
|
||||
let content = <Content>this.enteringView.getContent();
|
||||
if (content && content instanceof Content) {
|
||||
content.writeDimensions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,4 +53,3 @@ export class PageTransition extends Transition {
|
||||
function parsePxUnit(val: string): number {
|
||||
return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user