Allegro Seller Info 0.1.17
• tech • 454 słowa • 3 minuty czytania
Poranne przeglądanie listy obserwowanych/poszukiwanych elementów na Allegro ukazało standardową bolączkę mojego skryptu - przestał działać na listach aukcji. Co może świadczyć, że znów coś pozmieniano i “ulepszono” w serwisie.
Na pierwszy rzut oka udało mi się zlokalizować problem w pobieraniu “propsów” z obiektów React-a. W ostatniej wersji coś tam mieszali, a teraz wygląda na to, że znów to robią. Chyba zmieniła się struktura (niekoniecznie DOM-a), bo jakby potrzebne mi obiekty są “zaszyte” poziom niżej - doszedł return
w łańcuchu dostępu do obiektu item
.
Przy okazji wykorzystałem genialny operator ?.
do uproszczenia kodu, bo łatwiejsze wydaje się i znacznie czytelniejszy staje się kod bez jawnych dodatków sprawdzających istnienie kolejnych elementów i obiektów.
function getReactInst(dom) {
return dom[Object.keys(dom).find(key => key.startsWith('__reactInternalInstance$'))]?.return;
}
// [...]
var item = getReactInst(node)?.return?.pendingProps?.item;
W JS wprowadzone kilka ciekawych operatorów, może o części z nich coś napiszę przy najbliższej okazji.
Wspomniane wcześniej zmiany “głębokości” na elementach listy generują kolejny problem. W poprzedniej wersji aktualizację listy ofert dokonywano przez usuwanie i dodawanie elementów. Teraz modyfikacje zachodzą “poziom” niżej - przesunięto manipulowanie z elementu article
na article > div
. To wymaga rozszerzenia obsługi zdarzeń o reakcję na wszelkie modyfikacje na elemencie <article/>
(target), czyli dochodzi prosty if w callback-u MutationObserver
-a:
var node = mutation.target;
if (node.nodeName == 'ARTICLE')
UpdateOffer(node);
Dobrze, że UpdateOffer
nie wykonuje żadnych operacji, gdy wykryje, że bieżący element już został wcześniej zaktualizowany. Bez tego dochodziłoby do zapętlenia się, gdyż dodanie wstawki (UpdateOffer
) w elemencie <article/>
generuje kolejne zdarzenie modyfikacji, w obsłudze którego następowałoby kolejne wywołanie UpdateOffer
i itd…
W ostatniej wersji wywaliłem “oczekiwanie” na gotowość listy przed odświeżeniem bazowej jej zawartości po załadowaniu strony. Sprawę miał załatwiać MutationObserver
, a ewentualny wyścig prosta pętla. Niestety czasem można zauwazyć, że kilka pierwszych widocznych elementów nie jest poprawianych przez żaden z tych mechanizmów - obserwator nie dostaje zmian, a UpdateOffer
trafia na brak “propsów”. Dlatego przywróciłem tamten mechanizm niwelujący wyścig:
function UpdateListBase() {
if (listing._reactRootContainer) {
for (var node of listNode.getElementsByTagName('article'))
UpdateOffer(node);
return;
}
setTimeout(UpdateListBase, 100);
}
UpdateListBase();
Nie wiem, czy to stricte wynika z ostatnich zmian na stronie, czy może moja decyzja w poprzedniej wersji była pochopna.
Na koniec zauważyłem w logach konsoli, przy załadowaniu kolejnej podstrony z ofertami, jeszcze inny problem:
Uncaught TypeError: Cannot read property 'children' of undefined
at UpdateOffer (userscript.html?name=Allegro%20Seller%20Info.user.js:62)
at MutationObserver.eval (userscript.html?name=Allegro%20Seller%20Info.user.js:91)
Występuje to zawsze w tym samym momencie - przy budowaniu doładowanych elementów listy. Wiążę to z faktem dodawania pustego article
do listy, a później jego zawartości w article > div
. Przez co w pierwszym obsługiwanym zdarzeniu element jest pusty, dlatego dodałem kolejnego if-a z ewentualnym zaniechaniem działań w UpdateOffer
.
Niestety problem z brakiem informacji o sprzedającym w propsach dla ofert z “Allegro Lokalnie” nadal występuje.
Poprawiona wersja skryptu z numerem 0.1.17 dostępna jest już w moim repozytorium UserScripts.
Komentarze (0)