Changeset 58150 in webkit
- Timestamp:
- Apr 22, 2010 10:47:06 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r58149 r58150 1 2010-04-22 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 Links around blocks (e.g. divs) results in too many VoiceOver call outs 6 https://bugs.webkit.org/show_bug.cgi?id=37079 7 8 The new test cases verify the accessibility tree created by an image inside a link, and verify 9 that adding a div with role=presentation now has no effect on the accessibility tree (as expected). 10 11 * accessibility/image-link-inline-cont-expected.txt: Added. 12 * accessibility/image-link-inline-cont.html: Added. 13 * accessibility/image-link.html: Added. 14 * platform/gtk/Skipped: 15 * platform/mac/accessibility/image-link-expected.txt: Added. 16 * platform/win/Skipped: 17 18 Test to check that accessibility tree doesn't get duplicate content in the presence 19 of inline continuations (this was a bug in an earlier version of this patch). 20 21 * accessibility/inline-continuations-expected.txt: Added. 22 * accessibility/inline-continuations.html: Added. 23 1 24 2010-04-22 Shinichiro Hamaji <hamaji@chromium.org> 2 25 -
trunk/LayoutTests/platform/gtk/Skipped
r58111 r58150 85 85 accessibility/aria-roles.html 86 86 accessibility/aria-tables.html 87 accessibility/image-link.html 88 accessibility/image-link-inline-cont.html 87 89 accessibility/image-map1.html 88 90 accessibility/image-map2.html 91 accessibility/inline-continuations.html 89 92 accessibility/internal-link-anchors2.html 90 93 accessibility/label-for-control-hittest.html -
trunk/LayoutTests/platform/win/Skipped
r58021 r58150 393 393 accessibility/iframe-bastardization.html 394 394 accessibility/ignore-spacer-elements.html 395 accessibility/image-link.html 395 396 accessibility/image-map1.html 396 397 accessibility/image-map2.html -
trunk/WebCore/ChangeLog
r58149 r58150 1 2010-04-22 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 Links around blocks (e.g. divs) results in too many VoiceOver call outs 6 https://bugs.webkit.org/show_bug.cgi?id=37079 7 8 The basic change is to modify the AccessibilityRenderObject tree 9 traversal methods to account for inline continuations in the 10 render tree and make the accessibility tree look as if 11 continuations didn't exist - the same as if CSS blocks could just 12 sit in CSS inlines. This is slightly tricky code but creates a 13 much saner accessibility tree. 14 15 Tests: accessibility/image-link-inline-cont.html 16 accessibility/image-link.html 17 accessibility/inline-continuations.html 18 19 * accessibility/AccessibilityRenderObject.cpp: 20 (WebCore::isInlineWithContinuation): Helper function for traversal functions to use in accounting for continuations. 21 (WebCore::firstChildInContinuation): ditto 22 (WebCore::firstChildConsideringContinuation): ditto 23 (WebCore::lastChildConsideringContinuation): ditto 24 (WebCore::startOfContinuations): ditto 25 (WebCore::endOfContinuations): ditto 26 (WebCore::childBeforeConsideringContinuations): ditto 27 (WebCore::firstChildIsInlineContinuation): ditto 28 (WebCore::lastChildHasContinuation): ditto 29 (WebCore::AccessibilityRenderObject::firstChild): Account for inline continuations. 30 (WebCore::AccessibilityRenderObject::lastChild): ditto 31 (WebCore::AccessibilityRenderObject::previousSibling): Account for inline continuations 32 and their anonymous block parents. 33 (WebCore::AccessibilityRenderObject::nextSibling): ditto 34 (WebCore::AccessibilityRenderObject::parentObjectIfExists): Account for inline continuations. 35 (WebCore::AccessibilityRenderObject::parentObject): Account for inline continuations. 36 * rendering/RenderInline.h: Make RenderInline::inlineContinuation public. 37 1 38 2010-04-22 Shinichiro Hamaji <hamaji@chromium.org> 2 39 -
trunk/WebCore/accessibility/AccessibilityRenderObject.cpp
r58037 r58150 119 119 } 120 120 121 static inline bool isInlineWithContinuation(RenderObject* renderer) 122 { 123 if (!renderer->isRenderInline()) 124 return false; 125 126 return toRenderInline(renderer)->continuation(); 127 } 128 129 static inline RenderObject* firstChildInContinuation(RenderObject* renderer) 130 { 131 RenderObject* r = toRenderInline(renderer)->continuation(); 132 133 while (r) { 134 if (r->isRenderBlock()) 135 return r; 136 if (RenderObject* child = r->firstChild()) 137 return child; 138 r = toRenderInline(r)->continuation(); 139 } 140 141 return 0; 142 } 143 144 static inline RenderObject* firstChildConsideringContinuation(RenderObject* renderer) 145 { 146 RenderObject* firstChild = renderer->firstChild(); 147 148 if (!firstChild && isInlineWithContinuation(renderer)) 149 firstChild = firstChildInContinuation(renderer); 150 151 return firstChild; 152 } 153 154 155 static inline RenderObject* lastChildConsideringContinuation(RenderObject* renderer) 156 { 157 RenderObject* lastChild = renderer->lastChild(); 158 RenderObject* prev = renderer; 159 RenderObject* cur = renderer; 160 161 if (!cur->isRenderInline() && !cur->isRenderBlock()) 162 return renderer; 163 164 while (cur) { 165 prev = cur; 166 167 if (RenderObject* lc = cur->lastChild()) 168 lastChild = lc; 169 170 if (cur->isRenderInline()) { 171 cur = toRenderInline(cur)->inlineContinuation(); 172 ASSERT(cur || !toRenderInline(prev)->continuation()); 173 } else 174 cur = toRenderBlock(cur)->inlineContinuation(); 175 } 176 177 return lastChild; 178 } 179 121 180 AccessibilityObject* AccessibilityRenderObject::firstChild() const 122 181 { … … 124 183 return 0; 125 184 126 RenderObject* firstChild = m_renderer->firstChild(); 185 RenderObject* firstChild = firstChildConsideringContinuation(m_renderer); 186 127 187 if (!firstChild) 128 188 return 0; … … 135 195 if (!m_renderer) 136 196 return 0; 137 138 RenderObject* lastChild = m_renderer->lastChild(); 197 198 RenderObject* lastChild = lastChildConsideringContinuation(m_renderer); 199 139 200 if (!lastChild) 140 201 return 0; … … 143 204 } 144 205 206 static inline RenderInline* startOfContinuations(RenderObject* r) 207 { 208 if (r->isInlineContinuation()) 209 return toRenderInline(r->node()->renderer()); 210 211 // Blocks with a previous continuation always have a next continuation 212 if (r->isRenderBlock() && toRenderBlock(r)->inlineContinuation()) 213 return toRenderInline(toRenderBlock(r)->inlineContinuation()->node()->renderer()); 214 215 return 0; 216 } 217 218 static inline RenderObject* endOfContinuations(RenderObject* renderer) 219 { 220 RenderObject* prev = renderer; 221 RenderObject* cur = renderer; 222 223 if (!cur->isRenderInline() && !cur->isRenderBlock()) 224 return renderer; 225 226 while (cur) { 227 prev = cur; 228 if (cur->isRenderInline()) { 229 cur = toRenderInline(cur)->inlineContinuation(); 230 ASSERT(cur || !toRenderInline(prev)->continuation()); 231 } else 232 cur = toRenderBlock(cur)->inlineContinuation(); 233 } 234 235 return prev; 236 } 237 238 239 static inline RenderObject* childBeforeConsideringContinuations(RenderInline* r, RenderObject* child) 240 { 241 RenderBoxModelObject* curContainer = r; 242 RenderObject* cur = 0; 243 RenderObject* prev = 0; 244 245 while (curContainer) { 246 if (curContainer->isRenderInline()) { 247 cur = curContainer->firstChild(); 248 while (cur) { 249 if (cur == child) 250 return prev; 251 prev = cur; 252 cur = cur->nextSibling(); 253 } 254 255 curContainer = toRenderInline(curContainer)->continuation(); 256 } else if (curContainer->isRenderBlock()) { 257 if (curContainer == child) 258 return prev; 259 260 prev = curContainer; 261 curContainer = toRenderBlock(curContainer)->inlineContinuation(); 262 } 263 } 264 265 ASSERT_NOT_REACHED(); 266 267 return 0; 268 } 269 270 static inline bool firstChildIsInlineContinuation(RenderObject* renderer) 271 { 272 return renderer->firstChild() && renderer->firstChild()->isInlineContinuation(); 273 } 274 145 275 AccessibilityObject* AccessibilityRenderObject::previousSibling() const 146 276 { 147 277 if (!m_renderer) 148 278 return 0; 149 150 RenderObject* previousSibling = m_renderer->previousSibling(); 279 280 RenderObject* previousSibling = 0; 281 282 // Case 1: The node is a block and is an inline's continuation. In that case, the inline's 283 // last child is our previous sibling (or further back in the continuation chain) 284 RenderInline* startOfConts; 285 if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer))) 286 previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer); 287 288 // Case 2: Anonymous block parent of the end of a continuation - skip all the way to before 289 // the parent of the start, since everything in between will be linked up via the continuation. 290 else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(m_renderer)) 291 previousSibling = startOfContinuations(m_renderer->firstChild())->parent()->previousSibling(); 292 293 // Case 3: The node has an actual previous sibling 294 else if (RenderObject* ps = m_renderer->previousSibling()) 295 previousSibling = ps; 296 297 // Case 4: This node has no previous siblings, but its parent is an inline, 298 // and is another node's inline continutation. Follow the continuation chain. 299 else if (m_renderer->parent()->isRenderInline() && (startOfConts = startOfContinuations(m_renderer->parent()))) 300 previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer->parent()->firstChild()); 301 151 302 if (!previousSibling) 152 303 return 0; … … 155 306 } 156 307 308 static inline bool lastChildHasContinuation(RenderObject* renderer) 309 { 310 return renderer->lastChild() && isInlineWithContinuation(renderer->lastChild()); 311 } 312 157 313 AccessibilityObject* AccessibilityRenderObject::nextSibling() const 158 314 { 159 315 if (!m_renderer) 160 316 return 0; 161 162 RenderObject* nextSibling = m_renderer->nextSibling(); 317 318 RenderObject* nextSibling = 0; 319 320 // Case 1: node is a block and has an inline continuation. Next sibling is the inline continuation's 321 // first child. 322 RenderInline* inlineContinuation; 323 if (m_renderer->isRenderBlock() && (inlineContinuation = toRenderBlock(m_renderer)->inlineContinuation())) 324 nextSibling = firstChildConsideringContinuation(inlineContinuation); 325 326 // Case 2: Anonymous block parent of the start of a continuation - skip all the way to 327 // after the parent of the end, since everything in between will be linked up via the continuation. 328 else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) 329 nextSibling = endOfContinuations(m_renderer->lastChild())->parent()->nextSibling(); 330 331 // Case 3: node has an actual next sibling 332 else if (RenderObject* ns = m_renderer->nextSibling()) 333 nextSibling = ns; 334 335 // Case 4: node is an inline with a continuation. Next sibling is the next sibling of the end 336 // of the continuation chain. 337 else if (isInlineWithContinuation(m_renderer)) 338 nextSibling = endOfContinuations(m_renderer)->nextSibling(); 339 340 // Case 5: node has no next sibling, and its parent is an inline with a continuation. 341 else if (isInlineWithContinuation(m_renderer->parent())) { 342 RenderObject* continuation = toRenderInline(m_renderer->parent())->continuation(); 343 344 // Case 4a: continuation is a block - in this case the block itself is the next sibling. 345 if (continuation->isRenderBlock()) 346 nextSibling = continuation; 347 // Case 4b: continuation is an inline - in this case the inline's first child is the next sibling 348 else 349 nextSibling = firstChildConsideringContinuation(continuation); 350 } 351 163 352 if (!nextSibling) 164 353 return 0; … … 171 360 if (!m_renderer) 172 361 return 0; 173 362 174 363 RenderObject* parent = m_renderer->parent(); 364 365 // Case 1: node is a block and is an inline's continuation. Parent 366 // is the start of the continuation chain. 367 RenderInline* startOfConts = 0; 368 if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer))) 369 parent = startOfConts; 370 371 // Case 2: node's parent is an inline which is some node's continuation; parent is 372 // the earliest node in the continuation chain. 373 else if (parent && parent->isRenderInline() && (startOfConts = startOfContinuations(parent))) 374 parent = startOfConts; 375 175 376 if (!parent) 176 377 return 0; … … 185 386 186 387 RenderObject* parent = m_renderer->parent(); 388 389 // Case 1: node is a block and is an inline's continuation. Parent 390 // is the start of the continuation chain. 391 RenderInline* startOfConts = 0; 392 if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer))) 393 parent = startOfConts; 394 395 // Case 2: node's parent is an inline which is some node's continuation; parent is 396 // the earliest node in the continuation chain. 397 else if (parent && parent->isRenderInline() && (startOfConts = startOfContinuations(parent))) 398 parent = startOfConts; 399 187 400 if (!parent) 188 401 return 0; -
trunk/WebCore/rendering/RenderInline.h
r54784 r58150 72 72 void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; } 73 73 74 RenderInline* inlineContinuation() const; 75 74 76 private: 75 77 virtual RenderObjectChildList* virtualChildren() { return children(); } … … 127 129 virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; 128 130 129 RenderInline* inlineContinuation() const;130 131 void setContinuation(RenderBoxModelObject* c) { m_continuation = c; } 131 132
Note: See TracChangeset
for help on using the changeset viewer.