@@ -10,6 +10,9 @@ const popupPorts = new Set();
1010const IMAGE_FETCH_TIMEOUT_MS = 12000 ;
1111const FRAME_COLLECTION_TIMEOUT_MS = 45000 ;
1212const PRECOMPUTED_IR_TRANSFER_MAX_BYTES = 8 * 1024 * 1024 ;
13+ const DEFAULT_EXPORT_OPTIONS = Object . freeze ( {
14+ rootScrollBehavior : 'clip' ,
15+ } ) ;
1316
1417const FRAME_EXTRACTION_OPTIONS = {
1518 boxType : 'border' ,
@@ -53,7 +56,7 @@ extensionApi.runtime.onInstalled.addListener(() => {
5356extensionApi . contextMenus . onClicked . addListener ( ( info , tab ) => {
5457 if ( ! info . menuItemId . startsWith ( 'export-' ) ) return ;
5558 const format = info . menuItemId . slice ( 'export-' . length ) ;
56- startExport ( tab . id , format ) ;
59+ startExport ( tab . id , format , DEFAULT_EXPORT_OPTIONS ) ;
5760} ) ;
5861
5962extensionApi . runtime . onConnect ?. addListener ( ( port ) => {
@@ -69,8 +72,9 @@ extensionApi.runtime.onConnect?.addListener((port) => {
6972extensionApi . runtime . onMessage . addListener ( ( message , sender , sendResponse ) => {
7073 // From popup: start an export
7174 if ( message . action === 'export' ) {
75+ const exportOptions = normalizeExportOptions ( message . options ) ;
7276 extensionApi . tabs . query ( { active : true , currentWindow : true } ) . then ( ( [ tab ] ) => {
73- if ( tab ) startExport ( tab . id , message . format ) ;
77+ if ( tab ) startExport ( tab . id , message . format , exportOptions ) ;
7478 } ) ;
7579 return ;
7680 }
@@ -114,29 +118,36 @@ extensionApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
114118} ) ;
115119
116120// ── Export orchestration ──────────────────────────────────
117- async function startExport ( tabId , format ) {
121+ async function startExport ( tabId , format , exportOptions = DEFAULT_EXPORT_OPTIONS ) {
118122 const fmt = FORMATS [ format ] ;
119123 if ( ! fmt ) {
120124 notifyPopup ( 'export-error' , { error : `Unknown format: ${ format } ` } ) ;
121125 return ;
122126 }
123127
124128 try {
125- const mergedIr = selectPrecomputedIrForTransfer ( await collectMergedIrForTab ( tabId ) ) ;
129+ const normalizedOptions = normalizeExportOptions ( exportOptions ) ;
130+ const mergedIr = selectPrecomputedIrForTransfer ( await collectMergedIrForTab ( tabId , normalizedOptions ) ) ;
126131
127132 // 1. Set the requested format and precomputed IR in the content-script world
128133 await extensionApi . scripting . executeScript ( {
129134 target : { tabId } ,
130- func : ( f , ir ) => {
135+ func : ( f , ir , options ) => {
131136 globalThis . __web2vector_format = f ;
132137
133138 if ( Array . isArray ( ir ) ) {
134139 globalThis . __web2vector_precomputed_ir = ir ;
135140 } else {
136141 delete globalThis . __web2vector_precomputed_ir ;
137142 }
143+
144+ if ( options && typeof options === 'object' ) {
145+ globalThis . __web2vector_export_options = options ;
146+ } else {
147+ delete globalThis . __web2vector_export_options ;
148+ }
138149 } ,
139- args : [ format , mergedIr ] ,
150+ args : [ format , mergedIr , normalizedOptions ] ,
140151 } ) ;
141152
142153 // 2. Lazy-load writer bundle when required
@@ -162,7 +173,7 @@ async function startExport(tabId, format) {
162173 }
163174}
164175
165- async function collectMergedIrForTab ( tabId ) {
176+ async function collectMergedIrForTab ( tabId , exportOptions = DEFAULT_EXPORT_OPTIONS ) {
166177 try {
167178 return await withTimeout ( ( async ( ) => {
168179 await extensionApi . scripting . executeScript ( {
@@ -178,7 +189,10 @@ async function collectMergedIrForTab(tabId) {
178189 const frameResults = await extensionApi . scripting . executeScript ( {
179190 target : { tabId, allFrames : true } ,
180191 func : ( options ) => globalThis . __web2vectorFrameSupport ?. collectFrameData ?. ( options ) ?? null ,
181- args : [ FRAME_EXTRACTION_OPTIONS ] ,
192+ args : [ {
193+ ...FRAME_EXTRACTION_OPTIONS ,
194+ rootScrollBehavior : normalizeExportOptions ( exportOptions ) . rootScrollBehavior ,
195+ } ] ,
182196 } ) ;
183197
184198 return mergeFrameExtractionResults ( frameResults , { rootFrameId : 0 } ) ?. ir ?? null ;
@@ -213,6 +227,12 @@ function estimateSerializedSize(value) {
213227 }
214228}
215229
230+ function normalizeExportOptions ( options ) {
231+ return {
232+ rootScrollBehavior : options ?. rootScrollBehavior === 'expand' ? 'expand' : 'clip' ,
233+ } ;
234+ }
235+
216236async function withTimeout ( promise , timeoutMs , onTimeout ) {
217237 let timeoutId = null ;
218238
0 commit comments