C.W.K.
Stream
Lesson 04 of 08 · published

Anchor 4 — Popup 가 doorway

~8 min · popup, side-panel, case-study, single-responsibility

Level 0Extension 입덕
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"ChromeEmbed 의 popup.js 가 여섯 줄. Lesson 4 가 그게 맞는 숫자인 이유 — 그리고 'just one more popup feature' 손 뻗을 때 일어나는 것."
ChromeEmbed popup 의 placeholder mockup — 'Open Panel' 버튼 하나만 보임
v0.1 popup 의 placeholder — 버튼 하나, job 하나. 실제 screenshot 은 추후 교체.

여섯 줄

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. 유지.

Popup 이 doorway, panel 이 destination. 여섯 줄이 충분; 그 이상은 같은 workflow 공간 위해 panel 과 경쟁. Popup feature 안 추가 비용이 정확히 0; 추가 비용이 영구 duplication.
Popup status info 가 필요하다면... 맞는 move 가 상호작용 안 부르는 tiny preview (한 줄: 'Currently capturing context from this tab') 를 popup 에 렌더. chrome.storage 에서 read 하거나 SW 에 메시지; open 시 한 번 렌더; 실제로 뭔가 하려면 user 가 'Open Panel' click. Input field 추가 안 함, chat 추가 안 함 — popup 을 status-and-launcher 만으로 유지.

Code

popup.html — entire file: 버튼 하나, scoped style·html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Pippa</title>
    <style>
      body { width: 240px; padding: 12px; margin: 0; font-family: system-ui, sans-serif; }
      button { width: 100%; padding: 10px 14px; font: inherit; cursor: pointer; }
    </style>
  </head>
  <body>
    <button id="open-panel">Open Panel</button>
    <script src="popup.js"></script>
  </body>
</html>
popup.js — entire file: 여섯 줄, 한 job·javascript
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();
});

External links

Exercise

실제 embeds/chrome/popup.html 과 popup.js read. 모든 줄이 필요한 work 하는 거 주목 — 제거할 거 없음. 이제 'useful popup' 변형 sketch: 320px popup 에 text input, Send 버튼, 최근 3 메시지 표시. 그게 추가하는 코드 (최소 ~100 줄) 와 책임질 새 failure mode 추정 (send 동안 popup-close race, popup 과 panel 사이 message-state drift, 이중 chat UI 등). 그 복잡성이 자기 몫 얻는지 결정. ChromeEmbed v0.1 엔 답이 firmly 'no' — 하지만 질문하는 근육이 우연이 아닌 parallel-app popup 대신 doorway popup 생산하는 것.
Hint
Popup 에 quick-chat 추가하고 싶으면, user 가 그 chat 위해 panel 열어서 실제로 잃는 게 있는지 물어 봐. Panel 이 200ms 에 열리고 chat 이 어쨌든 5 초 걸리면, popup-bypass 가 절약 안 함. 예외가 전체 workflow 가 3 초 안에 맞는 extension — 그것들이 진정으로 popup-as-app 의 혜택. Pippa 가 그게 아님; Pippa 가 대화, 대화가 persistent, persistent surface 가 panel.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.