Skip to content

Commit

Permalink
fix(cdk/overlay): block scroll strategy throwing off scroll behavior …
Browse files Browse the repository at this point in the history
…feature detection (#17223)

To avoid a scrolling animation when we disable scrollig, we remove and re-set the
`scroll-behavior` property on the body without feature checking it. The problem is
that since we've set the property to *something*, our `scrollBehaviorSupported`
feature check will be thrown off because it checks for `'scrollBehavior' in
document.documentElement.style`.

Fixes #17221.

(cherry picked from commit f940d34)
  • Loading branch information
crisbeto authored and annieyw committed Jan 6, 2021
1 parent aade5d1 commit c04d8be
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
29 changes: 16 additions & 13 deletions src/cdk/overlay/scroll/block-scroll-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,16 @@
import {ScrollStrategy} from './scroll-strategy';
import {ViewportRuler} from '@angular/cdk/scrolling';
import {coerceCssPixelValue} from '@angular/cdk/coercion';
import {supportsScrollBehavior} from '@angular/cdk/platform';

/**
* Extended `CSSStyleDeclaration` that includes `scrollBehavior` which isn't part of the
* built-in TS typings. Once it is, this declaration can be removed safely.
* @docs-private
*/
type ScrollBehaviorCSSStyleDeclaration = CSSStyleDeclaration & {scrollBehavior: string};
const scrollBehaviorSupported = supportsScrollBehavior();

/**
* Strategy that will prevent the user from scrolling while the overlay is visible.
*/
export class BlockScrollStrategy implements ScrollStrategy {
private _previousHTMLStyles = {top: '', left: ''};
private _previousScrollPosition: { top: number, left: number };
private _previousScrollPosition: {top: number, left: number};
private _isEnabled = false;
private _document: Document;

Expand All @@ -31,7 +27,7 @@ export class BlockScrollStrategy implements ScrollStrategy {
}

/** Attaches this scroll strategy to an overlay. */
attach() { }
attach() {}

/** Blocks page-level scroll while the attached overlay is open. */
enable() {
Expand All @@ -58,8 +54,8 @@ export class BlockScrollStrategy implements ScrollStrategy {
if (this._isEnabled) {
const html = this._document.documentElement!;
const body = this._document.body!;
const htmlStyle = html.style as ScrollBehaviorCSSStyleDeclaration;
const bodyStyle = body.style as ScrollBehaviorCSSStyleDeclaration;
const htmlStyle = html.style;
const bodyStyle = body.style;
const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';
const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';

Expand All @@ -71,12 +67,19 @@ export class BlockScrollStrategy implements ScrollStrategy {

// Disable user-defined smooth scrolling temporarily while we restore the scroll position.
// See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
// Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,
// because it can throw off feature detections in `supportsScrollBehavior` which
// checks for `'scrollBehavior' in documentElement.style`.
if (scrollBehaviorSupported) {
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
}

window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top);

htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
if (scrollBehaviorSupported) {
htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/cdk/platform/features/scrolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function supportsScrollBehavior(): boolean {
// If we're not in the browser, it can't be supported.
if (typeof document !== 'object' || !document) {
scrollBehaviorSupported = false;
return scrollBehaviorSupported;
}

// If the element can have a `scrollBehavior` style, we can be sure that it's supported.
Expand Down

0 comments on commit c04d8be

Please sign in to comment.