зеркало из https://github.com/mozilla/gecko-dev.git
Very High Level (tm) Layout Documentation. Work In Progress, not part of any build or product. Cheers, mates!
This commit is contained in:
Родитель
9dd700b9b8
Коммит
eb023e0217
|
@ -0,0 +1,350 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Layout Overview</title>
|
||||
<meta http-equiv="content-type"
|
||||
content="text/html; charset=ISO-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Layout System Overview</h1>
|
||||
<br>
|
||||
<h3>Layout's Job: Provide the Presentation</h3>
|
||||
Layout is primarly concerned with providing a presentation to an HTML or
|
||||
XML document. This presentation is typically formatted in accordance with
|
||||
the requirements of the <a href="http://www.w3.org/TR/REC-CSS1">CSS1</a>
|
||||
and <a href="http://www.w3.org/TR/REC-CSS2/">CSS2</a> specifications from
|
||||
the W3C. Presentation formatting is also required to provide compatibility
|
||||
with legacy browsers (Microsoft Internet Exploroe and Netscape Navigator
|
||||
4.x). The decision about when to apply CSS-specified formatting and when
|
||||
to apply legacy formatting is controlled by the document's DOCTYPE specification.
|
||||
These layout modes are refered to as 'Standards' and 'NavQuirks' modes. (DOCTYPE
|
||||
and modes are explained in more detail <a
|
||||
href="http://www.mozilla.org/quality/help/bugzilla-helper.html">here</a>).<br>
|
||||
<br>
|
||||
The presentation generally is constrained the width of the window in which
|
||||
the presentation is to be displayed, and a height that extends as far as
|
||||
necessary. This is referred to as the Galley Mode presentation, and is what
|
||||
one expects from a typical browser. Additionally, layout must support a paginated
|
||||
presentation, where the width of the presentation is constrained by the dimensions
|
||||
of the printed output (paper) and the height of each page is fixed. This
|
||||
paged presentation presents several challenges not present in the galley
|
||||
presentation, namely how to break up elements that are larger than a single
|
||||
page, and how to handle changes to page dimensions.<br>
|
||||
<br>
|
||||
The original design of the Layout system allowed for multiple, possibly different,
|
||||
presentations to be supported simoultaneously from the same scontent model.
|
||||
In other words, the same HTML or XML document could be viewed as a normal
|
||||
galley presentation in a browser window, while simoultaneously being presented
|
||||
in a paged presentation to a printer, or even an aural presentation to a
|
||||
speach-synthesiser. To date the only real use of this multiple presentation
|
||||
ability is seen in printing, where multiple presentations are managed, all
|
||||
connected to the same content model. (note: it is unclear if this is really
|
||||
a benefit - it may have been better to use a copy of the content model for
|
||||
each presentation, and to remove the complexity of managing seperate presentations
|
||||
- analysis is needed here). The idea of supporting a non-visual presentation
|
||||
is interesting. Layout's support for aural presentations is undeveloped,
|
||||
though conceptually, it is possible and supported by the architecture.<br>
|
||||
<br>
|
||||
<h3>How Layout Does its Job: Frames and Reflow</h3>
|
||||
So, layout is concerned with providing a presentation, in galley or paged
|
||||
mode. Given a content model, how does the layout system actually create the
|
||||
presentation? Through the creation and management of frames. Frames are an
|
||||
encapsulation of a region on the screen, a region that contains geometry
|
||||
(size and location, stacking order). Generally frames correspond to the content
|
||||
elements, though there is often a one-to-many correspondence between content
|
||||
elements and frames. Layout creates frames for content based on either the
|
||||
specific HTML rules for an element or based ont he CSS display type of the
|
||||
element. In the case of the HTML-specific elements, the frame types that
|
||||
correspond to the element are hard-coded, but in the more general case where
|
||||
the display type is needes, the layout system must determine that display
|
||||
type by using the Style System. A content element is passed to the Style
|
||||
System and a request is made to resolve the style for that element. This
|
||||
causes the Style System to apply all style rules that correspond to the element
|
||||
and results in a resolved Style Context - the style data specific to that
|
||||
element. The Layout module looks at the 'display' field of the style context
|
||||
to determine what kind of frame to create (block, inline, table, etc.). The
|
||||
style context is associated with the frame via a reference becuase it is
|
||||
needed for many other computations during the formatting of the frames.<br>
|
||||
<br>
|
||||
Once a frame is created for a content element, it must be formatted. We refer
|
||||
to this as 'laying out' the frame, or as 'reflowing' the frame. Each frame
|
||||
implements a Reflow method to compute its position and size, among other
|
||||
things. For more details on the Reflow mechanism, see the Reflow Overview
|
||||
document... The CSS formatting requirements present two distinct layout
|
||||
models: 1) the in-flow model, where the geometry of an element is influenced
|
||||
by the geometry of the elemtns that preceed it, and 2) the positioned model,
|
||||
where the geometry of an element is not influenced by the geometry of the
|
||||
elements that preceed it, or in any case, is influenced more locally. The
|
||||
in-flow cased is considered the 'normal' case, and corresponds to normal
|
||||
HTML formatting. The later case, called 'out of flow' puts the document author
|
||||
in control of the layout, and the author must specify the locations and sizes
|
||||
of all of the elements that are positioned. There is, of course, some complexity
|
||||
inviolved with manageing these two models simoultanelusly...<br>
|
||||
<br>
|
||||
So far the general flow of layout looks like this:<br>
|
||||
<br>
|
||||
1) Obtain a document's content model<br>
|
||||
2) Utilize the Style System to resolve the style of each element in the content
|
||||
model<br>
|
||||
3) Construct the frames that correspond to the content model, according to
|
||||
the resolved style data.<br>
|
||||
4) Perform the initial layout, or initial reflow, on the newly constructed
|
||||
frame.<br>
|
||||
<br>
|
||||
This is pretty straight-forward, but is complicated somewhat by the notion
|
||||
of <i>incrementalism</i>. One of the goals of the Layout system's design
|
||||
is to create parts of the presentation as they become available, rather than
|
||||
waiting for the entire document to be read, parsed, and then presented. This
|
||||
is a major beneft for large documents because the user does not have to wait
|
||||
for the 200th page of text to be read in before the first page can be displayed
|
||||
- they can start reading something right away. So really, this sequence of
|
||||
operations Resolve Style, Create Frame, Layout Frame, gets repeated many
|
||||
times as the content becomes available. In the normal in-flow case this is
|
||||
quite natural because the sequential addition of new content results in sequential
|
||||
addition of new frames, and because everything is in-flow, the new frames
|
||||
do not influence the geometry of the frames that have already been formatted.
|
||||
When out-of-flow frames are present this is a more difficult problem, however.
|
||||
Sometimes a content element comes in incrementally, and invalidates the formatting
|
||||
of some of the frames that preceed it, frame that have already been formatted.
|
||||
In this case the Layout System has to detect that impact and reflow again
|
||||
the impacted frames. This is referred to as an <i>incremental reflow</i>.<br>
|
||||
<br>
|
||||
<a name="DHTML_interaction"></a>Another responsibility of layout is to manage
|
||||
dynamic changes to the content model, changes that occur after the document
|
||||
has been loaded and (possibly) presented. These dynamic changes are caused
|
||||
by manipulations of the content model via the <acronym
|
||||
title="Document Object Model">DOM<acronym></acronym></acronym> (generally
|
||||
through java script). When a content element is modified, added or removed,
|
||||
Layout is notified. If a content elements have been inserted, new frames
|
||||
are created and formatted (and impacts to other frames are managed by performing
|
||||
further incremental reflows). If content is removed, the corresponding frames
|
||||
are destroyed (again, impacts to other elements are managed). If a content
|
||||
element is modified, layout must determine if the chage influences the formatting
|
||||
of that or other elements' presentations, and must then reformat, or re-reflow,
|
||||
the impacted elements. In all cases, the determination of the impact is critical
|
||||
to avoid either the problem of not updating impacted elements, thus presenting
|
||||
an invalid presentation, or updating too much of the presentation and thus
|
||||
doing too much work, potentially causing performance problems.<br>
|
||||
<br>
|
||||
One very special case of dynamic content manipulation is the HTML Editor.
|
||||
Layout is used to implment both a full-blown WYSIWYG HTML editor, and a single
|
||||
and multi-line text entry control. In both cases, the content is manipulated
|
||||
by the user (via the DOM) and the resulting visual impacts must be show as
|
||||
quickly as possible, without disconcerting flicker or other artifacts that
|
||||
might bother the user. Consider a text entry field: the user types text into
|
||||
a form on the web. As the user types a new character it is inserted into
|
||||
the content model. This causes layout to be notified that a new piece of
|
||||
content has been entered, which causes Layout to create a new frame ad format
|
||||
it. This must happen very fast, so the user's typing is not delayed. In the
|
||||
case of the WYSIWYG HTML editor, the user expects that the modifications
|
||||
they make to the document will apear immediatly, not seconds later. This
|
||||
is especially critical when the user is typing into the document: it would
|
||||
be quite unusable if typing a character at the end of a document in the HTML
|
||||
editor caused the entire document to be reformated - it would be too slow,
|
||||
at least on low-end machines. thus the HTML editor and text controls put
|
||||
considerable performance requireents ont he layout system's handling of dynamic
|
||||
content manipulation.<br>
|
||||
<h3>The Fundamentals of Frames: Block and Line</h3>
|
||||
There are many types of frames that are desiged to model various formatting
|
||||
requirements of different HTML and XML elements. CSS2 defines several (block,
|
||||
inline, list-item, marker, run-in, compact, and various table types) and
|
||||
the standard HTML form controls require their own special frame types to
|
||||
be formated as expected. The most essential frame types are Block and Inline,
|
||||
and these correspond to the most important Layout concepts, the Block and
|
||||
Line.<br>
|
||||
<br>
|
||||
A block is a rectangular region that is composed of one or more lines. A
|
||||
line is a single row of text or other presentational elements. All layout
|
||||
happens in the context of a block, and all of the contents of a block are
|
||||
formatted into lines within that block. As the width of a block is changed,
|
||||
the contents of the lines must be reformatted. consider for example a large
|
||||
paragraph of text sitting in paragraph:<br>
|
||||
<br>
|
||||
<pre><p><br> We need documentation for users, web developers, and developers working
|
||||
on Mozilla. If you write your own code, document it. Much of the
|
||||
existing code <b>isn’t very well documented</b>. In the process of figuring
|
||||
things out, try and document your discoveries.
|
||||
If you’d like to contribute, let us know.<br></p></pre>
|
||||
There is one block that corresponds to the <p> element, ad then a number
|
||||
of lines of text that correspond to the text. As the width of the block changes
|
||||
(due to the window being resized, for example) the length of the lines within
|
||||
it changes, and thus more or less text appears on each line. The block is
|
||||
responsible for managing the lines. Note that lines may contain only inline
|
||||
elements, whereas block may contain both inline elements and other blocks.<br>
|
||||
<h3>Other Layout Models: XUL</h3>
|
||||
In addition to managing CSS-defined formatting, the layout system provides
|
||||
a way to integrate other layout schemes into the presentation. Currently
|
||||
layout supports the formatting of XUL elements, which utilize a constraint-based
|
||||
layout language. the Box is introduced into the layout system's frame model
|
||||
via an adapter (BoxToBlockAdapter) that translates the normal layout model
|
||||
into the box formatting model. Conceptually, this could be used to introduce
|
||||
other layout systems, but it might be worth noting that there was no specific
|
||||
facility designed into the layout system to accommodate this. Layout deals
|
||||
with frames, but as long as the layout system being considered has no need
|
||||
to influence presentational elements from other layout systems, it can be
|
||||
adapted using a frame-based adapter, ala XUL.<br>
|
||||
<br>
|
||||
<h2>Core Classes</h2>
|
||||
At the highest level, the layout system is a group of classes that manages
|
||||
the presentation within a fixed width and either unlimited height (galley
|
||||
presentation) or discrete page heights (paged presentation). Digging just
|
||||
a tiny bit deaper into the system we find that the complexity (and interest)
|
||||
mushrooms very rapidly. The idea of formatting text and graphics to fit within
|
||||
a given screen area sounds simple, but the interaction of in-flow and out-of-flow
|
||||
elements, the considerations of incremental page rendering, and the performance
|
||||
concerns of dynamic content changes makes for a system that has a lot of
|
||||
work to do, and a lot of data to manage. Here are the high-level classes
|
||||
that make up the layout system. Of course this is a small percentage of the
|
||||
total clases in layout (see the detailed design documents for the details
|
||||
on all of the classes, in the context of their actual role).<br>
|
||||
<h3>Presentation Shell / Presentation Context</h3>
|
||||
Together the presentation shell and the presentation context provide the
|
||||
root of the current presentation. The original design provided for a single
|
||||
Presentation Shell to manage multiple Presentation Contexts, to allow a single
|
||||
shell to handle multiple presentations. It is unclear if this is really possible,
|
||||
however, and in general iot is assumed that there is a one-to-one correspondence
|
||||
between a presentation shell and a presentation context. The two classes
|
||||
should probably be folded into one, or the distinction between them formalized
|
||||
and utilized in the code. The Presentation Shell currently owns a controlling
|
||||
reference to the Presentation Context. Further references to the Presentation
|
||||
Shell and Presentation Context will be made by using the term Presentation
|
||||
Shell.<br>
|
||||
<br>
|
||||
The Presentation Shell is the root of the presentation, and as such it owns
|
||||
and manges a lot of layout objects that are used to create and maintain a
|
||||
presentation (<font color="#990000">note that the DocumentViewer is the owner
|
||||
of the Presentation Shell, and in some cases the creator of the objkects
|
||||
used by the pPresentation Shell to manage the presentation. More details
|
||||
of the Document Viewer are needed here...</font>). The Presentation Shell,
|
||||
or PresShell, is first and foremost the owner of the formatting objects,
|
||||
the frames. Management of the frames is facilitated by the Frame Manager,
|
||||
an instance of which the PresShell owns. Additionally, the PresShell provides
|
||||
a specialized storage heap for frames, called an Arena, that is used to make
|
||||
allocation and deallocation of frames faster and less likely to fragment
|
||||
the global heap. <br>
|
||||
<br>
|
||||
The Presentation Shell also owns the root of the Style System, the Style
|
||||
Set. In many cases the Presentation Shell provides pass-through methods to
|
||||
the Style Set, and generally uses the Style Set to do style resolution and
|
||||
Style Sheet management.<br>
|
||||
<br>
|
||||
One of the critical aspects of the Presentation Shell is the handling of
|
||||
frame formatting, or reflow. The Presentation Shell owns and maintains a
|
||||
Reflow Queue where requests for reflow are held until it is time to perform
|
||||
a reflow, and then pulled out and executed.<br>
|
||||
<br>
|
||||
It is also important to see the Presentation Shell as an observer of many
|
||||
kinds of events in the system. For example, the Presentation Shell receives
|
||||
notifications of document load events, which are used to trigger updates
|
||||
to the formatting of the frames in some cases. The Presentation Shell also
|
||||
receives notifications about changes in cursor and focus states, whereby
|
||||
the selection and carat updates can be made visible.<br>
|
||||
<br>
|
||||
There are dozens of other data objects managed by the Presentation Shell
|
||||
and Presentation Context, all necessary for the internal implementation.
|
||||
These data members and their roles will be discussed in the Presentation
|
||||
Shell design documents. For this overview, the Frames, Style Set, and Reflow
|
||||
Queue are the most important high-level parts of the Presentation Shell.<br>
|
||||
<h3>Frame Manager</h3>
|
||||
The Frame Manager is used to, well, manage frames. Frames are to basic formatting
|
||||
objects used in layout, and the Frame Manager is responsible for making frames
|
||||
available to clients. There are several collections of frames maintained
|
||||
by the Frame Manager. The most basic is a list of all of the frames starting
|
||||
at the root frame. Clients generally do not want to incur the expense of
|
||||
traversing all of the frames from the root to find the frame they are interested
|
||||
in, so the Frame Manger provides some other mappings based on the needs of
|
||||
the clients.<br>
|
||||
<br>
|
||||
The most crucial mapping is the Prinmary Frame Map. This collection provides
|
||||
access to a frame that is designated as the primary frame for a piece of
|
||||
content. When a frame is created for a piece of content, it may be the 'primary
|
||||
frame' for that copntent element (content elements that require multiple
|
||||
frames have primary and secondary frames; only the primary frame is mapped).
|
||||
The Frame Manager is then instructed to store the mapping from a content
|
||||
element to the primary frame. This mapping facilitates updates to frames
|
||||
that result in changes to content (see <a href="#DHTML_interaction">discussion
|
||||
above</a>).<br>
|
||||
<br>
|
||||
Another important mapping maintained by the Frame Manager is that of the
|
||||
undisplayed content. When a content element is defined as having no display
|
||||
(via the CSS property 'display:none') it is noted by a special entry in the
|
||||
undisplayed map. This is important because no frame is generated for these
|
||||
elements yet changes to their style values and to the content elements still
|
||||
need to be handled by layout, in case their display state changes from 'none'
|
||||
to something elsed. The Undisplayed Map keeps track of all content and style
|
||||
data for elements that currently have no frames. (<font color="#990000">note:
|
||||
the original architecture of the layout system included the creation of frames
|
||||
for elements with no display. This changed somewhere along the line, but
|
||||
there is no indication of why the change was made. Presumably it is more
|
||||
time and space-efficient to prevent frame creation for elements with no display.)</font><br>
|
||||
<br>
|
||||
The Frame Manager also maintains a list of Forms and Form Controls, as <i>content
|
||||
nodes</i>. This is presumably related to the fact that layout is responsible
|
||||
for form submission, but this is a design flaw that is being corrected by
|
||||
moving form submission into the content world. These collections of Forms
|
||||
and Form Controls should be removed eventually.<br>
|
||||
<br>
|
||||
<h3>CSS Frame Constructor</h3>
|
||||
The Frame Constructor is responsible for resolving style values for content
|
||||
elements and creating the appropriate frames corresponding to that element.
|
||||
In addition to managing the creation of frames, the Frame Constructor is
|
||||
responsible for managing changes to the frames. Frame Construction is generally
|
||||
achieved by the use of stateless methods, but in some cases there is the
|
||||
need to provide context to frames created as children of a container. Ther
|
||||
Frame Manager uses the Frame Constructor State class to manage the important
|
||||
information about the container of a frame being created (<font
|
||||
color="#990000">and lots of other state-stuff too - need to describe more
|
||||
fully</font>).<br>
|
||||
<h3>Frame</h3>
|
||||
The Frame is the most fundamental layout object. The class nsFrame is the
|
||||
base class for all frames, and it inherits fromthe base class nsIFrame (note:
|
||||
nsIFrame is NOT an interface, it is an abstract base class. It was once an
|
||||
interface but was changed to be a base class when the Style System was modified
|
||||
- the name was not changed to reflect that it is not an interface). The Frame
|
||||
provides generic functionality that can be used by subclasses but cannot
|
||||
itself be instantiated.<br>
|
||||
<br>
|
||||
nsFrame:<br>
|
||||
The Frame provides a mechanism to navigate to a parent frame as well as child
|
||||
frames. All frames have a parent except for the root frame. The Frame is
|
||||
able to provide a reference to its parent and to its children upon request.
|
||||
The basic data that all frames maintain include: a rectangle describing the
|
||||
dimensions opf the frame, a pointer to the content that the frame is representing,
|
||||
the style context representing all of the stylistic data corresponding to
|
||||
the frame, a parent frame pointer, a sibling frame pointer, and a series
|
||||
of state bits.<br>
|
||||
<br>
|
||||
Frames are chained primarily by the sibling links. Given a frame, one can
|
||||
walk the sibling of that frame, and can also navigate back up to the parent
|
||||
frame. Specializations of the frame also allow for the management of child
|
||||
frames; this functionality is provided by the Container Frame.<br>
|
||||
<br>
|
||||
Container Frames:<br>
|
||||
The Containerr Frame is a specialization of the base frame class that introduces
|
||||
the ability to manage a list of child frames. All frames that need to manage
|
||||
child frames (e.g. frames that are not thenselves leaf frames) derive fdrom
|
||||
Container Frame.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Block Frame<br>
|
||||
</h3>
|
||||
<h3>Reflow State</h3>
|
||||
<h3>Reflow Metrics<br>
|
||||
</h3>
|
||||
<h3>Space Manager<br>
|
||||
</h3>
|
||||
<h3>StyleSet</h3>
|
||||
<h3>StyleContext</h3>
|
||||
<br>
|
||||
<br>
|
||||
<hr width="100%" size="2"><br>
|
||||
<b>Document History:<br>
|
||||
</b>
|
||||
<ul>
|
||||
<li>05/20/2002 - Marc Attinasi: created, wrote highest level intorduction
|
||||
to general layout concepts, links to relevant specs and existing documents.<br>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче