Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| index ab9da43fce5fef66783948fcbd08f5af0ac5076b..1653c69b141a248b1959d22b6c00c2665946f5b4 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableCol.cpp |
| @@ -160,6 +160,22 @@ LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const |
| return parentColumnGroup; |
| } |
| +LayoutTableCol* LayoutTableCol::lastColumnInGroup() const |
| +{ |
| + ASSERT(this->isTableColumnGroupWithColumnChildren()); |
| + |
| + LayoutTableCol* endCol = nullptr; |
| + LayoutTableCol* currentCol = this->nextColumn(); |
| + // If column has children, traverse the children to find last. |
| + if (this->firstChild()) { |
| + while (currentCol && currentCol->enclosingColumnGroup() == this) { |
| + endCol = currentCol; |
| + currentCol = currentCol->nextColumn(); |
| + } |
| + } |
| + return endCol; |
| +} |
| + |
| LayoutTableCol* LayoutTableCol::nextColumn() const |
| { |
| // If |this| is a column-group, the next column is the colgroup's first child column. |
| @@ -170,8 +186,9 @@ LayoutTableCol* LayoutTableCol::nextColumn() const |
| LayoutObject* next = nextSibling(); |
| // Failing that, the child is the last column in a column-group, so the next column is the next column/column-group after its column-group. |
| - if (!next && parent()->isLayoutTableCol()) |
| - next = parent()->nextSibling(); |
| + auto p = parent(); |
| + if (!next && p && p->isLayoutTableCol()) |
| + next = p->nextSibling(); |
|
Xianzhu
2016/03/28 00:44:42
Is this change necessary?
atotic1
2016/03/29 17:05:16
I've seen parent() be null while debugging. That's
|
| for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } |
| @@ -200,4 +217,92 @@ const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel |
| return style()->borderEnd(); |
| } |
| +LayoutRect LayoutTableCol::positionByCellSpan(unsigned absoluteColumnIndex) const |
| +{ |
| + LayoutTable * table = this->table(); |
| + LayoutRect position; |
| + |
| + if (!table) |
| + return position; |
| + |
| + LayoutTableSection* topSection = table->topNonEmptySection(); |
| + LayoutTableSection* bottomSection = table->bottomNonEmptySection(); |
| + if (!topSection || !bottomSection) |
| + return position; |
| + |
| + Vector<unsigned> colIndexes = getEffectiveColumnIndexes(); |
| + |
| + if (colIndexes.size() == 0) |
| + return position; |
| + |
| + unsigned startColumnIndex = colIndexes[0]; |
| + unsigned endColumnIndex = colIndexes.last(); |
| + |
| + // Tricky: if <col> has a span, we need to pick a <col> of width 1 |
| + // that starts at absoluteColumnIndex |
| + if (isTableColumn() && colIndexes.size() > 1) { |
| + unsigned wantedEffectiveColumn = table->absoluteColumnToEffectiveColumn(absoluteColumnIndex); |
| + size_t wantedIt = colIndexes.find(wantedEffectiveColumn); |
| + ASSERT(wantedIt != kNotFound); |
| + startColumnIndex = colIndexes[wantedIt]; |
| + endColumnIndex = startColumnIndex; |
| + } |
| + position = topSection->getCellPhysicalPosition(0, startColumnIndex); |
| + position.moveBy(topSection->location()); |
| + LayoutRect bottomPosition = bottomSection->getCellPhysicalPosition(bottomSection->numRows() - 1, endColumnIndex); |
| + bottomPosition.moveBy(bottomSection->location()); |
| + position.uniteEvenIfEmpty(bottomPosition); |
| + return position; |
| +} |
| + |
| +Vector<unsigned> LayoutTableCol::getEffectiveColumnIndexes() const |
| +{ |
| + LayoutTable * table = this->table(); |
| + Vector<unsigned> indexes; |
| + |
| + if (!table) |
| + return indexes; |
| + |
| + unsigned lastEffectiveColumn = table->lastEffectiveColumnIndex(); |
| + |
| + if (isTableColumn()) { |
| + unsigned idx = table->colElementToAbsoluteColumn(this); |
| + auto span = this->span(); |
| + unsigned lastSeenColumn = 0xFFFFFFFF; |
| + while (span--) { |
| + unsigned effectiveColumn = table->absoluteColumnToEffectiveColumn(idx++); |
| + if (effectiveColumn != lastSeenColumn && effectiveColumn <= lastEffectiveColumn) { |
| + indexes.append(effectiveColumn); |
| + lastSeenColumn = effectiveColumn; |
| + } |
| + } |
| + } else { // isTableColumnGroup. |
| + if (isTableColumnGroupWithColumnChildren()) { |
| + LayoutTableCol* currentCol = nullptr; |
| + auto lastCol = lastColumnInGroup(); |
| + do { |
| + currentCol = currentCol ? currentCol->nextColumn() : nextColumn(); |
| + if (currentCol) { |
| + auto colIndexes = currentCol->getEffectiveColumnIndexes(); |
| + for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) |
| + indexes.append(*c); |
| + } |
| + } while (currentCol && currentCol != lastCol); |
| + } else { // tableColumnGroup with no children. |
| + // It extends over 'span' absolute columns. |
| + unsigned idx = table->colElementToAbsoluteColumn(this); |
| + auto span = this->span(); |
| + unsigned lastSeenColumn = 0xFFFFFFFF; |
| + while (span--) { |
| + unsigned effectiveColumn = table->absoluteColumnToEffectiveColumn(idx++); |
| + if (effectiveColumn != lastSeenColumn && effectiveColumn <= lastEffectiveColumn) { |
| + indexes.append(effectiveColumn); |
| + lastSeenColumn = effectiveColumn; |
| + } |
| + } |
| + } |
| + } |
| + return indexes; |
| +} |
| + |
| } // namespace blink |