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 testNextPage('missing next page', '<main>No pagination</main>', null);
|
||||||
await testCurrentPage(
|
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',
|
'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,
|
11,
|
||||||
);
|
);
|
||||||
for (const page of [1, 2, 5, 10, 20]) {
|
for (const page of [1, 2, 5, 10, 20]) {
|
||||||
await testCurrentPage(
|
await testCurrentPage(
|
||||||
`URL page ${page}`,
|
`URL page ${page}`,
|
||||||
`https://www.amazon.com/s?k=home+security&page=${page}&ref=sr_pg_${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,
|
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(
|
await testCurrentPage(
|
||||||
'invalid URL page uses ref fallback',
|
'invalid URL page uses ref fallback',
|
||||||
'https://www.amazon.com/s?k=home+security&page=invalid&ref=sr_pg_9',
|
'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,
|
9,
|
||||||
);
|
);
|
||||||
await testCurrentPage(
|
await testCurrentPage(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Resolves the page being collected. Amazon's selected pagination element can
|
* Resolves the page represented by the currently rendered search results.
|
||||||
* point at the next page while the current results are still rendered, so the
|
* Amazon can update the URL before replacing the visible result DOM, so the
|
||||||
* document URL is the authoritative source whenever it carries a page number.
|
* rendered selected-page control is authoritative and the URL is only a fallback.
|
||||||
*/
|
*/
|
||||||
export async function collectAmazonCurrentPage(): Promise<number> {
|
export async function collectAmazonCurrentPage(): Promise<number> {
|
||||||
const currentUrl = new URL(window.location.href);
|
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;
|
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'));
|
const urlPage = parsePage(currentUrl.searchParams.get('page'));
|
||||||
if (urlPage) return urlPage;
|
if (urlPage) return urlPage;
|
||||||
|
|
||||||
@ -18,8 +44,10 @@ export async function collectAmazonCurrentPage(): Promise<number> {
|
|||||||
);
|
);
|
||||||
if (refPage) return refPage;
|
if (refPage) return refPage;
|
||||||
|
|
||||||
const selected = document.querySelector<HTMLElement>('.s-pagination-item.s-pagination-selected');
|
const anySelected = document.querySelector<HTMLElement>(
|
||||||
return parsePage(selected?.textContent?.trim()) || 1;
|
'.s-pagination-item.s-pagination-selected',
|
||||||
|
);
|
||||||
|
return parsePage(anySelected?.textContent?.trim()) || 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user