2010-04-22 Maciej Stachowiak <mjs@apple.com>
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Apr 2010 05:47:06 +0000 (05:47 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Apr 2010 05:47:06 +0000 (05:47 +0000)
        Reviewed by Dan Bernstein.

        Links around blocks (e.g. divs) results in too many VoiceOver call outs
        https://bugs.webkit.org/show_bug.cgi?id=37079

        The basic change is to modify the AccessibilityRenderObject tree
        traversal methods to account for inline continuations in the
        render tree and make the accessibility tree look as if
        continuations didn't exist - the same as if CSS blocks could just
        sit in CSS inlines. This is slightly tricky code but creates a
        much saner accessibility tree.

        Tests: accessibility/image-link-inline-cont.html
               accessibility/image-link.html
               accessibility/inline-continuations.html

        * accessibility/AccessibilityRenderObject.cpp:
        (WebCore::isInlineWithContinuation): Helper function for traversal functions to use in accounting for continuations.
        (WebCore::firstChildInContinuation): ditto
        (WebCore::firstChildConsideringContinuation): ditto
        (WebCore::lastChildConsideringContinuation): ditto
        (WebCore::startOfContinuations): ditto
        (WebCore::endOfContinuations): ditto
        (WebCore::childBeforeConsideringContinuations): ditto
        (WebCore::firstChildIsInlineContinuation): ditto
        (WebCore::lastChildHasContinuation): ditto
        (WebCore::AccessibilityRenderObject::firstChild): Account for inline continuations.
        (WebCore::AccessibilityRenderObject::lastChild): ditto
        (WebCore::AccessibilityRenderObject::previousSibling): Account for inline continuations
        and their anonymous block parents.
        (WebCore::AccessibilityRenderObject::nextSibling): ditto
        (WebCore::AccessibilityRenderObject::parentObjectIfExists): Account for inline continuations.
        (WebCore::AccessibilityRenderObject::parentObject): Account for inline continuations.
        * rendering/RenderInline.h: Make RenderInline::inlineContinuation public.
2010-04-22  Maciej Stachowiak  <mjs@apple.com>

        Reviewed by Dan Bernstein.

        Links around blocks (e.g. divs) results in too many VoiceOver call outs
        https://bugs.webkit.org/show_bug.cgi?id=37079

        The new test cases verify the accessibility tree created by an image inside a link, and verify
        that adding a div with role=presentation now has no effect on the accessibility tree (as expected).

        * accessibility/image-link-inline-cont-expected.txt: Added.
        * accessibility/image-link-inline-cont.html: Added.
        * accessibility/image-link.html: Added.
        * platform/gtk/Skipped:
        * platform/mac/accessibility/image-link-expected.txt: Added.
        * platform/win/Skipped:

        Test to check that accessibility tree doesn't get duplicate content in the presence
        of inline continuations (this was a bug in an earlier version of this patch).

        * accessibility/inline-continuations-expected.txt: Added.
        * accessibility/inline-continuations.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@58150 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/image-link-inline-cont-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/image-link-inline-cont.html [new file with mode: 0644]
LayoutTests/accessibility/image-link.html [new file with mode: 0644]
LayoutTests/accessibility/inline-continuations-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/inline-continuations.html [new file with mode: 0644]
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac/accessibility/image-link-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/Skipped
WebCore/ChangeLog
WebCore/accessibility/AccessibilityRenderObject.cpp
WebCore/rendering/RenderInline.h

index 6899a3c5f19d39cccd92ba332ba0bb4bbc6d15cf..65ed71d70275da67d083f24b8499c987773d7ba1 100644 (file)
@@ -1,3 +1,26 @@
+2010-04-22  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Links around blocks (e.g. divs) results in too many VoiceOver call outs
+        https://bugs.webkit.org/show_bug.cgi?id=37079
+        
+        The new test cases verify the accessibility tree created by an image inside a link, and verify
+        that adding a div with role=presentation now has no effect on the accessibility tree (as expected).
+
+        * accessibility/image-link-inline-cont-expected.txt: Added.
+        * accessibility/image-link-inline-cont.html: Added.
+        * accessibility/image-link.html: Added.
+        * platform/gtk/Skipped:
+        * platform/mac/accessibility/image-link-expected.txt: Added.
+        * platform/win/Skipped:
+        
+        Test to check that accessibility tree doesn't get duplicate content in the presence
+        of inline continuations (this was a bug in an earlier version of this patch).
+
+        * accessibility/inline-continuations-expected.txt: Added.
+        * accessibility/inline-continuations.html: Added.
+
 2010-04-22  Shinichiro Hamaji  <hamaji@chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/accessibility/image-link-inline-cont-expected.txt b/LayoutTests/accessibility/image-link-inline-cont-expected.txt
new file mode 100644 (file)
index 0000000..22a72dd
--- /dev/null
@@ -0,0 +1,9 @@
+Image link in the presence of inline continuations
+
+This test checks that a block inside a link does not unduly disturb the render tree via inline continuations. In particular, it checks that adding <div role=presentation> between a link and its contained image does not alter the accessibility tree at all, other than with respect to size.
+
+
+
+ PASS: accessibility trees were identical other than size.
+
+
diff --git a/LayoutTests/accessibility/image-link-inline-cont.html b/LayoutTests/accessibility/image-link-inline-cont.html
new file mode 100644 (file)
index 0000000..e25d805
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<head>
+<title>Image link in the presence of inline continuations</tile>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+</head>
+<body>
+
+<h2>Image link in the presence of inline continuations</h2>
+
+<p>This test checks that a block inside a link does not unduly disturb
+  the render tree via inline continuations. In particular, it checks
+  that adding &lt;div role=presentation> between a link and its
+  contained image does not alter the accessibility tree at all, other
+  than with respect to size.</p>
+
+  <div id="plain">
+    <a href="http://www.wowhead.com/?item=33924"><img alt="Delicious cake" src="resources/cake.png"></a>
+  </div>
+
+  <div id="with-div">
+    <a href="http://www.wowhead.com/?item=33924"><div role="presentation"><img alt="Delicious cake" src="resources/cake.png"></div></a>
+  </div>
+
+<pre id="result"></div>
+
+<script>
+function axTree(elt)
+{
+    var result = elt.allAttributes() + "\n\n";
+    var count = elt.childrenCount;
+    for (var i = 0; i < count; ++i) {
+        result += "Child " + i + ":\n" + axTree(elt.childAtIndex(i));
+    }
+    return result;
+}
+
+if (window.accessibilityController) {
+    var result = document.getElementById("result");
+    document.getElementById("plain").focus();
+    var plainResult = axTree(accessibilityController.focusedElement);
+    plainResult.replace(/AXSize.*\n/g, "");
+
+    document.getElementById("with-div").focus();
+    var withDivResult = axTree(accessibilityController.focusedElement);
+    withDivResult.replace(/AXSize.*\n/g, "");
+
+    if (plainResult == withDivResult) {
+        result.innerHTML = "PASS: accessibility trees were identical other than size."
+    } else {
+        result.innerHTML = "FAIL: accessibility trees differ.\nPlain image link: \n" + plainResult + "\nWith presentation div:\n" + withDivResult;
+    }
+}
+</script>
+</body>
diff --git a/LayoutTests/accessibility/image-link.html b/LayoutTests/accessibility/image-link.html
new file mode 100644 (file)
index 0000000..782c16e
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<head>
+<title>Image link test</tile>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+</head>
+<body>
+
+<h2>Image link in the presence of inline continuations</h2>
+
+<p>This test checks that the right accessibility tree is generated for a link inside an image</p>
+
+  <a id="test" href="http://www.wowhead.com/?item=33924"><img alt="Delicious cake" src="resources/cake.png"></a>
+
+  <div id="result"></div>
+
+<script>
+function axTree(elt)
+{
+    var result = elt.allAttributes() + "\n\n";
+    var count = elt.childrenCount;
+    for (var i = 0; i < count; ++i) {
+        result += "Child " + i + ":\n" + axTree(elt.childAtIndex(i));
+    }
+    return result;
+}
+
+if (window.accessibilityController) {
+    var result = document.getElementById("result");
+    document.getElementById("test").focus();
+    result.innerText += axTree(accessibilityController.focusedElement);
+}
+</script>
+</body>
diff --git a/LayoutTests/accessibility/inline-continuations-expected.txt b/LayoutTests/accessibility/inline-continuations-expected.txt
new file mode 100644 (file)
index 0000000..48b670d
--- /dev/null
@@ -0,0 +1,13 @@
+Inline continuations - accessibility tree linkage
+
+This test checks that the right accessibility tree is generated in the presence of inline continuations. Each of the five numbers below should be visited only ones traversing the accessibility tree.
+
+1
+2
+34
+5
+PASS nonGroupDescendants(accessibilityController.focusedElement) is 5
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/inline-continuations.html b/LayoutTests/accessibility/inline-continuations.html
new file mode 100644 (file)
index 0000000..3c3f498
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<head>
+<title>Inline continuations - accessibility tree linkage</tile>
+<link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
+<script src="../fast/js/resources/js-test-pre.js"></script>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+var successfullyParsed = false;
+</script>
+</head>
+<body>
+
+<h2>Inline continuations - accessibility tree linkage</h2>
+
+<p>This test checks that the right accessibility tree is generated in
+   the presence of inline continuations. Each of the five numbers
+   below should be visited only ones traversing the accessibility
+   tree.</p>
+
+<div contentEditable="true" id="test"><span>1<div>2</div>3</span><span>4</span><div>5</div></div>
+
+<div id="console"></div>
+
+<script>
+function nonGroupDescendants(elt)
+{
+    var result = 0;
+    var count = elt.childrenCount;
+    for (var i = 0; i < count; ++i) {
+        var child = elt.childAtIndex(i);
+          if (!child.role.match(/group/i))
+          result++;
+        result += nonGroupDescendants(child);
+    }
+    return result;
+}
+
+if (window.accessibilityController) {
+    var result = document.getElementById("result");
+    document.getElementById("test").focus();
+    shouldBe("nonGroupDescendants(accessibilityController.focusedElement)", "5");
+
+    // This should pass (and is a simpler test than above) if anonymous blocks were not in the AX tree
+    // shouldBe("accessibilityController.focusedElement.childrenCount", "5");
+}
+
+
+var successfullyParsed = true;
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
index 229e3c99cb9133e1b53ccd0a3bdfe6c4c456a98b..8e5eec295abe7f5a586ea4b8227c2904adfbcffd 100644 (file)
@@ -84,8 +84,11 @@ accessibility/aria-describedby-on-input.html
 accessibility/aria-labelledby-on-input.html
 accessibility/aria-roles.html
 accessibility/aria-tables.html
+accessibility/image-link.html
+accessibility/image-link-inline-cont.html
 accessibility/image-map1.html
 accessibility/image-map2.html
+accessibility/inline-continuations.html
 accessibility/internal-link-anchors2.html
 accessibility/label-for-control-hittest.html
 accessibility/legend.html
diff --git a/LayoutTests/platform/mac/accessibility/image-link-expected.txt b/LayoutTests/platform/mac/accessibility/image-link-expected.txt
new file mode 100644 (file)
index 0000000..a1cd90b
--- /dev/null
@@ -0,0 +1,57 @@
+Image link in the presence of inline continuations
+
+This test checks that the right accessibility tree is generated for a link inside an image
+
+
+AXRole: AXLink
+AXSubrole: (null)
+AXRoleDescription: link
+AXChildren: <array of size 1>
+AXHelp: 
+AXParent: <AXLink>
+AXSize: NSSize: {280, 213}
+AXTitle: 
+AXDescription: 
+AXValue: 
+AXFocused: 1
+AXEnabled: 1
+AXWindow: <AXLink>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXLink>
+AXEndTextMarker: <AXLink>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXTopLevelUIElement: <AXLink>
+AXURL: http://www.wowhead.com/?item=33924
+AXAccessKey: (null)
+
+
+Child 0:
+AXRole: AXImage
+AXSubrole: (null)
+AXRoleDescription: image
+AXChildren: <array of size 0>
+AXHelp: 
+AXParent: <AXImage>
+AXSize: NSSize: {280, 209}
+AXTitle: 
+AXDescription: Delicious cake
+AXValue: 
+AXFocused: 0
+AXEnabled: 1
+AXWindow: <AXImage>
+AXSelectedTextMarkerRange: (null)
+AXStartTextMarker: <AXImage>
+AXEndTextMarker: <AXImage>
+AXVisited: 0
+AXLinkedUIElements: (null)
+AXSelected: 0
+AXBlockQuoteLevel: 0
+AXTopLevelUIElement: <AXImage>
+AXURL: LayoutTests/accessibility/resources/cake.png
+AXAccessKey: (null)
+
+
+
index fd64f66ef2525fa58484c7d27ce4aa3aee95f3c1..b31de931a751de1c31e94cf7cf26f56a51558b54 100644 (file)
@@ -392,6 +392,7 @@ accessibility/document-attributes.html
 accessibility/editable-webarea-context-menu-point.html
 accessibility/iframe-bastardization.html
 accessibility/ignore-spacer-elements.html
+accessibility/image-link.html
 accessibility/image-map1.html
 accessibility/image-map2.html
 accessibility/img-aria-button-alt-tag.html
index c7ffb47f150c8a675a8eb2dcc94f88115c7a995c..479a28d6b1dfd68082a2d2d905e1938e37ae5634 100644 (file)
@@ -1,3 +1,40 @@
+2010-04-22  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Links around blocks (e.g. divs) results in too many VoiceOver call outs
+        https://bugs.webkit.org/show_bug.cgi?id=37079
+
+        The basic change is to modify the AccessibilityRenderObject tree
+        traversal methods to account for inline continuations in the
+        render tree and make the accessibility tree look as if
+        continuations didn't exist - the same as if CSS blocks could just
+        sit in CSS inlines. This is slightly tricky code but creates a
+        much saner accessibility tree.
+        
+        Tests: accessibility/image-link-inline-cont.html
+               accessibility/image-link.html
+               accessibility/inline-continuations.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::isInlineWithContinuation): Helper function for traversal functions to use in accounting for continuations.
+        (WebCore::firstChildInContinuation): ditto
+        (WebCore::firstChildConsideringContinuation): ditto
+        (WebCore::lastChildConsideringContinuation): ditto
+        (WebCore::startOfContinuations): ditto
+        (WebCore::endOfContinuations): ditto
+        (WebCore::childBeforeConsideringContinuations): ditto
+        (WebCore::firstChildIsInlineContinuation): ditto
+        (WebCore::lastChildHasContinuation): ditto
+        (WebCore::AccessibilityRenderObject::firstChild): Account for inline continuations.
+        (WebCore::AccessibilityRenderObject::lastChild): ditto
+        (WebCore::AccessibilityRenderObject::previousSibling): Account for inline continuations
+        and their anonymous block parents.
+        (WebCore::AccessibilityRenderObject::nextSibling): ditto
+        (WebCore::AccessibilityRenderObject::parentObjectIfExists): Account for inline continuations.
+        (WebCore::AccessibilityRenderObject::parentObject): Account for inline continuations.
+        * rendering/RenderInline.h: Make RenderInline::inlineContinuation public.
+
 2010-04-22  Shinichiro Hamaji  <hamaji@chromium.org>
 
         Reviewed by Darin Adler.
index c0ac3dff2916ad4a3acc70eee0aa1aae2b48c770..40b365a04edb0cb578eed7b5815f0e51f1f38dac 100644 (file)
@@ -118,12 +118,72 @@ void AccessibilityRenderObject::detach()
     m_renderer = 0;    
 }
 
+static inline bool isInlineWithContinuation(RenderObject* renderer)
+{
+    if (!renderer->isRenderInline())
+        return false;
+
+    return toRenderInline(renderer)->continuation();
+}
+
+static inline RenderObject* firstChildInContinuation(RenderObject* renderer)
+{
+    RenderObject* r = toRenderInline(renderer)->continuation();
+
+    while (r) {
+        if (r->isRenderBlock())
+            return r;
+        if (RenderObject* child = r->firstChild())
+            return child;
+        r = toRenderInline(r)->continuation(); 
+    }
+
+    return 0;
+}
+
+static inline RenderObject* firstChildConsideringContinuation(RenderObject* renderer)
+{
+    RenderObject* firstChild = renderer->firstChild();
+
+    if (!firstChild && isInlineWithContinuation(renderer))
+        firstChild = firstChildInContinuation(renderer);
+
+    return firstChild;
+}
+
+
+static inline RenderObject* lastChildConsideringContinuation(RenderObject* renderer)
+{
+    RenderObject* lastChild = renderer->lastChild();
+    RenderObject* prev = renderer;
+    RenderObject* cur = renderer;
+
+    if (!cur->isRenderInline() && !cur->isRenderBlock())
+        return renderer;
+
+    while (cur) {
+        prev = cur;
+
+        if (RenderObject* lc = cur->lastChild())
+            lastChild = lc;
+
+        if (cur->isRenderInline()) {
+            cur = toRenderInline(cur)->inlineContinuation();
+            ASSERT(cur || !toRenderInline(prev)->continuation());
+        } else
+            cur = toRenderBlock(cur)->inlineContinuation();
+    }
+
+    return lastChild;
+}
+
 AccessibilityObject* AccessibilityRenderObject::firstChild() const
 {
     if (!m_renderer)
         return 0;
     
-    RenderObject* firstChild = m_renderer->firstChild();
+    RenderObject* firstChild = firstChildConsideringContinuation(m_renderer);
+
     if (!firstChild)
         return 0;
     
@@ -134,32 +194,161 @@ AccessibilityObject* AccessibilityRenderObject::lastChild() const
 {
     if (!m_renderer)
         return 0;
-    
-    RenderObject* lastChild = m_renderer->lastChild();
+
+    RenderObject* lastChild = lastChildConsideringContinuation(m_renderer);
+
     if (!lastChild)
         return 0;
     
     return m_renderer->document()->axObjectCache()->getOrCreate(lastChild);
 }
 
+static inline RenderInline* startOfContinuations(RenderObject* r)
+{
+    if (r->isInlineContinuation())
+        return toRenderInline(r->node()->renderer());
+
+    // Blocks with a previous continuation always have a next continuation
+    if (r->isRenderBlock() && toRenderBlock(r)->inlineContinuation())
+        return toRenderInline(toRenderBlock(r)->inlineContinuation()->node()->renderer());
+
+    return 0;
+}
+
+static inline RenderObject* endOfContinuations(RenderObject* renderer)
+{
+    RenderObject* prev = renderer;
+    RenderObject* cur = renderer;
+
+    if (!cur->isRenderInline() && !cur->isRenderBlock())
+        return renderer;
+
+    while (cur) {
+        prev = cur;
+        if (cur->isRenderInline()) {
+            cur = toRenderInline(cur)->inlineContinuation();
+            ASSERT(cur || !toRenderInline(prev)->continuation());
+        } else 
+            cur = toRenderBlock(cur)->inlineContinuation();
+    }
+
+    return prev;
+}
+
+
+static inline RenderObject* childBeforeConsideringContinuations(RenderInline* r, RenderObject* child)
+{
+    RenderBoxModelObject* curContainer = r;
+    RenderObject* cur = 0;
+    RenderObject* prev = 0;
+
+    while (curContainer) {
+        if (curContainer->isRenderInline()) {
+            cur = curContainer->firstChild();
+            while (cur) {
+                if (cur == child)
+                    return prev;
+                prev = cur;
+                cur = cur->nextSibling();
+            }
+
+            curContainer = toRenderInline(curContainer)->continuation();
+        } else if (curContainer->isRenderBlock()) {
+            if (curContainer == child)
+                return prev;
+
+            prev = curContainer;
+            curContainer = toRenderBlock(curContainer)->inlineContinuation();
+        }
+    }
+
+    ASSERT_NOT_REACHED();
+
+    return 0;
+}
+
+static inline bool firstChildIsInlineContinuation(RenderObject* renderer)
+{
+    return renderer->firstChild() && renderer->firstChild()->isInlineContinuation();
+}
+
 AccessibilityObject* AccessibilityRenderObject::previousSibling() const
 {
     if (!m_renderer)
         return 0;
-    
-    RenderObject* previousSibling = m_renderer->previousSibling();
+
+    RenderObject* previousSibling = 0;
+
+    // Case 1: The node is a block and is an inline's continuation. In that case, the inline's
+    // last child is our previous sibling (or further back in the continuation chain)
+    RenderInline* startOfConts;
+    if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer)))
+        previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer);
+
+    // Case 2: Anonymous block parent of the end of a continuation - skip all the way to before
+    // the parent of the start, since everything in between will be linked up via the continuation.
+    else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(m_renderer))
+        previousSibling = startOfContinuations(m_renderer->firstChild())->parent()->previousSibling();
+
+    // Case 3: The node has an actual previous sibling
+    else if (RenderObject* ps = m_renderer->previousSibling())
+        previousSibling = ps;
+
+    // Case 4: This node has no previous siblings, but its parent is an inline,
+    // and is another node's inline continutation. Follow the continuation chain.
+    else if (m_renderer->parent()->isRenderInline() && (startOfConts = startOfContinuations(m_renderer->parent())))
+        previousSibling = childBeforeConsideringContinuations(startOfConts, m_renderer->parent()->firstChild());
+
     if (!previousSibling)
         return 0;
     
     return m_renderer->document()->axObjectCache()->getOrCreate(previousSibling);
 }
 
+static inline bool lastChildHasContinuation(RenderObject* renderer)
+{
+    return renderer->lastChild() && isInlineWithContinuation(renderer->lastChild());
+}
+
 AccessibilityObject* AccessibilityRenderObject::nextSibling() const
 {
     if (!m_renderer)
         return 0;
-    
-    RenderObject* nextSibling = m_renderer->nextSibling();
+
+    RenderObject* nextSibling = 0;
+
+    // Case 1: node is a block and has an inline continuation. Next sibling is the inline continuation's
+    // first child.
+    RenderInline* inlineContinuation;
+    if (m_renderer->isRenderBlock() && (inlineContinuation = toRenderBlock(m_renderer)->inlineContinuation()))
+        nextSibling = firstChildConsideringContinuation(inlineContinuation);
+
+    // Case 2: Anonymous block parent of the start of a continuation - skip all the way to
+    // after the parent of the end, since everything in between will be linked up via the continuation.
+    else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer))
+        nextSibling = endOfContinuations(m_renderer->lastChild())->parent()->nextSibling();
+
+    // Case 3: node has an actual next sibling
+    else if (RenderObject* ns = m_renderer->nextSibling())
+        nextSibling = ns;
+
+    // Case 4: node is an inline with a continuation. Next sibling is the next sibling of the end 
+    // of the continuation chain.
+    else if (isInlineWithContinuation(m_renderer))
+        nextSibling = endOfContinuations(m_renderer)->nextSibling();
+
+    // Case 5: node has no next sibling, and its parent is an inline with a continuation.
+    else if (isInlineWithContinuation(m_renderer->parent())) {
+        RenderObject* continuation = toRenderInline(m_renderer->parent())->continuation();
+        
+        // Case 4a: continuation is a block - in this case the block itself is the next sibling.
+        if (continuation->isRenderBlock())
+            nextSibling = continuation;
+        // Case 4b: continuation is an inline - in this case the inline's first child is the next sibling
+        else
+            nextSibling = firstChildConsideringContinuation(continuation);
+    }
+
     if (!nextSibling)
         return 0;
     
@@ -170,8 +359,20 @@ AccessibilityObject* AccessibilityRenderObject::parentObjectIfExists() const
 {
     if (!m_renderer)
         return 0;
-    
+
     RenderObject* parent = m_renderer->parent();
+
+    // Case 1: node is a block and is an inline's continuation. Parent
+    // is the start of the continuation chain.
+    RenderInline* startOfConts = 0;
+    if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer)))
+        parent = startOfConts;
+
+    // Case 2: node's parent is an inline which is some node's continuation; parent is 
+    // the earliest node in the continuation chain.
+    else if (parent && parent->isRenderInline() && (startOfConts = startOfContinuations(parent)))
+        parent = startOfConts;
+
     if (!parent)
         return 0;
 
@@ -184,6 +385,18 @@ AccessibilityObject* AccessibilityRenderObject::parentObject() const
         return 0;
     
     RenderObject* parent = m_renderer->parent();
+
+    // Case 1: node is a block and is an inline's continuation. Parent
+    // is the start of the continuation chain.
+    RenderInline* startOfConts = 0;
+    if (m_renderer->isRenderBlock() && (startOfConts = startOfContinuations(m_renderer)))
+        parent = startOfConts;
+
+    // Case 2: node's parent is an inline which is some node's continuation; parent is 
+    // the earliest node in the continuation chain.
+    else if (parent && parent->isRenderInline() && (startOfConts = startOfContinuations(parent)))
+        parent = startOfConts;
+
     if (!parent)
         return 0;
     
index 7fcb5161bc5010eb8e3b7296b531a3ee3cd962b6..4084b6ed03d89fb543509be512c3132b04358dae 100644 (file)
@@ -71,6 +71,8 @@ public:
     int verticalPositionFromCache(bool firstLine) const;
     void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
 
+    RenderInline* inlineContinuation() const;
+
 private:
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
@@ -126,7 +128,6 @@ private:
 
     virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
 
-    RenderInline* inlineContinuation() const;
     void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
     
     virtual void childBecameNonInline(RenderObject* child);