Ogólne#
Traversal#
W tym miejscu umieszczam powtarzające się specyficzne pojęcia i algorytmy w dziale TRAVERSAL, czyli mogą mieć one zastosowanie dla wszystkich interfejsów z tego działu.
Pojęcia#
Obiekty typu NodeIterator oraz TreeWalker mogą zostać użyte do filtracji oraz przechodzenia po węzłach w drzewie węzłów.
active flag
Każdy obiekt typu NodeIterator oraz TreeWalker ma przypisaną flagę aktywności # (active flag) zapobiegającą rekursywnym wywołaniom. Jest ona domyślnie nieaktywna (kwestia nierozstrzygnięta).
root
whatToShow
filter
Każdy obiekt typu NodeIterator oraz TreeWalker jest także skojarzony z węzłem będącym korzeniem # (root), maską bitów # (whatToShow) oraz zwrotnym filtrem # (filter).
iterator collection
Każdy obiekt typu NodeIterator jest skojarzony z kolekcją iteratora # (iterator collection), która jest kolekcją zakorzenioną na korzeniu z filtrem pasującym do każdego węzła.
Algorytmy#
pre-removing steps
Kroki przed-usuwania # (pre-removing steps) węzła toBeRemovedNode z iteratora węzłowego nodeIterator są następujące:
Kroki te będą używane przez ogólny algorytm usuwania węzła, który musi sprawdzić, czy usuwany węzeł może mieć wpływ na stan wszystkich iteratorów węzłowych (opis teoretyczny).
- Jeśli toBeRemovedNode nie jest przodkiem obejmującym dla wartości atrybutu
referenceNodew nodeIterator, to pomiń kolejne kroki. Jeśli wartością atrybutu
pointerBeforeReferenceNodew nodeIterator jest boolowskietrueto uruchom poniższe podkroki:- Niech next będzie pierwszym węzłem następującym dla toBeRemovedNode, który jest potomkiem obejmującym dla korzenia w nodeIterator i nie jest potomkiem obejmującym dla toBeRemovedNode, lub wartością
nulljeśli nie będzie takiego węzła. - Jeśli next nie jest wartością
null, to ustaw atrybutreferenceNodew nodeIterator na next i pomiń kolejne kroki. W przeciwnym razie ustaw wartość atrybut
pointerBeforeReferenceNodew nodeIterator na boolowskefalse.W tym momencie kolejne kroki nie zostają przerwane.
- Niech next będzie pierwszym węzłem następującym dla toBeRemovedNode, który jest potomkiem obejmującym dla korzenia w nodeIterator i nie jest potomkiem obejmującym dla toBeRemovedNode, lub wartością
- Ustaw atrybut
referenceNodew nodeIterator na potomka obejmującego dla ostatniego (zgodnie z porządkiem drzewa) brata poprzedzającego względem toBeRemovedNode, jeśli brat poprzedzający dla toBeRemovedNode nie jest wartościąnull, w przeciwnym razie na rodzica w toBeRemovedNode.
filter
Aby przefiltrować # (filter) węzeł node należy wykonać następujące kroki:
- Jeśli flaga aktywności jest ustawiona, to zrzuć wyjątek
"InvalidStateError". - Niech n będzie wartością atrybutu
nodeTypew node minus1. - Jeśli n-ty bit (gdzie
0jest najmniej znaczącym bitem) w masce bitowej nie jest ustawiony, to zwróćFILTER_SKIP. - Jeśli filtr ma wartość
null, to zwróćFILTER_ACCEPT. - Ustaw flagę aktywności.
- Niech result będzie wartością zwracaną przez wywołanie metody
acceptNode()w filtrze, gdzie node jest pierwszym przekazanym argument. - Usuń flagę aktywności.
- Jeśli jakiś wyjątek został zrzucony, to ponownie zrzuć wyjątek.
- Zwróć result.
traverse
Aby przejść # (traverse) w kierunku direction należy wykonać następujące kroki:
- Niech node będzie wartością atrybutu
referenceNodew obiekcie kontekstu. - Niech before node będzie wartością atrybutu
pointerBeforeReferenceNodew obiekcie kontekstu. - Wykonaj poniższe podkroki:
- Jeśli direction jest następujący
Jeśli before node ma boolowską wartość
false, to ustaw node na pierwszy węzeł następujący po node w kolekcji iteratora skojarzonej z obiektem kontekstu. Jeśli nie będzie takiego węzła, to zwróć wartośćnull.Jeśli before node ma boolowską wartość
true, to ustaw go na boolowską wartośćfalse.- Jeśli direction jest poprzedzający
Jeśli before node ma boolowską wartość
true, to ustaw node na pierwszy węzeł poprzedzający przed node w kolekcji iteratora skojarzonej z obiektem kontekstu. Jeśli nie będzie takiego węzła, to zwróć wartośćnull.Jeśli before node ma boolowską wartość
false, to ustaw go na boolowską wartośćtrue.
- Przefiltruj node i niech result będzie zwracaną wartością.
Jeśli result ma wartość
FILTER_ACCEPT, to idź do następnego kroku w ogólnym zestawie kroków.W przeciwnym razie uruchom te podkroki ponownie.
- Ustaw wartość atrybutu
referenceNodew obiekcie kontekstu na node, ustaw wartość atrybutupointerBeforeReferenceNodew obiekcie kontekstu na before node i zwróć node.
traverse children
Aby przejść przez dzieci # (traverse children) z typem type należy wykonać następujące kroki:
- Niech node będzie wartością atrybutu
currentNodew obiekcie kontekstu. - Ustaw node na pierwsze dziecko w node jeśli type to pierwszy, i ostatnie dziecko w node jeśli type to ostatni.
- Jeśli node ma wartość
null, to zwróć wartośćnull. Główna #: Wykonuj poniższe podkroki:
- Przefiltruj node i niech result będzie zwracaną wartością.
- Jeśli result ma wartość
FILTER_ACCEPT, to ustaw atrybutcurrentNodew obiekcie kontekstu na node i zwróć node. Jeśli result ma wartość
FILTER_SKIP, to uruchom wewnętrzne podkroki:- Niech child będzie pierwszym dzieckiem w node jeśli type to pierwszy, i ostatnim dzieckiem w node jeśli type to ostatni.
- Jeśli child nie ma wartości
null, to ustaw node na child i przejdź do (goto) Główna.
Powtarzaj poniższe wewnętrzne podkroki:
- Niech sibling będzie bratem następującym względem node jeśli type to pierwszy, i bratem poprzedzającym jeśli type to ostatni.
- Jeśli sibling nie ma wartości
null, to ustaw node na sibling i przejdź do (goto) Główna. - Niech parent będzie rodzicem w node.
- Jeśli parent ma wartość
null, parent jest korzeniem skojarzonym z obiektem kontekstu, lub parent jest wartością atrybutucurrentNodew obiekcie kontekstu, to zwróć wartośćnull. - W przeciwnym razie ustaw node na parent.
traverse siblings
Aby przejść przez braci # (traverse siblings) z typem type należy wykonać następujące kroki:
- Niech node będzie wartością atrybutu
currentNodew obiekcie kontekstu. - Jeśli node jest korzeniem skojarzonym z obiektem kontekstu, to zwróć wartości
null. Wykonaj poniższe podkroki:
- Niech sibling będzie bratem następującym względem node jeśli type to następujący, i bratem poprzedzającym jeśli type to poprzedzający.
Dopóki (while) sibling nie ma wartości
null, to uruchom wewnętrzne podkroki:- Ustaw node na sibling.
- Przefiltruj node i niech result będzie zwracaną wartością.
- Jeśli result ma wartość
FILTER_ACCEPT, to ustaw atrybutcurrentNodew obiekcie kontekstu na node i zwróć node. - Ustaw sibling na pierwsze dziecko w node jeśli type to następujący, i ostatnie dziecko w node jeśli type to poprzedzający.
- Jeśli result ma wartość
FILTER_REJECTlub sibling ma wartośćnull, to ustaw sibling na brata następującego względem node jeśli type to następujący, i brata poprzedzającego jeśli type to poprzedzający.
- Ustaw node na swojego rodzica.
- Jeśli node ma wartość
nulllub jest korzeniem skojarzonym z obiektem kontekstu, to zwróć wartośćnull. - Przefiltruj node i jeśli zwracaną wartością jest
FILTER_ACCEPT, to zwróć wartośćnull. - Uruchom te podkroki ponownie.