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

Popout! compatibilty (Fixes #3044) #3048

Merged
merged 3 commits into from
Mar 1, 2024

Conversation

Posnet
Copy link
Contributor

@Posnet Posnet commented Feb 14, 2024

For details of the actual buggy behavior see: League-of-Foundry-Developers/fvtt-module-popout#109

TL;DR - Moving a custom (or otherwise) HTML element to a new window involves adopting it into the new windows document. However any use of constructed CSS (i.e. new CSSStyleSheet) will be silently stripped or fail outright unless we are careful to construct new copies of the CSSStyleSheet object via the new window's constructor.

For custom elements that use constructed CSS, we have to implement the adoptedCallback method and manually reconstruct and reattach a new CSS object to the shadow DOM. This is because when a custom element is moved to a new document, any constructed CSS objects that it has adopted already are silently stripped.

We also need to update how we construct our CSS objects. Specifically we need to ensure we are accessing the current owner document of our custom element, and not bind the root document from which ever window we defined our custom element in.

We also can no longer use a static variable to store our CSS obj, since in Chrome based browsers the static element is shared across windows (though not the case in firefox). So we need to keep a map from document to CSS obj singleton and do the lookup manually.

@Posnet Posnet changed the title Popout! compatibilty #3044 [#3044] Popout! compatibilty Feb 14, 2024
@Posnet
Copy link
Contributor Author

Posnet commented Feb 14, 2024

Also I am not particularly attached to the current implementation of the fix. I know there is a fair amount of code duplication, and one might want to implement the CSS caching as free functions or as a mixin class and attach them to the respective custom elements. But I wanted to keep the changes minimal to show what was necessary for the fix and nothing more.

@Posnet Posnet changed the title [#3044] Popout! compatibilty Popout! compatibilty Fixes #3044 Feb 14, 2024
@Posnet Posnet changed the title Popout! compatibilty Fixes #3044 Popout! compatibilty (Fixes #3044) Feb 14, 2024
@Posnet Posnet force-pushed the Posnet/popout-3.x.x-fix branch from 2c8967b to fc156cd Compare February 14, 2024 14:58
For custom elements that use constructed CSS, we have to implement
the adoptedCallback method and manually reconstruct and reattach
a new CSS object to the shadow DOM. This is because when a custom
element is moved to a new document, any constructed CSS objects
that it has adopted already are silently stripped.

We also need to update how we construct our CSS objects. Specifically
we need to ensure we are accessing the current owner document of our
custom element, and not bind the root document from which ever window
we defined our custom element in.

We also can no longer use a static variable to store our CSS obj,
since in Chrome based browsers the static element is shared across
windows (though not the case in firefox). So we need to keep a map
from document to CSS obj singleton and do the lookup manually.
@Ator27
Copy link

Ator27 commented Feb 17, 2024

You're getting there! Thank you for working this. Still seems to have problems with some of the objects scaling/Sizing? In the effects tab and the Death Save Skull are examples.
Capture

@Fyorl Fyorl added this to the D&D5E 3.0.4 milestone Feb 22, 2024
@Fyorl Fyorl changed the base branch from 3.1.x to 3.0.x February 22, 2024 18:09
@Fyorl Fyorl requested a review from arbron February 22, 2024 18:41
@Fyorl
Copy link
Contributor

Fyorl commented Feb 22, 2024

Thanks for doing this work, I think it's worthwhile to make our custom elements agnostic of their owning Document if at all possible. I've factored out your suggested changes into a mixin to hopefully keep all the logic in one place. Even with your original changes though, I wasn't able to get this working with PopOut! in Firefox. Maybe I need a pre-release version of PopOut! to test? I'm unsure. The errors seemed to be related to this losing all of its methods entirely.

fill: var(--filigree-border-color, var(--dnd5e-color-gold));
z-index: -1;
/** @inheritDoc */
_buildCSS(sheet) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this could be a simple static CSS = , but I was trying to avoid using statics at all due to this note:

We also can no longer use a static variable to store our CSS obj, since in Chrome based browsers the static element is shared across windows (though not the case in firefox). So we need to keep a map from document to CSS obj singleton and do the lookup manually.

Even avoiding it though, it seems it was not working in Firefox. If we can get to the bottom of what's happening there, we can revisit this design hopefully.

@Posnet
Copy link
Contributor Author

Posnet commented Mar 1, 2024

@Fyorl I'll have a go at making a fix that uses that uses inline styles if you prefer, which would be simpler than the current fix.

The reason this this fix doesn't work on Firefox is due to browser implementation differences, that being moving custom elements (and even some normal elements) is essentially broken, the element in the new window will be missing all of it's non static methods and member variables. I stopped testing or supporting Firefox with PopOut! because of this and because there are parts of jQuery that have the same issue. So if a system or module is using custom html elements/web components or is using jQuery extensively it will never work on Firefox with PopOut!

Also because Foundry uses Electron so generally is better tested on blink based browsers. I actually prefer Firefox for normal web browsing, but have to use chrome with Foundry.

@Posnet
Copy link
Contributor Author

Posnet commented Mar 1, 2024

I have updated my gist showing the broken behavior https://gist.github.com/Posnet/9d87f790d4f3c64ed468559600c76302

@Fyorl
Copy link
Contributor

Fyorl commented Mar 1, 2024

@Fyorl I'll have a go at making a fix that uses that uses inline styles if you prefer, which would be simpler than the current fix.

Now you've clarified this part below, I think it's fine to use what we have for now. I'll make some additional tweaks to use the static CSS, which should simplify things further, and then we can have the performance benefits of adopted stylesheets for whatever they're worth at least.

The reason this this fix doesn't work on Firefox is due to browser implementation differences, that being moving custom elements (and even some normal elements) is essentially broken, the element in the new window will be missing all of it's non static methods and member variables.

I didn't realise it was non-static methods. It sounds like Firefox is a dead-end then here. Do we know if this is a bug or some security sandboxing on Firefox's part such that this will never work?

@arbron
Copy link
Collaborator

arbron commented Mar 1, 2024

I didn't realise it was non-static methods. It sounds like Firefox is a dead-end then here. Do we know if this is a bug or some security sandboxing on Firefox's part such that this will never work?

Looks like a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1502814

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.

4 participants