-
-
Notifications
You must be signed in to change notification settings - Fork 189
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
Mount and unmount Content Script UI with MutationObserver #537
Comments
You'll want to use the awaited element as the Something like this would work. I typed this up in github comments, so it probably isn't valid JS, and I haven't tested it. But hopefully it gives you a better idea of what you're looking for. let anchor;
const ui = createIntegratedUi(ctx, {
position: "inline",
anchor: () => anchor,
append: (anchor, root) => anchor.insertAdjacentElement("afterend", root),
onMount: async (container) => {
const root = ReactDOM.createRoot(container);
root.render(<Toolbar />);
return root;
},
onRemove: (root) => {
root.unmount();
},
});
watchDomChanges(ctx, '[class^="ToolbarContainer__StyledHeader"]', {
onAdd: (newAnchor) => {
anchor = newAnchor;
ui.mount();
},
onRemove: () => {
ui.remove();
},
}); function watchDomChanges(ctx: any, selector: any, callbacks: any) {
let prevAnchor: HTMLElement | undefined;
const observer = new MutationObserver(() => {
const el = document.querySelector(selector);
if (el && !prevAnchor) {
callbacks.onAdd(el);
} else if (!el && prevAnchor) {
callbacks.onRemove();
}
prevAnchor = el;
});
ctx.onInvalidated(() => observer.disconnect());
observer.observe(document.body, {
childList: true,
subtree: true,
});
const initialEl = document.querySelector(selector);
if (initialEl) {
callbacks.onAdd(initialEl);
prevAnchor = initialEl;
}
} |
@hexpl0it If you get something that works, I'd like to add auto-mounting/unmounting to WXT, if you would like to contribute your implementation. |
Thank you very much for this issue. I have recently encountered a similar problem. |
Think I'm gonna work on this soon. Here's what I'm thinking the API will look like: const ui = createXyzUi({
// ...
anchor: "#some-anchor",
})
ui.autoMount(); Here's the types I expect: type StopAutoMount = () => void;
interface UI {
autoMount(options?: { once?: boolean }): StopAutoMount;
} |
I've been thinking about this Issue in the back of my mind for a long time. We get a lot of questions about dynamic UI mounts. I just wonder what and how WXT should support. I have a feeling that BTW: Actually, I have a personal library for dynamic mounting, lol. |
Hmm, I recommended this function to addressing a single use case: mounting a UI inside a dynamic element that gets added and removed. If someone wants a custom implementation, like listening to focus events, or adding timeouts, they should write those themselves using
Nice! We can probably use it, does it support listening for when the element is removed from the DOM? |
If you are set in your mind on that policy, it's ok 👍 . Writing in the document that it is a single use case would avoid confusion users.
Supported by Basically, it goes like this. (recently, major bump to v4, so if there any bugs it might not work properly 😅 ) // waiting anchor
const anchor = await waitElement(targetAnchor);
if (anchor) {
ui.mount();
}
// waiting remove
const nowAnchor = await waitElement(targetAnchor, { detector: isNotExist });
if (nowAnchor === null) {
ui.unmount()
} |
I am onboard with adding functionality to WXT. |
Yeah, I’m willing to take this. I recently made my library support xpath for this issue :). I'm trying to write the test code first……but recently I've been so busy that I haven't had time. Need more time. |
For my extension I need to mount my app immediately after a precise div. However, this div is not immediately available when the page is loaded.
To do this I used MutationObserver:
However, this div can be removed following certain actions on the page. I would need to reassemble my component as soon as this div reappears. How can I do this?
The text was updated successfully, but these errors were encountered: