Introduction to Layout in Mozilla 编辑
Overview
- Basic data flow
- Key data structures
- Detailed walk-through
- Incrementalism
- Future tech-talks
- Wrap-up, Q&A
Basic Data Flow
- Source document arrives via network APIs
- Incrementally “pumped” through the single-threaded layout engine
- Parse, compute style, render; repeat
- CSS used for rendering all content
- Content theoretically separate from “presentation”
Key Data Structures
- Content node
- Elements, attributes, leaves
- DOM
- Frame
- Rectangular formatting primitive
- Geometric information
- [0..n] per content node
- 2nd thru nth are “continuations”
- Style context
- Non-geometric information
- May be shared by adjacent frames
- Reference counted, owned by frame
- View
- Clipping, z-order, transparency
- [0..1] per frame, owned by frame
- Widget
- Native window
- [0..1] per view, owned by view
Key Data Structures
- The document owns the content model, and one or more presentations
- Exposed programmatically via DOM APIs
- The presentation owns the frame hierarchy
- Frames own the style contexts, views, widgets
- Presentation has media type, dimensions, etc.
- May not be directly manipulated
Detailed Walk-Through
- Setting up
- Content model construction
- Frame construction
- Style resolution
- Reflow
- Painting
Setting Up
- Assume basic knowledge of embedding and network APIs (doc shell, streams)
- Content DLL auto-registers a Document Loader Factory (DLF)
@mozilla.org/content-viewer-factory/view;1?type=text/html
- All MIME types mapped to the same class, nsContentDLF
nsDocShell
- Receives inbound content via
nsDSURIContentListener
- Invokes
nsIDLF::CreateInstance
, passes MIME type to DLF
- Receives inbound content via
- nsContentDLF
- Creates a
nsHTMLDocument
object, invokesStartDocumentLoad
.- Creates a parser, returned as
nsIStreamListener
back to the docshell - Creates a content sink, which is linked to the parser and the document
- Creates a parser, returned as
- Creates a
DocumentViewerImpl
object, which is returned asnsIContentViewer
back to the docshell
- Creates a
DocumentViewerImpl
creates pres context and pres shell
Content Model Construction
- Content arrives from network via
nsIStreamListener::OnDataAvailable
- Parser tokenizes & processes content; invokes methods on
nsIContentSink
with parser node objects- Some buffering and fixup occurs here
OpenContainer
,CloseContainer
,AddLeaf
- Content sink creates and attaches content nodes using
nsIContent
interface- Content sink maintains stack of “live” elements
- More buffering and fixup occurs here
InsertChildAt
,AppendChildTo
,RemoveChildAt
Frame Construction
- Content sink uses
nsIDocument
interface to notify of Δs in content modelContentAppended
,ContentInserted
,ContentRemoved
PresShell
is registered as document observer- Receives
ContentAppended
, etc. notifications - Passes these to the style set object, who in turn passes to the frame constructor
- Receives
- Frame constructor creates frames
ConstructFrameInternal
recursively walks content tree, resolves style and creates frames- Either created by tag (
<select>
) or by display type (<p>
)
- Frame manager maintains mapping from content to frame
Style Resolution
- Compute stylistic information based on the style rules that apply for the frame’s content node
- Style data broken into different structures
- Display, visibility, font, color, background, …
- Inherit vs. reset
- Style context object is a placeholder for partially computed stylistic data
- Style data is computed lazily, as it is asked for
Reflow
- Recursively compute geometry (x, y, w, h) for frames, views, and widgets
- Given w & h constraints of “root frame” compute (x, y, w, h) for all children
- Constraints propagated “down” via
nsHTMLReflowState
- Desired size returned “up” via
nsHTMLReflowMetrics
- Basic pattern
- Parent frame initializes child reflow state (available w, h); places child frame (x, y); invokes child’s
Reflow
method - Child frame computes desired (w, h), returns via reflow metrics
- Parent frame sizes child frame and view based on child’s metrics
- Parent frame initializes child reflow state (available w, h); places child frame (x, y); invokes child’s
- N.B. many don’t work like this! (Tables, blocks, XUL boxes)
Reflow
- “Global” reflows
- Initial, resize, style-change
- Processed immediately via
PresShell
method
- Incremental reflows
- Targeted at a specific frame
- Dirty, content-changed, style-changed, user-defined
nsHTMLReflowCommand
object encapsulates info- Queued and processed asynchronously,
nsIPressShell::AppendReflowCommand
,ProcessReflowCommands
Incremental Reflow
- Recursively descend to target recovering reflow state
- Child rs.reason set to incremental
Incremental Reflow
- Process reflow “normally” at target frame
- Child rs.reason set based on rc’s type
Incremental Reflow
- Propagate damage to frames later “in the flow”
Incremental Reflow
- Multiple reflow commands are batched
nsReflowPath
maintains a tree of target frames- Amortize state recovery and damage propagation cost
Painting
- As reflow proceeds through the frame hierarchy, areas are invalidated via
nsIViewManager::UpdateView
- Unless immediate, invalid areas are coalesced and processed asynchronously via OS expose event
- Native expose event dispatched to widget; widget delegates to the view manager
- View manager paints views back-to-front, invoking
PresShell
’sPaint
method PresShell::Paint
walks from the view to the frame; invokesnsIFrame::Paint
for each layer
Incrementalism
- Single-threaded
- Simple (no locking)
- Can’t leave event queue unattended
- Content construction unwinds “at will”
- Parser and content sink do some buffering
- Content sink has “notification limits”
- Efficiency vs. responsiveness trade-off
- Frame construction runs to completion
- CSS parsing runs to completion
- Reflow runs to completion (mostly)
- Painting runs to completion
Future (?) Tech Talks
- Content model and DOM - jst, jkeiser
- Parser and content sink (esp. invalid content) - harishd
- Events - saari, joki
- Block-and-line reflow - waterson, dbaron
- Table reflow - karnaze
- Form controls - rods, bryner
- Style resolution and rule tree - dbaron
- Views, widgets, and painting - roc, kmcclusk
- Editor - kin, jfrancis
- XUL and box layout - hewitt, ben
- XBL - hewitt, ben
Conclusion
- Data flow
- Key data structures
- Detailed walk-through
- Incrementalism
- Q & A?
Original Document Information
- Author(s): Chris Waterson
- Last Updated Date: June 10, 2002
- Copyright Information: Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | Details.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论