Gecko:Reflow Refactoring: Difference between revisions
| Line 25: | Line 25: | ||
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot checkout <b>-r REFLOW_20050804_BRANCH</b> mozilla/client.mk | cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot checkout <b>-r REFLOW_20050804_BRANCH</b> mozilla/client.mk | ||
Using <code>client.mk</code> is essential because only layout is branched; the rest of the tree is pulled by date. | Using <code>client.mk</code> to pull the rest of the tree is essential because only layout is branched; the rest of the tree is pulled by date. | ||
== Rationale == | == Rationale == | ||
Revision as of 21:05, 5 October 2005
Summary
Reflow refactoring is the name for two related changes currently being worked on mainly by dbaron:
- Change intrinsic width computation so that it happens in separate methods on nsIFrame. (Currently preferred with calculation using the nsIFrame API can happen in two different ways as well: having only one codepath reduces incremental layout ("{inc}") bugs.)
- Change the way we handle incremental layout to use dirty bits on the frames rather than the reflow tree (which is essentially out-of-line dirty bits) and a complicated system of reflow reasons that often leads to weird incremental layout ("{inc}") bugs.
The goals of these changes are:
- simplification of code
- fixing incremental reflow ("{inc}") bugs
- fixing intrinsic sizing bugs
- allowing better integration of nsIBox and nsIFrame layout
- allowing easier implementation of new features like 'inline-block'
Quick Links
- Bug 300030
- Reflow Branch Checkins
- Open bugs with [reflow-refactor] in status whiteboard
- Open bugs with {inc} in summary
Build Instructions
Follow the normal build instructions and get the source from CVS, except when checking out client.mk, use
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot checkout -r REFLOW_20050804_BRANCH mozilla/client.mk
Using client.mk to pull the rest of the tree is essential because only layout is branched; the rest of the tree is pulled by date.
Rationale
The goal of the branch is to change the design in two areas of layout that have given us the most problems due to their complexity. It will also help make the nsIFrame and nsIBox layout methods a little more similar.
nsIFrame and nsIBox layout
Understanding the current situation with Mozilla's rendering objects requires understanding a bit of history, since it's currently in a state that nobody really intended.
CSS sort of has a notion of a rendering tree: a tree structure that's similar to the content tree but also contains pseudo-elements and does not contain objects that are display:none. In the original Gecko codebase, the objects in the rendering tree were intended to be implementations of nsIFrame. Different implementations would be used for different types of rendering objects: for example, objects with CSS display:block (nsBlockFrame), objects with CSS display:inline (nsInlineFrame), HTML <input type="text"> or <textarea> (nsTextControlFrame), or images resulting from <img> or <object> (nsImageFrame).
When the XUL layout model was implemented, nsIFrame was found not to be suitable for the flexible box model needed for XUL. So, for better or for worse, a second interface for rendering objects came into existence: nsIBox. XUL layout objects also delegate to singleton nsIBoxLayout objects for a number of the things that differentiate different types of rendering objects.
In an effort to reduce the size of box rendering objects (which had to implement nsIFrame and nsIBox), the two rendering object interfaces have been merged into nsIFrame and the merged list of methods is on track to be gradually consolidated. Base implementations of the separate methods are still split between nsBox and nsFrame, although the latter inherits from the former. The method nsIFrame::IsBoxFrame is the way the two types of objects can currently be distinguished.
The handling of the boundary between box and non-box rendering objects is currently handled in two places: the code in nsBoxFrame and nsLeafBoxFrame handles a box inside a non-box. The box methods on nsFrame handle a non-box being inside a box (although these used to be on a separate class called nsBoxToBlockAdaptor).
Intrinsic sizing changes
Incremental layout Changes
Design
Status
Currently a lot of the design is done but subject to change. CSS block/inline layout code and XUL box layout code have been converted to the new design and work well enough that the Firefox UI basically works (although with some glitches). However, form controls and tables have not yet been converted to the new design, and are disabled on the branch.
Future Development Tasks
- fix intrinsic sizing bug in default browser prompt (dbaron priority #1)
- convert table code (dbaron priority #2)
- convert form control code
- figure out whether to refactor
nsLeafFrame::GetDesiredSizeand implementnsLeafFrame::GetMinWidthandnsLeafFrame::GetPrefWidthin terms of it or whether to implementGetMinWidthandGetPrefWidthseparately for all the subclasses ofnsLeafFramethat useGetDesiredSize
- figure out whether to refactor
- Figure out whether the inline min/pref width interfaces currently on the branch (
nsIFrame::GetInlineMinWidthandGetInlinePrefWidth) are sufficient or whether we need to make additional architectural changes related to continuations (particularly making various special things use the existing next-in-flow model)
Future Testing Tasks
- Make sure dbaron's existing testcases work
- Develop testcases that test box-block boundaries better
- Extend intrinsic sizing testcases to check that padding, border, and margin are counted correctly, especially around box-block boundaries
- Test XUL user interfaces
- Test Web pages