Skip to content

Commit

Permalink
fix(platform): detect and ignore scrollBehavior polyfills (#20155)
Browse files Browse the repository at this point in the history
We use the `supportsScrollBehavior` function to check whether to try and pass in the scroll options object to `Scrollable.scrollTo` since passing it in on a browser that doesn't support it won't do anything. The problem is that the only way to detect if scroll behavior is supported is to look for the `scrollBehavior` property on a DOM element's CSS styles, however this will cause scroll behavior polyfills to be ignored since they only modify `Element.prototype.scrollTo`.

These changes try to detect whether `scrollTo` has been polyfilled, and if it has, we consider it as being supported.

Fixes #17847.
  • Loading branch information
crisbeto committed Aug 19, 2020
1 parent 20e5ea9 commit 6569041
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/cdk/platform/features/scrolling.ts
Expand Up @@ -28,9 +28,38 @@ export const enum RtlScrollAxisType {
/** Cached result of the way the browser handles the horizontal scroll axis in RTL mode. */
let rtlScrollAxisType: RtlScrollAxisType|undefined;

/** Cached result of the check that indicates whether the browser supports scroll behaviors. */
let scrollBehaviorSupported: boolean|undefined;

/** Check whether the browser supports scroll behaviors. */
export function supportsScrollBehavior(): boolean {
return !!(typeof document == 'object' && 'scrollBehavior' in document.documentElement!.style);
if (scrollBehaviorSupported == null) {
// If we're not in the browser, it can't be supported.
if (typeof document !== 'object' || !document) {
scrollBehaviorSupported = false;
}

// If the element can have a `scrollBehavior` style, we can be sure that it's supported.
if ('scrollBehavior' in document.documentElement!.style) {
scrollBehaviorSupported = true;
} else {
// At this point we have 3 possibilities: `scrollTo` isn't supported at all, it's
// supported but it doesn't handle scroll behavior, or it has been polyfilled.
const scrollToFunction: Function|undefined = Element.prototype.scrollTo;

if (scrollToFunction) {
// We can detect if the function has been polyfilled by calling `toString` on it. Native
// functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get
// the actual function source. Via https://davidwalsh.name/detect-native-function. Consider
// polyfilled functions as supporting scroll behavior.
scrollBehaviorSupported = !/\{\s*\[native code\]\s*\}/.test(scrollToFunction.toString());
} else {
scrollBehaviorSupported = false;
}
}
}

return scrollBehaviorSupported;
}

/**
Expand Down

0 comments on commit 6569041

Please sign in to comment.