"Popup 은 HTML 이야 — 그게 트릭. 'Chrome 만의 뭔가' 라고 생각하지 말고 chrome.* 접근권 가진 작은 webpage 라고 생각하기 시작하면, 나머지 extension API 도 더 이상 이질감 없어."
Manifest 에서 동작하는 popup 까지
Lesson 2 의 manifest 가 action block 을 선언했어:
"action": {
"default_popup": "popup.html",
"default_title": "ClipDeck"
}
그 default_popup field 가 약속이야 — toolbar icon 클릭하면 Chrome 이 그 이름의 HTML 파일을 popup window 안에 렌더. Chrome 은 그 파일 내용에 무관심해, 유효한 HTML page 이기만 하면 — "Hello world" 정적 문자열도 가능, React bundle 도 가능, 또는 — 여기서 만들 — active tab 읽어서 title 보여주는 얇은 shell.
이 lesson 은 clipdeck/ 에 두 새 파일 저장: popup.html / popup.js. Reload, 클릭, ClipDeck 이 처음으로 뭔가 해.
popup.html — 최소 skeleton
Popup 은 평범한 HTML 문서야, 알아둘 두 가지만:
- Popup window 는 content 에 자동 크기 조정, 약 800×600 까지.
body에 명시적width박아서 안정화. - MV3 는 inline JavaScript 금지 (Content Security Policy 통해). Script 는 별도 파일에 두고
<script src="popup.js">로 참조.<script>alert()</script>같은 inline script 안 돼, inlineonclickhandler 도 안 돼. 모든 MV2-시대 튜토리얼 reader 가 딱 한 번씩 이걸로 걸려.
popup.js — Active tab 읽기
chrome.tabs.query 가 "지금 user 가 보고 있는 tab 이 뭐야?" 물어보는 API. MV3 에선 Promise 반환 (또는 callback — 둘 다 됨). Filter property 셋이 중요:
active: true— 자기 window 안에서 focus 가짐currentWindow: true— 지금 이 window, background window 아님- 결과는 항상 배열 — 보통 length 1, 근데 MV3 가 보장하지는 않아.
tabs[0]?.title같은 식 또는 default 값 있는 array destructuring 으로 방어.
Popup script 가 하는 일은 작아: query / title 읽기 / 렌더. 그게 popup.js 본문 전체.
첫 클릭
popup.html 과 popup.js 를 clipdeck/ 에 저장한 다음:
chrome://extensions열기.- ClipDeck 카드의 reload (↻) 버튼 클릭.
- Toolbar 의 ClipDeck 아이콘 클릭.
작은 popup window 가 열려. Script 가 돌아. 그 tab 의 page title 이 popup 에 떠. Tab 바꾸고 아이콘 다시 클릭 — 새 tab 의 title 표시. chrome.tabs.query 가 popup 열릴 때마다 상태 read — 캐싱 없음, stale data 없음, 그 순간 Chrome UI 가 아는 거 그대로.
이 작은 데모가 왜 중요해
이게 모든 미래 ClipDeck 기능이 따를 형태:
- Manifest 가 surface 선언 (popup / side panel / content script / options page).
- 그 surface 의 HTML load.
- 그 surface 안의 JavaScript 가
chrome.*API 호출 — Chrome 상태 read 또는 변경. - UI update.
Track 2 가 background service worker 추가 (UI 없는 surface). Track 3 가 content script 추가 (host page 안의 UI 존재). Track 4 가 popup 을 더 풍부한 side panel 로 교체. Track 5 가 popup 에 selection capture + storage save 를 wire. 다 위 4 단계 패턴 위에 쌓는 거.
alert() 봤을 때랑 똑같아 — "잠깐, 브라우저가 진짜 내 말 듣네?" 그 느낌 잡고 있어. browser extension 이 존재하는 이유 전부. Pippa Chrome Embed v0.1 이 그 같은 놀라움을 household scale 로 늘린 거 — 같은 surprise, 그저 hardcoded query 대신 cwkPippa 의 brain 통과해서 흐를 뿐.Track 1 의 조기 회고
Popup 이 동작하면, ClipDeck 은 "disk 위의 파일" 에서 "동작하는 Chrome extension" 으로 선을 넘은 거야. Lesson 5 와 6 이 security model 과 gotchas 다루지만 — ClipDeck 자체는 이 시점부터 살아 있어. 매 미래 track 이 한 조각씩 더해. 이 데모의 작음에 속지 마: 여기서 dev loop 가 닫혀.