Add some class documentation to LayoutBlock

There was no explanation about LayoutBlock acting as the
concept of containing block. While at it, documented some
design decisions around the positioned descendant map.

Review URL: https://codereview.chromium.org/1304953005

git-svn-id: svn://svn.chromium.org/blink/trunk@201566 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a29cbd0e
......@@ -88,7 +88,21 @@ struct SameSizeAsLayoutBlock : public LayoutBox {
static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock should stay small");
// This map keeps track of the positioned objects associated with a containing
// block.
//
// This map is populated during layout. It is kept across layouts to handle
// that we skip unchanged sub-trees during layout, in such a way that we are
// able to lay out deeply nested out-of-flow descendants if their containing
// block got laid out. The map could be invalidated during style change but
// keeping track of containing blocks at that time is complicated (we are in
// the middle of recomputing the style so we can't rely on any of its
// information), which is why it's easier to just update it for every layout.
static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr;
// This map keeps track of the descendants whose 'height' is percentage associated
// with a containing block. Like |gPositionedDescendantsMap|, it is also recomputed
// for every layout (see the comment above about why).
static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr;
static TrackedContainerMap* gPositionedContainerMap = nullptr;
......
......@@ -49,6 +49,52 @@ typedef Vector<WordMeasurement, 64> WordMeasurements;
enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
// LayoutBlock is the class that is used by any LayoutObject
// that is a containing block.
// http://www.w3.org/TR/CSS2/visuren.html#containing-block
// See also LayoutObject::containingBlock() that is the function
// used to get the containing block of a LayoutObject.
//
// CSS is inconsistent and allows inline elements (LayoutInline) to be
// containing blocks, even though they are not blocks. Our
// implementation is as confused with inlines. See e.g.
// LayoutObject::containingBlock() vs LayoutObject::container().
//
// Containing blocks are a central concept for layout, in
// particular to the layout of out-of-flow positioned
// elements. They are used to determine the sizing as well
// as the positioning of the LayoutObjects.
//
// Out-of-flow positioned elements are laid out by their
// containing blocks so LayoutBlock keeps track of them
// through |gPositionedDescendantsMap| (see LayoutBlock.cpp).
// See LayoutBlock::layoutPositionedObjects() for the logic
// to lay them out.
//
//
// ***** HANDLING OUT-OF-FLOW POSITIONED OBJECTS *****
// Care should be taken to handle out-of-flow positioned objects during
// certain tree walks (e.g. layout()). The rule is that anything that
// cares about containing blocks should skip the out-of-flow elements
// in the normal tree walk and do an optional follow-up pass for them
// using LayoutBlock::positionedObjects().
// Not doing so will result in passing the wrong containing
// block as tree walks will always pass the parent as the
// containing block.
//
// Sample code of how to handle positioned objects in LayoutBlock:
//
// for (LayoutObject* child = firstChild(); child; child = child->nextSibling()) {
// if (child->isOutOfFlowPositioned())
// continue;
//
// // Handle normal flow children.
// ...
// }
// for (LayoutObject positionedObject : positionedObjects()) {
// // Handle out-of-flow positioned objects.
// ...
// }
class CORE_EXPORT LayoutBlock : public LayoutBox {
public:
friend class LineLayoutState;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment