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

Reply via email to