Gecko:Continuation Model: Difference between revisions

Jump to navigation Jump to search
Document changes done as part of fixing bug 299065
(→‎Relationship of continuations to frame tree structure: more text, since this is really important)
(Document changes done as part of fixing bug 299065)
Line 22: Line 22:
Again, a single rectangular frame cannot represent the layout of the node. Columns are similar.
Again, a single rectangular frame cannot represent the layout of the node. Columns are similar.


The first frame for an element is called the primary frame. The other frames are called continuation frames. Primary frames are created by nsCSSFrameConstructor in response to content insertion notifications. Continuation frames are created during reflow, when reflow detects that a content element cannot be fully laid out within the constraints assigned (e.g., when inline text will not fit within a particular width constraint, or when a block cannot be laid out within a particular height constraint).
Another case where a single DOM node is represented by multiple frames is when a text node contains bidirectional text (e.g. both Hebrew and English text). In this case, the text node and its inline ancestors are split so that each frame contains only unidirectional text.  


The frames for an element are put in a doubly-linked list. The links are accessible via nsIFrame::GetNextInFlow and nsIFrame::GetPrevInFlow.
The first frame for an element is called the primary frame. The other frames are called continuation frames. Primary frames are created by nsCSSFrameConstructor in response to content insertion notifications. Continuation frames are created during bidi resulution, and during reflow, when reflow detects that a content element cannot be fully laid out within the constraints assigned (e.g., when inline text will not fit within a particular width constraint, or when a block cannot be laid out within a particular height constraint).
 
Continuation frames created during reflow are called "fluid" continuations (or "in-flows"). Other continuation frames (currently, those created during bidi resolution), are, in contrast, "non-fluid". The NS_FRAME_IS_FLUID_CONTINUATION state bit indicates whether a continuation frame is fluid or not.
 
The frames for an element are put in a doubly-linked list. The links are accessible via nsIFrame::GetNextContinuation and nsIFrame::GetPrevContinuation. If only fluid continuations are to be accessed, nsIFrame::GetNextInFlow and nsIFrame::GetPrevInFlow are used instead.


The following diagram shows the relationship between the original frame tree considering just primary frames, and a possible layout with breaking and continuations:
The following diagram shows the relationship between the original frame tree considering just primary frames, and a possible layout with breaking and continuations:
Line 30: Line 34:
Original frame tree      Frame tree with A broken into three parts
Original frame tree      Frame tree with A broken into three parts
     Root                      Root
     Root                      Root
     |                      /  |   |
     |                      /  | \
     A                    A1  A2  A3
     A                    A1  A2  A3
     / \                  / |  |    |
     / \                  / |  |    |
Line 41: Line 45:
* nsSimplePageSequence creates multiple page children, each one associated with the entire document, separated by page breaks
* nsSimplePageSequence creates multiple page children, each one associated with the entire document, separated by page breaks
* nsColumnSetFrame creates multiple block children, each one associated with the column element, separated by column breaks
* nsColumnSetFrame creates multiple block children, each one associated with the column element, separated by column breaks
* nsBlockFrame creates multiple inline children, each one associated with the same inline element, separated by line breaks
* nsBlockFrame creates multiple inline children, each one associated with the same inline element, separated by line breaks, or by changes in text direction


=== Relationship of continuations to frame tree structure ===
=== Relationship of continuations to frame tree structure ===


It is worth emphasizing two points about the relationship of the prev-in-flow / next-in-flow linkage to the existing frame tree structure.
It is worth emphasizing two points about the relationship of the prev-continuation / next-continuation linkage to the existing frame tree structure.


First, if you want to traverse the frame tree or a subtree thereof to examine all the frames once, you do <em>not</em> want to traverse next-in-flow links.  All continuations are reachable by traversing the <code>GetNextSibling</code> links from the result of <code>GetFirstChild</code> for all child lists.
First, if you want to traverse the frame tree or a subtree thereof to examine all the frames once, you do <em>not</em> want to traverse next-continuation links.  All continuations are reachable by traversing the <code>GetNextSibling</code> links from the result of <code>GetFirstChild</code> for all child lists.


Second, the following property holds:
Second, the following property holds:
* Consider two frames F1 and F2 where F1's next-in-flow is F2 and their respective parent frames are P1 and P2. Then either P1's next in flow is P2, or P1 == P2 and P1/P2 is responsible for breaking F1 and F2.
* Consider two frames F1 and F2 where F1's next-continuation is F2 and their respective parent frames are P1 and P2. Then either P1's next continuation is P2, or P1 == P2 and P1/P2 is responsible for breaking F1 and F2.
In other words, continuations are sometimes siblings of each other, and sometimes not.  If their parent content was broken at the same point, then they are not siblings, since they are children of different continuations of the parent.  So in the frame tree for the markup
In other words, continuations are sometimes siblings of each other, and sometimes not.  If their parent content was broken at the same point, then they are not siblings, since they are children of different continuations of the parent.  So in the frame tree for the markup
   &lt;p&gt;This is &lt;b&gt;&lt;i&gt;some &lt;br/&gt;text&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;
   &lt;p&gt;This is &lt;b&gt;&lt;i&gt;some &lt;br/&gt;text&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;
Line 63: Line 67:
== Dynamic Reflow Considerations ==
== Dynamic Reflow Considerations ==


When we reflow a frame F with continuations, two things can happen:
When we reflow a frame F with fluid continuations, two things can happen:
* Some child frames do not fit in the passed-in width or height constraint. These frames must be "pushed" to F's next-in-flow. If F has no next-in-flow, we must create one under F's parent's next-in-flow --- or if F's parent is managing the breaking of F, then we create F's next in flow directly under F's parent. If F is a block, it pushes overflowing child frames to its "overflow" child list and forces F's next in flow to be reflowed. When we reflow a block, we pull the child frames from the prev-in-flow's overflow list into the current frame.
* Some child frames do not fit in the passed-in width or height constraint. These frames must be "pushed" to F's next-in-flow. If F has no next-in-flow, we must create one under F's parent's next-in-flow --- or if F's parent is managing the breaking of F, then we create F's next in flow directly under F's parent. If F is a block, it pushes overflowing child frames to its "overflow" child list and forces F's next in flow to be reflowed. When we reflow a block, we pull the child frames from the prev-in-flow's overflow list into the current frame.
* All child frames fit in the passed-in width or height constraint. Then child frames must be "pulled" from F's next-in-flow to fill in the available space. If F's next-in-flow becomes empty, we may be able to delete it.
* All child frames fit in the passed-in width or height constraint. Then child frames must be "pulled" from F's next-in-flow to fill in the available space. If F's next-in-flow becomes empty, we may be able to delete it.
67

edits

Navigation menu