diff --git a/dist/manifest.json b/dist/manifest.json index 8c70e0d..4c7e788 100644 --- a/dist/manifest.json +++ b/dist/manifest.json @@ -11,6 +11,13 @@ }, "default_popup": "popup.html" }, + "content_scripts": [ + { + "matches": ["https://*.coupang.com/*"], + "js": ["js/contentScript.js"], + "run_at": "document_idle" + } + ], "background": { "service_worker": "js/backgroundPage.js" }, diff --git a/dist/popup.html b/dist/popup.html index cf39f12..898045c 100644 --- a/dist/popup.html +++ b/dist/popup.html @@ -1,6 +1,7 @@ + Chrome Extension (built with TypeScript + React) diff --git a/src/popup/__tests__/test_popup.tsx b/src/popup/__tests__/test_popup.tsx index c5eaf33..968e183 100644 --- a/src/popup/__tests__/test_popup.tsx +++ b/src/popup/__tests__/test_popup.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { Popup } from "../component"; +import { Popup } from "../getProduct"; import renderer from "react-test-renderer"; it("component renders", () => { diff --git a/src/popup/component.tsx b/src/popup/component.tsx deleted file mode 100644 index f044012..0000000 --- a/src/popup/component.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from "react"; -import { Hello } from "@src/components/hello"; -import browser, { Tabs } from "webextension-polyfill"; -import { Scroller } from "@src/components/scroller"; - -// // // // - -// Scripts to execute in current tab -const scrollToTopPosition = 0; -const scrollToBottomPosition = 9999999; - -function scrollWindow(position: number) { - window.scroll(0, position); -} - -/** - * Executes a string of Javascript on the current tab - * @param code The string of code to execute on the current tab - */ -function executeScript(position: number): void { - // Query for the active tab in the current window - browser.tabs - .query({ active: true, currentWindow: true }) - .then((tabs: Tabs.Tab[]) => { - // Pulls current tab from browser.tabs.query response - const currentTab: Tabs.Tab | number = tabs[0]; - - // Short circuits function execution is current tab isn't found - if (!currentTab) { - return; - } - const currentTabId: number = currentTab.id as number; - - // Executes the script in the current tab - browser.scripting - .executeScript({ - target: { - tabId: currentTabId, - }, - func: scrollWindow, - args: [position], - }) - .then(() => { - console.log("Done Scrolling"); - }); - }); -} - -// // // // - -export function Popup() { - // Sends the `popupMounted` event - React.useEffect(() => { - browser.runtime.sendMessage({ popupMounted: true }); - }, []); - - // Renders the component tree - return ( -
-
- -
- { - executeScript(scrollToTopPosition); - }} - onClickScrollBottom={() => { - executeScript(scrollToBottomPosition); - }} - /> -
-
- ); -} diff --git a/src/popup/controlFont.tsx b/src/popup/controlFont.tsx new file mode 100644 index 0000000..1ff9ef4 --- /dev/null +++ b/src/popup/controlFont.tsx @@ -0,0 +1,33 @@ +import React from "react"; + +const ControlFont = () => { + const sendMessage = ( + type: "ENLARGE_CONTENT_FONT" | "RESET_CONTENT_FONT", + ) => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + if (!tabs[0]?.id) return; + chrome.tabs.sendMessage(tabs[0].id, { type }, (response) => { + console.log("메시지 전송됨:", response); + }); + }); + }; + + return ( +
+ + +
+ ); +}; + +export default ControlFont; diff --git a/src/popup/getProduct.tsx b/src/popup/getProduct.tsx new file mode 100644 index 0000000..65b5b34 --- /dev/null +++ b/src/popup/getProduct.tsx @@ -0,0 +1,67 @@ +import React, { useState } from "react"; +import "../css/app.css"; + +const getProduct = () => { + const [productInfo, setProductInfo] = useState<{ + productId: string; + productTitle: string; + } | null>(null); + + const [error, setError] = useState(""); + + const getProductInfo = () => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + if (!tabs[0]?.id) return; + + chrome.tabs.sendMessage( + tabs[0].id, + { type: "GET_PRODUCT_INFO" }, + (response) => { + if (response?.matched) { + const { productId, productTitle } = response; + setProductInfo({ productId, productTitle }); + setError(""); + const utterance = new SpeechSynthesisUtterance( + `상품명은 ${productTitle}이고, 상품 아이디는 ${productId}입니다.`, + ); + utterance.lang = "ko-KR"; + speechSynthesis.speak(utterance); + } else { + setProductInfo(null); + setError( + "❗ 현재 페이지는 '식품' 카테고리가 아닙니다.", + ); + } + }, + ); + }); + }; + return ( +
+

+ VOIM 상품 리더기 +

+ + + {productInfo && ( +
+

+ 상품명: {productInfo.productTitle} +

+

+ 상품 ID: {productInfo.productId} +

+
+ )} + + {error &&

{error}

} +
+ ); +}; + +export default getProduct; diff --git a/src/popup/index.tsx b/src/popup/index.tsx index eec7221..401ffba 100644 --- a/src/popup/index.tsx +++ b/src/popup/index.tsx @@ -1,10 +1,9 @@ import * as React from "react"; import { createRoot } from "react-dom/client"; import browser from "webextension-polyfill"; -import { Popup } from "./component"; +import GetProduct from "./getProduct"; import "../css/app.css"; - -// // // // +import ControlFont from "./controlFont"; browser.tabs .query({ active: true, currentWindow: true }) @@ -21,7 +20,13 @@ browser.tabs const container = document.getElementById("popup"); if (container) { const root = createRoot(container); - root.render(); + root.render( +
+

VOIM

+ + +
, + ); } else { console.error("popup이라는 id를 가진 요소가 존재하지 않아요!"); } diff --git a/src/popup/stories/Popup.stories.tsx b/src/popup/stories/Popup.stories.tsx index 5b6a145..2fa566d 100644 --- a/src/popup/stories/Popup.stories.tsx +++ b/src/popup/stories/Popup.stories.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { Popup } from "../component"; +import { Popup } from "../getProduct"; import { Meta } from "@storybook/react"; // // // //