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: - 05/20/2002 - Marc Attinasi: created, wrote highest level introduction
michael@0: to general layout concepts, links to relevant specs and existing documents.
michael@0:
michael@0:
michael@0:
michael@0: