mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-10-05 07:13:06 +08:00
fix: bind Amazon results to visible page
This commit is contained in:
parent
6fbf8b7bcd
commit
d42e19f42f
@ -44,23 +44,29 @@ const main = async () => {
|
||||
);
|
||||
await testNextPage('missing next page', '<main>No pagination</main>', null);
|
||||
await testCurrentPage(
|
||||
'URL page wins over stale pagination selection',
|
||||
'visible page wins over hidden stale pagination selection',
|
||||
'https://www.amazon.com/s?k=home+security&page=11&ref=sr_pg_11',
|
||||
'<span class="s-pagination-item s-pagination-selected">12</span>',
|
||||
'<div style="display:none"><span class="s-pagination-item s-pagination-selected">12</span></div><span class="s-pagination-item s-pagination-selected">11</span>',
|
||||
11,
|
||||
);
|
||||
for (const page of [1, 2, 5, 10, 20]) {
|
||||
await testCurrentPage(
|
||||
`URL page ${page}`,
|
||||
`https://www.amazon.com/s?k=home+security&page=${page}&ref=sr_pg_${page}`,
|
||||
`<span class="s-pagination-item s-pagination-selected">${page + 1}</span>`,
|
||||
`<span class="s-pagination-item s-pagination-selected">${page}</span>`,
|
||||
page,
|
||||
);
|
||||
}
|
||||
await testCurrentPage(
|
||||
'visible page wins while URL has advanced',
|
||||
'https://www.amazon.com/s?k=home+security&page=3&ref=sr_pg_3',
|
||||
'<span class="s-pagination-item s-pagination-selected">2</span>',
|
||||
2,
|
||||
);
|
||||
await testCurrentPage(
|
||||
'invalid URL page uses ref fallback',
|
||||
'https://www.amazon.com/s?k=home+security&page=invalid&ref=sr_pg_9',
|
||||
'<span class="s-pagination-item s-pagination-selected">10</span>',
|
||||
'<main>No selected pagination item</main>',
|
||||
9,
|
||||
);
|
||||
await testCurrentPage(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 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.
|
||||
* Resolves the page represented by the currently rendered search results.
|
||||
* Amazon can update the URL before replacing the visible result DOM, so the
|
||||
* rendered selected-page control is authoritative and the URL is only a fallback.
|
||||
*/
|
||||
export async function collectAmazonCurrentPage(): Promise<number> {
|
||||
const currentUrl = new URL(window.location.href);
|
||||
@ -10,6 +10,32 @@ export async function collectAmazonCurrentPage(): Promise<number> {
|
||||
return Number.isInteger(page) && page > 0 ? page : null;
|
||||
};
|
||||
|
||||
const isRendered = (node: HTMLElement) => {
|
||||
for (let current: HTMLElement | null = node; current; current = current.parentElement) {
|
||||
if (current.hidden || current.getAttribute('aria-hidden') === 'true') return false;
|
||||
const style = current.ownerDocument.defaultView?.getComputedStyle(current);
|
||||
if (
|
||||
style &&
|
||||
(style.display === 'none' ||
|
||||
style.visibility === 'hidden' ||
|
||||
style.visibility === 'collapse' ||
|
||||
style.opacity === '0')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (document.documentElement.getClientRects().length === 0) return true;
|
||||
return Array.from(node.getClientRects()).some((rect) => rect.width > 0 && rect.height > 0);
|
||||
};
|
||||
|
||||
const renderedSelectedPages = Array.from(
|
||||
document.querySelectorAll<HTMLElement>('.s-pagination-item.s-pagination-selected'),
|
||||
)
|
||||
.filter(isRendered)
|
||||
.map((node) => parsePage(node.textContent?.trim()))
|
||||
.filter((page): page is number => page !== null);
|
||||
if (renderedSelectedPages.length > 0) return renderedSelectedPages[0];
|
||||
|
||||
const urlPage = parsePage(currentUrl.searchParams.get('page'));
|
||||
if (urlPage) return urlPage;
|
||||
|
||||
@ -18,8 +44,10 @@ export async function collectAmazonCurrentPage(): Promise<number> {
|
||||
);
|
||||
if (refPage) return refPage;
|
||||
|
||||
const selected = document.querySelector<HTMLElement>('.s-pagination-item.s-pagination-selected');
|
||||
return parsePage(selected?.textContent?.trim()) || 1;
|
||||
const anySelected = document.querySelector<HTMLElement>(
|
||||
'.s-pagination-item.s-pagination-selected',
|
||||
);
|
||||
return parsePage(anySelected?.textContent?.trim()) || 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user