Skip to content

Commit 2c076d5

Browse files
crisbetowagnermaciel
authored andcommitted
fix(platform): detect and ignore scrollBehavior polyfills (#20155)
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. (cherry picked from commit 6569041)
1 parent 81f86e8 commit 2c076d5

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/cdk/platform/features/scrolling.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,38 @@ export const enum RtlScrollAxisType {
2828
/** Cached result of the way the browser handles the horizontal scroll axis in RTL mode. */
2929
let rtlScrollAxisType: RtlScrollAxisType|undefined;
3030

31+
/** Cached result of the check that indicates whether the browser supports scroll behaviors. */
32+
let scrollBehaviorSupported: boolean|undefined;
33+
3134
/** Check whether the browser supports scroll behaviors. */
3235
export function supportsScrollBehavior(): boolean {
33-
return !!(typeof document == 'object' && 'scrollBehavior' in document.documentElement!.style);
36+
if (scrollBehaviorSupported == null) {
37+
// If we're not in the browser, it can't be supported.
38+
if (typeof document !== 'object' || !document) {
39+
scrollBehaviorSupported = false;
40+
}
41+
42+
// If the element can have a `scrollBehavior` style, we can be sure that it's supported.
43+
if ('scrollBehavior' in document.documentElement!.style) {
44+
scrollBehaviorSupported = true;
45+
} else {
46+
// At this point we have 3 possibilities: `scrollTo` isn't supported at all, it's
47+
// supported but it doesn't handle scroll behavior, or it has been polyfilled.
48+
const scrollToFunction: Function|undefined = Element.prototype.scrollTo;
49+
50+
if (scrollToFunction) {
51+
// We can detect if the function has been polyfilled by calling `toString` on it. Native
52+
// functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get
53+
// the actual function source. Via https://davidwalsh.name/detect-native-function. Consider
54+
// polyfilled functions as supporting scroll behavior.
55+
scrollBehaviorSupported = !/\{\s*\[native code\]\s*\}/.test(scrollToFunction.toString());
56+
} else {
57+
scrollBehaviorSupported = false;
58+
}
59+
}
60+
}
61+
62+
return scrollBehaviorSupported;
3463
}
3564

3665
/**

0 commit comments

Comments
 (0)