Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'cancelAnimationFrame' called on an object that does not implement interface Window #2385

Closed
brawaru opened this issue Mar 2, 2020 · 2 comments

Comments

@brawaru
Copy link
Contributor

brawaru commented Mar 2, 2020

Reproduction

Large internal code base, code uses hooks, presumably useEffect does this.

Steps to reproduce

  1. Use… Firefox and run Preact inside content script (userscript, extension).
  2. Try rendering a component with useEffect and other funky stuff.

Expected Behavior

Component successfully renders, or at least, all errors are catched within error boundary component.

Actual Behavior

Component does not render, but fails due to attempt to call cancelAnimationFrame withing… window scope, but somehow it ends up that 'cancelAnimationFrame' called on an object that does not implement interface Window. Nothing is catched by error boundary.

Proposed Solution

Bind {cancel,request}AnimationFrame functions to ensure they are always called on an object that DOES implement interface Window, to make our odd friend, Firefox, happy. React had/has same issue at facebook/react#16606.

I was able to mitigate this issue by having this in my rollup config:

replace({
    values: {
         // FIX DARN FIREFOX!
        "requestAnimationFrame(": "unsafeWindow.requestAnimationFrame.bind(unsafeWindow)(",
        "cancelAnimationFrame(": "unsafeWindow.cancelAnimationFrame.bind(unsafeWindow)(",
    },
}),

Interesting fact: unsafeWindow === window, but only binding and using unsafeWindow works. Why? Well, can't help you with that question. Because Firefox DevTools yet again proven to be flawed and displays proxy to window as window object itself, Firefox apparently cannot distinguish them. Wow!

@marvinhagemeister
Copy link
Member

Does binding to window work the same way? Some googling seems to reveal that the global object is different in the extension context.

@brawaru
Copy link
Contributor Author

brawaru commented Mar 2, 2020

I actually think I narrowed down the issue. So apparently my manager dictates that window is a proxy to actual so-called unsafeWindow (page window itself) and Firefox DevTools weren't (by some reason) able to distinguish them. By replacing bind to double window unsafeWindow it works (cancelAnimationFrame.bind(unsafeWindow)). I guess that's then only my userscript usage case and I was mistaken it would be related to binding to window and what's happening in React. I'll close the issue, anyone who will encounter same issue may open another one. Sorry for bothering!

@brawaru brawaru closed this as completed Mar 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants