// content.js let lastContextMenuPos = null; let tooltipEl = null; document.addEventListener("contextmenu", (e) => { lastContextMenuPos = { x: e.pageX, y: e.pageY }; }); chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === "showTooltip") { if (!tooltipEl) { tooltipEl = document.createElement("div"); tooltipEl.id = "markinfo-tooltip"; tooltipEl.style.position = "absolute"; tooltipEl.style.zIndex = "999999"; tooltipEl.style.background = "#fff"; tooltipEl.style.border = "1px solid #ccc"; tooltipEl.style.borderRadius = "8px"; tooltipEl.style.boxShadow = "0 4px 12px rgba(0,0,0,0.15)"; tooltipEl.style.fontFamily = "'Roboto', sans-serif"; tooltipEl.style.fontSize = "14px"; tooltipEl.style.color = "#333"; tooltipEl.style.maxWidth = "600px"; tooltipEl.style.maxHeight = "500px"; // flex 컬럼 레이아웃으로 구성 tooltipEl.style.display = "flex"; tooltipEl.style.flexDirection = "column"; // 헤더: 항상 보이는 영역 (sticky) const headerDiv = document.createElement("div"); headerDiv.id = "markinfo-tooltip-header"; headerDiv.style.position = "sticky"; headerDiv.style.top = "0"; headerDiv.style.background = "#fff"; headerDiv.style.padding = "12px 16px"; headerDiv.style.borderBottom = "1px solid #ccc"; // 헤더 내부: 검색 키워드와 제작자 정보를 수직 정렬 const headerContent = document.createElement("div"); headerContent.style.display = "flex"; headerContent.style.flexDirection = "column"; // 검색 키워드 제목 const titleElem = document.createElement("h2"); titleElem.id = "tooltip-title"; titleElem.style.margin = "0"; titleElem.style.fontSize = "20px"; titleElem.style.color = "#2c3e50"; headerContent.appendChild(titleElem); // 제작자 정보 (작은 글씨) const creatorElem = document.createElement("span"); creatorElem.id = "tooltip-creator"; creatorElem.textContent = "내차는언제타냐: 지재권 검색기"; creatorElem.style.fontSize = "12px"; creatorElem.style.color = "#7f8c8d"; headerContent.appendChild(creatorElem); headerDiv.appendChild(headerContent); // 내부 닫기 버튼 (헤더 우측) const headerCloseBtn = document.createElement("button"); headerCloseBtn.textContent = "닫기"; headerCloseBtn.style.padding = "6px 10px"; headerCloseBtn.style.backgroundColor = "#e74c3c"; headerCloseBtn.style.color = "#fff"; headerCloseBtn.style.border = "none"; headerCloseBtn.style.borderRadius = "4px"; headerCloseBtn.style.cursor = "pointer"; headerCloseBtn.onclick = removeTooltip; headerDiv.appendChild(headerCloseBtn); // 본문 영역 (스크롤 가능) const bodyDiv = document.createElement("div"); bodyDiv.id = "markinfo-tooltip-body"; bodyDiv.style.padding = "16px"; bodyDiv.style.overflowY = "auto"; bodyDiv.style.flex = "1 1 auto"; tooltipEl.appendChild(headerDiv); tooltipEl.appendChild(bodyDiv); document.body.appendChild(tooltipEl); // 글로벌 닫기 버튼 (항상 보이는 우측 상단) ensureGlobalCloseButton(); } // 업데이트: 헤더 제목에 검색 키워드 설정 document.getElementById("tooltip-title").textContent = "검색 키워드: " + message.keyword; renderDetailInfo(message.detailInfo, message.keyword); if (lastContextMenuPos) { positionTooltip(tooltipEl, lastContextMenuPos); } else { tooltipEl.style.top = "10px"; tooltipEl.style.left = "10px"; } } }); function positionTooltip(tooltip, pos) { tooltip.style.left = (pos.x + 10) + "px"; tooltip.style.top = (pos.y + 10) + "px"; const rect = tooltip.getBoundingClientRect(); const docWidth = document.documentElement.clientWidth; const docHeight = document.documentElement.clientHeight; if (rect.right > docWidth) { tooltip.style.left = (docWidth - rect.width - 10) + "px"; } if (rect.bottom > docHeight) { tooltip.style.top = (docHeight - rect.height - 10) + "px"; } } function removeTooltip() { if (tooltipEl && tooltipEl.parentNode) { tooltipEl.parentNode.removeChild(tooltipEl); } tooltipEl = null; const globalClose = document.getElementById("tooltip-global-close"); if (globalClose && globalClose.parentNode) { globalClose.parentNode.removeChild(globalClose); } } function ensureGlobalCloseButton() { if (!document.getElementById("tooltip-global-close")) { const btn = document.createElement("button"); btn.id = "tooltip-global-close"; btn.textContent = "닫기"; btn.style.position = "fixed"; btn.style.top = "20px"; btn.style.right = "20px"; btn.style.padding = "8px 12px"; btn.style.backgroundColor = "#e74c3c"; btn.style.color = "#fff"; btn.style.border = "none"; btn.style.borderRadius = "4px"; btn.style.cursor = "pointer"; btn.style.zIndex = "1000000"; btn.onclick = removeTooltip; document.body.appendChild(btn); } } function renderDetailInfo(results, keyword) { const bodyDiv = document.getElementById("markinfo-tooltip-body"); if (!bodyDiv) return; let html = `
`; // 결과가 없을 경우 안전한 단어 표시 if (results.error) { html += `

오류: ${results.error}

`; } else if (!Array.isArray(results) || results.length === 0) { html += `

지식재산권이 없는 안전한 단어

`; } else { results.forEach((result, idx) => { html += `
`; html += `

${idx + 1}번 결과

`; // 상세 검색 결과 (출원번호 상세 조회) if (result.detail) { html += `

상세 정보

`; const dreg = result.detail.registration_info; html += `

상표명: ${dreg.trademarkName || "(상표명 없음)"}

`; html += `

출원번호: ${dreg.applicationNum || "(출원번호 없음)"}

`; html += `

출원날짜: ${dreg.applicationDate || "(출원날짜 없음)"}

`; html += `

권리상태: ${dreg.lastDisposalCodeName || "(권리상태 없음)"}

`; html += `

공고번호: ${dreg.publicationNum || "(공고번호 없음)"}

`; html += `

등록번호: ${dreg.registerNum || "(등록번호 없음)"}

`; html += `

권리정보

`; if (result.detail.rights_info && Object.keys(result.detail.rights_info).length > 0) { for (let key in result.detail.rights_info) { html += `

카테고리 코드: ${key}

`; result.detail.rights_info[key].forEach(item => { html += `

- 지정상품명: ${item.asignProductName || ""}

`; html += `

  영문: ${item.asignProductNameEn || ""}

`; html += `

  유사군코드: ${item.similarCodes || ""}

`; }); } } else { html += `

(권리정보 없음)

`; } html += `

출원인 정보

`; if (result.detail.applicant_info && result.detail.applicant_info.mapping) { const mapping = result.detail.applicant_info.mapping; html += `

국가명: ${mapping.nationalCodeName || "(없음)"}

`; html += `

출원인명: ${mapping.applicantName || "(없음)"}

`; } else { html += `

(출원인 정보 없음)

`; } } else if (result.detailError) { html += `

상세 정보 검색 오류: ${result.detailError}

`; } html += `
`; }); } html += `
`; bodyDiv.innerHTML = html; }