Changeset 164504 in webkit


Ignore:
Timestamp:
Feb 21, 2014 2:38:12 PM (10 years ago)
Author:
dbates@webkit.org
Message:

COL element in table has 0 for offsetWidth
https://bugs.webkit.org/show_bug.cgi?id=15277

Reviewed by David Hyatt.

Source/WebCore:

Implements offset{Left, Top, Width, Height} for table columns and column groups
per section Extensions to the HTMLElement Interface of the CSSOM View spec,
<http://www.w3.org/TR/cssom-view/#extensions-to-the-htmlelement-interface> (Draft 17 December 2013).

For now, we fail almost all of the offset{Height, Top} sub-tests in the included test
for the separate border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.

Test: fast/table/col-and-colgroup-offsets.html

  • rendering/RenderTable.cpp:

(WebCore::RenderTable::RenderTable): Initialize cached column offset top and offset height.
We cache these offsets since they are the same for all columns in the table.
(WebCore::RenderTable::invalidateCachedColumns): Clear cached effective column index map.
(WebCore::RenderTable::invalidateCachedColumnOffsets): Added.
(WebCore::RenderTable::layout): Invalidate cached column offsets as the location or height
of one or more sections may have changed.
(WebCore::RenderTable::updateColumnCache): Modified to build effective column index map.
(WebCore::RenderTable::effectiveIndexOfColumn): Added.
(WebCore::RenderTable::offsetTopForColumn): Added.
(WebCore::RenderTable::offsetLeftForColumn): Added.
(WebCore::RenderTable::offsetWidthForColumn): Added.
(WebCore::RenderTable::offsetHeightForColumn): Added.

  • rendering/RenderTable.h: Make isTableColumnGroupWithColumnChildren() const.
  • rendering/RenderTableCol.cpp:

(WebCore::RenderTableCol::offsetLeft): Added; turns around and calls RenderTable::offsetLeftForColumn().
(WebCore::RenderTableCol::offsetTop): Added; turns around and calls RenderTable::offsetTopForColumn().
(WebCore::RenderTableCol::offsetWidth): Added; turns around and calls RenderTable::offsetWidthForColumn().
(WebCore::RenderTableCol::offsetHeight): Added; turns around and calls RenderTable::offsetHeightForColumn().

  • rendering/RenderTableCol.h:

LayoutTests:

Added test to ensure that offset{Left, Top, Width, Height} return correct results
for table columns and column groups.

For now, we fail almost all of the offset{Height, Top} sub-tests for the separate
border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.

  • fast/table/col-and-colgroup-offsets-expected.txt: Added.
  • fast/table/col-and-colgroup-offsets.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r164495 r164504  
     12014-02-21  Daniel Bates  <dabates@apple.com>
     2
     3        COL element in table has 0 for offsetWidth
     4        https://bugs.webkit.org/show_bug.cgi?id=15277
     5
     6        Reviewed by David Hyatt.
     7
     8        Added test to ensure that offset{Left, Top, Width, Height} return correct results
     9        for table columns and column groups.
     10
     11        For now, we fail almost all of the offset{Height, Top} sub-tests for the separate
     12        border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.
     13
     14        * fast/table/col-and-colgroup-offsets-expected.txt: Added.
     15        * fast/table/col-and-colgroup-offsets.html: Added.
     16
    1172014-02-21  Benjamin Poulain  <bpoulain@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r164502 r164504  
     12014-02-21  Daniel Bates  <dabates@apple.com>
     2
     3        COL element in table has 0 for offsetWidth
     4        https://bugs.webkit.org/show_bug.cgi?id=15277
     5
     6        Reviewed by David Hyatt.
     7
     8        Implements offset{Left, Top, Width, Height} for table columns and column groups
     9        per section Extensions to the HTMLElement Interface of the CSSOM View spec,
     10        <http://www.w3.org/TR/cssom-view/#extensions-to-the-htmlelement-interface> (Draft 17 December 2013).
     11
     12        For now, we fail almost all of the offset{Height, Top} sub-tests in the included test
     13        for the separate border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.
     14
     15        Test: fast/table/col-and-colgroup-offsets.html
     16
     17        * rendering/RenderTable.cpp:
     18        (WebCore::RenderTable::RenderTable): Initialize cached column offset top and offset height.
     19        We cache these offsets since they are the same for all columns in the table.
     20        (WebCore::RenderTable::invalidateCachedColumns): Clear cached effective column index map.
     21        (WebCore::RenderTable::invalidateCachedColumnOffsets): Added.
     22        (WebCore::RenderTable::layout): Invalidate cached column offsets as the location or height
     23        of one or more sections may have changed.
     24        (WebCore::RenderTable::updateColumnCache): Modified to build effective column index map.
     25        (WebCore::RenderTable::effectiveIndexOfColumn): Added.
     26        (WebCore::RenderTable::offsetTopForColumn): Added.
     27        (WebCore::RenderTable::offsetLeftForColumn): Added.
     28        (WebCore::RenderTable::offsetWidthForColumn): Added.
     29        (WebCore::RenderTable::offsetHeightForColumn): Added.
     30        * rendering/RenderTable.h: Make isTableColumnGroupWithColumnChildren() const.
     31        * rendering/RenderTableCol.cpp:
     32        (WebCore::RenderTableCol::offsetLeft): Added; turns around and calls RenderTable::offsetLeftForColumn().
     33        (WebCore::RenderTableCol::offsetTop): Added; turns around and calls RenderTable::offsetTopForColumn().
     34        (WebCore::RenderTableCol::offsetWidth): Added; turns around and calls RenderTable::offsetWidthForColumn().
     35        (WebCore::RenderTableCol::offsetHeight): Added; turns around and calls RenderTable::offsetHeightForColumn().
     36        * rendering/RenderTableCol.h:
     37
    1382014-02-21  Enrica Casucci  <enrica@apple.com>
    239
  • trunk/Source/WebCore/rendering/RenderTable.cpp

    r163175 r164504  
    55 *           (C) 1999 Lars Knoll (knoll@kde.org)
    66 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    7  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
    88 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    99 *
     
    6565    , m_borderStart(0)
    6666    , m_borderEnd(0)
     67    , m_columnOffsetTop(-1)
     68    , m_columnOffsetHeight(-1)
    6769{
    6870    setChildrenInline(false);
     
    238240    m_columnRenderersValid = false;
    239241    m_columnRenderers.resize(0);
     242    m_effectiveColumnIndexMap.clear();
     243}
     244
     245void RenderTable::invalidateCachedColumnOffsets()
     246{
     247    m_columnOffsetTop = -1;
     248    m_columnOffsetHeight = -1;
    240249}
    241250
     
    558567    invalidateCollapsedBorders();
    559568
     569    // The location or height of one or more sections may have changed.
     570    invalidateCachedColumnOffsets();
     571
    560572    computeOverflow(clientLogicalBottom());
    561573
     
    850862    ASSERT(m_hasColElements);
    851863    ASSERT(m_columnRenderers.isEmpty());
     864    ASSERT(m_effectiveColumnIndexMap.isEmpty());
    852865    ASSERT(!m_columnRenderersValid);
    853866
     867    unsigned columnIndex = 0;
    854868    for (RenderTableCol* columnRenderer = firstColumn(); columnRenderer; columnRenderer = columnRenderer->nextColumn()) {
    855869        if (columnRenderer->isTableColumnGroupWithColumnChildren())
    856870            continue;
    857871        m_columnRenderers.append(columnRenderer);
     872        // FIXME: We should look to compute the effective column index successively from previous values instead of
     873        // calling colToEffCol(), which is in O(numEffCols()). Although it's unlikely that this is a hot function.
     874        m_effectiveColumnIndexMap.add(columnRenderer, colToEffCol(columnIndex));
     875        columnIndex += columnRenderer->span();
    858876    }
    859877    m_columnRenderersValid = true;
     878}
     879
     880unsigned RenderTable::effectiveIndexOfColumn(const RenderTableCol& column) const
     881{
     882    if (!m_columnRenderersValid)
     883        updateColumnCache();
     884    const RenderTableCol* columnToUse = &column;
     885    if (columnToUse->isTableColumnGroupWithColumnChildren())
     886        columnToUse = columnToUse->nextColumn(); // First column in column-group
     887    auto it = m_effectiveColumnIndexMap.find(columnToUse);
     888    ASSERT(it != m_effectiveColumnIndexMap.end());
     889    if (it == m_effectiveColumnIndexMap.end())
     890        return std::numeric_limits<unsigned>::max();
     891    return it->value;
     892}
     893
     894LayoutUnit RenderTable::offsetTopForColumn(const RenderTableCol& column) const
     895{
     896    if (effectiveIndexOfColumn(column) >= numEffCols())
     897        return 0;
     898    if (m_columnOffsetTop >= 0) {
     899        ASSERT(!needsLayout());
     900        return m_columnOffsetTop;
     901    }
     902    RenderTableSection* section = topNonEmptySection();
     903    return m_columnOffsetTop = section ? section->offsetTop() : LayoutUnit(0);
     904}
     905
     906LayoutUnit RenderTable::offsetLeftForColumn(const RenderTableCol& column) const
     907{
     908    unsigned columnIndex = effectiveIndexOfColumn(column);
     909    if (columnIndex >= numEffCols())
     910        return 0;
     911    return m_columnPos[columnIndex] + m_hSpacing + borderLeft();
     912}
     913
     914LayoutUnit RenderTable::offsetWidthForColumn(const RenderTableCol& column) const
     915{
     916    const RenderTableCol* currentColumn = &column;
     917    bool hasColumnChildren;
     918    if ((hasColumnChildren = currentColumn->isTableColumnGroupWithColumnChildren()))
     919        currentColumn = currentColumn->nextColumn(); // First column in column-group
     920    unsigned numberOfEffectiveColumns = numEffCols();
     921    ASSERT_WITH_SECURITY_IMPLICATION(m_columnPos.size() >= numberOfEffectiveColumns + 1);
     922    unsigned width = 0;
     923    while (currentColumn) {
     924        unsigned columnIndex = effectiveIndexOfColumn(*currentColumn);
     925        unsigned span = currentColumn->span();
     926        while (span && columnIndex < numberOfEffectiveColumns) {
     927            width += m_columnPos[columnIndex + 1] - m_columnPos[columnIndex] - m_hSpacing;
     928            span -= m_columns[columnIndex].span;
     929            ++columnIndex;
     930            if (span)
     931                width += m_hSpacing;
     932        }
     933        if (!hasColumnChildren)
     934            break;
     935        currentColumn = currentColumn->nextColumn();
     936        if (!currentColumn || currentColumn->isTableColumnGroup())
     937            break;
     938        width += m_hSpacing;
     939    }
     940    return width;
     941}
     942
     943LayoutUnit RenderTable::offsetHeightForColumn(const RenderTableCol& column) const
     944{
     945    if (effectiveIndexOfColumn(column) >= numEffCols())
     946        return 0;
     947    if (m_columnOffsetHeight >= 0) {
     948        ASSERT(!needsLayout());
     949        return m_columnOffsetHeight;
     950    }
     951    LayoutUnit height = 0;
     952    for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
     953        height += section->offsetHeight();
     954    m_columnOffsetHeight = height;
     955    return m_columnOffsetHeight;
    860956}
    861957
  • trunk/Source/WebCore/rendering/RenderTable.h

    r163171 r164504  
    55 *           (C) 1999 Lars Knoll (knoll@kde.org)
    66 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    7  * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2014 Apple Inc. All rights reserved.
    88 *
    99 * This library is free software; you can redistribute it and/or
     
    2929#include "CollapsedBorderValue.h"
    3030#include "RenderBlock.h"
     31#include <wtf/HashMap.h>
    3132#include <wtf/Vector.h>
    3233
     
    263264    void addColumn(const RenderTableCol*);
    264265    void removeColumn(const RenderTableCol*);
     266
     267    LayoutUnit offsetTopForColumn(const RenderTableCol&) const;
     268    LayoutUnit offsetLeftForColumn(const RenderTableCol&) const;
     269    LayoutUnit offsetWidthForColumn(const RenderTableCol&) const;
     270    LayoutUnit offsetHeightForColumn(const RenderTableCol&) const;
    265271
    266272protected:
     
    293299    void invalidateCachedColumns();
    294300
     301    void invalidateCachedColumnOffsets();
     302
    295303    virtual RenderBlock* firstLineBlock() const override final;
    296304    virtual void updateFirstLetter() override final;
     
    319327    mutable Vector<RenderTableCol*> m_columnRenderers;
    320328
     329    unsigned effectiveIndexOfColumn(const RenderTableCol&) const;
     330    typedef HashMap<const RenderTableCol*, unsigned> EffectiveColumnIndexMap;
     331    mutable EffectiveColumnIndexMap m_effectiveColumnIndexMap;
     332
    321333    mutable RenderTableSection* m_head;
    322334    mutable RenderTableSection* m_foot;
     
    339351    int m_borderStart;
    340352    int m_borderEnd;
     353    mutable LayoutUnit m_columnOffsetTop;
     354    mutable LayoutUnit m_columnOffsetHeight;
    341355};
    342356
  • trunk/Source/WebCore/rendering/RenderTableCol.cpp

    r162334 r164504  
    201201}
    202202
    203 }
     203LayoutUnit RenderTableCol::offsetLeft() const
     204{
     205    return table()->offsetLeftForColumn(*this);
     206}
     207
     208LayoutUnit RenderTableCol::offsetTop() const
     209{
     210    return table()->offsetTopForColumn(*this);
     211}
     212
     213LayoutUnit RenderTableCol::offsetWidth() const
     214{
     215    return table()->offsetWidthForColumn(*this);
     216}
     217
     218LayoutUnit RenderTableCol::offsetHeight() const
     219{
     220    return table()->offsetHeightForColumn(*this);
     221}
     222
     223}
  • trunk/Source/WebCore/rendering/RenderTableCol.h

    r162158 r164504  
    4444    void setSpan(unsigned span) { m_span = span; }
    4545
    46     bool isTableColumnGroupWithColumnChildren() { return firstChild(); }
     46    bool isTableColumnGroupWithColumnChildren() const { return firstChild(); }
    4747    bool isTableColumn() const { return style().display() == TABLE_COLUMN; }
    4848    bool isTableColumnGroup() const { return style().display() == TABLE_COLUMN_GROUP; }
     
    7171    const BorderValue& borderAdjoiningCellBefore(const RenderTableCell*) const;
    7272    const BorderValue& borderAdjoiningCellAfter(const RenderTableCell*) const;
     73
     74    virtual LayoutUnit offsetLeft() const override;
     75    virtual LayoutUnit offsetTop() const override;
     76    virtual LayoutUnit offsetWidth() const override;
     77    virtual LayoutUnit offsetHeight() const override;
    7378
    7479private:
Note: See TracChangeset for help on using the changeset viewer.