1
- import { Component , ElementRef , Optional , NgZone , ChangeDetectionStrategy , ViewEncapsulation } from '@angular/core' ;
1
+ import { ChangeDetectionStrategy , Component , ElementRef , Input , NgZone , Optional , ViewEncapsulation } from '@angular/core' ;
2
2
3
3
import { App } from '../app/app' ;
4
4
import { Ion } from '../ion' ;
@@ -8,6 +8,7 @@ import {nativeRaf, nativeTimeout, transitionEnd} from '../../util/dom';
8
8
import { ScrollView } from '../../util/scroll-view' ;
9
9
import { Tabs } from '../tabs/tabs' ;
10
10
import { ViewController } from '../nav/view-controller' ;
11
+ import { isTrueProperty } from '../../util/util' ;
11
12
12
13
13
14
/**
@@ -59,19 +60,23 @@ import {ViewController} from '../nav/view-controller';
59
60
}
60
61
} )
61
62
export class Content extends Ion {
62
- private _computedTop : number ;
63
- private _computedBottom : number ;
64
63
private _paddingTop : number ;
64
+ private _paddingRight : number ;
65
65
private _paddingBottom : number ;
66
+ private _paddingLeft : number ;
67
+ private _lastTop : number ;
68
+ private _lastBottom : number ;
66
69
private _scrollPadding : number ;
67
70
private _headerHeight : number ;
68
71
private _footerHeight : number ;
69
- private _tabbarOnTop : boolean = null ;
72
+ private _tabbarHeight : number ;
73
+ private _tabbarPlacement : string ;
70
74
private _inputPolling : boolean = false ;
71
75
private _scroll : ScrollView ;
72
76
private _scLsn : Function ;
73
77
private _scrollEle : HTMLElement ;
74
78
private _sbPadding : boolean ;
79
+ private _fullscreen : boolean ;
75
80
76
81
constructor (
77
82
private _elementRef : ElementRef ,
@@ -322,6 +327,22 @@ export class Content extends Ion {
322
327
this . getNativeElement ( ) . classList . add ( className ) ;
323
328
}
324
329
330
+ /**
331
+ * @input {boolean} By default, content is positioned between the headers
332
+ * and footers. However, using `fullscreen="true"`, the content will be
333
+ * able to scroll "under" the headers and footers. At first glance the
334
+ * fullscreen option may not look any different than the default, however,
335
+ * by adding a transparency effect to a header then the content can be
336
+ * seen under the header as the user scrolls.
337
+ */
338
+ @Input ( )
339
+ get fullscreen ( ) : boolean {
340
+ return ! ! this . _fullscreen ;
341
+ }
342
+ set fullscreen ( val : boolean ) {
343
+ this . _fullscreen = isTrueProperty ( val ) ;
344
+ }
345
+
325
346
/**
326
347
* @private
327
348
* DOM WRITE
@@ -414,13 +435,12 @@ export class Content extends Ion {
414
435
* DOM READ
415
436
*/
416
437
readDimensions ( ) {
417
- this . _computedTop = 0 ;
418
- this . _computedBottom = 0 ;
419
438
this . _paddingTop = 0 ;
439
+ this . _paddingRight = 0 ;
420
440
this . _paddingBottom = 0 ;
441
+ this . _paddingLeft = 0 ;
421
442
this . _headerHeight = 0 ;
422
- this . _footerHeight = 0 ;
423
- this . _tabbarOnTop = null ;
443
+ this . _tabbarPlacement = null ;
424
444
425
445
let ele : HTMLElement = this . _elementRef . nativeElement ;
426
446
let parentEle : HTMLElement = ele . parentElement ;
@@ -430,43 +450,34 @@ export class Content extends Ion {
430
450
ele = < HTMLElement > parentEle . children [ i ] ;
431
451
432
452
if ( ele . tagName === 'ION-CONTENT' ) {
433
- computedStyle = getComputedStyle ( ele ) ;
434
- this . _computedTop = parsePxUnit ( computedStyle . paddingTop ) ;
435
- this . _paddingTop += this . _computedTop ;
436
-
437
- this . _computedBottom = parsePxUnit ( computedStyle . paddingBottom ) ;
438
- this . _paddingBottom += this . _computedBottom ;
453
+ if ( this . _fullscreen ) {
454
+ computedStyle = getComputedStyle ( ele ) ;
455
+ this . _paddingTop = parsePxUnit ( computedStyle . paddingTop ) ;
456
+ this . _paddingBottom = parsePxUnit ( computedStyle . paddingBottom ) ;
457
+ this . _paddingRight = parsePxUnit ( computedStyle . paddingRight ) ;
458
+ this . _paddingLeft = parsePxUnit ( computedStyle . paddingLeft ) ;
459
+ }
439
460
440
461
} else if ( ele . tagName === 'ION-HEADER' ) {
441
462
this . _headerHeight = ele . clientHeight ;
442
- this . _paddingTop += this . _headerHeight ;
443
463
444
464
} else if ( ele . tagName === 'ION-FOOTER' ) {
445
465
this . _footerHeight = ele . clientHeight ;
446
- this . _paddingBottom += this . _footerHeight ;
447
466
}
448
467
}
449
468
450
469
ele = parentEle ;
451
470
let tabbarEle : HTMLElement ;
452
- let tabbarOnTop : boolean ;
453
471
454
472
while ( ele && ele . tagName !== 'ION-MODAL' && ! ele . classList . contains ( 'tab-subpage' ) ) {
455
473
456
474
if ( ele . tagName === 'ION-TABS' ) {
457
475
tabbarEle = < HTMLElement > ele . firstElementChild ;
458
- tabbarOnTop = ele . getAttribute ( 'tabbarplacement' ) === 'top' ;
459
-
460
- if ( tabbarOnTop ) {
461
- this . _paddingTop += tabbarEle . clientHeight ;
462
-
463
- } else {
464
- this . _paddingBottom += tabbarEle . clientHeight ;
465
- }
476
+ this . _tabbarHeight = tabbarEle . clientHeight ;
466
477
467
- if ( this . _tabbarOnTop === null ) {
478
+ if ( this . _tabbarPlacement === null ) {
468
479
// this is the first tabbar found, remember it's position
469
- this . _tabbarOnTop = tabbarOnTop ;
480
+ this . _tabbarPlacement = ele . getAttribute ( 'tabbarplacement' ) ;
470
481
}
471
482
}
472
483
@@ -479,18 +490,54 @@ export class Content extends Ion {
479
490
* DOM WRITE
480
491
*/
481
492
writeDimensions ( ) {
482
- // only add inline padding styles if the computed padding value, which would
483
- // have come from the app's css, is different than the new padding value
484
- if ( this . _paddingTop !== this . _computedTop ) {
485
- this . _scrollEle . style . paddingTop = ( this . _paddingTop > 0 ? this . _paddingTop + 'px' : '' ) ;
486
- }
493
+ let newVal : number ;
494
+
495
+ // only write when it has changed
496
+ if ( this . _fullscreen ) {
497
+ // adjust the content with padding, allowing content to scroll under headers/footers
498
+ // however, on iOS you cannot control the margins of the scrollbar (last tested iOS9.2)
499
+ // only add inline padding styles if the computed padding value, which would
500
+ // have come from the app's css, is different than the new padding value
501
+
502
+ newVal = this . _headerHeight + this . _paddingTop ;
503
+ if ( this . _tabbarPlacement === 'top' ) {
504
+ newVal += this . _tabbarHeight ;
505
+ }
506
+ if ( newVal !== this . _lastTop ) {
507
+ this . _scrollEle . style . paddingTop = ( newVal > 0 ? newVal + 'px' : '' ) ;
508
+ }
509
+
510
+ newVal = this . _footerHeight + this . _paddingBottom ;
511
+ if ( this . _tabbarPlacement === 'bottom' ) {
512
+ newVal += this . _tabbarHeight ;
513
+ }
514
+ if ( newVal !== this . _lastBottom ) {
515
+ this . _scrollEle . style . paddingBottom = ( newVal > 0 ? newVal + 'px' : '' ) ;
516
+ }
487
517
488
- if ( this . _paddingBottom !== this . _computedBottom ) {
489
- this . _scrollEle . style . paddingBottom = ( this . _paddingBottom > 0 ? this . _paddingBottom + 'px' : '' ) ;
518
+ } else {
519
+ // adjust the content with margins
520
+ newVal = this . _headerHeight ;
521
+ if ( this . _tabbarPlacement === 'top' ) {
522
+ newVal += this . _tabbarHeight ;
523
+ }
524
+ if ( newVal !== this . _lastTop ) {
525
+ this . _scrollEle . style . marginTop = ( newVal > 0 ? newVal + 'px' : '' ) ;
526
+ }
527
+
528
+ newVal = this . _footerHeight ;
529
+ if ( this . _tabbarPlacement === 'bottom' ) {
530
+ newVal += this . _tabbarHeight ;
531
+ }
532
+ if ( newVal !== this . _lastBottom ) {
533
+ this . _scrollEle . style . marginBottom = ( newVal > 0 ? newVal + 'px' : '' ) ;
534
+ }
490
535
}
491
536
492
- if ( this . _tabbarOnTop !== null && this . _tabs ) {
493
- if ( this . _tabbarOnTop ) {
537
+
538
+ if ( this . _tabbarPlacement !== null && this . _tabs ) {
539
+ // set the position of the tabbar
540
+ if ( this . _tabbarPlacement === 'top' ) {
494
541
this . _tabs . setTabbarPosition ( this . _headerHeight , - 1 ) ;
495
542
496
543
} else {
0 commit comments