f6376231d4da43ad10e08bc4101bc2cf0e8ab87f
[WebKit-https.git] / Source / WebCore / rendering / RenderTable.cpp
1 /*
2  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3  *           (C) 1997 Torben Weis (weis@kde.org)
4  *           (C) 1998 Waldo Bastian (bastian@kde.org)
5  *           (C) 1999 Lars Knoll (knoll@kde.org)
6  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
7  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
8  * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "RenderTable.h"
28
29 #include "AutoTableLayout.h"
30 #include "CollapsedBorderValue.h"
31 #include "Document.h"
32 #include "FixedTableLayout.h"
33 #include "FrameView.h"
34 #include "HitTestResult.h"
35 #include "HTMLNames.h"
36 #include "HTMLTableElement.h"
37 #include "LayoutRepainter.h"
38 #include "RenderChildIterator.h"
39 #include "RenderIterator.h"
40 #include "RenderLayer.h"
41 #include "RenderNamedFlowFragment.h"
42 #include "RenderTableCaption.h"
43 #include "RenderTableCell.h"
44 #include "RenderTableCol.h"
45 #include "RenderTableSection.h"
46 #include "RenderView.h"
47 #include "StyleInheritedData.h"
48 #include <wtf/StackStats.h>
49
50 namespace WebCore {
51
52 using namespace HTMLNames;
53
54 RenderTable::RenderTable(Element& element, RenderStyle&& style)
55     : RenderBlock(element, WTFMove(style), 0)
56     , m_head(nullptr)
57     , m_foot(nullptr)
58     , m_firstBody(nullptr)
59     , m_currentBorder(nullptr)
60     , m_collapsedBordersValid(false)
61     , m_collapsedEmptyBorderIsPresent(false)
62     , m_hasColElements(false)
63     , m_needsSectionRecalc(false)
64     , m_columnLogicalWidthChanged(false)
65     , m_columnRenderersValid(false)
66     , m_hasCellColspanThatDeterminesTableWidth(false)
67     , m_borderStart(0)
68     , m_borderEnd(0)
69     , m_columnOffsetTop(-1)
70     , m_columnOffsetHeight(-1)
71 {
72     setChildrenInline(false);
73     m_columnPos.fill(0, 1);
74 }
75
76 RenderTable::RenderTable(Document& document, RenderStyle&& style)
77     : RenderBlock(document, WTFMove(style), 0)
78     , m_head(nullptr)
79     , m_foot(nullptr)
80     , m_firstBody(nullptr)
81     , m_currentBorder(nullptr)
82     , m_collapsedBordersValid(false)
83     , m_collapsedEmptyBorderIsPresent(false)
84     , m_hasColElements(false)
85     , m_needsSectionRecalc(false)
86     , m_columnLogicalWidthChanged(false)
87     , m_columnRenderersValid(false)
88     , m_hasCellColspanThatDeterminesTableWidth(false)
89     , m_borderStart(0)
90     , m_borderEnd(0)
91 {
92     setChildrenInline(false);
93     m_columnPos.fill(0, 1);
94 }
95
96 RenderTable::~RenderTable()
97 {
98 }
99
100 void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
101 {
102     RenderBlock::styleDidChange(diff, oldStyle);
103     propagateStyleToAnonymousChildren(PropagateToAllChildren);
104
105     ETableLayout oldTableLayout = oldStyle ? oldStyle->tableLayout() : TAUTO;
106
107     // In the collapsed border model, there is no cell spacing.
108     m_hSpacing = collapseBorders() ? 0 : style().horizontalBorderSpacing();
109     m_vSpacing = collapseBorders() ? 0 : style().verticalBorderSpacing();
110     m_columnPos[0] = m_hSpacing;
111
112     if (!m_tableLayout || style().tableLayout() != oldTableLayout) {
113         // According to the CSS2 spec, you only use fixed table layout if an
114         // explicit width is specified on the table.  Auto width implies auto table layout.
115         if (style().tableLayout() == TFIXED && !style().logicalWidth().isAuto())
116             m_tableLayout = std::make_unique<FixedTableLayout>(this);
117         else
118             m_tableLayout = std::make_unique<AutoTableLayout>(this);
119     }
120
121     // If border was changed, invalidate collapsed borders cache.
122     if (oldStyle && oldStyle->border() != style().border())
123         invalidateCollapsedBorders();
124 }
125
126 static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, RenderObject* before)
127 {
128     if (!before || !ptr)
129         return;
130     RenderObject* o = before->previousSibling();
131     while (o && o != ptr)
132         o = o->previousSibling();
133     if (!o)
134         ptr = 0;
135 }
136
137 void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
138 {
139     bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
140
141     if (is<RenderTableCaption>(*child))
142         wrapInAnonymousSection = false;
143     else if (is<RenderTableCol>(*child)) {
144         m_hasColElements = true;
145         wrapInAnonymousSection = false;
146     } else if (is<RenderTableSection>(*child)) {
147         switch (child->style().display()) {
148             case TABLE_HEADER_GROUP:
149                 resetSectionPointerIfNotBefore(m_head, beforeChild);
150                 if (!m_head) {
151                     m_head = downcast<RenderTableSection>(child);
152                 } else {
153                     resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
154                     if (!m_firstBody) 
155                         m_firstBody = downcast<RenderTableSection>(child);
156                 }
157                 wrapInAnonymousSection = false;
158                 break;
159             case TABLE_FOOTER_GROUP:
160                 resetSectionPointerIfNotBefore(m_foot, beforeChild);
161                 if (!m_foot) {
162                     m_foot = downcast<RenderTableSection>(child);
163                     wrapInAnonymousSection = false;
164                     break;
165                 }
166                 FALLTHROUGH;
167             case TABLE_ROW_GROUP:
168                 resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
169                 if (!m_firstBody)
170                     m_firstBody = downcast<RenderTableSection>(child);
171                 wrapInAnonymousSection = false;
172                 break;
173             default:
174                 ASSERT_NOT_REACHED();
175         }
176     } else if (is<RenderTableCell>(*child) || is<RenderTableRow>(*child))
177         wrapInAnonymousSection = true;
178     else
179         wrapInAnonymousSection = true;
180
181     if (is<RenderTableSection>(*child))
182         setNeedsSectionRecalc();
183
184     if (!wrapInAnonymousSection) {
185         if (beforeChild && beforeChild->parent() != this)
186             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
187
188         RenderBox::addChild(child, beforeChild);
189         return;
190     }
191
192     if (!beforeChild && is<RenderTableSection>(lastChild()) && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
193         downcast<RenderTableSection>(*lastChild()).addChild(child);
194         return;
195     }
196
197     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
198         RenderObject* section = beforeChild->previousSibling();
199         if (is<RenderTableSection>(section) && section->isAnonymous()) {
200             downcast<RenderTableSection>(*section).addChild(child);
201             return;
202         }
203     }
204
205     RenderObject* lastBox = beforeChild;
206     while (lastBox && lastBox->parent()->isAnonymous() && !is<RenderTableSection>(*lastBox) && lastBox->style().display() != TABLE_CAPTION && lastBox->style().display() != TABLE_COLUMN_GROUP)
207         lastBox = lastBox->parent();
208     if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox) && lastBox->isTableSection()) {
209         RenderTableSection& section = downcast<RenderTableSection>(*lastBox);
210         if (beforeChild == &section)
211             beforeChild = section.firstRow();
212         section.addChild(child, beforeChild);
213         return;
214     }
215
216     if (beforeChild && !is<RenderTableSection>(*beforeChild) && beforeChild->style().display() != TABLE_CAPTION && beforeChild->style().display() != TABLE_COLUMN_GROUP)
217         beforeChild = nullptr;
218
219     RenderTableSection* section = RenderTableSection::createAnonymousWithParentRenderer(this);
220     addChild(section, beforeChild);
221     section->addChild(child);
222 }
223
224 void RenderTable::addCaption(const RenderTableCaption* caption)
225 {
226     ASSERT(m_captions.find(caption) == notFound);
227     m_captions.append(const_cast<RenderTableCaption*>(caption));
228 }
229
230 void RenderTable::removeCaption(const RenderTableCaption* oldCaption)
231 {
232     bool removed = m_captions.removeFirst(oldCaption);
233     ASSERT_UNUSED(removed, removed);
234 }
235
236 void RenderTable::invalidateCachedColumns()
237 {
238     m_columnRenderersValid = false;
239     m_columnRenderers.resize(0);
240     m_effectiveColumnIndexMap.clear();
241 }
242
243 void RenderTable::invalidateCachedColumnOffsets()
244 {
245     m_columnOffsetTop = -1;
246     m_columnOffsetHeight = -1;
247 }
248
249 void RenderTable::addColumn(const RenderTableCol*)
250 {
251     invalidateCachedColumns();
252 }
253
254 void RenderTable::removeColumn(const RenderTableCol*)
255 {
256     invalidateCachedColumns();
257     // We don't really need to recompute our sections, but we need to update our
258     // column count and whether we have a column. Currently, we only have one
259     // size-fit-all flag but we may have to consider splitting it.
260     setNeedsSectionRecalc();
261 }
262
263 void RenderTable::updateLogicalWidth()
264 {
265     recalcSectionsIfNeeded();
266
267     if (isOutOfFlowPositioned()) {
268         LogicalExtentComputedValues computedValues;
269         computePositionedLogicalWidth(computedValues);
270         setLogicalWidth(computedValues.m_extent);
271         setLogicalLeft(computedValues.m_position);
272         setMarginStart(computedValues.m_margins.m_start);
273         setMarginEnd(computedValues.m_margins.m_end);
274     }
275
276     RenderBlock& cb = *containingBlock();
277
278     LayoutUnit availableLogicalWidth = containingBlockLogicalWidthForContent();
279     bool hasPerpendicularContainingBlock = cb.style().isHorizontalWritingMode() != style().isHorizontalWritingMode();
280     LayoutUnit containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth;
281
282     Length styleLogicalWidth = style().logicalWidth();
283     if ((styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive()) || styleLogicalWidth.isIntrinsic())
284         setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
285     else {
286         // Subtract out any fixed margins from our available width for auto width tables.
287         LayoutUnit marginStart = minimumValueForLength(style().marginStart(), availableLogicalWidth);
288         LayoutUnit marginEnd = minimumValueForLength(style().marginEnd(), availableLogicalWidth);
289         LayoutUnit marginTotal = marginStart + marginEnd;
290
291         // Subtract out our margins to get the available content width.
292         LayoutUnit availableContentLogicalWidth = std::max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
293         if (shrinkToAvoidFloats() && cb.containsFloats() && !hasPerpendicularContainingBlock) {
294             // FIXME: Work with regions someday.
295             availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, 0);
296         }
297
298         // Ensure we aren't bigger than our available width.
299         setLogicalWidth(std::min(availableContentLogicalWidth, maxPreferredLogicalWidth()));
300         LayoutUnit maxWidth = maxPreferredLogicalWidth();
301         // scaledWidthFromPercentColumns depends on m_layoutStruct in TableLayoutAlgorithmAuto, which
302         // maxPreferredLogicalWidth fills in. So scaledWidthFromPercentColumns has to be called after
303         // maxPreferredLogicalWidth.
304         LayoutUnit scaledWidth = m_tableLayout->scaledWidthFromPercentColumns() + bordersPaddingAndSpacingInRowDirection();
305         maxWidth = std::max(scaledWidth, maxWidth);
306         setLogicalWidth(std::min(availableContentLogicalWidth, maxWidth));
307     }
308
309     // Ensure we aren't smaller than our min preferred width.
310     setLogicalWidth(std::max(logicalWidth(), minPreferredLogicalWidth()));
311
312     
313     // Ensure we aren't bigger than our max-width style.
314     Length styleMaxLogicalWidth = style().logicalMaxWidth();
315     if ((styleMaxLogicalWidth.isSpecified() && !styleMaxLogicalWidth.isNegative()) || styleMaxLogicalWidth.isIntrinsic()) {
316         LayoutUnit computedMaxLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMaxLogicalWidth, availableLogicalWidth);
317         setLogicalWidth(std::min(logicalWidth(), computedMaxLogicalWidth));
318     }
319
320     // Ensure we aren't smaller than our min-width style.
321     Length styleMinLogicalWidth = style().logicalMinWidth();
322     if ((styleMinLogicalWidth.isSpecified() && !styleMinLogicalWidth.isNegative()) || styleMinLogicalWidth.isIntrinsic()) {
323         LayoutUnit computedMinLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth);
324         setLogicalWidth(std::max(logicalWidth(), computedMinLogicalWidth));
325     }
326
327     // Finally, with our true width determined, compute our margins for real.
328     setMarginStart(0);
329     setMarginEnd(0);
330     if (!hasPerpendicularContainingBlock) {
331         LayoutUnit containerLogicalWidthForAutoMargins = availableLogicalWidth;
332         if (avoidsFloats() && cb.containsFloats())
333             containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(0); // FIXME: Work with regions someday.
334         ComputedMarginValues marginValues;
335         bool hasInvertedDirection =  cb.style().isLeftToRightDirection() == style().isLeftToRightDirection();
336         computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth(),
337             hasInvertedDirection ? marginValues.m_start : marginValues.m_end,
338             hasInvertedDirection ? marginValues.m_end : marginValues.m_start);
339         setMarginStart(marginValues.m_start);
340         setMarginEnd(marginValues.m_end);
341     } else {
342         setMarginStart(minimumValueForLength(style().marginStart(), availableLogicalWidth));
343         setMarginEnd(minimumValueForLength(style().marginEnd(), availableLogicalWidth));
344     }
345 }
346
347 // This method takes a RenderStyle's logical width, min-width, or max-width length and computes its actual value.
348 LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth)
349 {
350     if (styleLogicalWidth.isIntrinsic())
351         return computeIntrinsicLogicalWidthUsing(styleLogicalWidth, availableWidth, bordersPaddingAndSpacingInRowDirection());
352
353     // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
354     LayoutUnit borders = 0;
355     bool isCSSTable = !is<HTMLTableElement>(element());
356     if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive() && style().boxSizing() == CONTENT_BOX)
357         borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd());
358
359     return minimumValueForLength(styleLogicalWidth, availableWidth) + borders;
360 }
361
362 LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length& styleLogicalHeight)
363 {
364     LayoutUnit borderAndPaddingBefore = borderBefore() + (collapseBorders() ? LayoutUnit() : paddingBefore());
365     LayoutUnit borderAndPaddingAfter = borderAfter() + (collapseBorders() ? LayoutUnit() : paddingAfter());
366     LayoutUnit borderAndPadding = borderAndPaddingBefore + borderAndPaddingAfter;
367     if (styleLogicalHeight.isFixed()) {
368         // HTML tables size as though CSS height includes border/padding, CSS tables do not.
369         LayoutUnit borders = LayoutUnit();
370         // FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow.
371         if (is<HTMLTableElement>(element()) || style().boxSizing() == BORDER_BOX) {
372             borders = borderAndPadding;
373         }
374         return styleLogicalHeight.value() - borders;
375     } else if (styleLogicalHeight.isPercentOrCalculated())
376         return computePercentageLogicalHeight(styleLogicalHeight).valueOr(0);
377     else if (styleLogicalHeight.isIntrinsic())
378         return computeIntrinsicLogicalContentHeightUsing(styleLogicalHeight, logicalHeight() - borderAndPadding, borderAndPadding).valueOr(0);
379     else
380         ASSERT_NOT_REACHED();
381     return LayoutUnit();
382 }
383
384 void RenderTable::layoutCaption(RenderTableCaption* caption)
385 {
386     LayoutRect captionRect(caption->frameRect());
387
388     if (caption->needsLayout()) {
389         // The margins may not be available but ensure the caption is at least located beneath any previous sibling caption
390         // so that it does not mistakenly think any floats in the previous caption intrude into it.
391         caption->setLogicalLocation(LayoutPoint(caption->marginStart(), caption->marginBefore() + logicalHeight()));
392         // If RenderTableCaption ever gets a layout() function, use it here.
393         caption->layoutIfNeeded();
394     }
395     // Apply the margins to the location now that they are definitely available from layout
396     caption->setLogicalLocation(LayoutPoint(caption->marginStart(), caption->marginBefore() + logicalHeight()));
397
398     if (!selfNeedsLayout() && caption->checkForRepaintDuringLayout())
399         caption->repaintDuringLayoutIfMoved(captionRect);
400
401     setLogicalHeight(logicalHeight() + caption->logicalHeight() + caption->marginBefore() + caption->marginAfter());
402 }
403
404 void RenderTable::distributeExtraLogicalHeight(LayoutUnit extraLogicalHeight)
405 {
406     if (extraLogicalHeight <= 0)
407         return;
408
409     // FIXME: Distribute the extra logical height between all table sections instead of giving it all to the first one.
410     if (RenderTableSection* section = firstBody())
411         extraLogicalHeight -= section->distributeExtraLogicalHeightToRows(extraLogicalHeight);
412
413     // FIXME: We really would like to enable this ASSERT to ensure that all the extra space has been distributed.
414     // However our current distribution algorithm does not round properly and thus we can have some remaining height.
415     // ASSERT(!topSection() || !extraLogicalHeight);
416 }
417
418 void RenderTable::simplifiedNormalFlowLayout()
419 {
420     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
421         section->layoutIfNeeded();
422         section->computeOverflowFromCells();
423     }
424 }
425
426 void RenderTable::layout()
427 {
428     StackStats::LayoutCheckPoint layoutCheckPoint;
429     ASSERT(needsLayout());
430
431     if (simplifiedLayout())
432         return;
433
434     recalcSectionsIfNeeded();
435     // FIXME: We should do this recalc lazily in borderStart/borderEnd so that we don't have to make sure
436     // to call this before we call borderStart/borderEnd to avoid getting a stale value.
437     recalcBordersInRowDirection();
438
439     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
440     LayoutStateMaintainer statePusher(view(), *this, locationOffset(), hasTransform() || hasReflection() || style().isFlippedBlocksWritingMode());
441
442     LayoutUnit oldLogicalWidth = logicalWidth();
443     LayoutUnit oldLogicalHeight = logicalHeight();
444     setLogicalHeight(0);
445     updateLogicalWidth();
446
447     if (logicalWidth() != oldLogicalWidth) {
448         for (unsigned i = 0; i < m_captions.size(); i++)
449             m_captions[i]->setNeedsLayout(MarkOnlyThis);
450     }
451     // FIXME: The optimisation below doesn't work since the internal table
452     // layout could have changed.  we need to add a flag to the table
453     // layout that tells us if something has changed in the min max
454     // calculations to do it correctly.
455 //     if ( oldWidth != width() || columns.size() + 1 != columnPos.size() )
456     m_tableLayout->layout();
457
458     LayoutUnit totalSectionLogicalHeight = 0;
459     LayoutUnit oldTableLogicalTop = 0;
460     for (unsigned i = 0; i < m_captions.size(); i++)
461         oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
462
463     bool collapsing = collapseBorders();
464
465     for (auto& child : childrenOfType<RenderElement>(*this)) {
466         if (is<RenderTableSection>(child)) {
467             RenderTableSection& section = downcast<RenderTableSection>(child);
468             if (m_columnLogicalWidthChanged)
469                 section.setChildNeedsLayout(MarkOnlyThis);
470             section.layoutIfNeeded();
471             totalSectionLogicalHeight += section.calcRowLogicalHeight();
472             if (collapsing)
473                 section.recalcOuterBorder();
474             ASSERT(!section.needsLayout());
475         } else if (is<RenderTableCol>(child)) {
476             downcast<RenderTableCol>(child).layoutIfNeeded();
477             ASSERT(!child.needsLayout());
478         }
479     }
480
481     // If any table section moved vertically, we will just repaint everything from that
482     // section down (it is quite unlikely that any of the following sections
483     // did not shift).
484     bool sectionMoved = false;
485     LayoutUnit movedSectionLogicalTop = 0;
486
487     // FIXME: Collapse caption margin.
488     if (!m_captions.isEmpty()) {
489         for (unsigned i = 0; i < m_captions.size(); i++) {
490             if (m_captions[i]->style().captionSide() == CAPBOTTOM)
491                 continue;
492             layoutCaption(m_captions[i]);
493         }
494         if (logicalHeight() != oldTableLogicalTop) {
495             sectionMoved = true;
496             movedSectionLogicalTop = std::min(logicalHeight(), oldTableLogicalTop);
497         }
498     }
499
500     LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? LayoutUnit() : paddingBefore());
501     LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
502
503     setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
504
505     if (!isOutOfFlowPositioned())
506         updateLogicalHeight();
507
508     LayoutUnit computedLogicalHeight = 0;
509     
510     Length logicalHeightLength = style().logicalHeight();
511     if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive()))
512         computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
513     
514     Length logicalMaxHeightLength = style().logicalMaxHeight();
515     if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative())) {
516         LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMaxHeightLength);
517         computedLogicalHeight = std::min(computedLogicalHeight, computedMaxLogicalHeight);
518     }
519
520     Length logicalMinHeightLength = style().logicalMinHeight();
521     if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative())) {
522         LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMinHeightLength);
523         computedLogicalHeight = std::max(computedLogicalHeight, computedMinLogicalHeight);
524     }
525
526     distributeExtraLogicalHeight(computedLogicalHeight - totalSectionLogicalHeight);
527
528     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
529         section->layoutRows();
530
531     if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
532         // Completely empty tables (with no sections or anything) should at least honor specified height
533         // in strict mode.
534         setLogicalHeight(logicalHeight() + computedLogicalHeight);
535     }
536
537     LayoutUnit sectionLogicalLeft = style().isLeftToRightDirection() ? borderStart() : borderEnd();
538     if (!collapsing)
539         sectionLogicalLeft += style().isLeftToRightDirection() ? paddingStart() : paddingEnd();
540
541     // position the table sections
542     RenderTableSection* section = topSection();
543     while (section) {
544         if (!sectionMoved && section->logicalTop() != logicalHeight()) {
545             sectionMoved = true;
546             movedSectionLogicalTop = std::min(logicalHeight(), section->logicalTop()) + (style().isHorizontalWritingMode() ? section->visualOverflowRect().y() : section->visualOverflowRect().x());
547         }
548         section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeight()));
549
550         setLogicalHeight(logicalHeight() + section->logicalHeight());
551         section = sectionBelow(section);
552     }
553
554     setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
555
556     for (unsigned i = 0; i < m_captions.size(); i++) {
557         if (m_captions[i]->style().captionSide() != CAPBOTTOM)
558             continue;
559         layoutCaption(m_captions[i]);
560     }
561
562     if (isOutOfFlowPositioned())
563         updateLogicalHeight();
564
565     // table can be containing block of positioned elements.
566     bool dimensionChanged = oldLogicalWidth != logicalWidth() || oldLogicalHeight != logicalHeight();
567     layoutPositionedObjects(dimensionChanged);
568
569     updateLayerTransform();
570
571     // Layout was changed, so probably borders too.
572     invalidateCollapsedBorders();
573
574     // The location or height of one or more sections may have changed.
575     invalidateCachedColumnOffsets();
576
577     computeOverflow(clientLogicalBottom());
578
579     statePusher.pop();
580
581     if (view().layoutState()->pageLogicalHeight())
582         setPageLogicalOffset(view().layoutState()->pageLogicalOffset(this, logicalTop()));
583
584     bool didFullRepaint = repainter.repaintAfterLayout();
585     // Repaint with our new bounds if they are different from our old bounds.
586     if (!didFullRepaint && sectionMoved) {
587         if (style().isHorizontalWritingMode())
588             repaintRectangle(LayoutRect(visualOverflowRect().x(), movedSectionLogicalTop, visualOverflowRect().width(), visualOverflowRect().maxY() - movedSectionLogicalTop));
589         else
590             repaintRectangle(LayoutRect(movedSectionLogicalTop, visualOverflowRect().y(), visualOverflowRect().maxX() - movedSectionLogicalTop, visualOverflowRect().height()));
591     }
592
593     m_columnLogicalWidthChanged = false;
594     clearNeedsLayout();
595 }
596
597 void RenderTable::invalidateCollapsedBorders(RenderTableCell* cellWithStyleChange)
598 {
599     m_collapsedBordersValid = false;
600     m_collapsedBorders.clear();
601
602     for (auto& section : childrenOfType<RenderTableSection>(*this))
603         section.clearCachedCollapsedBorders();
604
605     if (!m_collapsedEmptyBorderIsPresent)
606         return;
607
608     if (cellWithStyleChange) {
609         // It is enough to invalidate just the surrounding cells when cell border style changes.
610         cellWithStyleChange->invalidateHasEmptyCollapsedBorders();
611         if (auto* below = cellBelow(cellWithStyleChange))
612             below->invalidateHasEmptyCollapsedBorders();
613         if (auto* above = cellAbove(cellWithStyleChange))
614             above->invalidateHasEmptyCollapsedBorders();
615         if (auto* before = cellBefore(cellWithStyleChange))
616             before->invalidateHasEmptyCollapsedBorders();
617         if (auto* after = cellAfter(cellWithStyleChange))
618             after->invalidateHasEmptyCollapsedBorders();
619         return;
620     }
621
622     for (auto& section : childrenOfType<RenderTableSection>(*this)) {
623         for (auto* row = section.firstRow(); row; row = row->nextRow()) {
624             for (auto* cell = row->firstCell(); cell; cell = cell->nextCell()) {
625                 ASSERT(cell->table() == this);
626                 cell->invalidateHasEmptyCollapsedBorders();
627             }
628         }
629     }
630     m_collapsedEmptyBorderIsPresent = false;
631 }
632
633 // Collect all the unique border values that we want to paint in a sorted list.
634 void RenderTable::recalcCollapsedBorders()
635 {
636     if (m_collapsedBordersValid)
637         return;
638     m_collapsedBorders.clear();
639     for (auto& section : childrenOfType<RenderTableSection>(*this)) {
640         for (RenderTableRow* row = section.firstRow(); row; row = row->nextRow()) {
641             for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) {
642                 ASSERT(cell->table() == this);
643                 cell->collectBorderValues(m_collapsedBorders);
644             }
645         }
646     }
647     RenderTableCell::sortBorderValues(m_collapsedBorders);
648     m_collapsedBordersValid = true;
649 }
650
651 void RenderTable::addOverflowFromChildren()
652 {
653     // Add overflow from borders.
654     // Technically it's odd that we are incorporating the borders into layout overflow, which is only supposed to be about overflow from our
655     // descendant objects, but since tables don't support overflow:auto, this works out fine.
656     if (collapseBorders()) {
657         LayoutUnit rightBorderOverflow = width() + outerBorderRight() - borderRight();
658         LayoutUnit leftBorderOverflow = borderLeft() - outerBorderLeft();
659         LayoutUnit bottomBorderOverflow = height() + outerBorderBottom() - borderBottom();
660         LayoutUnit topBorderOverflow = borderTop() - outerBorderTop();
661         LayoutRect borderOverflowRect(leftBorderOverflow, topBorderOverflow, rightBorderOverflow - leftBorderOverflow, bottomBorderOverflow - topBorderOverflow);
662         if (borderOverflowRect != borderBoxRect()) {
663             addLayoutOverflow(borderOverflowRect);
664             addVisualOverflow(borderOverflowRect);
665         }
666     }
667
668     // Add overflow from our caption.
669     for (unsigned i = 0; i < m_captions.size(); i++) 
670         addOverflowFromChild(m_captions[i]);
671
672     // Add overflow from our sections.
673     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
674         addOverflowFromChild(section);
675 }
676
677 void RenderTable::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
678 {
679     LayoutPoint adjustedPaintOffset = paintOffset + location();
680
681     PaintPhase paintPhase = paintInfo.phase;
682
683     if (!isDocumentElementRenderer()) {
684         LayoutRect overflowBox = visualOverflowRect();
685         flipForWritingMode(overflowBox);
686         overflowBox.moveBy(adjustedPaintOffset);
687         if (!overflowBox.intersects(paintInfo.rect))
688             return;
689     }
690
691     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
692     paintObject(paintInfo, adjustedPaintOffset);
693     if (pushedClip)
694         popContentsClip(paintInfo, paintPhase, adjustedPaintOffset);
695 }
696
697 void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
698 {
699     PaintPhase paintPhase = paintInfo.phase;
700     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasVisibleBoxDecorations() && style().visibility() == VISIBLE)
701         paintBoxDecorations(paintInfo, paintOffset);
702
703     if (paintPhase == PaintPhaseMask) {
704         paintMask(paintInfo, paintOffset);
705         return;
706     }
707
708     // We're done.  We don't bother painting any children.
709     if (paintPhase == PaintPhaseBlockBackground)
710         return;
711     
712     // We don't paint our own background, but we do let the kids paint their backgrounds.
713     if (paintPhase == PaintPhaseChildBlockBackgrounds)
714         paintPhase = PaintPhaseChildBlockBackground;
715
716     PaintInfo info(paintInfo);
717     info.phase = paintPhase;
718     info.updateSubtreePaintRootForChildren(this);
719
720     for (auto& box : childrenOfType<RenderBox>(*this)) {
721         if (!box.hasSelfPaintingLayer() && (box.isTableSection() || box.isTableCaption())) {
722             LayoutPoint childPoint = flipForWritingModeForChild(&box, paintOffset);
723             box.paint(info, childPoint);
724         }
725     }
726     
727     if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style().visibility() == VISIBLE) {
728         recalcCollapsedBorders();
729         // Using our cached sorted styles, we then do individual passes,
730         // painting each style of border from lowest precedence to highest precedence.
731         info.phase = PaintPhaseCollapsedTableBorders;
732         size_t count = m_collapsedBorders.size();
733         for (size_t i = 0; i < count; ++i) {
734             m_currentBorder = &m_collapsedBorders[i];
735             for (RenderTableSection* section = bottomSection(); section; section = sectionAbove(section)) {
736                 LayoutPoint childPoint = flipForWritingModeForChild(section, paintOffset);
737                 section->paint(info, childPoint);
738             }
739         }
740         m_currentBorder = 0;
741     }
742
743     // Paint outline.
744     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style().visibility() == VISIBLE)
745         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
746 }
747
748 void RenderTable::subtractCaptionRect(LayoutRect& rect) const
749 {
750     for (unsigned i = 0; i < m_captions.size(); i++) {
751         LayoutUnit captionLogicalHeight = m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
752         bool captionIsBefore = (m_captions[i]->style().captionSide() != CAPBOTTOM) ^ style().isFlippedBlocksWritingMode();
753         if (style().isHorizontalWritingMode()) {
754             rect.setHeight(rect.height() - captionLogicalHeight);
755             if (captionIsBefore)
756                 rect.move(0, captionLogicalHeight);
757         } else {
758             rect.setWidth(rect.width() - captionLogicalHeight);
759             if (captionIsBefore)
760                 rect.move(captionLogicalHeight, 0);
761         }
762     }
763 }
764
765 void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
766 {
767     if (!paintInfo.shouldPaintWithinRoot(*this))
768         return;
769
770     LayoutRect rect(paintOffset, size());
771     subtractCaptionRect(rect);
772
773     BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context());
774     if (!boxShadowShouldBeAppliedToBackground(rect.location(), bleedAvoidance))
775         paintBoxShadow(paintInfo, rect, style(), Normal);
776     paintBackground(paintInfo, rect, bleedAvoidance);
777     paintBoxShadow(paintInfo, rect, style(), Inset);
778
779     if (style().hasVisibleBorderDecoration() && !collapseBorders())
780         paintBorder(paintInfo, rect, style());
781 }
782
783 void RenderTable::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
784 {
785     if (style().visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
786         return;
787
788     LayoutRect rect(paintOffset, size());
789     subtractCaptionRect(rect);
790
791     paintMaskImages(paintInfo, rect);
792 }
793
794 void RenderTable::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) const
795 {
796     recalcSectionsIfNeeded();
797     // FIXME: Do the recalc in borderStart/borderEnd and make those const_cast this call.
798     // Then m_borderStart/m_borderEnd will be transparent a cache and it removes the possibility
799     // of reading out stale values.
800     const_cast<RenderTable*>(this)->recalcBordersInRowDirection();
801     // FIXME: Restructure the table layout code so that we can make this method const.
802     const_cast<RenderTable*>(this)->m_tableLayout->computeIntrinsicLogicalWidths(minWidth, maxWidth);
803
804     // FIXME: We should include captions widths here like we do in computePreferredLogicalWidths.
805 }
806
807 void RenderTable::computePreferredLogicalWidths()
808 {
809     ASSERT(preferredLogicalWidthsDirty());
810
811     computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
812
813     LayoutUnit bordersPaddingAndSpacing = bordersPaddingAndSpacingInRowDirection();
814     m_minPreferredLogicalWidth += bordersPaddingAndSpacing;
815     m_maxPreferredLogicalWidth += bordersPaddingAndSpacing;
816
817     m_tableLayout->applyPreferredLogicalWidthQuirks(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
818
819     for (unsigned i = 0; i < m_captions.size(); i++)
820         m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, m_captions[i]->minPreferredLogicalWidth());
821
822     auto& styleToUse = style();
823     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for min-width.
824     if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
825         m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
826         m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
827     }
828
829     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for maxWidth.
830     if (styleToUse.logicalMaxWidth().isFixed()) {
831         m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
832         m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
833     }
834
835     // FIXME: We should be adding borderAndPaddingLogicalWidth here, but m_tableLayout->computePreferredLogicalWidths already does,
836     // so a bunch of tests break doing this naively.
837     setPreferredLogicalWidthsDirty(false);
838 }
839
840 RenderTableSection* RenderTable::topNonEmptySection() const
841 {
842     RenderTableSection* section = topSection();
843     if (section && !section->numRows())
844         section = sectionBelow(section, SkipEmptySections);
845     return section;
846 }
847
848 void RenderTable::splitColumn(unsigned position, unsigned firstSpan)
849 {
850     // We split the column at "position", taking "firstSpan" cells from the span.
851     ASSERT(m_columns[position].span > firstSpan);
852     m_columns.insert(position, ColumnStruct(firstSpan));
853     m_columns[position + 1].span -= firstSpan;
854
855     // Propagate the change in our columns representation to the sections that don't need
856     // cell recalc. If they do, they will be synced up directly with m_columns later.
857     for (auto& section : childrenOfType<RenderTableSection>(*this)) {
858         if (section.needsCellRecalc())
859             continue;
860
861         section.splitColumn(position, firstSpan);
862     }
863
864     m_columnPos.grow(numEffCols() + 1);
865 }
866
867 void RenderTable::appendColumn(unsigned span)
868 {
869     unsigned newColumnIndex = m_columns.size();
870     m_columns.append(ColumnStruct(span));
871
872     // Unless the table has cell(s) with colspan that exceed the number of columns afforded
873     // by the other rows in the table we can use the fast path when mapping columns to effective columns.
874     m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTableWidth || span > 1;
875
876     // Propagate the change in our columns representation to the sections that don't need
877     // cell recalc. If they do, they will be synced up directly with m_columns later.
878     for (auto& section : childrenOfType<RenderTableSection>(*this)) {
879         if (section.needsCellRecalc())
880             continue;
881
882         section.appendColumn(newColumnIndex);
883     }
884
885     m_columnPos.grow(numEffCols() + 1);
886 }
887
888 RenderTableCol* RenderTable::firstColumn() const
889 {
890     for (auto& child : childrenOfType<RenderObject>(*this)) {
891         if (is<RenderTableCol>(child))
892             return &const_cast<RenderTableCol&>(downcast<RenderTableCol>(child));
893
894         // We allow only table-captions before columns or column-groups.
895         if (!is<RenderTableCaption>(child))
896             return nullptr;
897     }
898
899     return nullptr;
900 }
901
902 void RenderTable::updateColumnCache() const
903 {
904     ASSERT(m_hasColElements);
905     ASSERT(m_columnRenderers.isEmpty());
906     ASSERT(m_effectiveColumnIndexMap.isEmpty());
907     ASSERT(!m_columnRenderersValid);
908
909     unsigned columnIndex = 0;
910     for (RenderTableCol* columnRenderer = firstColumn(); columnRenderer; columnRenderer = columnRenderer->nextColumn()) {
911         if (columnRenderer->isTableColumnGroupWithColumnChildren())
912             continue;
913         m_columnRenderers.append(columnRenderer);
914         // FIXME: We should look to compute the effective column index successively from previous values instead of
915         // calling colToEffCol(), which is in O(numEffCols()). Although it's unlikely that this is a hot function.
916         m_effectiveColumnIndexMap.add(columnRenderer, colToEffCol(columnIndex));
917         columnIndex += columnRenderer->span();
918     }
919     m_columnRenderersValid = true;
920 }
921
922 unsigned RenderTable::effectiveIndexOfColumn(const RenderTableCol& column) const
923 {
924     if (!m_columnRenderersValid)
925         updateColumnCache();
926     const RenderTableCol* columnToUse = &column;
927     if (columnToUse->isTableColumnGroupWithColumnChildren())
928         columnToUse = columnToUse->nextColumn(); // First column in column-group
929     auto it = m_effectiveColumnIndexMap.find(columnToUse);
930     ASSERT(it != m_effectiveColumnIndexMap.end());
931     if (it == m_effectiveColumnIndexMap.end())
932         return std::numeric_limits<unsigned>::max();
933     return it->value;
934 }
935
936 LayoutUnit RenderTable::offsetTopForColumn(const RenderTableCol& column) const
937 {
938     if (effectiveIndexOfColumn(column) >= numEffCols())
939         return 0;
940     if (m_columnOffsetTop >= 0) {
941         ASSERT(!needsLayout());
942         return m_columnOffsetTop;
943     }
944     RenderTableSection* section = topNonEmptySection();
945     return m_columnOffsetTop = section ? section->offsetTop() : LayoutUnit(0);
946 }
947
948 LayoutUnit RenderTable::offsetLeftForColumn(const RenderTableCol& column) const
949 {
950     unsigned columnIndex = effectiveIndexOfColumn(column);
951     if (columnIndex >= numEffCols())
952         return 0;
953     return m_columnPos[columnIndex] + m_hSpacing + borderLeft();
954 }
955
956 LayoutUnit RenderTable::offsetWidthForColumn(const RenderTableCol& column) const
957 {
958     const RenderTableCol* currentColumn = &column;
959     bool hasColumnChildren;
960     if ((hasColumnChildren = currentColumn->isTableColumnGroupWithColumnChildren()))
961         currentColumn = currentColumn->nextColumn(); // First column in column-group
962     unsigned numberOfEffectiveColumns = numEffCols();
963     ASSERT_WITH_SECURITY_IMPLICATION(m_columnPos.size() >= numberOfEffectiveColumns + 1);
964     LayoutUnit width = 0;
965     LayoutUnit spacing = m_hSpacing;
966     while (currentColumn) {
967         unsigned columnIndex = effectiveIndexOfColumn(*currentColumn);
968         unsigned span = currentColumn->span();
969         while (span && columnIndex < numberOfEffectiveColumns) {
970             width += m_columnPos[columnIndex + 1] - m_columnPos[columnIndex] - spacing;
971             span -= m_columns[columnIndex].span;
972             ++columnIndex;
973             if (span)
974                 width += spacing;
975         }
976         if (!hasColumnChildren)
977             break;
978         currentColumn = currentColumn->nextColumn();
979         if (!currentColumn || currentColumn->isTableColumnGroup())
980             break;
981         width += spacing;
982     }
983     return width;
984 }
985
986 LayoutUnit RenderTable::offsetHeightForColumn(const RenderTableCol& column) const
987 {
988     if (effectiveIndexOfColumn(column) >= numEffCols())
989         return 0;
990     if (m_columnOffsetHeight >= 0) {
991         ASSERT(!needsLayout());
992         return m_columnOffsetHeight;
993     }
994     LayoutUnit height = 0;
995     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
996         height += section->offsetHeight();
997     m_columnOffsetHeight = height;
998     return m_columnOffsetHeight;
999 }
1000
1001 RenderTableCol* RenderTable::slowColElement(unsigned col, bool* startEdge, bool* endEdge) const
1002 {
1003     ASSERT(m_hasColElements);
1004
1005     if (!m_columnRenderersValid)
1006         updateColumnCache();
1007
1008     unsigned columnCount = 0;
1009     for (unsigned i = 0; i < m_columnRenderers.size(); i++) {
1010         RenderTableCol* columnRenderer = m_columnRenderers[i];
1011         unsigned span = columnRenderer->span();
1012         unsigned startCol = columnCount;
1013         ASSERT(span >= 1);
1014         unsigned endCol = columnCount + span - 1;
1015         columnCount += span;
1016         if (columnCount > col) {
1017             if (startEdge)
1018                 *startEdge = startCol == col;
1019             if (endEdge)
1020                 *endEdge = endCol == col;
1021             return columnRenderer;
1022         }
1023     }
1024     return 0;
1025 }
1026
1027 void RenderTable::recalcSections() const
1028 {
1029     ASSERT(m_needsSectionRecalc);
1030
1031     m_head = 0;
1032     m_foot = 0;
1033     m_firstBody = 0;
1034     m_hasColElements = false;
1035     m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTableWidth();
1036
1037     // We need to get valid pointers to caption, head, foot and first body again
1038     RenderObject* nextSibling;
1039     for (RenderObject* child = firstChild(); child; child = nextSibling) {
1040         nextSibling = child->nextSibling();
1041         switch (child->style().display()) {
1042         case TABLE_COLUMN:
1043         case TABLE_COLUMN_GROUP:
1044             m_hasColElements = true;
1045             break;
1046         case TABLE_HEADER_GROUP:
1047             if (is<RenderTableSection>(*child)) {
1048                 RenderTableSection& section = downcast<RenderTableSection>(*child);
1049                 if (!m_head)
1050                     m_head = &section;
1051                 else if (!m_firstBody)
1052                     m_firstBody = &section;
1053                 section.recalcCellsIfNeeded();
1054             }
1055             break;
1056         case TABLE_FOOTER_GROUP:
1057             if (is<RenderTableSection>(*child)) {
1058                 RenderTableSection& section = downcast<RenderTableSection>(*child);
1059                 if (!m_foot)
1060                     m_foot = &section;
1061                 else if (!m_firstBody)
1062                     m_firstBody = &section;
1063                 section.recalcCellsIfNeeded();
1064             }
1065             break;
1066         case TABLE_ROW_GROUP:
1067             if (is<RenderTableSection>(*child)) {
1068                 RenderTableSection& section = downcast<RenderTableSection>(*child);
1069                 if (!m_firstBody)
1070                     m_firstBody = &section;
1071                 section.recalcCellsIfNeeded();
1072             }
1073             break;
1074         default:
1075             break;
1076         }
1077     }
1078
1079     // repair column count (addChild can grow it too much, because it always adds elements to the last row of a section)
1080     unsigned maxCols = 0;
1081     for (auto& section : childrenOfType<RenderTableSection>(*this)) {
1082         unsigned sectionCols = section.numColumns();
1083         if (sectionCols > maxCols)
1084             maxCols = sectionCols;
1085     }
1086     
1087     m_columns.resize(maxCols);
1088     m_columnPos.resize(maxCols + 1);
1089
1090     ASSERT(selfNeedsLayout());
1091
1092     m_needsSectionRecalc = false;
1093 }
1094
1095 LayoutUnit RenderTable::calcBorderStart() const
1096 {
1097     if (!collapseBorders())
1098         return RenderBlock::borderStart();
1099
1100     // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2.
1101     if (!numEffCols())
1102         return 0;
1103
1104     float borderWidth = 0;
1105
1106     const BorderValue& tableStartBorder = style().borderStart();
1107     if (tableStartBorder.style() == BHIDDEN)
1108         return 0;
1109     if (tableStartBorder.style() > BHIDDEN)
1110         borderWidth = tableStartBorder.width();
1111
1112     if (RenderTableCol* column = colElement(0)) {
1113         // FIXME: We don't account for direction on columns and column groups.
1114         const BorderValue& columnAdjoiningBorder = column->style().borderStart();
1115         if (columnAdjoiningBorder.style() == BHIDDEN)
1116             return 0;
1117         if (columnAdjoiningBorder.style() > BHIDDEN)
1118             borderWidth = std::max(borderWidth, columnAdjoiningBorder.width());
1119         // FIXME: This logic doesn't properly account for the first column in the first column-group case.
1120     }
1121
1122     if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
1123         const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableStart();
1124         if (sectionAdjoiningBorder.style() == BHIDDEN)
1125             return 0;
1126
1127         if (sectionAdjoiningBorder.style() > BHIDDEN)
1128             borderWidth = std::max(borderWidth, sectionAdjoiningBorder.width());
1129
1130         if (const RenderTableCell* adjoiningStartCell = topNonEmptySection->firstRowCellAdjoiningTableStart()) {
1131             // FIXME: Make this work with perpendicular and flipped cells.
1132             const BorderValue& startCellAdjoiningBorder = adjoiningStartCell->borderAdjoiningTableStart();
1133             if (startCellAdjoiningBorder.style() == BHIDDEN)
1134                 return 0;
1135
1136             const BorderValue& firstRowAdjoiningBorder = adjoiningStartCell->row()->borderAdjoiningTableStart();
1137             if (firstRowAdjoiningBorder.style() == BHIDDEN)
1138                 return 0;
1139
1140             if (startCellAdjoiningBorder.style() > BHIDDEN)
1141                 borderWidth = std::max(borderWidth, startCellAdjoiningBorder.width());
1142             if (firstRowAdjoiningBorder.style() > BHIDDEN)
1143                 borderWidth = std::max(borderWidth, firstRowAdjoiningBorder.width());
1144         }
1145     }
1146     return CollapsedBorderValue::adjustedCollapsedBorderWidth(borderWidth, document().deviceScaleFactor(), !style().isLeftToRightDirection());
1147 }
1148
1149 LayoutUnit RenderTable::calcBorderEnd() const
1150 {
1151     if (!collapseBorders())
1152         return RenderBlock::borderEnd();
1153
1154     // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2.
1155     if (!numEffCols())
1156         return 0;
1157
1158     float borderWidth = 0;
1159
1160     const BorderValue& tableEndBorder = style().borderEnd();
1161     if (tableEndBorder.style() == BHIDDEN)
1162         return 0;
1163     if (tableEndBorder.style() > BHIDDEN)
1164         borderWidth = tableEndBorder.width();
1165
1166     unsigned endColumn = numEffCols() - 1;
1167     if (RenderTableCol* column = colElement(endColumn)) {
1168         // FIXME: We don't account for direction on columns and column groups.
1169         const BorderValue& columnAdjoiningBorder = column->style().borderEnd();
1170         if (columnAdjoiningBorder.style() == BHIDDEN)
1171             return 0;
1172         if (columnAdjoiningBorder.style() > BHIDDEN)
1173             borderWidth = std::max(borderWidth, columnAdjoiningBorder.width());
1174         // FIXME: This logic doesn't properly account for the last column in the last column-group case.
1175     }
1176
1177     if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
1178         const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableEnd();
1179         if (sectionAdjoiningBorder.style() == BHIDDEN)
1180             return 0;
1181
1182         if (sectionAdjoiningBorder.style() > BHIDDEN)
1183             borderWidth = std::max(borderWidth, sectionAdjoiningBorder.width());
1184
1185         if (const RenderTableCell* adjoiningEndCell = topNonEmptySection->firstRowCellAdjoiningTableEnd()) {
1186             // FIXME: Make this work with perpendicular and flipped cells.
1187             const BorderValue& endCellAdjoiningBorder = adjoiningEndCell->borderAdjoiningTableEnd();
1188             if (endCellAdjoiningBorder.style() == BHIDDEN)
1189                 return 0;
1190
1191             const BorderValue& firstRowAdjoiningBorder = adjoiningEndCell->row()->borderAdjoiningTableEnd();
1192             if (firstRowAdjoiningBorder.style() == BHIDDEN)
1193                 return 0;
1194
1195             if (endCellAdjoiningBorder.style() > BHIDDEN)
1196                 borderWidth = std::max(borderWidth, endCellAdjoiningBorder.width());
1197             if (firstRowAdjoiningBorder.style() > BHIDDEN)
1198                 borderWidth = std::max(borderWidth, firstRowAdjoiningBorder.width());
1199         }
1200     }
1201     return CollapsedBorderValue::adjustedCollapsedBorderWidth(borderWidth, document().deviceScaleFactor(), style().isLeftToRightDirection());
1202 }
1203
1204 void RenderTable::recalcBordersInRowDirection()
1205 {
1206     // FIXME: We need to compute the collapsed before / after borders in the same fashion.
1207     m_borderStart = calcBorderStart();
1208     m_borderEnd = calcBorderEnd();
1209 }
1210
1211 LayoutUnit RenderTable::borderBefore() const
1212 {
1213     if (collapseBorders()) {
1214         recalcSectionsIfNeeded();
1215         return outerBorderBefore();
1216     }
1217     return RenderBlock::borderBefore();
1218 }
1219
1220 LayoutUnit RenderTable::borderAfter() const
1221 {
1222     if (collapseBorders()) {
1223         recalcSectionsIfNeeded();
1224         return outerBorderAfter();
1225     }
1226     return RenderBlock::borderAfter();
1227 }
1228
1229 LayoutUnit RenderTable::outerBorderBefore() const
1230 {
1231     if (!collapseBorders())
1232         return 0;
1233     LayoutUnit borderWidth = 0;
1234     if (RenderTableSection* topSection = this->topSection()) {
1235         borderWidth = topSection->outerBorderBefore();
1236         if (borderWidth < 0)
1237             return 0;   // Overridden by hidden
1238     }
1239     const BorderValue& tb = style().borderBefore();
1240     if (tb.style() == BHIDDEN)
1241         return 0;
1242     if (tb.style() > BHIDDEN) {
1243         LayoutUnit collapsedBorderWidth = std::max<LayoutUnit>(borderWidth, tb.width() / 2);
1244         borderWidth = floorToDevicePixel(collapsedBorderWidth, document().deviceScaleFactor());
1245     }
1246     return borderWidth;
1247 }
1248
1249 LayoutUnit RenderTable::outerBorderAfter() const
1250 {
1251     if (!collapseBorders())
1252         return 0;
1253     LayoutUnit borderWidth = 0;
1254
1255     if (RenderTableSection* section = bottomSection()) {
1256         borderWidth = section->outerBorderAfter();
1257         if (borderWidth < 0)
1258             return 0; // Overridden by hidden
1259     }
1260     const BorderValue& tb = style().borderAfter();
1261     if (tb.style() == BHIDDEN)
1262         return 0;
1263     if (tb.style() > BHIDDEN) {
1264         float deviceScaleFactor = document().deviceScaleFactor();
1265         LayoutUnit collapsedBorderWidth = std::max<LayoutUnit>(borderWidth, (tb.width() + (1 / deviceScaleFactor)) / 2);
1266         borderWidth = floorToDevicePixel(collapsedBorderWidth, deviceScaleFactor);
1267     }
1268     return borderWidth;
1269 }
1270
1271 LayoutUnit RenderTable::outerBorderStart() const
1272 {
1273     if (!collapseBorders())
1274         return 0;
1275
1276     LayoutUnit borderWidth = 0;
1277
1278     const BorderValue& tb = style().borderStart();
1279     if (tb.style() == BHIDDEN)
1280         return 0;
1281     if (tb.style() > BHIDDEN)
1282         return CollapsedBorderValue::adjustedCollapsedBorderWidth(tb.width(), document().deviceScaleFactor(), !style().isLeftToRightDirection());
1283
1284     bool allHidden = true;
1285     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
1286         LayoutUnit sw = section->outerBorderStart();
1287         if (sw < 0)
1288             continue;
1289         allHidden = false;
1290         borderWidth = std::max(borderWidth, sw);
1291     }
1292     if (allHidden)
1293         return 0;
1294
1295     return borderWidth;
1296 }
1297
1298 LayoutUnit RenderTable::outerBorderEnd() const
1299 {
1300     if (!collapseBorders())
1301         return 0;
1302
1303     LayoutUnit borderWidth = 0;
1304
1305     const BorderValue& tb = style().borderEnd();
1306     if (tb.style() == BHIDDEN)
1307         return 0;
1308     if (tb.style() > BHIDDEN)
1309         return CollapsedBorderValue::adjustedCollapsedBorderWidth(tb.width(), document().deviceScaleFactor(), style().isLeftToRightDirection());
1310
1311     bool allHidden = true;
1312     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
1313         LayoutUnit sw = section->outerBorderEnd();
1314         if (sw < 0)
1315             continue;
1316         allHidden = false;
1317         borderWidth = std::max(borderWidth, sw);
1318     }
1319     if (allHidden)
1320         return 0;
1321
1322     return borderWidth;
1323 }
1324
1325 RenderTableSection* RenderTable::sectionAbove(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1326 {
1327     recalcSectionsIfNeeded();
1328
1329     if (section == m_head)
1330         return nullptr;
1331
1332     RenderObject* prevSection = section == m_foot ? lastChild() : section->previousSibling();
1333     while (prevSection) {
1334         if (is<RenderTableSection>(*prevSection) && prevSection != m_head && prevSection != m_foot && (skipEmptySections == DoNotSkipEmptySections || downcast<RenderTableSection>(*prevSection).numRows()))
1335             break;
1336         prevSection = prevSection->previousSibling();
1337     }
1338     if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections || m_head->numRows()))
1339         prevSection = m_head;
1340     return downcast<RenderTableSection>(prevSection);
1341 }
1342
1343 RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1344 {
1345     recalcSectionsIfNeeded();
1346
1347     if (section == m_foot)
1348         return nullptr;
1349
1350     RenderObject* nextSection = section == m_head ? firstChild() : section->nextSibling();
1351     while (nextSection) {
1352         if (is<RenderTableSection>(*nextSection) && nextSection != m_head && nextSection != m_foot && (skipEmptySections  == DoNotSkipEmptySections || downcast<RenderTableSection>(*nextSection).numRows()))
1353             break;
1354         nextSection = nextSection->nextSibling();
1355     }
1356     if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections || m_foot->numRows()))
1357         nextSection = m_foot;
1358     return downcast<RenderTableSection>(nextSection);
1359 }
1360
1361 RenderTableSection* RenderTable::bottomSection() const
1362 {
1363     recalcSectionsIfNeeded();
1364
1365     if (m_foot)
1366         return m_foot;
1367
1368     for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
1369         if (is<RenderTableSection>(*child))
1370             return downcast<RenderTableSection>(child);
1371     }
1372
1373     return nullptr;
1374 }
1375
1376 RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
1377 {
1378     recalcSectionsIfNeeded();
1379
1380     // Find the section and row to look in
1381     unsigned r = cell->rowIndex();
1382     RenderTableSection* section = nullptr;
1383     unsigned rAbove = 0;
1384     if (r > 0) {
1385         // cell is not in the first row, so use the above row in its own section
1386         section = cell->section();
1387         rAbove = r - 1;
1388     } else {
1389         section = sectionAbove(cell->section(), SkipEmptySections);
1390         if (section) {
1391             ASSERT(section->numRows());
1392             rAbove = section->numRows() - 1;
1393         }
1394     }
1395
1396     // Look up the cell in the section's grid, which requires effective col index
1397     if (section) {
1398         unsigned effCol = colToEffCol(cell->col());
1399         RenderTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effCol);
1400         return aboveCell.primaryCell();
1401     } else
1402         return nullptr;
1403 }
1404
1405 RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
1406 {
1407     recalcSectionsIfNeeded();
1408
1409     // Find the section and row to look in
1410     unsigned r = cell->rowIndex() + cell->rowSpan() - 1;
1411     RenderTableSection* section = nullptr;
1412     unsigned rBelow = 0;
1413     if (r < cell->section()->numRows() - 1) {
1414         // The cell is not in the last row, so use the next row in the section.
1415         section = cell->section();
1416         rBelow = r + 1;
1417     } else {
1418         section = sectionBelow(cell->section(), SkipEmptySections);
1419         if (section)
1420             rBelow = 0;
1421     }
1422
1423     // Look up the cell in the section's grid, which requires effective col index
1424     if (section) {
1425         unsigned effCol = colToEffCol(cell->col());
1426         RenderTableSection::CellStruct& belowCell = section->cellAt(rBelow, effCol);
1427         return belowCell.primaryCell();
1428     } else
1429         return nullptr;
1430 }
1431
1432 RenderTableCell* RenderTable::cellBefore(const RenderTableCell* cell) const
1433 {
1434     recalcSectionsIfNeeded();
1435
1436     RenderTableSection* section = cell->section();
1437     unsigned effCol = colToEffCol(cell->col());
1438     if (!effCol)
1439         return nullptr;
1440     
1441     // If we hit a colspan back up to a real cell.
1442     RenderTableSection::CellStruct& prevCell = section->cellAt(cell->rowIndex(), effCol - 1);
1443     return prevCell.primaryCell();
1444 }
1445
1446 RenderTableCell* RenderTable::cellAfter(const RenderTableCell* cell) const
1447 {
1448     recalcSectionsIfNeeded();
1449
1450     unsigned effCol = colToEffCol(cell->col() + cell->colSpan());
1451     if (effCol >= numEffCols())
1452         return nullptr;
1453     return cell->section()->primaryCellAt(cell->rowIndex(), effCol);
1454 }
1455
1456 RenderBlock* RenderTable::firstLineBlock() const
1457 {
1458     return nullptr;
1459 }
1460
1461 void RenderTable::updateFirstLetter()
1462 {
1463 }
1464
1465 int RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
1466 {
1467     return firstLineBaseline().valueOrCompute([&] {
1468         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
1469     });
1470 }
1471
1472 Optional<int> RenderTable::inlineBlockBaseline(LineDirectionMode) const
1473 {
1474     // Tables are skipped when computing an inline-block's baseline.
1475     return Optional<int>();
1476 }
1477
1478 Optional<int> RenderTable::firstLineBaseline() const
1479 {
1480     // The baseline of a 'table' is the same as the 'inline-table' baseline per CSS 3 Flexbox (CSS 2.1
1481     // doesn't define the baseline of a 'table' only an 'inline-table').
1482     // This is also needed to properly determine the baseline of a cell if it has a table child.
1483
1484     if (isWritingModeRoot())
1485         return Optional<int>();
1486
1487     recalcSectionsIfNeeded();
1488
1489     const RenderTableSection* topNonEmptySection = this->topNonEmptySection();
1490     if (!topNonEmptySection)
1491         return Optional<int>();
1492
1493     if (Optional<int> baseline = topNonEmptySection->firstLineBaseline())
1494         return Optional<int>(topNonEmptySection->logicalTop() + baseline.value());
1495
1496     // FIXME: A table row always has a baseline per CSS 2.1. Will this return the right value?
1497     return Optional<int>();
1498 }
1499
1500 LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy, PaintPhase phase)
1501 {
1502     LayoutRect rect;
1503     // Don't clip out the table's side of the collapsed borders if we're in the paint phase that will ask the sections to paint them.
1504     // Likewise, if we're self-painting we avoid clipping them out as the clip rect that will be passed down to child layers from RenderLayer will do that instead.
1505     if (phase == PaintPhaseChildBlockBackgrounds || layer()->isSelfPaintingLayer()) {
1506         rect = borderBoxRectInRegion(region);
1507         rect.setLocation(location + rect.location());
1508     } else
1509         rect = RenderBox::overflowClipRect(location, region, relevancy);
1510     
1511     // If we have a caption, expand the clip to include the caption.
1512     // FIXME: Technically this is wrong, but it's virtually impossible to fix this
1513     // for real until captions have been re-written.
1514     // FIXME: This code assumes (like all our other caption code) that only top/bottom are
1515     // supported.  When we actually support left/right and stop mapping them to top/bottom,
1516     // we might have to hack this code first (depending on what order we do these bug fixes in).
1517     if (!m_captions.isEmpty()) {
1518         if (style().isHorizontalWritingMode()) {
1519             rect.setHeight(height());
1520             rect.setY(location.y());
1521         } else {
1522             rect.setWidth(width());
1523             rect.setX(location.x());
1524         }
1525     }
1526
1527     return rect;
1528 }
1529
1530 bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
1531 {
1532     LayoutPoint adjustedLocation = accumulatedOffset + location();
1533
1534     // Check kids first.
1535     if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(adjustedLocation, currentRenderNamedFlowFragment()))) {
1536         for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
1537             if (is<RenderBox>(*child) && !downcast<RenderBox>(*child).hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
1538                 LayoutPoint childPoint = flipForWritingModeForChild(downcast<RenderBox>(child), adjustedLocation);
1539                 if (child->nodeAtPoint(request, result, locationInContainer, childPoint, action)) {
1540                     updateHitTestResult(result, toLayoutPoint(locationInContainer.point() - childPoint));
1541                     return true;
1542                 }
1543             }
1544         }
1545     }
1546
1547     // Check our bounds next.
1548     LayoutRect boundsRect(adjustedLocation, size());
1549     if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && locationInContainer.intersects(boundsRect)) {
1550         updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(adjustedLocation)));
1551         if (!result.addNodeToRectBasedTestResult(element(), request, locationInContainer, boundsRect))
1552             return true;
1553     }
1554
1555     return false;
1556 }
1557
1558 RenderTable* RenderTable::createAnonymousWithParentRenderer(const RenderObject* parent)
1559 {
1560     auto table = new RenderTable(parent->document(), RenderStyle::createAnonymousStyleWithDisplay(parent->style(), parent->style().display() == INLINE ? INLINE_TABLE : TABLE));
1561     table->initializeStyle();
1562     return table;
1563 }
1564
1565 const BorderValue& RenderTable::tableStartBorderAdjoiningCell(const RenderTableCell& cell) const
1566 {
1567     ASSERT(cell.isFirstOrLastCellInRow());
1568     if (hasSameDirectionAs(cell.row()))
1569         return style().borderStart();
1570
1571     return style().borderEnd();
1572 }
1573
1574 const BorderValue& RenderTable::tableEndBorderAdjoiningCell(const RenderTableCell& cell) const
1575 {
1576     ASSERT(cell.isFirstOrLastCellInRow());
1577     if (hasSameDirectionAs(cell.row()))
1578         return style().borderEnd();
1579
1580     return style().borderStart();
1581 }
1582
1583 void RenderTable::markForPaginationRelayoutIfNeeded()
1584 {
1585     if (!view().layoutState()->isPaginated() || (!view().layoutState()->pageLogicalHeightChanged() && (!view().layoutState()->pageLogicalHeight() || view().layoutState()->pageLogicalOffset(this, logicalTop()) == pageLogicalOffset())))
1586         return;
1587     
1588     // When a table moves, we have to dirty all of the sections too.
1589     if (!needsLayout())
1590         setChildNeedsLayout(MarkOnlyThis);
1591     for (auto& child : childrenOfType<RenderTableSection>(*this)) {
1592         if (!child.needsLayout())
1593             child.setChildNeedsLayout(MarkOnlyThis);
1594     }
1595 }
1596
1597 }