Here, I am trying to render a JSX element inside a shadowDOM.
If the user pressed a shortcut key in keyboard means, I am trying to show the JSX element. And if the user pressed the ESCAPE key means, I should hide the component by removing the child from the shadowDOM
The problem I am facing here is, whenever the content script is executed, the div (overlay) keeps creating but not appended to the shadowRoot. And once the listener is triggered, the shadowDOM appends all the created div.
So, What I am trying to achieve here is the overlay div should create only once, and should not create whenever the content script is loaded.
I have tried hide/show the JSX component by controlling the style, Still facing the same issue
Is there any better way to handle this ?
background.js
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "sampleContextMenu",
title: "Save to typeless",
contexts: ["selection"],
});
});
chrome.commands.getAll((commands) => {
console.log("All available commands:", commands);
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.key === "Escape") {
console.log("Escape key is pressed !");
chrome.tabs.executeScript(null, { file: "/static/js/extension.js" }, () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, { show: false, action: "overlay" });
});
});
} else if (!message.show) {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, request);
});
});
}
});
chrome.commands.onCommand.addListener(function (command) {
if (command === "trigger-action") {
chrome.tabs.executeScript(null, { file: "/static/js/extension.js" }, () => {
console.log("onCommand event received for message: ", command);
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const tab = tabs[0];
chrome.tabs.sendMessage(tab.id, { tab, show: true, action: "search" });
});
});
}
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
chrome.tabs.executeScript(null, { file: "/static/js/extension.js" }, () => {
chrome.tabs.sendMessage(tab.id, { info, tab, show: true, action: "overlay" });
});
});
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript(null, { file: "/static/js/extension.js" });
});
content.js
import * as React from "react";
import ReactDOM from "react-dom";
import { useEffect } from "react";
import Overlay from "../components/Overlay/Overlay";
import SearchOverlay from "../components/Chat/SearchOverlay";
import "./index.css";
const Extension = ({ data }: any) => {
switch (data.action) {
case "search":
return <SearchOverlay />;
case "overlay":
return <Overlay data={data} />;
default:
return <div></div>;
}
};
// Add our extension to the document
document.addEventListener("keydown", function (event) {
// Check if a specific key was pressed, e.g., the 'A' key
if (event.key === "Escape") {
chrome.runtime.sendMessage({ key: event.key });
}
});
console.log("Content script is running !!");
let extensionRoot = document.getElementById("extension-host");
if (extensionRoot) {
// Create the shadow root
const shadowRoot = extensionRoot.shadowRoot;
if (shadowRoot) {
var div = shadowRoot.getElementById("extension");
if (!div) {
div = document.createElement("div");
div.id = "overlay";
var linkNode = document.createElement("link");
linkNode.type = "text/css";
linkNode.rel = "stylesheet";
linkNode.href = "//fonts.googleapis.com/css?family=Inter";
document.head.appendChild(linkNode);
chrome.runtime.onMessage.addListener((request: any, sender: any, sendResponse: any) => {
console.log("request", request);
if (request.show) {
//@ts-ignore
shadowRoot.appendChild(div);
} else {
//@ts-ignore
shadowRoot.removeChild(div);
}
console.log("sender", sender);
console.log("sendResponse", sendResponse);
ReactDOM.render(<Extension data={request} />, div);
});
}
}
}