/** * Resolves the page being collected. Amazon's selected pagination element can * point at the next page while the current results are still rendered, so the * document URL is the authoritative source whenever it carries a page number. */ export async function collectAmazonCurrentPage(): Promise { const currentUrl = new URL(window.location.href); const parsePage = (value: string | null | undefined) => { const page = Number.parseInt(value || '', 10); return Number.isInteger(page) && page > 0 ? page : null; }; const urlPage = parsePage(currentUrl.searchParams.get('page')); if (urlPage) return urlPage; const refPage = parsePage( /(?:^|_)pg_(\d+)(?:_|$)/.exec(currentUrl.searchParams.get('ref') || '')?.[1], ); if (refPage) return refPage; const selected = document.querySelector('.s-pagination-item.s-pagination-selected'); return parsePage(selected?.textContent?.trim()) || 1; } /** * Reads the next search-page URL without navigating from the injected script. * Navigation must happen only after browser.scripting.executeScript has returned, * otherwise Amazon can move the frame into BFCache and destroy the script context. */ export async function collectAmazonNextPageUrl() { const nextButton = document.querySelector('.s-pagination-next'); if (!nextButton || nextButton.classList.contains('s-pagination-disabled')) return null; const href = nextButton.getAttribute('href'); return href ? new URL(href, window.location.href).toString() : null; }