CSS Zibaldone
[ Home ] -
[ Articoli ] -
[ Traduzioni ] -
[ Altro ] -
[ Appunti sui CSS ] -
[ L'autore ]
Sei qui:
Home >
Traduzioni >
Design di alto livello dello Space Manager
Design di alto livello dello Space Manager
Articolo originale:
http://lxr.mozilla.org/seamonkey/source/layout/doc/HLD-SpaceManager.html
Traduzione: Gabriele Romanato (18 agosto 2007)
Introduzione
Lo Space Manager (e classi e strutture associate) vengono usati dal layout
Block e Line per controllare le zone rettangolari che sono occupate o disponibili,
per la corretta gestione degli elementi flottati e degli elementi che fluiscono
intorno a questi ultimi. Quando gli elementi sono flottati a destra o a sinistra in un layout,
essi occupano spazio ed influenzano il posizionamento degli altri elementi.
Lo Space Manager ha il compito di registrare dove viene occupato spazio e dove invece è disponibile.
Questa informazione viene usata dal layout di blocco per
calcolare correttamente dove devono essere posizionati altri
elementi flottati, e quanto spazio resta disponibile per i normali elementi
nel flusso che scorrono attorno alle parti flottate.
Lo Space Manager lavora congiuntamente con diverse altre classi. Le classi che vengono
considerate parte dello Space Manager sono:
- nsSpaceManager
- nsBandData
- nsBlockBandData
- BandRect / BandList (private)
- FrameInfo (private)
- nsBandtrapezoid
Al di fuori dello Space Manager stesso, i client dello Space Manager rivestono
un ruolo importante nella gestione dello spazio disponibile ed in uso.
Le classi principali che interagiscono con lo Space Manager sono:
- nsBlockReflowState
- nsBlockFrame
- nsBoxToBlockAdaptor
Il modello di interazione generico consiste nel creare uno Space Manager
per un frame di blocco nel contesto di un Reflow, e di associarlo con il
BlockReflowState in modo che venga passato ai metodi di reflow dei frame figli.
Dopo il reflow, lo Space Manager viene distrutto. Durante il reflow, lo Space
Manager memorizza lo spazio occupato dai float
(UpdateSpaceManager in nsBlockFrame) e fornisce informazioni sullo spazio disponibile per
gli altri elementi
(GetAvailableSpace
in nsBlockReflowState).
Inoltre vi è il bisogno di gestire l'impatto sulle righe
causato dai cambiamenti agli elementi flottati. Questo viene detto
Propagation
of Float Damage e viene gestito dal Block Frame, che fa uso dello
Space Manager.
Quando un float viene risistemato in modo incrementale, lo Space Manager
si accorge se la zona del float è cambiata. Se ciò avviene,
lo spazio verticale (che comprende la precendente zona del float e la sua
nuova zona) viene segnalato nell'
nsIntervalSet interno come "danno potenziale del float"
(il metodo è
IncludeInDamage).
Durante la risistemazione incrementale delle righe "sporche"
il frame di blocco può incontrare righe che NON sono sporche.
In questo caso viene chiesto allo Space Manager se vi è un danno dei float, e
in caso affermativo il blocco prosegue verificando se il danno interseca l'area della
riga non-sporca, rendendola sporca se vi è un'intersezione.
In questo modo i cambiamenti ai float su altre righe possono avere un impatto
su righe altrimenti "pulite", e lo Space Manager ne facilita
l'individuazione.
Modello di dati
Diagramma classi/componenti

- nsSpaceManager: Il punto centrale della gestione dello spazio
occupato dai float in un blocco.
- nsBandData: Fornisce informazioni sui frame
che occupano una zona di spazio occupato o disponibile.
- nsBlockBandData: Una specializzazione di nsBandData usata da
nsBlockReflowState per determinare lo spazio disponibile, l'impatto dei float e
il punto in cui i float ricevono il clear. Essenzialmente un contenitore
specifico per nsBandData generico.
- BandRect: Conserva i confini di una zona, insieme con i frame associati alla zona.
I BandRect sono un elenco linkato (fornito dalla super-classe PRCListStr)
che forniscono anche alcuni metodi geometrici
(SplitVertically,
SplitHorizontally) e alcuni metodi che
interrogano o manipolano i frame associati alla zona (IsOccupiedBy, AddFrame, RemoveFrame).
- BandList: Una sottoclasse di BandRect che fornisce un elenco di interfacce
- Head(), Tail(), IsEmpty(), ecc.
- FrameInfo: Una struttura che conserva le informazioni
sul rettangolo associato con uno specifico frame, in un elenco
linkato.
- nsBandTrapezoid: Rappresenta le regioni discrete all'interno
di una zona che sono
Available, Occupied da un singolo frame o Occupied da diversi
frame. Viene usato per comunicare le informazioni
sullo spazio nella zona ai client di Space Manager. Non vi è un uso
interno di
nsBandTrapezoid da parte dello Space Manager, piuttosto esso usa il suo
BandList interno per creare una collezione BandData, costituita soprattutto da dati nsTrapezoid.
Casi d'uso
Caso d'uso 1: Space Manager viene creato/distrutto
Le istanze di Space Manager vengono create nel metodo Reflow di nsBlockFrame.
- Viene creata un'istanza.
- Il precedente Space Manager di BlockReflowState viene salvato.
- La nuova istanza di Space Manager viene associata al BlockReflowState.
- Dopo che il Reflow del frame è completo,
la precedente istanza di Space Manager viene ri-associata con il BlockReflowState.
- Il nuovo Space Manager viene distrutto.
Se il BlockReflowState ha già un'istanza di Space Manager ad esso
associata, viene memorizzata prima di essere sostituita e quindi restituita
all'istanza di dopo che la nuova è stata distrutta. Di fatto gli Space Manager
sono "annidati" durante il reflow, con ciascun blocco che introduce il proprio
Space Manager.
Caso d'uso 2: Un float viene aggiunto allo Space Manager
Dopo che uno Space Manager è stato creato per un reflow di blocco, si può
aggiungere un float ad esso. Ciò avviene nel metodo
nsBlockReflowState::RecoverFloats e
nsBlockReflowState::FlowAndPlaceFloat (prima veniva fatto in nsBlockFrame::UpdateSpaceManager).
L'algoritmo generale in nsBlockReflowState::RecoverFloats è:
-
Per ogni riga nel blocco, verificare se ha blocchi flottati.
- Se i float sono sulla riga, eseguire una reiterazione sui float aggiungendoli tutti
allo Space Manager tramite il metodo AddRectRegion. Il rettangolo effettivo per il frame
viene memorizzato in nsFloatCache, e così non deve essere ricalcolato.
-
Se il blocco ha dei figli di blocco, si trasferisca lo Space Manager
all'origine del blocco figlio, e si aggiorni lo Space Manager nel contesto
del blocco figlio, ricorsivamente. Una volta compiuta questa operazione,
si ripristinino le coordinate dello Space Manager trasferendo il negativo dell'origine
del blocco figlio.
L'algoritmo generale in nsBlockReflowState::FlowAndPlaceFloat è:
- Viene registrata la regione che il float occupa attualmente.
- Viene ricercata la zona di spazio disponibile (con nsBlockReflowState::GetAvailableSpace).
- Il frame del float ottenuto dall'argomento
di nsFloatCache viene risistemato
e il suo rettangolo è ottenuto con GetRect.
- Vengono aggiunti i margini del float.
- Verificare se il float può essere posizionato nella zona corrente. In caso contrario,
passare alla zona successiva.
- Verificare il tipo di float e se questo può
essere aggiunto allo Space Manager.
- Allineare il float alla parte superiore del suo blocco contenitore se la regola
CSS2/9.5.1/4
non viene rispettata.
- Aggiungere il float usando nsSpaceManager::AddRectRegion.
-
Confrontare l'area che il float occupava con l'area che occupa ora: se è diversa,
memorizzare l'intervallo verticale interessato usando
nsSpaceManager::IncludeInDamage.
Caso d'uso 3: Space Manager viene usato per trovare lo spazio disponibile
per il reflow
nsBlockFrame fa uso dello Space Manager per ottenere
lo spazio disponibile per il reflow di un figlio di blocco o inline.
Il frame di blocco usa un metodo helper sulla classe
nsBlockReflowState per effettuare il calcolo effettivo dello spazio disponibile
sulla base dei dati dello Space Manager. Ecco il suo funzionamento
nel caso di un reflow di un frame inline all'interno di un blocco
(e anche nel caso del reflow di un frame di blocco e, parzialmente,
per la preparazione di un ridimensionamento).
- nsBlockFrame libera prima tutte le informazioni sui float
per la riga da risistemare.
- GetAvailableSpace viene chiamato su BlockReflowState.
- BlockReflowState chiama GetAvailableSpace sulla sua istanza BlockBandData
(preparata nel costruttore di BlockReflowState in base allo
SpaceManager e all'area di contenuto calcolata).
- BlockBandData ottiene i dati della zona dallo Space Manager
con una chiamata allo Space Manager associato con l'istanza BlockBandData.
- BlockBandData passa in rassegna la collezione dei trapezoid restituiti dal metodo
GetBandData dello Space Manager (in forma di contenitori nsBandData) e determina
il limite destro dello spazio disponibile.
- BlockReflowState memorizza il rettangolo di spazio disponibile per l'uso nel resto
della sequenza di reflow.
Caso d'uso 4: Propagazione del Float Damage: individuare e gestire il danno dei float
Questo processo è gestito dal Block Frame.
- Una riga non-sporca viene trovata dal Block Frame in ReflowDirtyLines.
- Block Frame chiama il suo metodo PropagateFloatDamage.
- Space Manager deve stabilire se vi è un danno dei float.
- In caso affermativo, Block Frame chiede a Space Manager se la riga in questione
interseca il danno dei float.
- Se la riga non lo interseca, allora
la riga viene marcata come sporca.
- La riga viene ancora marcata come sporca se:
- è stata influenzata dai float, ma non lo è più.
- non è stata influenzata dai float, ma ora lo è.
-
è influenzata dai float ed è un blocco.
Problemi/bug riscontrati durante la documentazione:
- BandRect e BandList sono public in nsSpaceManager.h - dovrebbero essere
private (compilare bene)
- i dati membri di nsSpaceManager vengono dichiarati protected, ma non ci sono sottoclassi.
Dovrebbero essere private (compilare bene).
- nsBlockFrame::Paint si confonde con nsBlockBandData e il blocco #if 0
- rimuovere questo e l'include (compilare bene).
- nsSpaceManager non ha modo di dare il clear all'intervallo del Float Damage impostato
- ce ne sarebbe bisogno se SpaceManager persistesse oltre un Reflow.