Allegro Seller Info 0.1.17

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *