This is a page for documenting the nsCSSFrameConstructor with the goal of simplifying, stabilizing and bugfixing it.
A major piece of information that we need to document is the constraints that various frames have on what child and parent frames it must or must not have. We should also document which transformations we perform between the content tree and the frame tree to enforce those constraints. This is tracked on the pages:
Ideas for design changes
We need a better way of keeping track of containing frames for out-of-flow frames. Currently this logic is duplicated in both frames and the frame ctor. Additionally, the frameCtor spends time on keeping track of the current containers even though most of the time we don't use them.
One way to fix this is move the logic of what is what type of container into the frame. This way the frame ctor can ask each frame as its processing the frame children if the frame is a container. We can then easily figure out which frames are current containers in ContentInserted by walking the parent chain.
Another solution is to make frames that need the information manually walk the parent chain until the desired block is found. This information could possibly be cached in the frame ctor.
XBL is currently too entangled in the frame ctor. XBL needs two things:
- munge notifications so that ContentAppended/Inserted/Removed is done on the right frame, and at the right child index in that frame
- Ability to create child lists that contains the mixture of anonymous and explicit children.
1 could be done by the binding manager by letting all notifications go through the binding manager. It already is an nsIDocumentObserver so it should have all neccesary information. Better apis into the binding manager is another solution.
2 has to be fixed by creating a better api that the frame ctor can use to access the flattened tree. One possible solution for accessing the flattened tree is to use a treewalker. However this might be an unneccesarily big change.
The ultimate goal is to move as much of the xbl logic as possible out of the frame constructor.
Hash for creator functions
Rather then the current neverending list of if-statements to figure out which frame to create we should have a hash table that maps tag+ns to creator function. The hash table can also contain information about which type of frame will be constructed so that we can create, for example, wrapping table frames beforehand.
In some cases the type of frame created varies (for example for images) so we might need to call a function to get the type.
These constructor functions should be able to create a whole tree of frames if neccesary. For example for list boxes or form controls.
We should have a similar (or even identical) hash keyed on display type for when the first hash doesn't produce a frame. Eventually we might want to move all frame types into this hash, but we need at least the content css property implemented for that.
Bug 323233 filed.
Until we have better transformation code in place we will probably need better state management code for the frame ctor. Logic should be moved into the frames so that we can rebuild the right state in a more reliable manner.
Frame teardown should be a lot simpler, (Do)DeletingFrameSubtree should die and frames should be able to just clean themselfs up.
Bug 323105 filed.
Currently we link together the frametree from bottom up. We recursivly walk into each element for which to create frames. First we create the frame for the element itself, and then we create a framelist for all its children. Not until the childlist is fully created we insert anything into the parent. Then as we unwrap the callstack we insert the finished childlists into each element.
The reason for this is that inserting a new childframe into a parent is slow (due to having to walk the linked-list of children) and forces reflow events to be created.
This seems unneccesarily complicated. A better approach would probably be to insert frames as we go and let the caller worry about posting reflow events. The downside is that we'd have to keep a pointer to the last frame in the child-frame-list.