Skip to content

Fallback findCanvasEventTarget to findEventTarget #22959

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

JoeOsborn
Copy link
Contributor

Also fix canvas tag lookup bug, which would return a string rather than an offscreenCanvases entry.

Fixes #22942 , seemingly with no other patches needed; call sites already have to handle a variety of object shapes out of this function.

@@ -362,13 +362,9 @@ var LibraryHTML5 = {
return GL.offscreenCanvases[target.substr(1)] // Remove '#' prefix
// If not found, if one is querying by using DOM tag name selector 'canvas', grab the first
// OffscreenCanvas that we can find.
|| (target == 'canvas' && Object.keys(GL.offscreenCanvases)[0])
|| (target == 'canvas' && Object.keys(GL.offscreenCanvases) && GL.offscreenCanvases[Object.keys(GL.offScreenCanvases)[0]])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line looks like it might be more complex that it needs to be.

About just target == 'canvas' && Object.values(GL.offscreenCanvases)[0]?

Can we make this a separate PR? Ideally with a test. I guess we have very little testing for this since the existing code seems simply broken?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that change and will push it here, but I think this whole lookup thing is pretty hacked together/"best effort".

@JoeOsborn
Copy link
Contributor Author

As for a test which shows the bug, I guess there are two bugs here---one is that there's no use of specialEventTargets, and the other is that tag lookups are broken. I'll prepare one parameterized test for findCanvasEventTarget, varying on whether it's an ID, a tag, or a special target, both before and after an offscreen canvas has been created.

@JoeOsborn
Copy link
Contributor Author

I've added a set of tests that fails when the old function definition is in place, and passes with the new definition.

@JoeOsborn JoeOsborn force-pushed the 22942-findCanvasEventTarget branch from f9c7414 to fc261ee Compare November 21, 2024 19:27
@JoeOsborn JoeOsborn force-pushed the 22942-findCanvasEventTarget branch from fc261ee to d89f1dd Compare November 21, 2024 19:29
#else
|| document.querySelector(target);
#endif
|| (target == 'canvas' && Object.values(GL.offscreenCanvases)[0])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this also missing the .canvas similar to in #22958

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was worried it would, but in fact we want the whole offscreenCanvases entry because the caller might need the shared canvas pointer. All of the callers do a check for the presence of an .offscreenCanvas field.

@sbc100 sbc100 requested a review from juj November 21, 2024 20:14
Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems correct to. We should probably wait on @juj for approval though

@JoeOsborn
Copy link
Contributor Author

I mentioned this on Discord, but we actually have a big problem here: specialHTMLTargets is likely to only have reasonable values on the main thread, since it isn't shared across workers and probably will be configured using MAIN_THREAD_EM_ASM or something (at any rate, it's possible it would be set up on one thread and used on a different thread, which has the same issue). So a findCanvasEventTarget (or indeed a findEventTarget) won't do what we want for canvases that are referred to by specialHTMLTarget names. Only ID lookups or tag lookups actually work.

It seemed like it was working because !canvas was the suggested special name and the ID of the objects involved has typically been #canvas, and the offscreenCanvases array is keyed by the ID of the element involved. So stripping the first character from the ID ends up being like a pun in that case.

What's the right solution? To key offscreenCanvases based on target, rather than canvas ID? To ignore specialHTMLTargets completely in findCanvasEventTarget?

@JoeOsborn
Copy link
Contributor Author

Just wanted to ping here—I’m a bit stuck because I’m not sure what the right behavior should be.

@JoeOsborn
Copy link
Contributor Author

Can I get some feedback on this one? I was stuck because the correct behavior isn't clear and I'd like a maintainer to weigh in.

@sbc100
Copy link
Collaborator

sbc100 commented Jan 25, 2025

I'm afraid this is at the limits of my understanding too. However it does seem expected/understandable that the list of specialHTMLTargets would be thread-specific since canvases themselves are thread specific and any given thread could have a different set of them.

Is the issue that you new test is failing in a certain configuration? Or is this more of a general concern that this is the wrong fix?

@JoeOsborn
Copy link
Contributor Author

I agree it makes sense that special targets would be thread specific, but it complicates the handoff from main to proxy thread (on screen to offscreen canvas) in a proxy to pthread situation. So the options seem to be:

  1. Use the deprecated lookup strategy for findCanvasEventTarget, where #canvas means something special and not the html element with ID canvas
  2. Proxy accesses to specialHTMLTargets to the main thread, or proxy all calls to find*EventTarget to the main thread; but then we can’t easily get the offscreencanvas after it’s been transferred, right?
  3. Make the offscreenCanvases dictionary keyed on target selector strings rather than IDs. This means selectors besides IDs or !IDs won’t always do the right thing in that two queries that should produce the same canvas/offscreenCanvas might not—probably better to require that canvases have either an ID or are in the specialHTMLTargets, so that an identifier or !identifier will uniquely identify the canvas.
  4. Eliminate findCanvasEventTarget and replace its uses with either the regular findEventTarget or a function to get a specific offscreencanvas.
  5. Return offscreen canvases as numeric handles or something so that client code is responsible for maintaining references to them, and we don’t need findCanvasEventtTarget anymore?

Other ideas I’m not thinking of? It’s been a minute since I was deep into this bug.

@sbc100
Copy link
Collaborator

sbc100 commented Jan 25, 2025

I agree it makes sense that special targets would be thread specific, but it complicates the handoff from main to proxy thread (on screen to offscreen canvas) in a proxy to pthread situation.

Just to be clear, is this something that doesn't work today? And never has worked?

@JoeOsborn
Copy link
Contributor Author

Yes, I believe it only worked if you used specialHTMLTarget[“!canvas”] specifically because canvas is also an element name and likely because #canvas is special cased in the lookup code. The offscreencanvas would be keyed by “canvas” in the offscreenCanvases map, and by luck it would be retrieved by !canvas (special target) after the ! was trimmed off and produced “canvas”, an element name selector, since the specialHTMLTargets map would be empty in all threads but the main thread.

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

Successfully merging this pull request may close these issues.

findCanvasEventTarget doesn't use specialHTMLTargets
2 participants