| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
| 3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
| 4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
| 5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
All rights reserved. |
| 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 m_tableLayout = adoptPtr(new LayoutTableAlgorithmFixed(this)); | 96 m_tableLayout = adoptPtr(new LayoutTableAlgorithmFixed(this)); |
| 97 else | 97 else |
| 98 m_tableLayout = adoptPtr(new LayoutTableAlgorithmAuto(this)); | 98 m_tableLayout = adoptPtr(new LayoutTableAlgorithmAuto(this)); |
| 99 } | 99 } |
| 100 | 100 |
| 101 // If border was changed, invalidate collapsed borders cache. | 101 // If border was changed, invalidate collapsed borders cache. |
| 102 if (!needsLayout() && oldStyle && oldStyle->border() != style()->border()) | 102 if (!needsLayout() && oldStyle && oldStyle->border() != style()->border()) |
| 103 invalidateCollapsedBorders(); | 103 invalidateCollapsedBorders(); |
| 104 } | 104 } |
| 105 | 105 |
| 106 static inline void resetSectionPointerIfNotBefore(LayoutTableSection*& ptr, Rend
erObject* before) | 106 static inline void resetSectionPointerIfNotBefore(LayoutTableSection*& ptr, Layo
utObject* before) |
| 107 { | 107 { |
| 108 if (!before || !ptr) | 108 if (!before || !ptr) |
| 109 return; | 109 return; |
| 110 RenderObject* o = before->previousSibling(); | 110 LayoutObject* o = before->previousSibling(); |
| 111 while (o && o != ptr) | 111 while (o && o != ptr) |
| 112 o = o->previousSibling(); | 112 o = o->previousSibling(); |
| 113 if (!o) | 113 if (!o) |
| 114 ptr = 0; | 114 ptr = 0; |
| 115 } | 115 } |
| 116 | 116 |
| 117 static inline bool needsTableSection(RenderObject* object) | 117 static inline bool needsTableSection(LayoutObject* object) |
| 118 { | 118 { |
| 119 // Return true if 'object' can't exist in an anonymous table without being | 119 // Return true if 'object' can't exist in an anonymous table without being |
| 120 // wrapped in a table section box. | 120 // wrapped in a table section box. |
| 121 EDisplay display = object->style()->display(); | 121 EDisplay display = object->style()->display(); |
| 122 return display != TABLE_CAPTION && display != TABLE_COLUMN_GROUP && display
!= TABLE_COLUMN; | 122 return display != TABLE_CAPTION && display != TABLE_COLUMN_GROUP && display
!= TABLE_COLUMN; |
| 123 } | 123 } |
| 124 | 124 |
| 125 void LayoutTable::addChild(RenderObject* child, RenderObject* beforeChild) | 125 void LayoutTable::addChild(LayoutObject* child, LayoutObject* beforeChild) |
| 126 { | 126 { |
| 127 bool wrapInAnonymousSection = !child->isOutOfFlowPositioned(); | 127 bool wrapInAnonymousSection = !child->isOutOfFlowPositioned(); |
| 128 | 128 |
| 129 if (child->isTableCaption()) { | 129 if (child->isTableCaption()) { |
| 130 wrapInAnonymousSection = false; | 130 wrapInAnonymousSection = false; |
| 131 } else if (child->isLayoutTableCol()) { | 131 } else if (child->isLayoutTableCol()) { |
| 132 m_hasColElements = true; | 132 m_hasColElements = true; |
| 133 wrapInAnonymousSection = false; | 133 wrapInAnonymousSection = false; |
| 134 } else if (child->isTableSection()) { | 134 } else if (child->isTableSection()) { |
| 135 switch (child->style()->display()) { | 135 switch (child->style()->display()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 RenderBox::addChild(child, beforeChild); | 175 RenderBox::addChild(child, beforeChild); |
| 176 return; | 176 return; |
| 177 } | 177 } |
| 178 | 178 |
| 179 if (!beforeChild && lastChild() && lastChild()->isTableSection() && lastChil
d()->isAnonymous() && !lastChild()->isBeforeContent()) { | 179 if (!beforeChild && lastChild() && lastChild()->isTableSection() && lastChil
d()->isAnonymous() && !lastChild()->isBeforeContent()) { |
| 180 lastChild()->addChild(child); | 180 lastChild()->addChild(child); |
| 181 return; | 181 return; |
| 182 } | 182 } |
| 183 | 183 |
| 184 if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == t
his) { | 184 if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == t
his) { |
| 185 RenderObject* section = beforeChild->previousSibling(); | 185 LayoutObject* section = beforeChild->previousSibling(); |
| 186 if (section && section->isTableSection() && section->isAnonymous()) { | 186 if (section && section->isTableSection() && section->isAnonymous()) { |
| 187 section->addChild(child); | 187 section->addChild(child); |
| 188 return; | 188 return; |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 | 191 |
| 192 RenderObject* lastBox = beforeChild; | 192 LayoutObject* lastBox = beforeChild; |
| 193 while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSecti
on() && needsTableSection(lastBox)) | 193 while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSecti
on() && needsTableSection(lastBox)) |
| 194 lastBox = lastBox->parent(); | 194 lastBox = lastBox->parent(); |
| 195 if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) { | 195 if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) { |
| 196 if (beforeChild == lastBox) | 196 if (beforeChild == lastBox) |
| 197 beforeChild = lastBox->slowFirstChild(); | 197 beforeChild = lastBox->slowFirstChild(); |
| 198 lastBox->addChild(child, beforeChild); | 198 lastBox->addChild(child, beforeChild); |
| 199 return; | 199 return; |
| 200 } | 200 } |
| 201 | 201 |
| 202 if (beforeChild && !beforeChild->isTableSection() && needsTableSection(befor
eChild)) | 202 if (beforeChild && !beforeChild->isTableSection() && needsTableSection(befor
eChild)) |
| 203 beforeChild = 0; | 203 beforeChild = 0; |
| 204 | 204 |
| 205 LayoutTableSection* section = LayoutTableSection::createAnonymousWithParentR
enderer(this); | 205 LayoutTableSection* section = LayoutTableSection::createAnonymousWithParentR
enderer(this); |
| 206 addChild(section, beforeChild); | 206 addChild(section, beforeChild); |
| 207 section->addChild(child); | 207 section->addChild(child); |
| 208 } | 208 } |
| 209 | 209 |
| 210 void LayoutTable::addChildIgnoringContinuation(RenderObject* newChild, RenderObj
ect* beforeChild) | 210 void LayoutTable::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObj
ect* beforeChild) |
| 211 { | 211 { |
| 212 // We need to bypass the RenderBlock implementation and instead do a normal
addChild() (or we | 212 // We need to bypass the RenderBlock implementation and instead do a normal
addChild() (or we |
| 213 // won't get there at all), so that any missing anonymous table part rendere
rs are | 213 // won't get there at all), so that any missing anonymous table part rendere
rs are |
| 214 // inserted. Otherwise we might end up with an insane render tree with inlin
es or blocks as | 214 // inserted. Otherwise we might end up with an insane render tree with inlin
es or blocks as |
| 215 // direct children of a table, which will break assumptions made all over th
e code, which may | 215 // direct children of a table, which will break assumptions made all over th
e code, which may |
| 216 // lead to crashers and security issues. | 216 // lead to crashers and security issues. |
| 217 addChild(newChild, beforeChild); | 217 addChild(newChild, beforeChild); |
| 218 } | 218 } |
| 219 | 219 |
| 220 void LayoutTable::addCaption(const LayoutTableCaption* caption) | 220 void LayoutTable::addCaption(const LayoutTableCaption* caption) |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() ) | 452 // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() ) |
| 453 m_tableLayout->layout(); | 453 m_tableLayout->layout(); |
| 454 | 454 |
| 455 LayoutUnit totalSectionLogicalHeight = 0; | 455 LayoutUnit totalSectionLogicalHeight = 0; |
| 456 LayoutUnit oldTableLogicalTop = 0; | 456 LayoutUnit oldTableLogicalTop = 0; |
| 457 for (unsigned i = 0; i < m_captions.size(); i++) | 457 for (unsigned i = 0; i < m_captions.size(); i++) |
| 458 oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]
->marginBefore() + m_captions[i]->marginAfter(); | 458 oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]
->marginBefore() + m_captions[i]->marginAfter(); |
| 459 | 459 |
| 460 bool collapsing = collapseBorders(); | 460 bool collapsing = collapseBorders(); |
| 461 | 461 |
| 462 for (RenderObject* child = firstChild(); child; child = child->nextSibli
ng()) { | 462 for (LayoutObject* child = firstChild(); child; child = child->nextSibli
ng()) { |
| 463 if (child->isTableSection()) { | 463 if (child->isTableSection()) { |
| 464 LayoutTableSection* section = toLayoutTableSection(child); | 464 LayoutTableSection* section = toLayoutTableSection(child); |
| 465 if (m_columnLogicalWidthChanged) | 465 if (m_columnLogicalWidthChanged) |
| 466 layouter.setChildNeedsLayout(section); | 466 layouter.setChildNeedsLayout(section); |
| 467 section->layoutIfNeeded(); | 467 section->layoutIfNeeded(); |
| 468 totalSectionLogicalHeight += section->calcRowLogicalHeight(); | 468 totalSectionLogicalHeight += section->calcRowLogicalHeight(); |
| 469 if (collapsing) | 469 if (collapsing) |
| 470 section->recalcOuterBorder(); | 470 section->recalcOuterBorder(); |
| 471 ASSERT(!section->needsLayout()); | 471 ASSERT(!section->needsLayout()); |
| 472 } else if (child->isLayoutTableCol()) { | 472 } else if (child->isLayoutTableCol()) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 clearNeedsLayout(); | 582 clearNeedsLayout(); |
| 583 } | 583 } |
| 584 | 584 |
| 585 // Collect all the unique border values that we want to paint in a sorted list. | 585 // Collect all the unique border values that we want to paint in a sorted list. |
| 586 void LayoutTable::recalcCollapsedBorders() | 586 void LayoutTable::recalcCollapsedBorders() |
| 587 { | 587 { |
| 588 if (m_collapsedBordersValid) | 588 if (m_collapsedBordersValid) |
| 589 return; | 589 return; |
| 590 m_collapsedBordersValid = true; | 590 m_collapsedBordersValid = true; |
| 591 m_collapsedBorders.clear(); | 591 m_collapsedBorders.clear(); |
| 592 for (RenderObject* section = firstChild(); section; section = section->nextS
ibling()) { | 592 for (LayoutObject* section = firstChild(); section; section = section->nextS
ibling()) { |
| 593 if (!section->isTableSection()) | 593 if (!section->isTableSection()) |
| 594 continue; | 594 continue; |
| 595 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); ro
w; row = row->nextRow()) { | 595 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); ro
w; row = row->nextRow()) { |
| 596 for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->ne
xtCell()) { | 596 for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->ne
xtCell()) { |
| 597 ASSERT(cell->table() == this); | 597 ASSERT(cell->table() == this); |
| 598 cell->collectBorderValues(m_collapsedBorders); | 598 cell->collectBorderValues(m_collapsedBorders); |
| 599 } | 599 } |
| 600 } | 600 } |
| 601 } | 601 } |
| 602 LayoutTableCell::sortBorderValues(m_collapsedBorders); | 602 LayoutTableCell::sortBorderValues(m_collapsedBorders); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 | 717 |
| 718 void LayoutTable::splitColumn(unsigned position, unsigned firstSpan) | 718 void LayoutTable::splitColumn(unsigned position, unsigned firstSpan) |
| 719 { | 719 { |
| 720 // We split the column at "position", taking "firstSpan" cells from the span
. | 720 // We split the column at "position", taking "firstSpan" cells from the span
. |
| 721 ASSERT(m_columns[position].span > firstSpan); | 721 ASSERT(m_columns[position].span > firstSpan); |
| 722 m_columns.insert(position, ColumnStruct(firstSpan)); | 722 m_columns.insert(position, ColumnStruct(firstSpan)); |
| 723 m_columns[position + 1].span -= firstSpan; | 723 m_columns[position + 1].span -= firstSpan; |
| 724 | 724 |
| 725 // Propagate the change in our columns representation to the sections that d
on't need | 725 // Propagate the change in our columns representation to the sections that d
on't need |
| 726 // cell recalc. If they do, they will be synced up directly with m_columns l
ater. | 726 // cell recalc. If they do, they will be synced up directly with m_columns l
ater. |
| 727 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { | 727 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 728 if (!child->isTableSection()) | 728 if (!child->isTableSection()) |
| 729 continue; | 729 continue; |
| 730 | 730 |
| 731 LayoutTableSection* section = toLayoutTableSection(child); | 731 LayoutTableSection* section = toLayoutTableSection(child); |
| 732 if (section->needsCellRecalc()) | 732 if (section->needsCellRecalc()) |
| 733 continue; | 733 continue; |
| 734 | 734 |
| 735 section->splitColumn(position, firstSpan); | 735 section->splitColumn(position, firstSpan); |
| 736 } | 736 } |
| 737 | 737 |
| 738 m_columnPos.grow(numEffCols() + 1); | 738 m_columnPos.grow(numEffCols() + 1); |
| 739 } | 739 } |
| 740 | 740 |
| 741 void LayoutTable::appendColumn(unsigned span) | 741 void LayoutTable::appendColumn(unsigned span) |
| 742 { | 742 { |
| 743 unsigned newColumnIndex = m_columns.size(); | 743 unsigned newColumnIndex = m_columns.size(); |
| 744 m_columns.append(ColumnStruct(span)); | 744 m_columns.append(ColumnStruct(span)); |
| 745 | 745 |
| 746 // Unless the table has cell(s) with colspan that exceed the number of colum
ns afforded | 746 // Unless the table has cell(s) with colspan that exceed the number of colum
ns afforded |
| 747 // by the other rows in the table we can use the fast path when mapping colu
mns to effective columns. | 747 // by the other rows in the table we can use the fast path when mapping colu
mns to effective columns. |
| 748 m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTab
leWidth || span > 1; | 748 m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTab
leWidth || span > 1; |
| 749 | 749 |
| 750 // Propagate the change in our columns representation to the sections that d
on't need | 750 // Propagate the change in our columns representation to the sections that d
on't need |
| 751 // cell recalc. If they do, they will be synced up directly with m_columns l
ater. | 751 // cell recalc. If they do, they will be synced up directly with m_columns l
ater. |
| 752 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { | 752 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 753 if (!child->isTableSection()) | 753 if (!child->isTableSection()) |
| 754 continue; | 754 continue; |
| 755 | 755 |
| 756 LayoutTableSection* section = toLayoutTableSection(child); | 756 LayoutTableSection* section = toLayoutTableSection(child); |
| 757 if (section->needsCellRecalc()) | 757 if (section->needsCellRecalc()) |
| 758 continue; | 758 continue; |
| 759 | 759 |
| 760 section->appendColumn(newColumnIndex); | 760 section->appendColumn(newColumnIndex); |
| 761 } | 761 } |
| 762 | 762 |
| 763 m_columnPos.grow(numEffCols() + 1); | 763 m_columnPos.grow(numEffCols() + 1); |
| 764 } | 764 } |
| 765 | 765 |
| 766 LayoutTableCol* LayoutTable::firstColumn() const | 766 LayoutTableCol* LayoutTable::firstColumn() const |
| 767 { | 767 { |
| 768 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { | 768 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 769 if (child->isLayoutTableCol()) | 769 if (child->isLayoutTableCol()) |
| 770 return toLayoutTableCol(child); | 770 return toLayoutTableCol(child); |
| 771 } | 771 } |
| 772 | 772 |
| 773 return 0; | 773 return 0; |
| 774 } | 774 } |
| 775 | 775 |
| 776 void LayoutTable::updateColumnCache() const | 776 void LayoutTable::updateColumnCache() const |
| 777 { | 777 { |
| 778 ASSERT(m_hasColElements); | 778 ASSERT(m_hasColElements); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 { | 817 { |
| 818 ASSERT(m_needsSectionRecalc); | 818 ASSERT(m_needsSectionRecalc); |
| 819 | 819 |
| 820 m_head = 0; | 820 m_head = 0; |
| 821 m_foot = 0; | 821 m_foot = 0; |
| 822 m_firstBody = 0; | 822 m_firstBody = 0; |
| 823 m_hasColElements = false; | 823 m_hasColElements = false; |
| 824 m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTable
Width(); | 824 m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTable
Width(); |
| 825 | 825 |
| 826 // We need to get valid pointers to caption, head, foot and first body again | 826 // We need to get valid pointers to caption, head, foot and first body again |
| 827 RenderObject* nextSibling; | 827 LayoutObject* nextSibling; |
| 828 for (RenderObject* child = firstChild(); child; child = nextSibling) { | 828 for (LayoutObject* child = firstChild(); child; child = nextSibling) { |
| 829 nextSibling = child->nextSibling(); | 829 nextSibling = child->nextSibling(); |
| 830 switch (child->style()->display()) { | 830 switch (child->style()->display()) { |
| 831 case TABLE_COLUMN: | 831 case TABLE_COLUMN: |
| 832 case TABLE_COLUMN_GROUP: | 832 case TABLE_COLUMN_GROUP: |
| 833 m_hasColElements = true; | 833 m_hasColElements = true; |
| 834 break; | 834 break; |
| 835 case TABLE_HEADER_GROUP: | 835 case TABLE_HEADER_GROUP: |
| 836 if (child->isTableSection()) { | 836 if (child->isTableSection()) { |
| 837 LayoutTableSection* section = toLayoutTableSection(child); | 837 LayoutTableSection* section = toLayoutTableSection(child); |
| 838 if (!m_head) | 838 if (!m_head) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 860 section->recalcCellsIfNeeded(); | 860 section->recalcCellsIfNeeded(); |
| 861 } | 861 } |
| 862 break; | 862 break; |
| 863 default: | 863 default: |
| 864 break; | 864 break; |
| 865 } | 865 } |
| 866 } | 866 } |
| 867 | 867 |
| 868 // repair column count (addChild can grow it too much, because it always add
s elements to the last row of a section) | 868 // repair column count (addChild can grow it too much, because it always add
s elements to the last row of a section) |
| 869 unsigned maxCols = 0; | 869 unsigned maxCols = 0; |
| 870 for (RenderObject* child = firstChild(); child; child = child->nextSibling()
) { | 870 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 871 if (child->isTableSection()) { | 871 if (child->isTableSection()) { |
| 872 LayoutTableSection* section = toLayoutTableSection(child); | 872 LayoutTableSection* section = toLayoutTableSection(child); |
| 873 unsigned sectionCols = section->numColumns(); | 873 unsigned sectionCols = section->numColumns(); |
| 874 if (sectionCols > maxCols) | 874 if (sectionCols > maxCols) |
| 875 maxCols = sectionCols; | 875 maxCols = sectionCols; |
| 876 } | 876 } |
| 877 } | 877 } |
| 878 | 878 |
| 879 m_columns.resize(maxCols); | 879 m_columns.resize(maxCols); |
| 880 m_columnPos.resize(maxCols + 1); | 880 m_columnPos.resize(maxCols + 1); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 return borderWidth; | 1109 return borderWidth; |
| 1110 } | 1110 } |
| 1111 | 1111 |
| 1112 LayoutTableSection* LayoutTable::sectionAbove(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const | 1112 LayoutTableSection* LayoutTable::sectionAbove(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const |
| 1113 { | 1113 { |
| 1114 recalcSectionsIfNeeded(); | 1114 recalcSectionsIfNeeded(); |
| 1115 | 1115 |
| 1116 if (section == m_head) | 1116 if (section == m_head) |
| 1117 return 0; | 1117 return 0; |
| 1118 | 1118 |
| 1119 RenderObject* prevSection = section == m_foot ? lastChild() : section->previ
ousSibling(); | 1119 LayoutObject* prevSection = section == m_foot ? lastChild() : section->previ
ousSibling(); |
| 1120 while (prevSection) { | 1120 while (prevSection) { |
| 1121 if (prevSection->isTableSection() && prevSection != m_head && prevSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSect
ion(prevSection)->numRows())) | 1121 if (prevSection->isTableSection() && prevSection != m_head && prevSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSect
ion(prevSection)->numRows())) |
| 1122 break; | 1122 break; |
| 1123 prevSection = prevSection->previousSibling(); | 1123 prevSection = prevSection->previousSibling(); |
| 1124 } | 1124 } |
| 1125 if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections |
| m_head->numRows())) | 1125 if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections |
| m_head->numRows())) |
| 1126 prevSection = m_head; | 1126 prevSection = m_head; |
| 1127 return toLayoutTableSection(prevSection); | 1127 return toLayoutTableSection(prevSection); |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 LayoutTableSection* LayoutTable::sectionBelow(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const | 1130 LayoutTableSection* LayoutTable::sectionBelow(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const |
| 1131 { | 1131 { |
| 1132 recalcSectionsIfNeeded(); | 1132 recalcSectionsIfNeeded(); |
| 1133 | 1133 |
| 1134 if (section == m_foot) | 1134 if (section == m_foot) |
| 1135 return 0; | 1135 return 0; |
| 1136 | 1136 |
| 1137 RenderObject* nextSection = section == m_head ? firstChild() : section->next
Sibling(); | 1137 LayoutObject* nextSection = section == m_head ? firstChild() : section->next
Sibling(); |
| 1138 while (nextSection) { | 1138 while (nextSection) { |
| 1139 if (nextSection->isTableSection() && nextSection != m_head && nextSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSec
tion(nextSection)->numRows())) | 1139 if (nextSection->isTableSection() && nextSection != m_head && nextSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSec
tion(nextSection)->numRows())) |
| 1140 break; | 1140 break; |
| 1141 nextSection = nextSection->nextSibling(); | 1141 nextSection = nextSection->nextSibling(); |
| 1142 } | 1142 } |
| 1143 if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections |
| m_foot->numRows())) | 1143 if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections |
| m_foot->numRows())) |
| 1144 nextSection = m_foot; | 1144 nextSection = m_foot; |
| 1145 return toLayoutTableSection(nextSection); | 1145 return toLayoutTableSection(nextSection); |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 LayoutTableSection* LayoutTable::bottomSection() const | 1148 LayoutTableSection* LayoutTable::bottomSection() const |
| 1149 { | 1149 { |
| 1150 recalcSectionsIfNeeded(); | 1150 recalcSectionsIfNeeded(); |
| 1151 | 1151 |
| 1152 if (m_foot) | 1152 if (m_foot) |
| 1153 return m_foot; | 1153 return m_foot; |
| 1154 | 1154 |
| 1155 for (RenderObject* child = lastChild(); child; child = child->previousSiblin
g()) { | 1155 for (LayoutObject* child = lastChild(); child; child = child->previousSiblin
g()) { |
| 1156 if (child->isTableSection()) | 1156 if (child->isTableSection()) |
| 1157 return toLayoutTableSection(child); | 1157 return toLayoutTableSection(child); |
| 1158 } | 1158 } |
| 1159 | 1159 |
| 1160 return 0; | 1160 return 0; |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 LayoutTableCell* LayoutTable::cellAbove(const LayoutTableCell* cell) const | 1163 LayoutTableCell* LayoutTable::cellAbove(const LayoutTableCell* cell) const |
| 1164 { | 1164 { |
| 1165 recalcSectionsIfNeeded(); | 1165 recalcSectionsIfNeeded(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 | 1304 |
| 1305 return rect; | 1305 return rect; |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 bool LayoutTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, HitTestAction action) | 1308 bool LayoutTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, HitTestAction action) |
| 1309 { | 1309 { |
| 1310 LayoutPoint adjustedLocation = accumulatedOffset + location(); | 1310 LayoutPoint adjustedLocation = accumulatedOffset + location(); |
| 1311 | 1311 |
| 1312 // Check kids first. | 1312 // Check kids first. |
| 1313 if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(ad
justedLocation))) { | 1313 if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(ad
justedLocation))) { |
| 1314 for (RenderObject* child = lastChild(); child; child = child->previousSi
bling()) { | 1314 for (LayoutObject* child = lastChild(); child; child = child->previousSi
bling()) { |
| 1315 if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() &&
(child->isTableSection() || child->isTableCaption())) { | 1315 if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() &&
(child->isTableSection() || child->isTableCaption())) { |
| 1316 LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(
child), adjustedLocation); | 1316 LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(
child), adjustedLocation); |
| 1317 if (child->nodeAtPoint(request, result, locationInContainer, chi
ldPoint, action)) { | 1317 if (child->nodeAtPoint(request, result, locationInContainer, chi
ldPoint, action)) { |
| 1318 updateHitTestResult(result, toLayoutPoint(locationInContaine
r.point() - childPoint)); | 1318 updateHitTestResult(result, toLayoutPoint(locationInContaine
r.point() - childPoint)); |
| 1319 return true; | 1319 return true; |
| 1320 } | 1320 } |
| 1321 } | 1321 } |
| 1322 } | 1322 } |
| 1323 } | 1323 } |
| 1324 | 1324 |
| 1325 // Check our bounds next. | 1325 // Check our bounds next. |
| 1326 LayoutRect boundsRect(adjustedLocation, size()); | 1326 LayoutRect boundsRect(adjustedLocation, size()); |
| 1327 if (visibleToHitTestRequest(request) && (action == HitTestBlockBackground ||
action == HitTestChildBlockBackground) && locationInContainer.intersects(bounds
Rect)) { | 1327 if (visibleToHitTestRequest(request) && (action == HitTestBlockBackground ||
action == HitTestChildBlockBackground) && locationInContainer.intersects(bounds
Rect)) { |
| 1328 updateHitTestResult(result, flipForWritingMode(locationInContainer.point
() - toLayoutSize(adjustedLocation))); | 1328 updateHitTestResult(result, flipForWritingMode(locationInContainer.point
() - toLayoutSize(adjustedLocation))); |
| 1329 if (!result.addNodeToRectBasedTestResult(node(), request, locationInCont
ainer, boundsRect)) | 1329 if (!result.addNodeToRectBasedTestResult(node(), request, locationInCont
ainer, boundsRect)) |
| 1330 return true; | 1330 return true; |
| 1331 } | 1331 } |
| 1332 | 1332 |
| 1333 return false; | 1333 return false; |
| 1334 } | 1334 } |
| 1335 | 1335 |
| 1336 LayoutTable* LayoutTable::createAnonymousWithParentRenderer(const RenderObject*
parent) | 1336 LayoutTable* LayoutTable::createAnonymousWithParentRenderer(const LayoutObject*
parent) |
| 1337 { | 1337 { |
| 1338 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parent->style(), TABLE); | 1338 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parent->style(), TABLE); |
| 1339 LayoutTable* newTable = new LayoutTable(0); | 1339 LayoutTable* newTable = new LayoutTable(0); |
| 1340 newTable->setDocumentForAnonymous(&parent->document()); | 1340 newTable->setDocumentForAnonymous(&parent->document()); |
| 1341 newTable->setStyle(newStyle.release()); | 1341 newTable->setStyle(newStyle.release()); |
| 1342 return newTable; | 1342 return newTable; |
| 1343 } | 1343 } |
| 1344 | 1344 |
| 1345 const BorderValue& LayoutTable::tableStartBorderAdjoiningCell(const LayoutTableC
ell* cell) const | 1345 const BorderValue& LayoutTable::tableStartBorderAdjoiningCell(const LayoutTableC
ell* cell) const |
| 1346 { | 1346 { |
| 1347 ASSERT(cell->isFirstOrLastCellInRow()); | 1347 ASSERT(cell->isFirstOrLastCellInRow()); |
| 1348 if (hasSameDirectionAs(cell->row())) | 1348 if (hasSameDirectionAs(cell->row())) |
| 1349 return style()->borderStart(); | 1349 return style()->borderStart(); |
| 1350 | 1350 |
| 1351 return style()->borderEnd(); | 1351 return style()->borderEnd(); |
| 1352 } | 1352 } |
| 1353 | 1353 |
| 1354 const BorderValue& LayoutTable::tableEndBorderAdjoiningCell(const LayoutTableCel
l* cell) const | 1354 const BorderValue& LayoutTable::tableEndBorderAdjoiningCell(const LayoutTableCel
l* cell) const |
| 1355 { | 1355 { |
| 1356 ASSERT(cell->isFirstOrLastCellInRow()); | 1356 ASSERT(cell->isFirstOrLastCellInRow()); |
| 1357 if (hasSameDirectionAs(cell->row())) | 1357 if (hasSameDirectionAs(cell->row())) |
| 1358 return style()->borderEnd(); | 1358 return style()->borderEnd(); |
| 1359 | 1359 |
| 1360 return style()->borderStart(); | 1360 return style()->borderStart(); |
| 1361 } | 1361 } |
| 1362 | 1362 |
| 1363 } | 1363 } |
| OLD | NEW |