David and I were talking about frame construction the other day, and I
figured I should summarize the conversation and see what people think.
In brief, there are various situations in CSS (and certainly in our
implementation of it) where boxes need to be wrapped in other boxes.
The spec calls for this for table-related display values and for
block-inside-inline situations. Our code additionally does this for
children of mathml elements and xul boxes.
Right now we have four separate solutions for these similar problems:
1) Block-inside-inline is handled by constructing the child frames, then
analyzing the resulting frame list and breaking it up into up to 3
pieces as needed (initial inline, block, trailing inline). Mutations
are handles via reframing the containing block in most cases, with very
complicated optimizations for a few cases we hit on Tp.
2) Table display values are handled via a complicated system of keeping
track of what our currently-open table anonymous boxes are, with calls
sprinkled through the frame constructor to create and "close" them as
needed. Mutations are not really handled.
3) Kids of MathML are handled by constructing the child frames, then
analyzing the child list and wrapping runs of non-blocks in blocks.
Mutations aren't really handled.
4) Kids of XUL boxes are handled by constructing the child frames, then
analyzing the child list (this is a separate pass from the MathML
analysis) and wrapping it all in a block if need be. Mutations are
handled by reframing sufficiently up the frame tree.
We would like somewhat to consolidate these four processing steps. So
far what I'm thinking of goes about as follows:
Step 1: Convert ConstructFrameByDisplayType to constructing
via FrameConstructionData.
Step 2: In ProcessChildren, start by building a list (probably
nsAutoTArray, but maybe linked list depending on how big these
lists end up, I guess) of structs that have the following
information:
*) The content node
*) The style context
*) The XBL-resolved tag + namespace (if needed; I'm not
sure it will be)
*) The FrameConstructionData to use for this node
This list can have the nodes that are display:none already
filtered out. It would NOT have whitespace textnodes filtered
out yet.
Step 3: Analyze this list and figure out what wrapper frames we need as
parents. This is not just a matter of going down the list and
creating/"closing" the parents, because some cases require
lookahead (for example an inline child of an inline that has
other kids which are blocks might end up in either the anonymous
block or the trailing inline depending on what its following
siblings look like).
Step 4: Go ahead and construct the frames.
Mutations will be a little fun; that includes removal and dynamic
additions. For the dynamic case the analysis step would need to take
into account the previous and next siblings of the new frames (and their
parents).
Thoughts? Obvious problems with this approach? Other suggestions?
-Boris
_______________________________________________
dev-tech-layout mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-layout