Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1997 Martin Jones (mjones (at) kde.org)
      3  *           (C) 1997 Torben Weis (weis (at) kde.org)
      4  *           (C) 1998 Waldo Bastian (bastian (at) kde.org)
      5  *           (C) 1999 Lars Knoll (knoll (at) kde.org)
      6  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      7  * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
      8  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      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 "core/rendering/RenderTableCol.h"
     28 
     29 #include "HTMLNames.h"
     30 #include "core/html/HTMLTableColElement.h"
     31 #include "core/loader/cache/ImageResource.h"
     32 #include "core/rendering/RenderTable.h"
     33 #include "core/rendering/RenderTableCell.h"
     34 
     35 namespace WebCore {
     36 
     37 using namespace HTMLNames;
     38 
     39 RenderTableCol::RenderTableCol(Element* element)
     40     : RenderBox(element)
     41     , m_span(1)
     42 {
     43     // init RenderObject attributes
     44     setInline(true); // our object is not Inline
     45     updateFromElement();
     46 }
     47 
     48 void RenderTableCol::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
     49 {
     50     RenderBox::styleDidChange(diff, oldStyle);
     51 
     52     // If border was changed, notify table.
     53     if (parent()) {
     54         RenderTable* table = this->table();
     55         if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style()->border())
     56             table->invalidateCollapsedBorders();
     57     }
     58 }
     59 
     60 void RenderTableCol::updateFromElement()
     61 {
     62     unsigned oldSpan = m_span;
     63     Node* n = node();
     64     if (n && (n->hasTagName(colTag) || n->hasTagName(colgroupTag))) {
     65         HTMLTableColElement* tc = static_cast<HTMLTableColElement*>(n);
     66         m_span = tc->span();
     67     } else
     68         m_span = !(style() && style()->display() == TABLE_COLUMN_GROUP);
     69     if (m_span != oldSpan && style() && parent())
     70         setNeedsLayoutAndPrefWidthsRecalc();
     71 }
     72 
     73 void RenderTableCol::insertedIntoTree()
     74 {
     75     RenderBox::insertedIntoTree();
     76     table()->addColumn(this);
     77 }
     78 
     79 void RenderTableCol::willBeRemovedFromTree()
     80 {
     81     RenderBox::willBeRemovedFromTree();
     82     table()->removeColumn(this);
     83 }
     84 
     85 bool RenderTableCol::isChildAllowed(RenderObject* child, RenderStyle* style) const
     86 {
     87     // We cannot use isTableColumn here as style() may return 0.
     88     return child->isRenderTableCol() && style->display() == TABLE_COLUMN;
     89 }
     90 
     91 bool RenderTableCol::canHaveChildren() const
     92 {
     93     // Cols cannot have children. This is actually necessary to fix a bug
     94     // with libraries.uc.edu, which makes a <p> be a table-column.
     95     return isTableColumnGroup();
     96 }
     97 
     98 LayoutRect RenderTableCol::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
     99 {
    100     // For now, just repaint the whole table.
    101     // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
    102     // might have propagated a background color or borders into.
    103     // FIXME: check for repaintContainer each time here?
    104 
    105     RenderTable* parentTable = table();
    106     if (!parentTable)
    107         return LayoutRect();
    108     return parentTable->clippedOverflowRectForRepaint(repaintContainer);
    109 }
    110 
    111 void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*)
    112 {
    113     // FIXME: Repaint only the rect the image paints in.
    114     repaint();
    115 }
    116 
    117 void RenderTableCol::clearPreferredLogicalWidthsDirtyBits()
    118 {
    119     setPreferredLogicalWidthsDirty(false);
    120 
    121     for (RenderObject* child = firstChild(); child; child = child->nextSibling())
    122         child->setPreferredLogicalWidthsDirty(false);
    123 }
    124 
    125 RenderTable* RenderTableCol::table() const
    126 {
    127     RenderObject* table = parent();
    128     if (table && !table->isTable())
    129         table = table->parent();
    130     return table && table->isTable() ? toRenderTable(table) : 0;
    131 }
    132 
    133 RenderTableCol* RenderTableCol::enclosingColumnGroup() const
    134 {
    135     if (!parent()->isRenderTableCol())
    136         return 0;
    137 
    138     RenderTableCol* parentColumnGroup = toRenderTableCol(parent());
    139     ASSERT(parentColumnGroup->isTableColumnGroup());
    140     ASSERT(isTableColumn());
    141     return parentColumnGroup;
    142 }
    143 
    144 RenderTableCol* RenderTableCol::nextColumn() const
    145 {
    146     // If |this| is a column-group, the next column is the colgroup's first child column.
    147     if (RenderObject* firstChild = this->firstChild())
    148         return toRenderTableCol(firstChild);
    149 
    150     // Otherwise it's the next column along.
    151     RenderObject* next = nextSibling();
    152 
    153     // 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.
    154     if (!next && parent()->isRenderTableCol())
    155         next = parent()->nextSibling();
    156 
    157     for (; next && !next->isRenderTableCol(); next = next->nextSibling()) {
    158         // We allow captions mixed with columns and column-groups.
    159         if (next->isTableCaption())
    160             continue;
    161 
    162         return 0;
    163     }
    164 
    165     return toRenderTableCol(next);
    166 }
    167 
    168 const BorderValue& RenderTableCol::borderAdjoiningCellStartBorder(const RenderTableCell*) const
    169 {
    170     return style()->borderStart();
    171 }
    172 
    173 const BorderValue& RenderTableCol::borderAdjoiningCellEndBorder(const RenderTableCell*) const
    174 {
    175     return style()->borderEnd();
    176 }
    177 
    178 const BorderValue& RenderTableCol::borderAdjoiningCellBefore(const RenderTableCell* cell) const
    179 {
    180     ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()) == this);
    181     return style()->borderStart();
    182 }
    183 
    184 const BorderValue& RenderTableCol::borderAdjoiningCellAfter(const RenderTableCell* cell) const
    185 {
    186     ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1) == this);
    187     return style()->borderEnd();
    188 }
    189 
    190 }
    191