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