Changeset 125739 in webkit


Ignore:
Timestamp:
Aug 15, 2012 8:05:59 PM (12 years ago)
Author:
morrita@google.com
Message:

Regression(121518) TextFieldDecorationElement formatting is broken.
https://bugs.webkit.org/show_bug.cgi?id=90913

Reviewed by Dimitri Glazkov.

Source/WebCore:

NodeRenderingContext::nextRenderer() has a problem which cannot retrieve the renderer
across an insertion point in some case. That is because ad-hoc composed tree traversal on
NodeRenderingContext is broken. The problem is hidden before r121518 though.

This change rewrite nextRenderer() using ComposedShadowTreeWalker to eliminate the ad-hoc
traversal. previousRenderer() is also rewritten in the same way.

Test: fast/dom/shadow/shadow-div-reflow.html

  • dom/NodeRenderingContext.cpp:

(WebCore):
(WebCore::NodeRenderingContext::nextRenderer):
(WebCore::NodeRenderingContext::previousRenderer):

LayoutTests:

  • fast/dom/shadow/shadow-div-reflow-expected.html: Added.
  • fast/dom/shadow/shadow-div-reflow.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r125736 r125739  
     12012-08-15  MORITA Hajime  <morrita@google.com>
     2
     3        Regression(121518) TextFieldDecorationElement formatting is broken.
     4        https://bugs.webkit.org/show_bug.cgi?id=90913
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        * fast/dom/shadow/shadow-div-reflow-expected.html: Added.
     9        * fast/dom/shadow/shadow-div-reflow.html: Added.
     10
    1112012-08-14  Jeffrey Pfau  <jpfau@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r125737 r125739  
     12012-08-15  MORITA Hajime  <morrita@google.com>
     2
     3        Regression(121518) TextFieldDecorationElement formatting is broken.
     4        https://bugs.webkit.org/show_bug.cgi?id=90913
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        NodeRenderingContext::nextRenderer() has a problem which cannot retrieve the renderer
     9        across an insertion point in some case. That is because ad-hoc composed tree traversal on
     10        NodeRenderingContext is broken. The problem is hidden before r121518 though.
     11
     12        This change rewrite nextRenderer() using ComposedShadowTreeWalker to eliminate the ad-hoc
     13        traversal. previousRenderer() is also rewritten in the same way.
     14
     15        Test: fast/dom/shadow/shadow-div-reflow.html
     16
     17        * dom/NodeRenderingContext.cpp:
     18        (WebCore):
     19        (WebCore::NodeRenderingContext::nextRenderer):
     20        (WebCore::NodeRenderingContext::previousRenderer):
     21
    1222012-08-15  Julien Chaffraix  <jchaffraix@webkit.org>
    223
  • trunk/Source/WebCore/dom/NodeRenderingContext.cpp

    r124491 r125739  
    5050using namespace HTMLNames;
    5151
    52 static RenderObject* firstRendererOf(Node*);
    53 static RenderObject* lastRendererOf(Node*);
    54 
    5552NodeRenderingContext::NodeRenderingContext(Node* node)
    5653    : m_node(node)
     
    8380}
    8481
    85 static inline RenderObject* nextRendererOfInsertionPoint(InsertionPoint* parent, Node* current)
    86 {
    87     size_t start = parent->indexOf(current);
    88     if (notFound == start)
    89         return 0;
    90 
    91     for (size_t i = start + 1; i < parent->size(); ++i) {
    92         if (RenderObject* renderer = parent->at(i)->renderer())
    93             return renderer;
    94     }
    95 
    96     return 0;
    97 }
    98 
    99 static inline RenderObject* previousRendererOfInsertionPoint(InsertionPoint* parent, Node* current)
    100 {
    101     RenderObject* lastRenderer = 0;
    102 
    103     for (size_t i = 0; i < parent->size(); ++i) {
    104         if (parent->at(i) == current)
    105             break;
    106         if (RenderObject* renderer = parent->at(i)->renderer())
    107             lastRenderer = renderer;
    108     }
    109 
    110     return lastRenderer;
    111 }
    112 
    113 static inline RenderObject* firstRendererOfInsertionPoint(InsertionPoint* parent)
    114 {
    115     size_t size = parent->size();
    116     for (size_t i = 0; i < size; ++i) {
    117         if (RenderObject* renderer = parent->at(i)->renderer())
    118             return renderer;
    119     }
    120 
    121     return firstRendererOf(parent->firstChild());
    122 }
    123 
    124 static inline RenderObject* lastRendererOfInsertionPoint(InsertionPoint* parent)
    125 {
    126     size_t size = parent->size();
    127     for (size_t i = 0; i < size; ++i) {
    128         if (RenderObject* renderer = parent->at(size - 1 - i)->renderer())
    129             return renderer;
    130     }
    131 
    132     return lastRendererOf(parent->lastChild());
    133 }
    134 
    135 static inline RenderObject* firstRendererOf(Node* node)
    136 {
    137     for (; node; node = node->nextSibling()) {
    138         if (node->renderer()) {
    139             // Do not return elements that are attached to a different flow-thread.
    140             if (node->renderer()->style() && !node->renderer()->style()->flowThread().isEmpty())
    141                 continue;
    142             return node->renderer();
    143         }
    144 
    145         if (isInsertionPoint(node) && toInsertionPoint(node)->isActive()) {
    146             if (RenderObject* first = firstRendererOfInsertionPoint(toInsertionPoint(node)))
    147                 return first;
    148         }
    149     }
    150 
    151     return 0;
    152 }
    153 
    154 static inline RenderObject* lastRendererOf(Node* node)
    155 {
    156     for (; node; node = node->previousSibling()) {
    157         if (node->renderer()) {
    158             // Do not return elements that are attached to a different flow-thread.
    159             if (node->renderer()->style() && !node->renderer()->style()->flowThread().isEmpty())
    160                 continue;
    161             return node->renderer();
    162         }
    163         if (isInsertionPoint(node) && toInsertionPoint(node)->isActive()) {
    164             if (RenderObject* last = lastRendererOfInsertionPoint(toInsertionPoint(node)))
    165                 return last;
    166         }
    167     }
    168 
    169     return 0;
    170 }
    171 
    17282RenderObject* NodeRenderingContext::nextRenderer() const
    17383{
     
    17888        return m_parentFlowRenderer->nextRendererForNode(m_node);
    17989
    180     if (m_parentDetails.insertionPoint()) {
    181         if (RenderObject* found = nextRendererOfInsertionPoint(m_parentDetails.insertionPoint(), m_node))
    182             return found;
    183         return NodeRenderingContext(m_parentDetails.insertionPoint()).nextRenderer();
    184     }
    185 
    18690    // Avoid an O(N^2) problem with this function by not checking for
    18791    // nextRenderer() when the parent element hasn't attached yet.
    188     if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached())
     92    if (m_parentDetails.node() && !m_parentDetails.node()->attached())
    18993        return 0;
    19094
    191     return firstRendererOf(m_node->nextSibling());
     95    ComposedShadowTreeWalker walker(m_node);
     96    do {
     97        walker.nextSibling();
     98        if (!walker.get())
     99            return 0;
     100        if (RenderObject* renderer = walker.get()->renderer()) {
     101            // Do not return elements that are attached to a different flow-thread.
     102            if (renderer->style() && !renderer->style()->flowThread().isEmpty())
     103                continue;
     104            return renderer;
     105        }
     106    } while (true);
     107
     108    ASSERT_NOT_REACHED();
     109    return 0;
    192110}
    193111
     
    200118        return m_parentFlowRenderer->previousRendererForNode(m_node);
    201119
    202     if (m_parentDetails.insertionPoint()) {
    203         if (RenderObject* found = previousRendererOfInsertionPoint(m_parentDetails.insertionPoint(), m_node))
    204             return found;
    205         return NodeRenderingContext(m_parentDetails.insertionPoint()).previousRenderer();
    206     }
    207 
    208120    // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
    209121    // however, when I tried adding it, several tests failed.
    210     return lastRendererOf(m_node->previousSibling());
     122
     123    ComposedShadowTreeWalker walker(m_node);
     124    do {
     125        walker.previousSibling();
     126        if (!walker.get())
     127            return 0;
     128        if (RenderObject* renderer = walker.get()->renderer()) {
     129            // Do not return elements that are attached to a different flow-thread.
     130            if (renderer->style() && !renderer->style()->flowThread().isEmpty())
     131                continue;
     132            return renderer;
     133        }
     134    } while (true);
     135
     136    ASSERT_NOT_REACHED();
     137    return 0;
    211138}
    212139
Note: See TracChangeset for help on using the changeset viewer.