189 lines
8.4 KiB
JavaScript
189 lines
8.4 KiB
JavaScript
// 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";
|
|
headerDiv.style.display = "flex";
|
|
headerDiv.style.justifyContent = "space-between";
|
|
headerDiv.style.alignItems = "center";
|
|
|
|
// 검색 키워드 제목
|
|
const titleElem = document.createElement("h2");
|
|
titleElem.id = "tooltip-title";
|
|
titleElem.style.margin = "0";
|
|
titleElem.style.fontSize = "20px";
|
|
titleElem.style.color = "#2c3e50";
|
|
headerDiv.appendChild(titleElem);
|
|
|
|
// 내부 닫기 버튼 (헤더 내)
|
|
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 = `<div style="line-height: 1.6;">`;
|
|
if (results.error) {
|
|
html += `<p style="color: red; font-weight: bold;">오류: ${results.error}</p>`;
|
|
} else if (!Array.isArray(results) || results.length === 0) {
|
|
html += `<p style="color: #7f8c8d;">검색 결과가 없습니다.</p>`;
|
|
} else {
|
|
results.forEach((result, idx) => {
|
|
html += `<div style="margin-bottom: 24px; padding-bottom: 12px; border-bottom: 1px solid #ecf0f1;">`;
|
|
html += `<h3 style="margin: 0 0 8px 0; font-size: 18px; color: #2980b9;">${idx + 1}번 결과</h3>`;
|
|
// 상세 검색 결과 (출원번호 상세 조회)
|
|
if (result.detail) {
|
|
html += `<h4 style="margin: 12px 0 6px; font-size: 16px; color: #16a085; border-bottom: 1px solid #16a085; display: inline-block;">상세 정보</h4>`;
|
|
const dreg = result.detail.registration_info;
|
|
html += `<p style="margin: 6px 0;"><strong>상표명:</strong> ${dreg.trademarkName || "(상표명 없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>출원번호:</strong> ${dreg.applicationNum || "(출원번호 없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>출원날짜:</strong> ${dreg.applicationDate || "(출원날짜 없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>권리상태:</strong> ${dreg.lastDisposalCodeName || "(권리상태 없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>공고번호:</strong> ${dreg.publicationNum || "(공고번호 없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>등록번호:</strong> ${dreg.registerNum || "(등록번호 없음)"}</p>`;
|
|
|
|
html += `<h4 style="margin: 12px 0 6px; font-size: 16px; color: #8e44ad; border-bottom: 1px solid #8e44ad; display: inline-block;">권리정보</h4>`;
|
|
if (result.detail.rights_info && Object.keys(result.detail.rights_info).length > 0) {
|
|
for (let key in result.detail.rights_info) {
|
|
html += `<p style="margin: 6px 0;"><strong>카테고리 코드:</strong> ${key}</p>`;
|
|
result.detail.rights_info[key].forEach(item => {
|
|
html += `<p style="margin-left: 20px; margin: 4px 0;">- 지정상품명: ${item.asignProductName || ""}</p>`;
|
|
html += `<p style="margin-left: 20px; margin: 4px 0;"> 영문: ${item.asignProductNameEn || ""}</p>`;
|
|
html += `<p style="margin-left: 20px; margin: 4px 0;"> 유사군코드: ${item.similarCodes || ""}</p>`;
|
|
});
|
|
}
|
|
} else {
|
|
html += `<p style="margin: 6px 0; color: #7f8c8d;">(권리정보 없음)</p>`;
|
|
}
|
|
|
|
html += `<h4 style="margin: 12px 0 6px; font-size: 16px; color: #e67e22; border-bottom: 1px solid #e67e22; display: inline-block;">출원인 정보</h4>`;
|
|
if (result.detail.applicant_info && result.detail.applicant_info.mapping) {
|
|
const mapping = result.detail.applicant_info.mapping;
|
|
html += `<p style="margin: 6px 0;"><strong>국가명:</strong> ${mapping.nationalCodeName || "(없음)"}</p>`;
|
|
html += `<p style="margin: 6px 0;"><strong>출원인명:</strong> ${mapping.applicantName || "(없음)"}</p>`;
|
|
} else {
|
|
html += `<p style="margin: 6px 0; color: #7f8c8d;">(출원인 정보 없음)</p>`;
|
|
}
|
|
} else if (result.detailError) {
|
|
html += `<p style="color: red; font-weight: bold;">상세 정보 검색 오류: ${result.detailError}</p>`;
|
|
}
|
|
html += `</div>`;
|
|
});
|
|
}
|
|
html += `</div>`;
|
|
bodyDiv.innerHTML = html;
|
|
}
|