azon_seeker/src/page-worker/web-injectors/amazon-search-pagination.ts
2026-09-02 10:36:04 +08:00

37 lines
1.5 KiB
TypeScript

/**
* 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<number> {
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<HTMLElement>('.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<HTMLAnchorElement>('.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;
}