"Manifest 에 선언. SW 에서 manipulate. User gesture 아래에서 open. 세 문장, 한 lesson 안의 세 lesson — 그리고 어느 하나라도 건너뛰면 API 가 조용히 동작 거부하는 세 가지 실제 방법."
Step 1 — Manifest 에 선언
두 field 가 함께 default panel 등록:
side_panel.default_path— panel 열릴 때 Chrome 이 load 할 extension 안 HTML file. Panel 존재 자체에 필수.permissions의"sidePanel"— SW 에서chrome.sidePanel.*호출 필수. 그게 없으면 API 자체가 undefined.
그것만으로 panel 이 Chrome 의 side-panel chooser 에 보임에 충분. User 가 수동 선택 가능; 그 외 wire 안 됨.
Step 2 — SW 에서 behavior 구성
chrome.sidePanel API 가 실제로 쓸 세 method 노출:
chrome.sidePanel.setOptions({ tabId?, path, enabled })— panel HTML 과 enabled 상태 설정, 선택적으로 tab 별. 한 tab target 하려면tabId전달; global default 면 생략.chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: boolean })— toolbar icon click 이 popup 대신 panel 열지 toggle. Icon click 의 popup 과 mutually exclusive: click 이 panel 열거나 popup 열거나.chrome.sidePanel.open({ tabId? | windowId? })— programmatic panel 열기. User-gesture handler (action click, keyboard command, context menu) 에서 호출해야 함, 아니면 reject.
셋 다 SW 에 살아. Panel 자체는 자기 visibility 구성 안 함 — cross-tab perspective 가진 SW 에 그 권한이 있어.
User-gesture 규칙
chrome.sidePanel.open() 가 엄격한 거. Timer, alarm, webRequest event, user gesture 에서 안 온 content-script 메시지에서 호출하면 Side panel can only be opened by a user gesture 로 reject. 정당한 trigger:
chrome.action.onClicked— toolbar icon click. Manifest 에default_popup없을 때만 fire.chrome.commands.onCommand— manifestcommandsblock 에 선언된 keyboard shortcut.chrome.contextMenus.onClicked— right-click menu item.- 실제 user click 에 응답하는 popup 이나 panel 에서 온 메시지일 때의
chrome.runtime.onMessage— Chrome 이 그걸 gesture-derived event 로 다룸.
이 규칙은 보안 baseline: extension 이 user action 없이 user 얼굴에 panel 띄울 수 없음. 존중해; timeout 으로 gesture fake 시도 안 함.
Two-step per-tab 패턴
ClipDeck 에 최종 side-panel 패턴은 per-tab — 각 tab 이 자기 panel context 받아, 나중에 현재 site 별 clip filter 나 per-tab annotation 유지 가능. Setup:
- Manifest 가 default
path와sidePanelpermission 선언. - SW 가
chrome.tabs.onActivatedlisten. 매 event 마다chrome.sidePanel.setOptions({ tabId, path: 'panel.html', enabled: true })호출. - SW 가 install/startup 시
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true })별도 한 번 호출, toolbar icon click 이 popup 대신 panel 열게 — 그게 원하는 UX 면.
Popup 공존 선택
ClipDeck 은 popup 과 panel 둘 다 ship. Toolbar icon 이 default 로 뭘 열지 골라야 함:
action.default_popup: "popup.html"유지 ANDopenPanelOnActionClick: false→ toolbar click 이 popup 열고, panel 은 자기 toggle 이나 버튼으로만 열림.default_popup제거 ANDopenPanelOnActionClick: true설정 → toolbar click 이 panel 열고; popup 은 icon 에서 닿을 수 없음 (키보드나 다른 flow 로 여전히 열 수는 있음).- 둘 다 유지: 불가. Chrome 이 매 click 에 선택 강제.
ClipDeck 현재 선택: popup 을 default 로 유지 (더 빨리 load, "reset / quick stats" 버튼 가짐), popup 에 user-gesture handler 에서 chrome.sidePanel.open() 부르는 "Open clip list" 버튼 추가.
open() 은 user gesture 필요. 어느 step 이라도 빠지면 panel 이 존재 안 하든, 안 나타나든, misleading error 로 reject.setOptions({ tabId, path, enabled: true }) 를 너무 일찍 — Chrome 이 tab 등록 끝내기 전 — 호출하면 silently fail. 가장 안전한 패턴은 chrome.tabs.onActivated 와 chrome.tabs.onUpdated 함께 listen: tab 이 active 되거나 load 끝낼 때마다 setOptions 재적용. 살짝 redundant, ordering 면역.