Changeset 125739 in webkit
- Timestamp:
- Aug 15, 2012 8:05:59 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r125736 r125739 1 2012-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 1 11 2012-08-14 Jeffrey Pfau <jpfau@apple.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r125737 r125739 1 2012-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 1 22 2012-08-15 Julien Chaffraix <jchaffraix@webkit.org> 2 23 -
trunk/Source/WebCore/dom/NodeRenderingContext.cpp
r124491 r125739 50 50 using namespace HTMLNames; 51 51 52 static RenderObject* firstRendererOf(Node*);53 static RenderObject* lastRendererOf(Node*);54 55 52 NodeRenderingContext::NodeRenderingContext(Node* node) 56 53 : m_node(node) … … 83 80 } 84 81 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 172 82 RenderObject* NodeRenderingContext::nextRenderer() const 173 83 { … … 178 88 return m_parentFlowRenderer->nextRendererForNode(m_node); 179 89 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 186 90 // Avoid an O(N^2) problem with this function by not checking for 187 91 // 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()) 189 93 return 0; 190 94 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; 192 110 } 193 111 … … 200 118 return m_parentFlowRenderer->previousRendererForNode(m_node); 201 119 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 208 120 // FIXME: We should have the same O(N^2) avoidance as nextRenderer does 209 121 // 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; 211 138 } 212 139
Note: See TracChangeset
for help on using the changeset viewer.