"popup 한테 주어진 시간은 200 밀리초야. 그 안에 쓸모 있어 보이지 않으면 user는 이미 다른 데로 가 있어. 이 lesson은 그 제약이 크기와 focus와 그리는 순서에 실제로 뭘 요구하는지, 그리고 대충 만든 popup이 신뢰를 잃는 여섯 가지 길에 대한 얘기야."
Size window
Chrome이 popup을 content에 auto-size, bound 안에서:
너비: 최대 800 px까지 되는데 실제로 좋은 구간은 280–360 px 야. 그보다 넓어지면 popup이 아니라 잘못 뜬 tab 처럼 느껴져.
Height: Chrome이 scroll 하기 전 max ~600 px. 13" laptop screen에 scroll 없이 맞도록 480 px 아래 유지 시도.
Padding: 12–16 px generous. 8 px comfortable. 8 보다 작으면 요소 답답.
Popup이 content load 시 jitter 안 하도록 body에 명시적 dimension 설정:
popup이 몇 초라도 열려 있을 거면 side panel 처럼 chrome.storage.onChanged를 구독해 둬. 그사이 user가 다른 tab에서 뭔가 바꿀 수 있고, popup은 그걸 바로 비춰 줘야 하거든. 구독 해제는 따로 안 해도 돼. popup이 닫히면 그 JavaScript 자리가 통째로 죽으면서 listener도 같이 사라져.
Popup = one shot, one purpose. 구조 먼저 렌더, data로 refine. Sub-200 ms가 즉각 느껴짐. sub-100 ms가 native 느낌. Browse 나 configure는 다른 데로.
Popup auto-close 함정. Popup 안에서 chrome.tabs.create, chrome.windows.create, 또는 window 여는 어떤 chrome.action API 든 호출하면 popup 즉시 닫힘. 가끔 그게 원하는 거 (action 완료, 자기 dismiss). 가끔 안 (user가 두 가지 하고 싶었음). Two-step 상호작용에는 두 번째 step 미루든가 둘 다 side panel로 옮기든가.
Code
popup.html — primary action 셋, secondary link 둘·html
clipdeck/popup.html을 첫 번째 code block으로, clipdeck/popup.js를 두 번째로 교체. Extension reload. Toolbar icon click — popup이 placeholder 0으로 즉시 렌더, 다음 실제 count가 ms 안에 들어옴. 세 primary 버튼 테스트: Save current selection (먼저 텍스트 선택, 후 click)이 clip 추가. Open clip list가 side panel 열고 popup 닫음. Pause on this site는 마지막에서 두 번째 lesson에서 wire, 지금은 그냥 있는지 확인. Popup 열기, 다른 window에서 Ctrl+Shift+K로 clip 저장, 다시 전환 — popup count가 re-open 없이 update.
Hint
Placeholder 0이 실제 숫자로 교체 안 되면 refreshStats()가 throw 중 — popup DevTools (popup 우클릭 → Inspect → Console) 열어 error 확인. 흔한 게 chrome:// special-page 케이스에서 new URL(tab.url) 동작하지만 host filter가 매칭 0 반환해 siteCount가 명백한 error 없이 0 유지. Popup이 예상보다 넓으면 padding이 명시적 width 안으로 먹도록 body에 box-sizing: border-box 설정 확인. Save current selection이 실제 web page 에서도 alert 하면 content script가 load 안 됨 — content.js가 content_scripts.matches 안에 있는지 확인.
Progress
Progress is local-only — sign in to sync across devices.