casual-simulation / casualos

Casual Open Simulation for the Web
https://ab1.bot
MIT License
48 stars 8 forks source link

Calling a function on an HTML element created from a Preact Hook does not work #455

Open KallynGowdy opened 2 months ago

KallynGowdy commented 2 months ago

Calling a function on a HTML element that was created from inside a Preact Hook callback does not work. This happens because CasualOS allows multiple distinct documents, and uses them to distinguish between function call handlers. Unfortunately, Preact doesn't know about these separate documents, so whenever an element needs to be created as a result of a Preact hook (like useState()), then it uses the default (_root) document. This can cause a custom app to have elements from two distinct documents, and because function call handlers kept separate based on document, elements that are created in this way do not have functioning function call handlers (like .focus()).

See this gist for an example.

Possible solutions to this are to:

  1. Rework the frontend so that elements are not separated by document and so then functions can be called no matter where they have been created. (This would only fix this particular issue)
  2. Rework the backend so that there is only ever one document. (This would fix not only this issue, but also additional issues that can arise if users end up moving elements between custom apps or trying to compare elements using instanceof HTMLElement)

For now, the only workaround is to ditch using os.registerApp() and os.compileApp(), and instead only use document and os.appHooks.render(). This would cause everything to use the same HTML document and therefore avoid the issue. Before using document, be sure to wait for the @onDocumentAvailable shout.