"ChromeEmbed 의 popup.js 가 여섯 줄. Lesson 4 가 그게 맞는 숫자인 이유 — 그리고 'just one more popup feature' 손 뻗을 때 일어나는 것."
여섯 줄
document.getElementById('open-panel')?.addEventListener('click', async () => {
const windowInfo = await chrome.windows.getCurrent().catch(() => null);
if (windowInfo?.id !== undefined) {
await chrome.sidePanel.open({ windowId: windowInfo.id }).catch(() => {});
}
window.close();
});
Handler 하나. 'Open Panel' 버튼 click → 현재 window fetch → 그 window 에서 side panel 열기 → popup 닫기. Popup HTML 이 비슷하게 tiny — 'Open Panel' label 된 styled 버튼.
이게 맞는 이유
- Single responsibility — popup 이 launcher. 그 이상은 panel 과 실제 경험 surface 로서 경쟁.
- 예측 가능한 lifecycle — popup 열림, popup 닫힘. 관리할 상태 없음, 처리할 rerender 없음, debug 할 race condition 없음.
- 빠른 paint — popup HTML load, JS 돔, click handler attach. 아마 open 부터 ready 까지 50 ms 미만.
- 경쟁 UI 없음 — Pippa 가 panel iframe 에 살아; popup 이 parallel chat UI host 안 하고 user 를 그것 가리키는 게 mental model singular 유지.
안 동작하는 대안
Popup useful 하게 만들고 싶으면? Quick-chat input, most-recent-message preview, brain selector 추가. 각각:
- Panel 에 이미 존재하는 UI 중복.
- panel iframe 이 이미 하는 cwkPippa backend 에 메시지 필요 — popup 에 그 messaging 재구현하거나 SW → iframe (오늘 깔끔한 API 없음) 통해 route.
- Lifecycle 문제: user 가 popup 바깥 뭔가 하는 순간 popup 죽음, 그래서 click 시 in flight 인 operation 잃음.
'Useful popup' design 이 항상 doorway-popup 이 완전 피하는 duplication cost 지불. ChromeEmbed 의 선택: 비용 지불 안 함.
Window vs Tab 선택
Popup 이 chrome.sidePanel.open 에 { windowId } 전달. 두 결과:
- Panel 이 전체 window 위해 열림. Window 안 tab 전환이 panel 열린 채 유지하면서 content 가 active tab 별 update (background bus + Lesson 5 의 bridge 통해).
- User 가 여전히 Chrome 의 표준 side-panel chrome 통해 panel 닫기 가능.
{ tabId } 대신 전달하면 그 한 tab 으로 panel scope; user 가 tab 전환하는 순간 panel 닫힘. 전체 window 의 browsing session 너머 ambient 되고 싶은 household extension 엔 잘못된 UX.
Optional chaining
document.getElementById('open-panel')?.addEventListener(...) — optional chaining 이 paranoia. Popup HTML 이 바뀌고 버튼 id mis-spell 되면, popup 이 gracefully degrade (JS error 없음, 그냥 non-functional 버튼). 6-줄 script 엔 overkill; 백 git revision 후 update 할 수도 있는 extension 엔 courtesy. 유지.