michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: Layout Overview michael@0: michael@0: michael@0: michael@0:

Layout System Overview

michael@0:
michael@0:

Layout's Job: Provide the Presentation

michael@0: Layout is primarily concerned with providing a presentation to an HTML or michael@0: XML document. This presentation is typically formatted in accordance with michael@0: the requirements of the CSS1 michael@0: and CSS2 specifications from michael@0: the W3C. Presentation formatting is also required to provide compatibility michael@0: with legacy browsers (Microsoft Internet Explorer and Netscape Navigator michael@0: 4.x). The decision about when to apply CSS-specified formatting and when michael@0: to apply legacy formatting is controlled by the document's DOCTYPE specification. michael@0: These layout modes are referred to as 'Standards' and 'NavQuirks' modes. (DOCTYPE michael@0: and modes are explained in more detail here).
michael@0:
michael@0: The presentation generally is constrained by the width of the window in which michael@0: the presentation is to be displayed, and a height that extends as far as michael@0: necessary. This is referred to as the Galley Mode presentation, and is what michael@0: one expects from a typical browser. Additionally, layout must support a paginated michael@0: presentation, where the width of the presentation is constrained by the dimensions michael@0: of the printed output (paper) and the height of each page is fixed. This michael@0: paged presentation presents several challenges not present in the galley michael@0: presentation, namely how to break up elements that are larger than a single michael@0: page, and how to handle changes to page dimensions.
michael@0:
michael@0: The original design of the Layout system allowed for multiple, possibly different, michael@0: presentations to be supported simultaneously from the same content model. michael@0: In other words, the same HTML or XML document could be viewed as a normal michael@0: galley presentation in a browser window, while simultaneously being presented michael@0: in a paged presentation to a printer, or even an aural presentation to a michael@0: speech-synthesizer. To date the only real use of this multiple presentation michael@0: ability is seen in printing, where multiple presentations are managed, all michael@0: connected to the same content model. (note: it is unclear if this is really michael@0: a benefit - it may have been better to use a copy of the content model for michael@0: each presentation, and to remove the complexity of managing separate presentations michael@0: - analysis is needed here). The idea of supporting a non-visual presentation michael@0: is interesting. Layout's support for aural presentations is undeveloped, michael@0: though conceptually, it is possible and supported by the architecture.
michael@0:
michael@0:

How Layout Does its Job: Frames and Reflow

michael@0: So, layout is concerned with providing a presentation, in galley or paged michael@0: mode. Given a content model, how does the layout system actually create the michael@0: presentation? Through the creation and management of frames. Frames are an michael@0: encapsulation of a region on the screen, a region that contains geometry michael@0: (size and location, stacking order). Generally frames correspond to the content michael@0: elements, though there is often a one-to-many correspondence between content michael@0: elements and frames. Layout creates frames for content based on either the michael@0: specific HTML rules for an element or based on the CSS display type of the michael@0: element. In the case of the HTML-specific elements, the frame types that michael@0: correspond to the element are hard-coded, but in the more general case where michael@0: the display type is needes, the layout system must determine that display michael@0: type by using the Style System. A content element is passed to the Style michael@0: System and a request is made to resolve the style for that element. This michael@0: causes the Style System to apply all style rules that correspond to the element michael@0: and results in a resolved Style Context - the style data specific to that michael@0: element. The Layout module looks at the 'display' field of the style context michael@0: to determine what kind of frame to create (block, inline, table, etc.). The michael@0: style context is associated with the frame via a reference because it is michael@0: needed for many other computations during the formatting of the frames.
michael@0:
michael@0: Once a frame is created for a content element, it must be formatted. We refer michael@0: to this as 'laying out' the frame, or as 'reflowing' the frame. Each frame michael@0: implements a Reflow method to compute its position and size, among other michael@0: things. For more details on the Reflow mechanism, see the Reflow Overview michael@0: document...  The CSS formatting requirements present two distinct layout michael@0: models: 1) the in-flow model, where the geometry of an element is influenced michael@0: by the geometry of the elements that precede it, and 2) the positioned model, michael@0: where the geometry of an element is not influenced by the geometry of the michael@0: elements that precede it, or in any case, is influenced more locally. The michael@0: in-flow cased is considered the 'normal' case, and corresponds to normal michael@0: HTML formatting. The later case, called 'out of flow' puts the document author michael@0: in control of the layout, and the author must specify the locations and sizes michael@0: of all of the elements that are positioned. There is, of course, some complexity michael@0: involved with managing these two models simultanelusly...
michael@0:
michael@0: So far the general flow of layout looks like this:
michael@0:
michael@0: 1) Obtain a document's content model
michael@0: 2) Utilize the Style System to resolve the style of each element in the content michael@0: model
michael@0: 3) Construct the frames that correspond to the content model, according to michael@0: the resolved style data.
michael@0: 4) Perform the initial layout, or initial reflow, on the newly constructed michael@0: frame.
michael@0:
michael@0: This is pretty straight-forward, but is complicated somewhat by the notion michael@0: of incrementalism. One of the goals of the Layout system's design michael@0: is to create parts of the presentation as they become available, rather than michael@0: waiting for the entire document to be read, parsed, and then presented. This michael@0: is a major benefit for large documents because the user does not have to wait michael@0: for the 200th page of text to be read in before the first page can be displayed michael@0: - they can start reading something right away. So really, this sequence of michael@0: operations Resolve Style, Create Frame, Layout Frame, gets repeated many michael@0: times as the content becomes available. In the normal in-flow case this is michael@0: quite natural because the sequential addition of new content results in sequential michael@0: addition of new frames, and because everything is in-flow, the new frames michael@0: do not influence the geometry of the frames that have already been formatted. michael@0: When out-of-flow frames are present this is a more difficult problem, however. michael@0: Sometimes a content element comes in incrementally, and invalidates the formatting michael@0: of some of the frames that precede it, frame that have already been formatted. michael@0: In this case the Layout System has to detect that impact and reflow again michael@0: the impacted frames. This is referred to as an incremental reflow.
michael@0:
michael@0: Another responsibility of layout is to manage michael@0: dynamic changes to the content model, changes that occur after the document michael@0: has been loaded and (possibly) presented. These dynamic changes are caused michael@0: by manipulations of the content model via the DOM (generally michael@0: through java script). When a content element is modified, added or removed, michael@0: Layout is notified. If content elements have been inserted, new frames are michael@0: created and formatted (and impacts to other frames are managed by performing michael@0: further incremental reflows). If content is removed, the corresponding frames michael@0: are destroyed (again, impacts to other elements are managed). If a content michael@0: element is modified, layout must determine if the chage influences the formatting michael@0: of that or other elements' presentations, and must then reformat, or re-reflow, michael@0: the impacted elements. In all cases, the determination of the impact is critical michael@0: to avoid either the problem of not updating impacted elements, thus presenting michael@0: an invalid presentation, or updating too much of the presentation and thus michael@0: doing too much work, potentially causing performance problems.
michael@0:
michael@0: One very special case of dynamic content manipulation is the HTML Editor. michael@0: Layout is used to implement both a full-blown WYSIWYG HTML editor, and a single michael@0: and multi-line text entry control. In both cases, the content is manipulated michael@0: by the user (via the DOM) and the resulting visual impacts must be shown as michael@0: quickly as possible, without disconcerting flicker or other artifacts that michael@0: might bother the user. Consider a text entry field: the user types text into michael@0: a form on the web. As the user types a new character it is inserted into michael@0: the content model. This causes layout to be notified that a new piece of michael@0: content has been entered, which causes Layout to create a new frame and format michael@0: it. This must happen very fast, so the user's typing is not delayed. In the michael@0: case of the WYSIWYG HTML editor, the user expects that the modifications michael@0: they make to the document will apear immediately, not seconds later. This michael@0: is especially critical when the user is typing into the document: it would michael@0: be quite unusable if typing a character at the end of a document in the HTML michael@0: editor caused the entire document to be reformated - it would be too slow, michael@0: at least on low-end machines. Thus the HTML editor and text controls put michael@0: considerable performance requirements on the layout system's handling of dynamic michael@0: content manipulation.
michael@0:

The Fundamentals of Frames: Block and Line

michael@0: There are many types of frames that are designed to model various formatting michael@0: requirements of different HTML and XML elements. CSS2 defines several (block, michael@0: inline, list-item, marker, run-in, compact, and various table types) and michael@0: the standard HTML form controls require their own special frame types to michael@0: be formatted as expected. The most essential frame types are Block and Inline, michael@0: and these correspond to the most important Layout concepts, the Block and michael@0: Line.
michael@0:
michael@0: A block is a rectangular region that is composed of one or more lines. A michael@0: line is a single row of text or other presentational elements. All layout michael@0: happens in the context of a block, and all of the contents of a block are michael@0: formatted into lines within that block. As the width of a block is changed, michael@0: the contents of the lines must be reformatted. consider for example a large michael@0: paragraph of text sitting in paragraph:
michael@0:
michael@0:
<p>
We need documentation for users, web developers, and developers working michael@0: on Mozilla. If you write your own code, document it. Much of the michael@0: existing code <b>isn’t very well documented</b>. In the process of figuring michael@0: things out, try and document your discoveries. michael@0: If you’d like to contribute, let us know.
</p>
michael@0: There is one block that corresponds to the <p> element, and then a number michael@0: of lines of text that correspond to the text. As the width of the block changes michael@0: (due to the window being resized, for example) the length of the lines within michael@0: it changes, and thus more or less text appears on each line. The block is michael@0: responsible for managing the lines. Note that lines may contain only inline michael@0: elements, whereas block may contain both inline elements and other blocks.
michael@0:

Other Layout Models: XUL

michael@0: In addition to managing CSS-defined formatting, the layout system provides michael@0: a way to integrate other layout schemes into the presentation. Currently michael@0: layout supports the formatting of XUL elements, which utilize a constraint-based michael@0: layout language. The Box is introduced into the layout system's frame model michael@0: via an adapter (BoxToBlockAdapter) that translates the normal layout model michael@0: into the box formatting model. Conceptually, this could be used to introduce michael@0: other layout systems, but it might be worth noting that there was no specific michael@0: facility designed into the layout system to accommodate this. Layout deals michael@0: with frames, but as long as the layout system being considered has no need michael@0: to influence presentational elements from other layout systems, it can be michael@0: adapted using a frame-based adapter, ala XUL.
michael@0:
michael@0:

Core Classes

michael@0: At the highest level, the layout system is a group of classes that manages michael@0: the presentation within a fixed width and either unlimited height (galley michael@0: presentation) or discrete page heights (paged presentation). Digging just michael@0: a tiny bit deeper into the system we find that the complexity (and interest) michael@0: mushrooms very rapidly. The idea of formatting text and graphics to fit within michael@0: a given screen area sounds simple, but the interaction of in-flow and out-of-flow michael@0: elements, the considerations of incremental page rendering, and the performance michael@0: concerns of dynamic content changes makes for a system that has a lot of michael@0: work to do, and a lot of data to manage. Here are the high-level classes michael@0: that make up the layout system. Of course this is a small percentage of the michael@0: total clases in layout (see the detailed design documents for the details michael@0: on all of the classes, in the context of their actual role).
michael@0:

Presentation Shell / Presentation Context

michael@0: Together the presentation shell and the presentation context provide the michael@0: root of the current presentation. The original design provided for a single michael@0: Presentation Shell to manage multiple Presentation Contexts, to allow a single michael@0: shell to handle multiple presentations. It is unclear if this is really possible, michael@0: however, and in general it is assumed that there is a one-to-one correspondence michael@0: between a presentation shell and a presentation context. The two classes michael@0: should probably be folded into one, or the distinction between them formalized michael@0: and utilized in the code. The Presentation Shell currently owns a controlling michael@0: reference to the Presentation Context. Further references to the Presentation michael@0: Shell and Presentation Context will be made by using the term Presentation michael@0: Shell.
michael@0:
michael@0: The Presentation Shell is the root of the presentation, and as such it owns michael@0: and manges a lot of layout objects that are used to create and maintain a michael@0: presentation (note that the DocumentViewer is the owner michael@0: of the Presentation Shell, and in some cases the creator of the objects michael@0: used by the Presentation Shell to manage the presentation. More details michael@0: of the Document Viewer are needed here...). The Presentation Shell, michael@0: or PresShell, is first and foremost the owner of the formatting objects, michael@0: the frames. Management of the frames is facilitated by the Frame Manager, michael@0: an instance of which the PresShell owns. Additionally, the PresShell provides michael@0: a specialized storage heap for frames, called an Arena, that is used to make michael@0: allocation and deallocation of frames faster and less likely to fragment michael@0: the global heap.
michael@0:
michael@0: The Presentation Shell also owns the root of the Style System, the Style michael@0: Set. In many cases the Presentation Shell provides pass-through methods to michael@0: the Style Set, and generally uses the Style Set to do style resolution and michael@0: Style Sheet management.
michael@0:
michael@0: One of the critical aspects of the Presentation Shell is the handling of michael@0: frame formatting, or reflow. The Presentation Shell owns and maintains a michael@0: Reflow Queue where requests for reflow are held until it is time to perform michael@0: a reflow, and then pulled out and executed.
michael@0:
michael@0: It is also important to see the Presentation Shell as an observer of many michael@0: kinds of events in the system. For example, the Presentation Shell receives michael@0: notifications of document load events, which are used to trigger updates michael@0: to the formatting of the frames in some cases. The Presentation Shell also michael@0: receives notifications about changes in cursor and focus states, whereby michael@0: the selection and caret updates can be made visible.
michael@0:
michael@0: There are dozens of other data objects managed by the Presentation Shell michael@0: and Presentation Context, all necessary for the internal implementation. michael@0: These data members and their roles will be discussed in the Presentation michael@0: Shell design documents. For this overview, the Frames, Style Set, and Reflow michael@0: Queue are the most important high-level parts of the Presentation Shell.
michael@0:

Frame Manager

michael@0: The Frame Manager is used to, well, manage frames. Frames are basic formatting michael@0: objects used in layout, and the Frame Manager is responsible for making frames michael@0: available to clients. There are several collections of frames maintained michael@0: by the Frame Manager. The most basic is a list of all of the frames starting michael@0: at the root frame. Clients generally do not want to incur the expense of michael@0: traversing all of the frames from the root to find the frame they are interested michael@0: in, so the Frame Manager provides some other mappings based on the needs of michael@0: the clients.
michael@0:
michael@0: The most crucial mapping is the Primary Frame Map. This collection provides michael@0: access to a frame that is designated as the primary frame for a piece of michael@0: content. When a frame is created for a piece of content, it may be the 'primary michael@0: frame' for that content element (content elements that require multiple michael@0: frames have primary and secondary frames; only the primary frame is mapped). michael@0: The Frame Manager is then instructed to store the mapping from a content michael@0: element to the primary frame. This mapping facilitates updates to frames michael@0: that result in changes to content (see discussion michael@0: above).
michael@0:
michael@0: Another important mapping maintained by the Frame Manager is that of the michael@0: undisplayed content. When a content element is defined as having no display michael@0: (via the CSS property 'display:none') it is noted by a special entry in the michael@0: undisplayed map. This is important because no frame is generated for these michael@0: elements yet changes to their style values and to the content elements still michael@0: need to be handled by layout, in case their display state changes from 'none' michael@0: to something else. The Undisplayed Map keeps track of all content and style michael@0: data for elements that currently have no frames. (note: michael@0: the original architecture of the layout system included the creation of frames michael@0: for elements with no display. This changed somewhere along the line, but michael@0: there is no indication of why the change was made. Presumably it is more michael@0: time and space-efficient to prevent frame creation for elements with no display.)
michael@0:
michael@0: The Frame Manager also maintains a list of Forms and Form Controls, as content michael@0: nodes. This is presumably related to the fact that layout is responsible michael@0: for form submission, but this is a design flaw that is being corrected by michael@0: moving form submission into the content world. These collections of Forms michael@0: and Form Controls should be removed eventually.
michael@0:
michael@0:

CSS Frame Constructor

michael@0: The Frame Constructor is responsible for resolving style values for content michael@0: elements and creating the appropriate frames corresponding to that element. michael@0: In addition to managing the creation of frames, the Frame Constructor is michael@0: responsible for managing changes to the frames. Frame Construction is generally michael@0: achieved by the use of stateless methods, but in some cases there is the michael@0: need to provide context to frames created as children of a container. The michael@0: Frame Manager uses the Frame Constructor State class to manage the important michael@0: information about the container of a frame being created (and lots of other state-stuff too - need to describe more michael@0: fully).
michael@0:

Frame

michael@0: The Frame is the most fundamental layout object. The class nsFrame is the michael@0: base class for all frames, and it inherits from the base class nsIFrame (note: michael@0: nsIFrame is NOT an interface, it is an abstract base class. It was once an michael@0: interface but was changed to be a base class when the Style System was modified michael@0: - the name was not changed to reflect that it is not an interface). The Frame michael@0: provides generic functionality that can be used by subclasses but cannot michael@0: itself be instantiated.
michael@0:
michael@0: nsFrame:
michael@0: The Frame provides a mechanism to navigate to a parent frame as well as child michael@0: frames. All frames have a parent except for the root frame. The Frame is michael@0: able to provide a reference to its parent and to its children upon request. michael@0: The basic data that all frames maintain include: a rectangle describing the michael@0: dimensions of the frame, a pointer to the content that the frame is representing, michael@0: the style context representing all of the stylistic data corresponding to michael@0: the frame, a parent frame pointer, a sibling frame pointer, and a series michael@0: of state bits.
michael@0:
michael@0: Frames are chained primarily by the sibling links. Given a frame, one can michael@0: walk the sibling of that frame, and can also navigate back up to the parent michael@0: frame. Specializations of the frame also allow for the management of child michael@0: frames; this functionality is provided by the Container Frame.
michael@0:
michael@0: Container Frames:
michael@0: The Container Frame is a specialization of the base frame class that introduces michael@0: the ability to manage a list of child frames. All frames that need to manage michael@0: child frames (e.g. frames that are not themselves leaf frames) derive from michael@0: Container Frame.
michael@0:
michael@0:
michael@0:
michael@0:

Block Frame
michael@0:

michael@0:

Reflow State

michael@0:

Reflow Metrics
michael@0:

michael@0:

Space Manager
michael@0:

michael@0:

StyleSet

michael@0:

StyleContext

michael@0:
michael@0:
michael@0:

michael@0: Document History:
michael@0:
michael@0: michael@0: michael@0: