Home | History | Annotate | Download | only in rendering
      1 /*
      2  * This file is part of the render object implementation for KHTML.
      3  *
      4  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      5  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      6  * Copyright (C) 2003 Apple Computer, Inc.
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Library General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Library General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Library General Public License
     19  * along with this library; see the file COPYING.LIB.  If not, write to
     20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21  * Boston, MA 02110-1301, USA.
     22  *
     23  */
     24 
     25 #include "config.h"
     26 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
     27 
     28 #include "core/frame/UseCounter.h"
     29 #include "core/rendering/LayoutRepainter.h"
     30 #include "core/rendering/RenderLayer.h"
     31 #include "core/rendering/RenderView.h"
     32 #include "platform/fonts/Font.h"
     33 #include "wtf/StdLibExtras.h"
     34 #include "wtf/unicode/CharacterNames.h"
     35 
     36 using namespace std;
     37 
     38 namespace WebCore {
     39 
     40 class FlexBoxIterator {
     41 public:
     42     FlexBoxIterator(RenderDeprecatedFlexibleBox* parent)
     43         : m_box(parent)
     44         , m_largestOrdinal(1)
     45     {
     46         if (m_box->style()->boxOrient() == HORIZONTAL && !m_box->style()->isLeftToRightDirection())
     47             m_forward = m_box->style()->boxDirection() != BNORMAL;
     48         else
     49             m_forward = m_box->style()->boxDirection() == BNORMAL;
     50         if (!m_forward) {
     51             // No choice, since we're going backwards, we have to find out the highest ordinal up front.
     52             RenderBox* child = m_box->firstChildBox();
     53             while (child) {
     54                 if (child->style()->boxOrdinalGroup() > m_largestOrdinal)
     55                     m_largestOrdinal = child->style()->boxOrdinalGroup();
     56                 child = child->nextSiblingBox();
     57             }
     58         }
     59 
     60         reset();
     61     }
     62 
     63     void reset()
     64     {
     65         m_currentChild = 0;
     66         m_ordinalIteration = -1;
     67     }
     68 
     69     RenderBox* first()
     70     {
     71         reset();
     72         return next();
     73     }
     74 
     75     RenderBox* next()
     76     {
     77         do {
     78             if (!m_currentChild) {
     79                 ++m_ordinalIteration;
     80 
     81                 if (!m_ordinalIteration)
     82                     m_currentOrdinal = m_forward ? 1 : m_largestOrdinal;
     83                 else {
     84                     if (static_cast<size_t>(m_ordinalIteration) >= m_ordinalValues.size() + 1)
     85                         return 0;
     86 
     87                     // Only copy+sort the values once per layout even if the iterator is reset.
     88                     if (m_ordinalValues.size() != m_sortedOrdinalValues.size()) {
     89                         copyToVector(m_ordinalValues, m_sortedOrdinalValues);
     90                         sort(m_sortedOrdinalValues.begin(), m_sortedOrdinalValues.end());
     91                     }
     92                     m_currentOrdinal = m_forward ? m_sortedOrdinalValues[m_ordinalIteration - 1] : m_sortedOrdinalValues[m_sortedOrdinalValues.size() - m_ordinalIteration];
     93                 }
     94 
     95                 m_currentChild = m_forward ? m_box->firstChildBox() : m_box->lastChildBox();
     96             } else
     97                 m_currentChild = m_forward ? m_currentChild->nextSiblingBox() : m_currentChild->previousSiblingBox();
     98 
     99             if (m_currentChild && notFirstOrdinalValue())
    100                 m_ordinalValues.add(m_currentChild->style()->boxOrdinalGroup());
    101         } while (!m_currentChild || (!m_currentChild->isAnonymous()
    102                  && m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal));
    103         return m_currentChild;
    104     }
    105 
    106 private:
    107     bool notFirstOrdinalValue()
    108     {
    109         unsigned int firstOrdinalValue = m_forward ? 1 : m_largestOrdinal;
    110         return m_currentOrdinal == firstOrdinalValue && m_currentChild->style()->boxOrdinalGroup() != firstOrdinalValue;
    111     }
    112 
    113     RenderDeprecatedFlexibleBox* m_box;
    114     RenderBox* m_currentChild;
    115     bool m_forward;
    116     unsigned int m_currentOrdinal;
    117     unsigned int m_largestOrdinal;
    118     HashSet<unsigned int> m_ordinalValues;
    119     Vector<unsigned int> m_sortedOrdinalValues;
    120     int m_ordinalIteration;
    121 };
    122 
    123 RenderDeprecatedFlexibleBox::RenderDeprecatedFlexibleBox(Element* element)
    124     : RenderBlock(element)
    125 {
    126     setChildrenInline(false); // All of our children must be block-level
    127     m_stretchingChildren = false;
    128     if (!isAnonymous()) {
    129         const KURL& url = document().url();
    130         if (url.protocolIs("chrome"))
    131             UseCounter::count(document(), UseCounter::DeprecatedFlexboxChrome);
    132         else if (url.protocolIs("chrome-extension"))
    133             UseCounter::count(document(), UseCounter::DeprecatedFlexboxChromeExtension);
    134         else
    135             UseCounter::count(document(), UseCounter::DeprecatedFlexboxWebContent);
    136     }
    137 }
    138 
    139 RenderDeprecatedFlexibleBox::~RenderDeprecatedFlexibleBox()
    140 {
    141 }
    142 
    143 RenderDeprecatedFlexibleBox* RenderDeprecatedFlexibleBox::createAnonymous(Document* document)
    144 {
    145     RenderDeprecatedFlexibleBox* renderer = new RenderDeprecatedFlexibleBox(0);
    146     renderer->setDocumentForAnonymous(document);
    147     return renderer;
    148 }
    149 
    150 static LayoutUnit marginWidthForChild(RenderBox* child)
    151 {
    152     // A margin basically has three types: fixed, percentage, and auto (variable).
    153     // Auto and percentage margins simply become 0 when computing min/max width.
    154     // Fixed margins can be added in as is.
    155     Length marginLeft = child->style()->marginLeft();
    156     Length marginRight = child->style()->marginRight();
    157     LayoutUnit margin = 0;
    158     if (marginLeft.isFixed())
    159         margin += marginLeft.value();
    160     if (marginRight.isFixed())
    161         margin += marginRight.value();
    162     return margin;
    163 }
    164 
    165 static bool childDoesNotAffectWidthOrFlexing(RenderObject* child)
    166 {
    167     // Positioned children and collapsed children don't affect the min/max width.
    168     return child->isOutOfFlowPositioned() || child->style()->visibility() == COLLAPSE;
    169 }
    170 
    171 static LayoutUnit contentWidthForChild(RenderBox* child)
    172 {
    173     if (child->hasOverrideWidth())
    174         return child->overrideLogicalContentWidth();
    175     return child->logicalWidth() - child->borderAndPaddingLogicalWidth();
    176 }
    177 
    178 static LayoutUnit contentHeightForChild(RenderBox* child)
    179 {
    180     if (child->hasOverrideHeight())
    181         return child->overrideLogicalContentHeight();
    182     return child->logicalHeight() - child->borderAndPaddingLogicalHeight();
    183 }
    184 
    185 void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    186 {
    187     RenderStyle* oldStyle = style();
    188     if (oldStyle && !oldStyle->lineClamp().isNone() && newStyle->lineClamp().isNone())
    189         clearLineClamp();
    190 
    191     RenderBlock::styleWillChange(diff, newStyle);
    192 }
    193 
    194 void RenderDeprecatedFlexibleBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
    195 {
    196     if (hasMultipleLines() || isVertical()) {
    197         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    198             if (childDoesNotAffectWidthOrFlexing(child))
    199                 continue;
    200 
    201             LayoutUnit margin = marginWidthForChild(child);
    202             LayoutUnit width = child->minPreferredLogicalWidth() + margin;
    203             minLogicalWidth = max(width, minLogicalWidth);
    204 
    205             width = child->maxPreferredLogicalWidth() + margin;
    206             maxLogicalWidth = max(width, maxLogicalWidth);
    207         }
    208     } else {
    209         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    210             if (childDoesNotAffectWidthOrFlexing(child))
    211                 continue;
    212 
    213             LayoutUnit margin = marginWidthForChild(child);
    214             minLogicalWidth += child->minPreferredLogicalWidth() + margin;
    215             maxLogicalWidth += child->maxPreferredLogicalWidth() + margin;
    216         }
    217     }
    218 
    219     maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
    220 
    221     LayoutUnit scrollbarWidth = instrinsicScrollbarLogicalWidth();
    222     maxLogicalWidth += scrollbarWidth;
    223     minLogicalWidth += scrollbarWidth;
    224 }
    225 
    226 void RenderDeprecatedFlexibleBox::computePreferredLogicalWidths()
    227 {
    228     ASSERT(preferredLogicalWidthsDirty());
    229 
    230     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
    231     if (style()->width().isFixed() && style()->width().value() > 0)
    232         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
    233     else
    234         computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
    235 
    236     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
    237         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
    238         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
    239     }
    240 
    241     if (style()->maxWidth().isFixed()) {
    242         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
    243         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
    244     }
    245 
    246     LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
    247     m_minPreferredLogicalWidth += borderAndPadding;
    248     m_maxPreferredLogicalWidth += borderAndPadding;
    249 
    250     clearPreferredLogicalWidthsDirty();
    251 }
    252 
    253 void RenderDeprecatedFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
    254 {
    255     ASSERT(needsLayout());
    256 
    257     if (!relayoutChildren && simplifiedLayout())
    258         return;
    259 
    260     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
    261     LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
    262 
    263     // Regions changing widths can force us to relayout our children.
    264     RenderFlowThread* flowThread = flowThreadContainingBlock();
    265     if (logicalWidthChangedInRegions(flowThread))
    266         relayoutChildren = true;
    267     if (updateRegionsAndShapesLogicalSize(flowThread))
    268         relayoutChildren = true;
    269 
    270     LayoutSize previousSize = size();
    271 
    272     updateLogicalWidth();
    273     updateLogicalHeight();
    274 
    275     if (previousSize != size()
    276         || (parent()->isDeprecatedFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
    277         && parent()->style()->boxAlign() == BSTRETCH))
    278         relayoutChildren = true;
    279 
    280     setHeight(0);
    281 
    282     m_stretchingChildren = false;
    283 
    284     if (isHorizontal())
    285         layoutHorizontalBox(relayoutChildren);
    286     else
    287         layoutVerticalBox(relayoutChildren);
    288 
    289     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
    290     updateLogicalHeight();
    291 
    292     if (previousSize.height() != height())
    293         relayoutChildren = true;
    294 
    295     layoutPositionedObjects(relayoutChildren || isRoot());
    296 
    297     computeRegionRangeForBlock(flowThread);
    298 
    299     computeOverflow(oldClientAfterEdge);
    300 
    301     statePusher.pop();
    302 
    303     updateLayerTransform();
    304 
    305     if (view()->layoutState()->pageLogicalHeight())
    306         setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop()));
    307 
    308     // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
    309     // we overflow or not.
    310     if (hasOverflowClip())
    311         layer()->scrollableArea()->updateAfterLayout();
    312 
    313     // Repaint with our new bounds if they are different from our old bounds.
    314     repainter.repaintAfterLayout();
    315 
    316     clearNeedsLayout();
    317 }
    318 
    319 // The first walk over our kids is to find out if we have any flexible children.
    320 static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChildren, unsigned int& highestFlexGroup, unsigned int& lowestFlexGroup, bool& haveFlex)
    321 {
    322     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    323         // Check to see if this child flexes.
    324         if (!childDoesNotAffectWidthOrFlexing(child) && child->style()->boxFlex() > 0.0f) {
    325             // We always have to lay out flexible objects again, since the flex distribution
    326             // may have changed, and we need to reallocate space.
    327             child->clearOverrideSize();
    328             if (!relayoutChildren)
    329                 child->setChildNeedsLayout(MarkOnlyThis);
    330             haveFlex = true;
    331             unsigned int flexGroup = child->style()->boxFlexGroup();
    332             if (lowestFlexGroup == 0)
    333                 lowestFlexGroup = flexGroup;
    334             if (flexGroup < lowestFlexGroup)
    335                 lowestFlexGroup = flexGroup;
    336             if (flexGroup > highestFlexGroup)
    337                 highestFlexGroup = flexGroup;
    338         }
    339     }
    340 }
    341 
    342 void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
    343 {
    344     LayoutUnit toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
    345     LayoutUnit yPos = borderTop() + paddingTop();
    346     LayoutUnit xPos = borderLeft() + paddingLeft();
    347     bool heightSpecified = false;
    348     LayoutUnit oldHeight = 0;
    349 
    350     LayoutUnit remainingSpace = 0;
    351 
    352 
    353     FlexBoxIterator iterator(this);
    354     unsigned int highestFlexGroup = 0;
    355     unsigned int lowestFlexGroup = 0;
    356     bool haveFlex = false, flexingChildren = false;
    357     gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex);
    358 
    359     RenderBlock::startDelayUpdateScrollInfo();
    360 
    361     // We do 2 passes.  The first pass is simply to lay everyone out at
    362     // their preferred widths.  The second pass handles flexing the children.
    363     do {
    364         // Reset our height.
    365         setHeight(yPos);
    366 
    367         xPos = borderLeft() + paddingLeft();
    368 
    369         // Our first pass is done without flexing.  We simply lay the children
    370         // out within the box.  We have to do a layout first in order to determine
    371         // our box's intrinsic height.
    372         LayoutUnit maxAscent = 0, maxDescent = 0;
    373         for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    374             if (child->isOutOfFlowPositioned())
    375                 continue;
    376 
    377             SubtreeLayoutScope layoutScope(child);
    378             if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
    379                 layoutScope.setChildNeedsLayout(child);
    380 
    381             // Compute the child's vertical margins.
    382             child->computeAndSetBlockDirectionMargins(this);
    383 
    384             if (!child->needsLayout())
    385                 child->markForPaginationRelayoutIfNeeded(layoutScope);
    386 
    387             // Now do the layout.
    388             child->layoutIfNeeded();
    389 
    390             // Update our height and overflow height.
    391             if (style()->boxAlign() == BBASELINE) {
    392                 LayoutUnit ascent = child->firstLineBoxBaseline();
    393                 if (ascent == -1)
    394                     ascent = child->height() + child->marginBottom();
    395                 ascent += child->marginTop();
    396                 LayoutUnit descent = (child->height() + child->marginHeight()) - ascent;
    397 
    398                 // Update our maximum ascent.
    399                 maxAscent = max(maxAscent, ascent);
    400 
    401                 // Update our maximum descent.
    402                 maxDescent = max(maxDescent, descent);
    403 
    404                 // Now update our height.
    405                 setHeight(max(yPos + maxAscent + maxDescent, height()));
    406             }
    407             else
    408                 setHeight(max(height(), yPos + child->height() + child->marginHeight()));
    409         }
    410 
    411         if (!iterator.first() && hasLineIfEmpty())
    412             setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
    413 
    414         setHeight(height() + toAdd);
    415 
    416         oldHeight = height();
    417         updateLogicalHeight();
    418 
    419         relayoutChildren = false;
    420         if (oldHeight != height())
    421             heightSpecified = true;
    422 
    423         // Now that our height is actually known, we can place our boxes.
    424         m_stretchingChildren = (style()->boxAlign() == BSTRETCH);
    425         for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    426             if (child->isOutOfFlowPositioned()) {
    427                 child->containingBlock()->insertPositionedObject(child);
    428                 RenderLayer* childLayer = child->layer();
    429                 childLayer->setStaticInlinePosition(xPos); // FIXME: Not right for regions.
    430                 if (childLayer->staticBlockPosition() != yPos) {
    431                     childLayer->setStaticBlockPosition(yPos);
    432                     if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
    433                         child->setChildNeedsLayout(MarkOnlyThis);
    434                 }
    435                 continue;
    436             }
    437 
    438             if (child->style()->visibility() == COLLAPSE) {
    439                 // visibility: collapsed children do not participate in our positioning.
    440                 // But we need to lay them down.
    441                 child->layoutIfNeeded();
    442                 continue;
    443             }
    444 
    445             SubtreeLayoutScope layoutScope(child);
    446 
    447             // We need to see if this child's height has changed, since we make block elements
    448             // fill the height of a containing box by default.
    449             // Now do a layout.
    450             LayoutUnit oldChildHeight = child->height();
    451             child->updateLogicalHeight();
    452             if (oldChildHeight != child->height())
    453                 layoutScope.setChildNeedsLayout(child);
    454 
    455             if (!child->needsLayout())
    456                 child->markForPaginationRelayoutIfNeeded(layoutScope);
    457 
    458             child->layoutIfNeeded();
    459 
    460             // We can place the child now, using our value of box-align.
    461             xPos += child->marginLeft();
    462             LayoutUnit childY = yPos;
    463             switch (style()->boxAlign()) {
    464                 case BCENTER:
    465                     childY += child->marginTop() + max<LayoutUnit>(0, (contentHeight() - (child->height() + child->marginHeight())) / 2);
    466                     break;
    467                 case BBASELINE: {
    468                     LayoutUnit ascent = child->firstLineBoxBaseline();
    469                     if (ascent == -1)
    470                         ascent = child->height() + child->marginBottom();
    471                     ascent += child->marginTop();
    472                     childY += child->marginTop() + (maxAscent - ascent);
    473                     break;
    474                 }
    475                 case BEND:
    476                     childY += contentHeight() - child->marginBottom() - child->height();
    477                     break;
    478                 default: // BSTART
    479                     childY += child->marginTop();
    480                     break;
    481             }
    482 
    483             placeChild(child, LayoutPoint(xPos, childY));
    484 
    485             xPos += child->width() + child->marginRight();
    486         }
    487 
    488         remainingSpace = borderLeft() + paddingLeft() + contentWidth() - xPos;
    489 
    490         m_stretchingChildren = false;
    491         if (flexingChildren)
    492             haveFlex = false; // We're done.
    493         else if (haveFlex) {
    494             // We have some flexible objects.  See if we need to grow/shrink them at all.
    495             if (!remainingSpace)
    496                 break;
    497 
    498             // Allocate the remaining space among the flexible objects.  If we are trying to
    499             // grow, then we go from the lowest flex group to the highest flex group.  For shrinking,
    500             // we go from the highest flex group to the lowest group.
    501             bool expanding = remainingSpace > 0;
    502             unsigned int start = expanding ? lowestFlexGroup : highestFlexGroup;
    503             unsigned int end = expanding? highestFlexGroup : lowestFlexGroup;
    504             for (unsigned int i = start; i <= end && remainingSpace; i++) {
    505                 // Always start off by assuming the group can get all the remaining space.
    506                 LayoutUnit groupRemainingSpace = remainingSpace;
    507                 do {
    508                     // Flexing consists of multiple passes, since we have to change ratios every time an object hits its max/min-width
    509                     // For a given pass, we always start off by computing the totalFlex of all objects that can grow/shrink at all, and
    510                     // computing the allowed growth before an object hits its min/max width (and thus
    511                     // forces a totalFlex recomputation).
    512                     LayoutUnit groupRemainingSpaceAtBeginning = groupRemainingSpace;
    513                     float totalFlex = 0.0f;
    514                     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    515                         if (allowedChildFlex(child, expanding, i))
    516                             totalFlex += child->style()->boxFlex();
    517                     }
    518                     LayoutUnit spaceAvailableThisPass = groupRemainingSpace;
    519                     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    520                         LayoutUnit allowedFlex = allowedChildFlex(child, expanding, i);
    521                         if (allowedFlex) {
    522                             LayoutUnit projectedFlex = (allowedFlex == LayoutUnit::max()) ? allowedFlex : LayoutUnit(allowedFlex * (totalFlex / child->style()->boxFlex()));
    523                             spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex);
    524                         }
    525                     }
    526 
    527                     // The flex groups may not have any flexible objects this time around.
    528                     if (!spaceAvailableThisPass || totalFlex == 0.0f) {
    529                         // If we just couldn't grow/shrink any more, then it's time to transition to the next flex group.
    530                         groupRemainingSpace = 0;
    531                         continue;
    532                     }
    533 
    534                     // Now distribute the space to objects.
    535                     for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) {
    536                         if (child->style()->visibility() == COLLAPSE)
    537                             continue;
    538 
    539                         if (allowedChildFlex(child, expanding, i)) {
    540                             LayoutUnit spaceAdd = LayoutUnit(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex));
    541                             if (spaceAdd) {
    542                                 child->setOverrideLogicalContentWidth(contentWidthForChild(child) + spaceAdd);
    543                                 flexingChildren = true;
    544                                 relayoutChildren = true;
    545                             }
    546 
    547                             spaceAvailableThisPass -= spaceAdd;
    548                             remainingSpace -= spaceAdd;
    549                             groupRemainingSpace -= spaceAdd;
    550 
    551                             totalFlex -= child->style()->boxFlex();
    552                         }
    553                     }
    554                     if (groupRemainingSpace == groupRemainingSpaceAtBeginning) {
    555                         // This is not advancing, avoid getting stuck by distributing the remaining pixels.
    556                         LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
    557                         for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
    558                             if (allowedChildFlex(child, expanding, i)) {
    559                                 child->setOverrideLogicalContentWidth(contentWidthForChild(child) + spaceAdd);
    560                                 flexingChildren = true;
    561                                 relayoutChildren = true;
    562                                 remainingSpace -= spaceAdd;
    563                                 groupRemainingSpace -= spaceAdd;
    564                             }
    565                         }
    566                     }
    567                 } while (absoluteValue(groupRemainingSpace) >= 1);
    568             }
    569 
    570             // We didn't find any children that could grow.
    571             if (haveFlex && !flexingChildren)
    572                 haveFlex = false;
    573         }
    574     } while (haveFlex);
    575 
    576     RenderBlock::finishDelayUpdateScrollInfo();
    577 
    578     if (remainingSpace > 0 && ((style()->isLeftToRightDirection() && style()->boxPack() != Start)
    579         || (!style()->isLeftToRightDirection() && style()->boxPack() != End))) {
    580         // Children must be repositioned.
    581         LayoutUnit offset = 0;
    582         if (style()->boxPack() == Justify) {
    583             // Determine the total number of children.
    584             int totalChildren = 0;
    585             for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    586                 if (childDoesNotAffectWidthOrFlexing(child))
    587                     continue;
    588                 ++totalChildren;
    589             }
    590 
    591             // Iterate over the children and space them out according to the
    592             // justification level.
    593             if (totalChildren > 1) {
    594                 --totalChildren;
    595                 bool firstChild = true;
    596                 for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    597                     if (childDoesNotAffectWidthOrFlexing(child))
    598                         continue;
    599 
    600                     if (firstChild) {
    601                         firstChild = false;
    602                         continue;
    603                     }
    604 
    605                     offset += remainingSpace/totalChildren;
    606                     remainingSpace -= (remainingSpace/totalChildren);
    607                     --totalChildren;
    608 
    609                     placeChild(child, child->location() + LayoutSize(offset, 0));
    610                 }
    611             }
    612         } else {
    613             if (style()->boxPack() == Center)
    614                 offset += remainingSpace / 2;
    615             else // END for LTR, START for RTL
    616                 offset += remainingSpace;
    617             for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    618                 if (childDoesNotAffectWidthOrFlexing(child))
    619                     continue;
    620 
    621                 placeChild(child, child->location() + LayoutSize(offset, 0));
    622             }
    623         }
    624     }
    625 
    626     // So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of
    627     // a height change, we revert our height back to the intrinsic height before returning.
    628     if (heightSpecified)
    629         setHeight(oldHeight);
    630 }
    631 
    632 void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
    633 {
    634     LayoutUnit yPos = borderTop() + paddingTop();
    635     LayoutUnit toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
    636     bool heightSpecified = false;
    637     LayoutUnit oldHeight = 0;
    638 
    639     LayoutUnit remainingSpace = 0;
    640 
    641     FlexBoxIterator iterator(this);
    642     unsigned int highestFlexGroup = 0;
    643     unsigned int lowestFlexGroup = 0;
    644     bool haveFlex = false, flexingChildren = false;
    645     gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex);
    646 
    647     // We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of
    648     // mainstream block layout); this is not really part of the XUL box model.
    649     bool haveLineClamp = !style()->lineClamp().isNone();
    650     if (haveLineClamp)
    651         applyLineClamp(iterator, relayoutChildren);
    652 
    653     RenderBlock::startDelayUpdateScrollInfo();
    654 
    655     // We do 2 passes.  The first pass is simply to lay everyone out at
    656     // their preferred widths.  The second pass handles flexing the children.
    657     // Our first pass is done without flexing.  We simply lay the children
    658     // out within the box.
    659     do {
    660         setHeight(borderTop() + paddingTop());
    661         LayoutUnit minHeight = height() + toAdd;
    662 
    663         for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    664             if (child->isOutOfFlowPositioned()) {
    665                 child->containingBlock()->insertPositionedObject(child);
    666                 RenderLayer* childLayer = child->layer();
    667                 childLayer->setStaticInlinePosition(borderStart() + paddingStart()); // FIXME: Not right for regions.
    668                 if (childLayer->staticBlockPosition() != height()) {
    669                     childLayer->setStaticBlockPosition(height());
    670                     if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
    671                         child->setChildNeedsLayout(MarkOnlyThis);
    672                 }
    673                 continue;
    674             }
    675 
    676             SubtreeLayoutScope layoutScope(child);
    677             if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))))
    678                 layoutScope.setChildNeedsLayout(child);
    679 
    680             if (child->style()->visibility() == COLLAPSE) {
    681                 // visibility: collapsed children do not participate in our positioning.
    682                 // But we need to lay them down.
    683                 child->layoutIfNeeded();
    684                 continue;
    685             }
    686 
    687             // Compute the child's vertical margins.
    688             child->computeAndSetBlockDirectionMargins(this);
    689 
    690             // Add in the child's marginTop to our height.
    691             setHeight(height() + child->marginTop());
    692 
    693             if (!child->needsLayout())
    694                 child->markForPaginationRelayoutIfNeeded(layoutScope);
    695 
    696             // Now do a layout.
    697             child->layoutIfNeeded();
    698 
    699             // We can place the child now, using our value of box-align.
    700             LayoutUnit childX = borderLeft() + paddingLeft();
    701             switch (style()->boxAlign()) {
    702                 case BCENTER:
    703                 case BBASELINE: // Baseline just maps to center for vertical boxes
    704                     childX += child->marginLeft() + max<LayoutUnit>(0, (contentWidth() - (child->width() + child->marginWidth())) / 2);
    705                     break;
    706                 case BEND:
    707                     if (!style()->isLeftToRightDirection())
    708                         childX += child->marginLeft();
    709                     else
    710                         childX += contentWidth() - child->marginRight() - child->width();
    711                     break;
    712                 default: // BSTART/BSTRETCH
    713                     if (style()->isLeftToRightDirection())
    714                         childX += child->marginLeft();
    715                     else
    716                         childX += contentWidth() - child->marginRight() - child->width();
    717                     break;
    718             }
    719 
    720             // Place the child.
    721             placeChild(child, LayoutPoint(childX, height()));
    722             setHeight(height() + child->height() + child->marginBottom());
    723         }
    724 
    725         yPos = height();
    726 
    727         if (!iterator.first() && hasLineIfEmpty())
    728             setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
    729 
    730         setHeight(height() + toAdd);
    731 
    732         // Negative margins can cause our height to shrink below our minimal height (border/padding).
    733         // If this happens, ensure that the computed height is increased to the minimal height.
    734         if (height() < minHeight)
    735             setHeight(minHeight);
    736 
    737         // Now we have to calc our height, so we know how much space we have remaining.
    738         oldHeight = height();
    739         updateLogicalHeight();
    740         if (oldHeight != height())
    741             heightSpecified = true;
    742 
    743         remainingSpace = borderTop() + paddingTop() + contentHeight() - yPos;
    744 
    745         if (flexingChildren)
    746             haveFlex = false; // We're done.
    747         else if (haveFlex) {
    748             // We have some flexible objects.  See if we need to grow/shrink them at all.
    749             if (!remainingSpace)
    750                 break;
    751 
    752             // Allocate the remaining space among the flexible objects.  If we are trying to
    753             // grow, then we go from the lowest flex group to the highest flex group.  For shrinking,
    754             // we go from the highest flex group to the lowest group.
    755             bool expanding = remainingSpace > 0;
    756             unsigned int start = expanding ? lowestFlexGroup : highestFlexGroup;
    757             unsigned int end = expanding? highestFlexGroup : lowestFlexGroup;
    758             for (unsigned int i = start; i <= end && remainingSpace; i++) {
    759                 // Always start off by assuming the group can get all the remaining space.
    760                 LayoutUnit groupRemainingSpace = remainingSpace;
    761                 do {
    762                     // Flexing consists of multiple passes, since we have to change ratios every time an object hits its max/min-width
    763                     // For a given pass, we always start off by computing the totalFlex of all objects that can grow/shrink at all, and
    764                     // computing the allowed growth before an object hits its min/max width (and thus
    765                     // forces a totalFlex recomputation).
    766                     LayoutUnit groupRemainingSpaceAtBeginning = groupRemainingSpace;
    767                     float totalFlex = 0.0f;
    768                     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    769                         if (allowedChildFlex(child, expanding, i))
    770                             totalFlex += child->style()->boxFlex();
    771                     }
    772                     LayoutUnit spaceAvailableThisPass = groupRemainingSpace;
    773                     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    774                         LayoutUnit allowedFlex = allowedChildFlex(child, expanding, i);
    775                         if (allowedFlex) {
    776                             LayoutUnit projectedFlex = (allowedFlex == LayoutUnit::max()) ? allowedFlex : static_cast<LayoutUnit>(allowedFlex * (totalFlex / child->style()->boxFlex()));
    777                             spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex);
    778                         }
    779                     }
    780 
    781                     // The flex groups may not have any flexible objects this time around.
    782                     if (!spaceAvailableThisPass || totalFlex == 0.0f) {
    783                         // If we just couldn't grow/shrink any more, then it's time to transition to the next flex group.
    784                         groupRemainingSpace = 0;
    785                         continue;
    786                     }
    787 
    788                     // Now distribute the space to objects.
    789                     for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) {
    790                         if (allowedChildFlex(child, expanding, i)) {
    791                             LayoutUnit spaceAdd = static_cast<LayoutUnit>(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex));
    792                             if (spaceAdd) {
    793                                 child->setOverrideLogicalContentHeight(contentHeightForChild(child) + spaceAdd);
    794                                 flexingChildren = true;
    795                                 relayoutChildren = true;
    796                             }
    797 
    798                             spaceAvailableThisPass -= spaceAdd;
    799                             remainingSpace -= spaceAdd;
    800                             groupRemainingSpace -= spaceAdd;
    801 
    802                             totalFlex -= child->style()->boxFlex();
    803                         }
    804                     }
    805                     if (groupRemainingSpace == groupRemainingSpaceAtBeginning) {
    806                         // This is not advancing, avoid getting stuck by distributing the remaining pixels.
    807                         LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
    808                         for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
    809                             if (allowedChildFlex(child, expanding, i)) {
    810                                 child->setOverrideLogicalContentHeight(contentHeightForChild(child) + spaceAdd);
    811                                 flexingChildren = true;
    812                                 relayoutChildren = true;
    813                                 remainingSpace -= spaceAdd;
    814                                 groupRemainingSpace -= spaceAdd;
    815                             }
    816                         }
    817                     }
    818                 } while (absoluteValue(groupRemainingSpace) >= 1);
    819             }
    820 
    821             // We didn't find any children that could grow.
    822             if (haveFlex && !flexingChildren)
    823                 haveFlex = false;
    824         }
    825     } while (haveFlex);
    826 
    827     RenderBlock::finishDelayUpdateScrollInfo();
    828 
    829     if (style()->boxPack() != Start && remainingSpace > 0) {
    830         // Children must be repositioned.
    831         LayoutUnit offset = 0;
    832         if (style()->boxPack() == Justify) {
    833             // Determine the total number of children.
    834             int totalChildren = 0;
    835             for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    836                 if (childDoesNotAffectWidthOrFlexing(child))
    837                     continue;
    838 
    839                 ++totalChildren;
    840             }
    841 
    842             // Iterate over the children and space them out according to the
    843             // justification level.
    844             if (totalChildren > 1) {
    845                 --totalChildren;
    846                 bool firstChild = true;
    847                 for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    848                     if (childDoesNotAffectWidthOrFlexing(child))
    849                         continue;
    850 
    851                     if (firstChild) {
    852                         firstChild = false;
    853                         continue;
    854                     }
    855 
    856                     offset += remainingSpace/totalChildren;
    857                     remainingSpace -= (remainingSpace/totalChildren);
    858                     --totalChildren;
    859                     placeChild(child, child->location() + LayoutSize(0, offset));
    860                 }
    861             }
    862         } else {
    863             if (style()->boxPack() == Center)
    864                 offset += remainingSpace / 2;
    865             else // END
    866                 offset += remainingSpace;
    867             for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    868                 if (childDoesNotAffectWidthOrFlexing(child))
    869                     continue;
    870                 placeChild(child, child->location() + LayoutSize(0, offset));
    871             }
    872         }
    873     }
    874 
    875     // So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of
    876     // a height change, we revert our height back to the intrinsic height before returning.
    877     if (heightSpecified)
    878         setHeight(oldHeight);
    879 }
    880 
    881 void RenderDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutChildren)
    882 {
    883     UseCounter::count(document(), UseCounter::LineClamp);
    884 
    885     int maxLineCount = 0;
    886     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    887         if (childDoesNotAffectWidthOrFlexing(child))
    888             continue;
    889 
    890         child->clearOverrideSize();
    891         if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))
    892             || (child->style()->height().isAuto() && child->isRenderBlock())) {
    893             child->setChildNeedsLayout(MarkOnlyThis);
    894 
    895             // Dirty all the positioned objects.
    896             if (child->isRenderBlock()) {
    897                 toRenderBlock(child)->markPositionedObjectsForLayout();
    898                 toRenderBlock(child)->clearTruncation();
    899             }
    900         }
    901         child->layoutIfNeeded();
    902         if (child->style()->height().isAuto() && child->isRenderBlock())
    903             maxLineCount = max(maxLineCount, toRenderBlock(child)->lineCount());
    904     }
    905 
    906     // Get the number of lines and then alter all block flow children with auto height to use the
    907     // specified height. We always try to leave room for at least one line.
    908     LineClampValue lineClamp = style()->lineClamp();
    909     int numVisibleLines = lineClamp.isPercentage() ? max(1, (maxLineCount + 1) * lineClamp.value() / 100) : lineClamp.value();
    910     if (numVisibleLines >= maxLineCount)
    911         return;
    912 
    913     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    914         if (childDoesNotAffectWidthOrFlexing(child) || !child->style()->height().isAuto() || !child->isRenderBlock())
    915             continue;
    916 
    917         RenderBlock* blockChild = toRenderBlock(child);
    918         int lineCount = blockChild->lineCount();
    919         if (lineCount <= numVisibleLines)
    920             continue;
    921 
    922         LayoutUnit newHeight = blockChild->heightForLineCount(numVisibleLines);
    923         if (newHeight == child->height())
    924             continue;
    925 
    926         child->setOverrideLogicalContentHeight(newHeight - child->borderAndPaddingHeight());
    927         child->forceChildLayout();
    928 
    929         // FIXME: For now don't support RTL.
    930         if (style()->direction() != LTR)
    931             continue;
    932 
    933         // Get the last line
    934         RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount - 1);
    935         if (!lastLine)
    936             continue;
    937 
    938         RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines - 1);
    939         if (!lastVisibleLine)
    940             continue;
    941 
    942         const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' };
    943         DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2));
    944         DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
    945         const Font& font = style(numVisibleLines == 1)->font();
    946 
    947         // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
    948         LayoutUnit totalWidth;
    949         InlineBox* anchorBox = lastLine->lastChild();
    950         if (anchorBox && anchorBox->renderer()->style()->isLink())
    951             totalWidth = anchorBox->logicalWidth() + font.width(RenderBlockFlow::constructTextRun(this, font, ellipsisAndSpace, 2, style()));
    952         else {
    953             anchorBox = 0;
    954             totalWidth = font.width(RenderBlockFlow::constructTextRun(this, font, &horizontalEllipsis, 1, style()));
    955         }
    956 
    957         // See if this width can be accommodated on the last visible line
    958         RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
    959         RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
    960 
    961         // FIXME: Directions of src/destBlock could be different from our direction and from one another.
    962         if (!srcBlock->style()->isLeftToRightDirection())
    963             continue;
    964 
    965         bool leftToRight = destBlock->style()->isLeftToRightDirection();
    966         if (!leftToRight)
    967             continue;
    968 
    969         LayoutUnit blockRightEdge = destBlock->logicalRightOffsetForLine(lastVisibleLine->y(), false);
    970         if (!lastVisibleLine->lineCanAccommodateEllipsis(leftToRight, blockRightEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth))
    971             continue;
    972 
    973         // Let the truncation code kick in.
    974         // FIXME: the text alignment should be recomputed after the width changes due to truncation.
    975         LayoutUnit blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false);
    976         lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
    977         destBlock->setHasMarkupTruncation(true);
    978     }
    979 }
    980 
    981 void RenderDeprecatedFlexibleBox::clearLineClamp()
    982 {
    983     FlexBoxIterator iterator(this);
    984     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
    985         if (childDoesNotAffectWidthOrFlexing(child))
    986             continue;
    987 
    988         child->clearOverrideSize();
    989         if ((child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))
    990             || (child->style()->height().isAuto() && child->isRenderBlock())) {
    991             child->setChildNeedsLayout();
    992 
    993             if (child->isRenderBlock()) {
    994                 toRenderBlock(child)->markPositionedObjectsForLayout();
    995                 toRenderBlock(child)->clearTruncation();
    996             }
    997         }
    998     }
    999 }
   1000 
   1001 void RenderDeprecatedFlexibleBox::placeChild(RenderBox* child, const LayoutPoint& location)
   1002 {
   1003     LayoutRect oldRect = child->frameRect();
   1004 
   1005     // Place the child.
   1006     child->setLocation(location);
   1007 
   1008     // If the child moved, we have to repaint it as well as any floating/positioned
   1009     // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   1010     // repaint ourselves (and the child) anyway.
   1011     if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
   1012         child->repaintDuringLayoutIfMoved(oldRect);
   1013 }
   1014 
   1015 LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsigned int group)
   1016 {
   1017     if (childDoesNotAffectWidthOrFlexing(child) || child->style()->boxFlex() == 0.0f || child->style()->boxFlexGroup() != group)
   1018         return 0;
   1019 
   1020     if (expanding) {
   1021         if (isHorizontal()) {
   1022             // FIXME: For now just handle fixed values.
   1023             LayoutUnit maxWidth = LayoutUnit::max();
   1024             LayoutUnit width = contentWidthForChild(child);
   1025             if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed())
   1026                 maxWidth = child->style()->maxWidth().value();
   1027             else if (child->style()->maxWidth().type() == Intrinsic)
   1028                 maxWidth = child->maxPreferredLogicalWidth();
   1029             else if (child->style()->maxWidth().type() == MinIntrinsic)
   1030                 maxWidth = child->minPreferredLogicalWidth();
   1031             if (maxWidth == LayoutUnit::max())
   1032                 return maxWidth;
   1033             return max<LayoutUnit>(0, maxWidth - width);
   1034         } else {
   1035             // FIXME: For now just handle fixed values.
   1036             LayoutUnit maxHeight = LayoutUnit::max();
   1037             LayoutUnit height = contentHeightForChild(child);
   1038             if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed())
   1039                 maxHeight = child->style()->maxHeight().value();
   1040             if (maxHeight == LayoutUnit::max())
   1041                 return maxHeight;
   1042             return max<LayoutUnit>(0, maxHeight - height);
   1043         }
   1044     }
   1045 
   1046     // FIXME: For now just handle fixed values.
   1047     if (isHorizontal()) {
   1048         LayoutUnit minWidth = child->minPreferredLogicalWidth();
   1049         LayoutUnit width = contentWidthForChild(child);
   1050         if (child->style()->minWidth().isFixed())
   1051             minWidth = child->style()->minWidth().value();
   1052         else if (child->style()->minWidth().type() == Intrinsic)
   1053             minWidth = child->maxPreferredLogicalWidth();
   1054         else if (child->style()->minWidth().type() == MinIntrinsic)
   1055             minWidth = child->minPreferredLogicalWidth();
   1056         else if (child->style()->minWidth().type() == Auto)
   1057             minWidth = 0;
   1058 
   1059         LayoutUnit allowedShrinkage = min<LayoutUnit>(0, minWidth - width);
   1060         return allowedShrinkage;
   1061     } else {
   1062         Length minHeight = child->style()->minHeight();
   1063         if (minHeight.isFixed() || minHeight.isAuto()) {
   1064             LayoutUnit minHeight = child->style()->minHeight().value();
   1065             LayoutUnit height = contentHeightForChild(child);
   1066             LayoutUnit allowedShrinkage = min<LayoutUnit>(0, minHeight - height);
   1067             return allowedShrinkage;
   1068         }
   1069     }
   1070 
   1071     return 0;
   1072 }
   1073 
   1074 const char* RenderDeprecatedFlexibleBox::renderName() const
   1075 {
   1076     if (isFloating())
   1077         return "RenderDeprecatedFlexibleBox (floating)";
   1078     if (isOutOfFlowPositioned())
   1079         return "RenderDeprecatedFlexibleBox (positioned)";
   1080     // FIXME: Temporary hack while the new generated content system is being implemented.
   1081     if (isPseudoElement())
   1082         return "RenderDeprecatedFlexibleBox (generated)";
   1083     if (isAnonymous())
   1084         return "RenderDeprecatedFlexibleBox (generated)";
   1085     if (isRelPositioned())
   1086         return "RenderDeprecatedFlexibleBox (relative positioned)";
   1087     return "RenderDeprecatedFlexibleBox";
   1088 }
   1089 
   1090 } // namespace WebCore
   1091