diff --git a/src/background/index.ts b/src/background/index.ts index b8806f7..f260326 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -9,6 +9,7 @@ import { } from "./constants"; import { initCommandListeners } from "./listeners/commandListeners"; import { handleModalToggle } from "./listeners/modalCommandHandler"; +import { handleIconToggle } from "./listeners/iconHandler"; /** * 백그라운드 스크립트 초기화 @@ -420,7 +421,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { chrome.action.onClicked.addListener(async (tab) => { try { logger.debug("툴바 아이콘 클릭됨"); - await handleModalToggle(); + await handleIconToggle(); } catch (error) { logger.error("툴바 아이콘 클릭 처리 중 오류 발생:", error); } diff --git a/src/background/listeners/iconHandler.ts b/src/background/listeners/iconHandler.ts new file mode 100644 index 0000000..e21f246 --- /dev/null +++ b/src/background/listeners/iconHandler.ts @@ -0,0 +1,124 @@ +export async function handleIconToggle(): Promise { + const tabs = await chrome.tabs.query({ + active: true, + currentWindow: true, + }); + + if (tabs[0]?.id) { + await chrome.scripting.executeScript({ + target: { tabId: tabs[0].id }, + func: function () { + const iframeId = "floating-button-extension-iframe"; + let iframe = document.getElementById( + iframeId, + ) as HTMLIFrameElement; + + // 항상 iframeHiddenByAltA 먼저 검사 + chrome.storage.local.get( + [ + "iframeInvisible", + "iframeHiddenByAltA", + "iframeHiddenByAltV", + ], + (result) => { + const isInvisible = result.iframeInvisible ?? false; + const hiddenByAltV = result.iframeHiddenByAltV ?? false; + const hiddenByAltA = result.iframeHiddenByAltA ?? false; + + if (!iframe) { + // Alt+V로 숨겨진 상태일 때만 iframe 생성 + if (isInvisible) { + iframe = document.createElement("iframe"); + iframe.id = iframeId; + iframe.src = + chrome.runtime.getURL("iframe.html"); + iframe.setAttribute("tabindex", "1"); + + iframe.style.position = "fixed"; + iframe.style.top = "70px"; + iframe.style.right = "20px"; + iframe.style.width = "65px"; + iframe.style.height = "130px"; + iframe.style.border = "none"; + iframe.style.background = "transparent"; + iframe.style.zIndex = "2147483647"; + + iframe.onload = () => { + iframe.focus(); + iframe.contentWindow?.document + .getElementById("root") + ?.focus(); + }; + + const handleMessage = function ( + event: MessageEvent, + ) { + if (event.source !== iframe.contentWindow) + return; + + if (event.data.type === "RESIZE_IFRAME") { + if (event.data.isOpen) { + iframe.style.width = "100%"; + iframe.style.height = "100%"; + iframe.style.top = "0"; + iframe.style.right = "0"; + } else { + iframe.style.width = "65px"; + iframe.style.height = "130px"; + iframe.style.top = "70px"; + iframe.style.right = "20px"; + } + } + }; + window.addEventListener( + "message", + handleMessage, + ); + document.body.appendChild(iframe); + + chrome.storage.local.set({ + iframeInvisible: false, + iframeHiddenByAltA: false, + iframeHiddenByAltV: true, + }); + + iframe.onload = function () { + if (iframe.contentWindow) { + iframe.contentWindow.postMessage( + { type: "TOGGLE_MODAL" }, + "*", + ); + } + }; + } + } else { + // iframe이 이미 존재할 때 + if (iframe.contentWindow) { + iframe.contentWindow.postMessage( + { type: "TOGGLE_MODAL" }, + "*", + ); + + if (hiddenByAltV) { + iframe.remove(); + chrome.storage.local.set({ + iframeInvisible: true, + iframeHiddenByAltA: false, + iframeHiddenByAltV: false, + }); + } + } + } + if (isInvisible && hiddenByAltA) { + chrome.storage.local.set({ + iframeInvisible: false, + iframeHiddenByAltA: false, + iframeHiddenByAltV: false, + }); + } + }, + ); + }, + }); + } +} diff --git a/src/background/listeners/iframeCommandHandler.ts b/src/background/listeners/iframeCommandHandler.ts index 173231d..438b945 100644 --- a/src/background/listeners/iframeCommandHandler.ts +++ b/src/background/listeners/iframeCommandHandler.ts @@ -27,11 +27,17 @@ export async function handleIframeToggle(): Promise { const hiddenByAltA = result.iframeHiddenByAltA ?? false; + if (hiddenByAltA) { + // ALT+A로 숨긴 경우에는 iframe을 생성하지 않음 + return; + } + if (existingIframe) { existingIframe.remove(); chrome.storage.local.set({ iframeInvisible: true, - iframeHiddenByAltA: true, + iframeHiddenByAltA: false, + iframeHiddenByAltV: true, }); } else if (!hiddenByAltA) { // hiddenByAltA가 false일 때만 iframe 생성 @@ -93,6 +99,7 @@ export async function handleIframeToggle(): Promise { chrome.storage.local.set({ iframeInvisible: false, iframeHiddenByAltA: false, + iframeHiddenByAltV: false, }); } }, diff --git a/src/background/listeners/sidebarCommandHandler.ts b/src/background/listeners/sidebarCommandHandler.ts index 7f2b5c6..eab85ff 100644 --- a/src/background/listeners/sidebarCommandHandler.ts +++ b/src/background/listeners/sidebarCommandHandler.ts @@ -1,5 +1,3 @@ -import { logger } from "@src/utils/logger"; - export async function handleSidebarToggle(): Promise { const tabs = await chrome.tabs.query({ active: true, @@ -26,6 +24,10 @@ export async function handleSidebarToggle(): Promise { const isInvisible = result.iframeInvisible ?? false; const hiddenByAltA = result.iframeHiddenByAltA ?? false; + if (hiddenByAltA) { + // ALT+A로 숨긴 경우에는 iframe을 생성하지 않음 + return; + } // ALT+V로 숨긴 경우에만 iframe 생성하고 사이드바 띄우기 if (isInvisible) { diff --git a/src/background/listeners/styleCommandHandler.ts b/src/background/listeners/styleCommandHandler.ts index db1fea3..bd0621d 100644 --- a/src/background/listeners/styleCommandHandler.ts +++ b/src/background/listeners/styleCommandHandler.ts @@ -8,19 +8,29 @@ export async function handleStyleToggle(): Promise { }); if (tabs[0]?.id) { - const currentStyleState = await chrome.storage.local.get([ + const result = await chrome.storage.local.get([ + "iframeHiddenByAltV", "stylesEnabled", ]); - const isStylesEnabled = currentStyleState.stylesEnabled ?? true; + const isStylesEnabled = result.stylesEnabled ?? true; + const wasHiddenByAltV = result.iframeHiddenByAltV ?? false; settingsService.setStylesEnabled(isStylesEnabled); await chrome.scripting.executeScript({ target: { tabId: tabs[0].id }, - func: function () { + func: (wasHiddenByAltV: boolean) => { const iframeId = "floating-button-extension-iframe"; const existingIframe = document.getElementById(iframeId); - + if (!existingIframe && wasHiddenByAltV) { + // ALT+V로 숨겨진 경우에는 iframe을 생성하지 않음 + chrome.storage.local.set({ + iframeInvisible: true, + iframeHiddenByAltA: true, + iframeHiddenByAltV: false, + }); + return; + } if (existingIframe) { existingIframe.remove(); chrome.storage.local.set({ @@ -74,9 +84,11 @@ export async function handleStyleToggle(): Promise { chrome.storage.local.set({ iframeInvisible: false, iframeHiddenByAltA: false, + iframeHiddenByAltV: false, }); } }, + args: [wasHiddenByAltV], }); if (isStylesEnabled) {