Skip to content

Commit 298b02b

Browse files
committed
fix: approach not working in Safari
1 parent 301f365 commit 298b02b

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

src/lib/tabs/tab-body.ts

+25-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import {
1818
AfterViewChecked,
1919
ViewEncapsulation,
2020
ChangeDetectionStrategy,
21+
OnChanges,
22+
SimpleChanges,
2123
} from '@angular/core';
2224
import {
2325
trigger,
@@ -65,6 +67,7 @@ export type MdTabBodyOriginState = 'left' | 'right';
6567
changeDetection: ChangeDetectionStrategy.OnPush,
6668
host: {
6769
'class': 'mat-tab-body',
70+
'[class.mat-tab-body-active]': 'active',
6871
},
6972
animations: [
7073
trigger('translateTab', [
@@ -87,7 +90,7 @@ export type MdTabBodyOriginState = 'left' | 'right';
8790
])
8891
]
8992
})
90-
export class MdTabBody implements OnInit, AfterViewChecked {
93+
export class MdTabBody implements OnInit, OnChanges, AfterViewChecked {
9194
/** The portal host inside of this container into which the tab body content will be loaded. */
9295
@ViewChild(PortalHostDirective) _portalHost: PortalHostDirective;
9396

@@ -103,6 +106,9 @@ export class MdTabBody implements OnInit, AfterViewChecked {
103106
/** The tab body content to display. */
104107
@Input('content') _contentPortal: TemplatePortal<any>;
105108

109+
/** Whether the tab is currently active. */
110+
@Input() active: boolean;
111+
106112
/** Scroll position of the tab before the user switched away. */
107113
private _lastScrollPosition = 0;
108114

@@ -153,7 +159,24 @@ export class MdTabBody implements OnInit, AfterViewChecked {
153159
ngAfterViewChecked() {
154160
if (this._isCenterPosition(this._position) && !this._portalHost.hasAttached()) {
155161
this._portalHost.attach(this._contentPortal);
156-
this._contentElement.nativeElement.scrollTop = this._lastScrollPosition;
162+
163+
if (this._lastScrollPosition) {
164+
// Depending on the browser, the scrollable element can end up being
165+
// either the host element or the element with all the content.
166+
this._contentElement.nativeElement.scrollTop =
167+
this._elementRef.nativeElement.scrollTop =
168+
this._lastScrollPosition;
169+
}
170+
}
171+
}
172+
173+
ngOnChanges(changes: SimpleChanges) {
174+
// Cache the scroll position before moving away from the tab. Note that this has to be done
175+
// throught change detection and as early as possible, because some browsers (namely Safari)
176+
// will reset the scroll position when we switch from an absolute to a relative position.
177+
if (changes.active && changes.active.previousValue) {
178+
this._lastScrollPosition = this._elementRef.nativeElement.scrollTop ||
179+
this._contentElement.nativeElement.scrollTop;
157180
}
158181
}
159182

@@ -166,7 +189,6 @@ export class MdTabBody implements OnInit, AfterViewChecked {
166189
_onTranslateTabComplete(e: AnimationEvent) {
167190
// If the end state is that the tab is not centered, then detach the content.
168191
if (!this._isCenterPosition(e.toState) && !this._isCenterPosition(this._position)) {
169-
this._lastScrollPosition = this._contentElement.nativeElement.scrollTop || 0;
170192
this._portalHost.detach();
171193
}
172194

src/lib/tabs/tab-group.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
*ngFor="let tab of _tabs; let i = index"
3030
[id]="_getTabContentId(i)"
3131
[attr.aria-labelledby]="_getTabLabelId(i)"
32-
[class.mat-tab-body-active]="selectedIndex == i"
32+
[active]="selectedIndex === i"
3333
[content]="tab.content"
3434
[position]="tab.position"
3535
[origin]="tab.origin"

src/lib/tabs/tab-group.spec.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,9 @@ describe('MdTabGroup', () => {
280280

281281
// Ensure that there is content and scroll down 100px.
282282
expect(tabElements[1].offsetHeight).toBeGreaterThan(0, 'Expected tab to have some content.');
283-
tabElements[1].scrollTop = 100;
283+
284+
// Handle some differences in the way browsers determine what element is scrollable.
285+
tabElements[1].scrollTop = tabElements[1].parentElement!.scrollTop = 100;
284286

285287
// Move to another tab.
286288
testComponent.selectedIndex = 0;
@@ -292,7 +294,8 @@ describe('MdTabGroup', () => {
292294
fixture.detectChanges();
293295
tick(500);
294296

295-
expect(tabElements[1].scrollTop).toBe(100, 'Expected scroll position to be restored.');
297+
expect(tabElements[1].scrollTop || tabElements[1].parentElement!.scrollTop)
298+
.toBe(100, 'Expected scroll position to be restored.');
296299
}));
297300
});
298301

0 commit comments

Comments
 (0)