michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: HTML Layout Internals michael@0: michael@0: michael@0: michael@0:

michael@0: HTML Layout Internals

michael@0: michael@0:

michael@0: Big picture

michael@0: An HTML document comes in from netlib into the HTML parser.  The parser michael@0: creates parser nodes and feeds them to the content sink.  The content michael@0: sink constructs a content model that represents the hierarchical structure michael@0: of the document.  As different sub-trees in the content model are michael@0: fully available, the stylesheet processor iterates over them and creates michael@0: the corresponding frame hierarchy.  The frames recursively layout michael@0: and render themselves. michael@0:

The part that we are going to drill down into is the code in the block michael@0: and inline frame classes.  Block and inline are the two primary display michael@0: types specified in CSS and are used in the layout of most of the HTML tags.  michael@0: The table related tags have their own display types like "table-cell", michael@0: "table-row", etc. and their implementation is a separate topic in itself. michael@0:

michael@0: Block and inline code

michael@0: The main classes involved in the layout of HTML documents are nsBlockFrame michael@0: and nsInlineFrame, both of which inherit from nsContainerFrame (why?).  michael@0: These classes are persistent across reflows and are organized in a hierarchy michael@0: to constitute the frame model of the Gecko system.  The frame model michael@0: is derived by applying style and presentation semantics to the content michael@0: model.  Each frame in the frame model has a one to one correspondence michael@0: with a rectangular region on the presentation context (screen, printer, michael@0: etc.) and contains the formatting information needed to render that rectangle.  michael@0: The block and inline frame classes implement the nsIFrame and nsIHTMLReflow michael@0: interfaces.  The nsIFrame interface contains methods for managing michael@0: child frames and linkage with sibling frames, accessing the style context michael@0: associated with the frame, painting the frame, and handling events that michael@0: are passed in from the widget hierarchy.  The nsIHTMLReflow interface michael@0: inherits from the nsIReflow interface and adds methods related to word michael@0: breaking and whitespace querying.  The nsIReflow interface defines michael@0: the Reflow() method that initiates the reflow process along with the WillReflow() michael@0: and DidReflow() methods that get called before and after the reflow process michael@0: respectively.  nsReflowState and nsReflowMetrics are parameters to michael@0: the templatized nsIReflow interface: the former is used to hold state during michael@0: reflow of a frame and the latter is used to return the frame's desired michael@0: size and alignment to the parent frame during the reflow process. michael@0:

nsBlockReflowContext and nsBlockReflowState both hold state information michael@0: during the reflow process.  nsBlockReflowContext encapsulates the michael@0: state and algorithm for reflowing child block frames.  nsBlockReflowState michael@0: contains state and methods used by a block frame to reflow itself.  michael@0: Both these classes are instantiated once per block frame. michael@0:

The nsLineLayout class is the engine used by the block and inline frame michael@0: classes to layout themselves on a line.  Frames get passed in to the michael@0: nsLineLayout class via the BeginSpan() and EndSpan() methods.  Each michael@0: span represents a run of frames with the same style data (???).  Other michael@0: methods exist on the nsLineLayout class to position and size the frames michael@0: on the current line. michael@0:

nsBlockBandData is the class used to manage the processing of the space-manager michael@0: (nsSpaceManager) band data.  It provides HTML/CSS specific semantics michael@0: on top of the general space management facilities provided by nsSpaceManager. michael@0:

nsSpaceManager is a class that is told about regions that reserve space michael@0: and exposes methods to query for available space in a given band. michael@0:

The nsLineBox class represents a horizontal line of frames and is singly michael@0: linked to the next line box in the document.  It is basically a container michael@0: of a frame list that share the property of being on the same line in the michael@0: formatted output of the document. michael@0:

The nsTextRun class holds on to a list of frames containing pieces of michael@0: text that form a logical text run.  This is needed because a single michael@0: text run can occur on leaves at many levels of the document's content tree.  michael@0: This class gives the text layout process an efficient way to get access michael@0: to text runs and, so, determine where word breaks should occur. michael@0:

michael@0: Questions

michael@0: What are anonymous blocks (nsBlockFrame.h)? michael@0:
What is the difference between a span and a band (nsLineLayout)? michael@0:
Why do nsBlockFrame and nsInlineFrame both inherit from nsContainerFrame? michael@0:

michael@0: To Do

michael@0: michael@0:
    michael@0:
  1. michael@0: Provide more information about methods and state of each of the classes michael@0: above.
  2. michael@0: michael@0:
  3. michael@0: Give a description of how the above classes interact with each other as michael@0: a simple HTML document is laid out.  Then, add in different features michael@0: to the HTML that exercise different areas of the code, like floats, anonymous michael@0: blocks, etc.
  4. michael@0:
michael@0: michael@0: michael@0: