Api requests not sending in Firefox
i've built this extension, there are a lot of api requests, these are working in chrome smoothly, when i build my extension with --target of firefox all works great
but non of my requests even fire
26 Replies
Are you targetting Mv2 or Mv3 FF?
Mv2 target
@louisgv
Are these req running being posted from BGSW or page runtime?
page runtime
are these fetch or a messaging call to the BGSW?
these are fetch to backend api with react query
@louisgv this is not so much priority now, can you help me with how can i render my extension on every textarea that is collapsablle and not on screen, like there are so many comments, and we open them up for writing replys, then write our reply, in all of those textareas i want to render an icon and an emoji selector, now it works but on one only and when i close and open it again its not there
i know that there is a way to handle this, but I really can't figure out how to do this from reading docs @louisgv
If I were to do it, I would just mount an overlay anchor then attach element on top each with their own DOM query
i really dont know how can i do it
and just play with absolute/screen positioning and disable/hide element as needed
export const getOverlayAnchorList: PlasmoGetOverlayAnchorList = async () =>
document.querySelectorAll(
'#reply-dialog-container > #reply-dialog-id > div#body > div#main > #input-container > #outer > #child-input > tp-yt-iron-autogrow-textarea#textarea > div.textarea-container'
);
this does not work
import cssText from 'data-text:../style.css';
import type {
PlasmoCSConfig,
PlasmoCSUIJSXContainer,
PlasmoCSUIProps,
PlasmoGetOverlayAnchorList,
PlasmoRender
} from 'plasmo';
import type { FC } from 'react';
import { createRoot } from 'react-dom/client';
import App from '~youtube-comment-emoji/components/App';
export const config: PlasmoCSConfig = {
matches: ['https://studio.youtube.com/*']
};
const getStyle = () => {
if (!document.getElementById('mastertube')) {
const style = document.createElement('style');
style.id = 'mastertube';
style.textContent = cssText;
document.head.appendChild(style);
return style;
}
};
// Youtube Sidebar Root
export const getOverlayAnchorList: PlasmoGetOverlayAnchorList = async () =>
document.querySelectorAll(
'#reply-dialog-container > #reply-dialog-id > div#body > div#main > #input-container > #outer > #child-input > tp-yt-iron-autogrow-textarea#textarea > div.textarea-container'
);
// Starting Point
const PlasmoOverlay: FC<PlasmoCSUIProps> = () => {
return <App />;
};
// React Render
export const render: PlasmoRender<PlasmoCSUIJSXContainer> = async ({
createRootContainer
}) => {
if (!createRootContainer) {
console.error('Could not create root container');
return;
}
const rootContainer = await createRootContainer();
const root = createRoot(rootContainer);
root.render(<PlasmoOverlay />);
};
export default PlasmoOverlay;
it throws me errorprobably yeah, I made it for some pretty basic usecase. Youtube is not basic afaik - you would need to make some custom logic within your component
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'type')
i get this error in console
else if (anchor.type === "inline")
anchor.element.insertAdjacentElement("afterend", shadowHost);
The error source from Plasmo
I mean am i writing it all wrong syntax related?
that's because the default createRootContainer is looking for a getRootContainer function - these features are a bit complex :d...
i can't get my head around these 😦 so what should I write?
Study this examples: https://github.com/PlasmoHQ/examples/blob/main/with-content-scripts-ui/contents/plasmo-root-container.tsx
GitHub
examples/with-content-scripts-ui/contents/plasmo-root-container.tsx...
🔰 Example projects that demonstrate how to use the Plasmo Framework and integrate with popular tools - PlasmoHQ/examples
The idea is that you wouldn't be calling the internal
createRootContainer
but rather, call your own getRootContainer
import cssText from 'data-text:../style.css';
import type {
PlasmoCSConfig,
PlasmoCSUIJSXContainer,
PlasmoCSUIProps,
PlasmoRender
} from 'plasmo';
import type { FC } from 'react';
import { createRoot } from 'react-dom/client';
import App from '~youtube-comment-emoji/components/App';
export const config: PlasmoCSConfig = {
matches: ['https://studio.youtube.com/*']
};
const getStyle = () => {
if (!document.getElementById('mastertube')) {
const style = document.createElement('style');
style.id = 'mastertube';
style.textContent = cssText;
document.head.appendChild(style);
return style;
}
};
// Youtube Sidebar Root
export const getRootContainer = () => {
return new Promise((resolve) => {
const checkInterval = setInterval(() => {
const rootContainerParent = document.querySelector(
'#reply-dialog-container > #reply-dialog-id > div#body > div#main > #input-container > #outer > #child-input > tp-yt-iron-autogrow-textarea#textarea > div.textarea-container'
); // Sidebar Id
console.log(rootContainerParent);
if (rootContainerParent) {
clearInterval(checkInterval);
getStyle();
const rootContainer = document.createElement('div');
rootContainerParent.insertBefore(
rootContainer,
rootContainerParent.firstChild
);
resolve(rootContainer);
}
}, 137);
});
};
// Starting Point
const PlasmoOverlay: FC<PlasmoCSUIProps> = () => {
return <App />;
};
// React Render
export const render: PlasmoRender<PlasmoCSUIJSXContainer> = async ({
createRootContainer
}) => {
if (!createRootContainer) {
console.error('Could not create root container');
return;
}
const rootContainer = await createRootContainer();
const root = createRoot(rootContainer);
root.render(<PlasmoOverlay />);
};
export default PlasmoOverlay;
so with this
it only renders on one only
and clears interval and never checks againyup, now you will just need to figure out how to deal with the youtube site :d...
youtube is really cumbersome you know....
can i render it with react and not plasmo related? 🤔
yeah that's what I meant by above
you can do all your bidding in react
Like I would start from this: https://github.com/PlasmoHQ/examples/blob/main/with-content-scripts-ui/contents/plasmo-overlay.tsx
GitHub
examples/with-content-scripts-ui/contents/plasmo-overlay.tsx at mai...
🔰 Example projects that demonstrate how to use the Plasmo Framework and integrate with popular tools - PlasmoHQ/examples
And do it all with react - the plasmo belt and whistle overlayAnchorList and etc... are very flaky API, they're convenient for some quick usecases
but for complex logic - I'd just get it done manually
import cssText from "data-text:~/contents/plasmo-overlay.css"
import type { PlasmoCSConfig } from "plasmo"
export const config: PlasmoCSConfig = {
matches: ["https://www.plasmo.com/*"],
css: ["font.css"]
}
export const getStyle = () => {
const style = document.createElement("style")
style.textContent = cssText
return style
}
const PlasmoOverlay = () => {
return (
<span
className="hw-top"
style={{
padding: 12
}}>
CSUI OVERLAY FIXED POSITION
</span>
)
}
export default PlasmoOverlay
wo what i return is what i want in the right position?That default to mount your component to the very top of the page - now inside that component, you can spawn your other stuffs in there
treat it like your little container for more good stuff - i.e it be the manager of all your input fields on that page
let me check
how can i move my icon on textarea that is not on screen yet and will be and have it be shown on other textareas that are not on screen yet
shet 😆
i think im figuring out ways to do this with new MutationObserver
@louisgv do you know a convinient way of rendering the icons in fluent way?
const App = () => {
useEffect(() => {
const handleIconShow = () => {
const replyTextarea = document.querySelectorAll(
'#reply-dialog-container > #reply-dialog-id > div#body > div#main > #input-container > #outer > #child-input > tp-yt-iron-autogrow-textarea#textarea > div.textarea-container'
);
console.log(replyTextarea);
};
handleIconShow();
// Listen for changes to the URL and extract the video ID
const observer = new MutationObserver(handleIconShow);
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
}, []);
what im doing you think is ok?
you said you would do that manually
how can i do that so?
this is the App component
im selecting all the textareas as they appear
but i want to render a component for eachYup, once you have them element, just set it in a react ref, then mount your react comp there