- Revision
- 100057
- Author
- [email protected]
- Date
- 2011-11-11 18:23:09 -0800 (Fri, 11 Nov 2011)
Log Message
New iframe content may not be reflected in the ax tree.
https://bugs.webkit.org/show_bug.cgi?id=72100
Reviewed by Chris Fleizach.
Source/WebCore:
The core issue was that when childrenChanged was called on a
web area from an iframe that was just detached, it wasn't calling
childrenChanged on its parent scroll area, or that scroll area's
parent iframe element. To fix this, now AccessibilityScrollView
implements setNeedsToUpdateChildren and parentObjectIfExists,
and childrenChanged calls setNeedsToUpdateChildren on every object
in the parent chain, not just AccessibilityRenderObjects.
Test: accessibility/loading-iframe-updates-axtree.html
* accessibility/AXObjectCache.h:
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::setNeedsToUpdateChildren):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::parentObjectIfExists):
(WebCore::AccessibilityRenderObject::childrenChanged):
* accessibility/AccessibilityRenderObject.h:
(WebCore::AccessibilityRenderObject::setNeedsToUpdateChildren):
* accessibility/AccessibilityScrollView.cpp:
(WebCore::AccessibilityScrollView::AccessibilityScrollView):
(WebCore::AccessibilityScrollView::updateChildrenIfNecessary):
(WebCore::AccessibilityScrollView::parentObject):
(WebCore::AccessibilityScrollView::parentObjectIfExists):
* accessibility/AccessibilityScrollView.h:
(WebCore::AccessibilityScrollView::setNeedsToUpdateChildren):
LayoutTests:
Add new test that makes sure that if you explore the accessibility
tree of an iframe and that iframe subsequently loads new content,
the iframe AccessibilityObject's descendants are updated to point
to the new content, not the old content.
* accessibility/loading-iframe-updates-axtree-expected.txt: Added.
* accessibility/loading-iframe-updates-axtree.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (100056 => 100057)
--- trunk/LayoutTests/ChangeLog 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/LayoutTests/ChangeLog 2011-11-12 02:23:09 UTC (rev 100057)
@@ -1,3 +1,18 @@
+2011-11-11 Dominic Mazzoni <[email protected]>
+
+ New iframe content may not be reflected in the ax tree.
+ https://bugs.webkit.org/show_bug.cgi?id=72100
+
+ Reviewed by Chris Fleizach.
+
+ Add new test that makes sure that if you explore the accessibility
+ tree of an iframe and that iframe subsequently loads new content,
+ the iframe AccessibilityObject's descendants are updated to point
+ to the new content, not the old content.
+
+ * accessibility/loading-iframe-updates-axtree-expected.txt: Added.
+ * accessibility/loading-iframe-updates-axtree.html: Added.
+
2011-11-11 Julien Chaffraix <[email protected]>
Crash in styleDidChange when changing a table cell's height.
Added: trunk/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt (0 => 100057)
--- trunk/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt 2011-11-12 02:23:09 UTC (rev 100057)
@@ -0,0 +1,19 @@
+Before
+
+
+After
+
+End of test
+
+This tests that if an iframe loads new content after its accessibility object has already been accessed, the iframe accessibility object's descendants are the new scroll area and web area, not the old deleted ones.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS iframe.isEqual(newIframe) is true
+PASS scrollarea.isEqual(newScrollarea) is false
+PASS subwebarea.isEqual(newSubwebarea) is false
+PASS newSubwebarea.childrenCount > 0 is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/accessibility/loading-iframe-updates-axtree.html (0 => 100057)
--- trunk/LayoutTests/accessibility/loading-iframe-updates-axtree.html (rev 0)
+++ trunk/LayoutTests/accessibility/loading-iframe-updates-axtree.html 2011-11-12 02:23:09 UTC (rev 100057)
@@ -0,0 +1,66 @@
+<html>
+<head>
+<script src=""
+
+ <script>
+ if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+ function runTest()
+ {
+ description("This tests that if an iframe loads new content after its accessibility object has already been accessed, the iframe accessibility object's descendants are the new scroll area and web area, not the old deleted ones.");
+
+ if (window.accessibilityController) {
+ window.root = accessibilityController.rootElement;
+ window.body = root.childAtIndex(0);
+ window.iframe = body.childAtIndex(1).childAtIndex(0);
+ window.scrollarea = iframe.childAtIndex(0);
+ window.subwebarea = scrollarea.childAtIndex(0);
+ }
+
+ window.iframeElement = document.getElementById("iframe");
+ iframeElement.addEventListener("load", function() {
+ if (window.accessibilityController) {
+ window.newIframe = body.childAtIndex(1).childAtIndex(0);
+ window.newScrollarea = newIframe.childAtIndex(0);
+ window.newSubwebarea = newScrollarea.childAtIndex(0);
+
+ shouldBeTrue("iframe.isEqual(newIframe)");
+ shouldBeFalse("scrollarea.isEqual(newScrollarea)");
+ shouldBeFalse("subwebarea.isEqual(newSubwebarea)");
+ shouldBeTrue("newSubwebarea.childrenCount > 0");
+ }
+
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ }, false);
+
+ // Load content into the iframe. This will trigger the event
+ // handler above, which will check that the accessibility tree
+ // was updated with new content.
+ window.iframeElement.src = "" me</button></body>";
+
+ }
+
+ window.addEventListener('load', function() {
+ setTimeout(runTest, 10);
+ }, false);
+
+ </script>
+</head>
+<body>
+
+<p>Before</p>
+
+<iframe id="iframe"></iframe>
+
+<p>After</p>
+
+<p>End of test</p>
+
+<p id="description"></p>
+<div id="console"></div>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (100056 => 100057)
--- trunk/Source/WebCore/ChangeLog 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/ChangeLog 2011-11-12 02:23:09 UTC (rev 100057)
@@ -1,3 +1,36 @@
+2011-11-11 Dominic Mazzoni <[email protected]>
+
+ New iframe content may not be reflected in the ax tree.
+ https://bugs.webkit.org/show_bug.cgi?id=72100
+
+ Reviewed by Chris Fleizach.
+
+ The core issue was that when childrenChanged was called on a
+ web area from an iframe that was just detached, it wasn't calling
+ childrenChanged on its parent scroll area, or that scroll area's
+ parent iframe element. To fix this, now AccessibilityScrollView
+ implements setNeedsToUpdateChildren and parentObjectIfExists,
+ and childrenChanged calls setNeedsToUpdateChildren on every object
+ in the parent chain, not just AccessibilityRenderObjects.
+
+ Test: accessibility/loading-iframe-updates-axtree.html
+
+ * accessibility/AXObjectCache.h:
+ * accessibility/AccessibilityObject.h:
+ (WebCore::AccessibilityObject::setNeedsToUpdateChildren):
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::parentObjectIfExists):
+ (WebCore::AccessibilityRenderObject::childrenChanged):
+ * accessibility/AccessibilityRenderObject.h:
+ (WebCore::AccessibilityRenderObject::setNeedsToUpdateChildren):
+ * accessibility/AccessibilityScrollView.cpp:
+ (WebCore::AccessibilityScrollView::AccessibilityScrollView):
+ (WebCore::AccessibilityScrollView::updateChildrenIfNecessary):
+ (WebCore::AccessibilityScrollView::parentObject):
+ (WebCore::AccessibilityScrollView::parentObjectIfExists):
+ * accessibility/AccessibilityScrollView.h:
+ (WebCore::AccessibilityScrollView::setNeedsToUpdateChildren):
+
2011-11-11 Iain Merrick <[email protected]>
[chromium] Fix CCThreadProxy::setVisible
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2011-11-12 02:23:09 UTC (rev 100057)
@@ -76,6 +76,7 @@
// will only return the AccessibilityObject if it already exists
AccessibilityObject* get(RenderObject*);
+ AccessibilityObject* get(Widget*);
void remove(RenderObject*);
void remove(Widget*);
@@ -171,7 +172,6 @@
static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
AXID getAXID(AccessibilityObject*);
- AccessibilityObject* get(Widget*);
};
bool nodeHasRole(Node*, const String& role);
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2011-11-12 02:23:09 UTC (rev 100057)
@@ -564,6 +564,7 @@
virtual bool canHaveChildren() const { return true; }
virtual bool hasChildren() const { return m_haveChildren; }
virtual void updateChildrenIfNecessary();
+ virtual void setNeedsToUpdateChildren() { }
virtual void clearChildren();
virtual void detachFromParent() { }
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2011-11-12 02:23:09 UTC (rev 100057)
@@ -435,6 +435,10 @@
AccessibilityObject* AccessibilityRenderObject::parentObjectIfExists() const
{
+ // WebArea's parent should be the scroll view containing it.
+ if (isWebArea())
+ return axObjectCache()->get(m_renderer->frame()->view());
+
return axObjectCache()->get(renderParentObject());
}
@@ -3402,36 +3406,25 @@
if (!m_renderer)
return;
- bool sentChildrenChanged = false;
-
+ axObjectCache()->postNotification(this, document(), AXObjectCache::AXChildrenChanged, true);
+
// Go up the accessibility parent chain, but only if the element already exists. This method is
// called during render layouts, minimal work should be done.
// If AX elements are created now, they could interrogate the render tree while it's in a funky state.
// At the same time, process ARIA live region changes.
for (AccessibilityObject* parent = this; parent; parent = parent->parentObjectIfExists()) {
- if (!parent->isAccessibilityRenderObject())
- continue;
-
- AccessibilityRenderObject* axParent = toAccessibilityRenderObject(parent);
-
- // Send the children changed notification on the first accessibility render object ancestor.
- if (!sentChildrenChanged) {
- axObjectCache()->postNotification(axParent->renderer(), AXObjectCache::AXChildrenChanged, true);
- sentChildrenChanged = true;
- }
-
- axParent->setNeedsToUpdateChildren();
-
+ parent->setNeedsToUpdateChildren();
+
// These notifications always need to be sent because screenreaders are reliant on them to perform.
// In other words, they need to be sent even when the screen reader has not accessed this live region since the last update.
// If this element supports ARIA live regions, then notify the AT of changes.
- if (axParent->supportsARIALiveRegion())
- axObjectCache()->postNotification(axParent->renderer(), AXObjectCache::AXLiveRegionChanged, true);
+ if (parent->supportsARIALiveRegion())
+ axObjectCache()->postNotification(parent, parent->document(), AXObjectCache::AXLiveRegionChanged, true);
// If this element is an ARIA text control, notify the AT of changes.
- if (axParent->isARIATextControl() && !axParent->isNativeTextControl() && !axParent->node()->isContentEditable())
- axObjectCache()->postNotification(axParent->renderer(), AXObjectCache::AXValueChanged, true);
+ if (parent->isARIATextControl() && !parent->isNativeTextControl() && !parent->node()->isContentEditable())
+ axObjectCache()->postNotification(parent, parent->document(), AXObjectCache::AXValueChanged, true);
}
}
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h 2011-11-12 02:23:09 UTC (rev 100057)
@@ -261,7 +261,7 @@
protected:
RenderObject* m_renderer;
AccessibilityRole m_ariaRole;
- mutable bool m_childrenDirty;
+ bool m_childrenDirty;
void setRenderObject(RenderObject* renderer) { m_renderer = renderer; }
void ariaLabeledByElements(Vector<Element*>& elements) const;
@@ -280,6 +280,7 @@
PlainTextRange ariaSelectedTextRange() const;
Element* rootEditableElementForPosition(const Position&) const;
bool nodeIsTextControl(const Node*) const;
+ virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; }
Element* menuElementForMenuButton() const;
Element* menuItemElementForMenu() const;
@@ -320,7 +321,6 @@
virtual bool ariaLiveRegionBusy() const;
bool inheritsPresentationalRole() const;
- void setNeedsToUpdateChildren() const { m_childrenDirty = true; }
mutable AccessibilityRole m_roleForMSAA;
};
Modified: trunk/Source/WebCore/accessibility/AccessibilityScrollView.cpp (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AccessibilityScrollView.cpp 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AccessibilityScrollView.cpp 2011-11-12 02:23:09 UTC (rev 100057)
@@ -39,6 +39,7 @@
AccessibilityScrollView::AccessibilityScrollView(ScrollView* view)
: m_scrollView(view)
+ , m_childrenDirty(false)
{
}
@@ -74,6 +75,9 @@
void AccessibilityScrollView::updateChildrenIfNecessary()
{
+ if (m_childrenDirty)
+ clearChildren();
+
if (!m_haveChildren)
addChildren();
@@ -174,10 +178,22 @@
return 0;
HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
- if (owner && owner->renderPart())
- return axObjectCache()->getOrCreate(owner->renderPart()->parent());
+ if (owner && owner->renderer())
+ return axObjectCache()->getOrCreate(owner->renderer());
+
+ return 0;
+}
+AccessibilityObject* AccessibilityScrollView::parentObjectIfExists() const
+{
+ if (!m_scrollView->isFrameView())
+ return 0;
+
+ HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
+ if (owner && owner->renderer())
+ return axObjectCache()->get(owner->renderer());
+
return 0;
}
-
+
} // namespace WebCore
Modified: trunk/Source/WebCore/accessibility/AccessibilityScrollView.h (100056 => 100057)
--- trunk/Source/WebCore/accessibility/AccessibilityScrollView.h 2011-11-12 02:10:55 UTC (rev 100056)
+++ trunk/Source/WebCore/accessibility/AccessibilityScrollView.h 2011-11-12 02:23:09 UTC (rev 100057)
@@ -54,11 +54,13 @@
virtual void addChildren();
virtual AccessibilityObject* accessibilityHitTest(const LayoutPoint&) const;
virtual void updateChildrenIfNecessary();
+ virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; }
void updateScrollbars();
virtual FrameView* documentFrameView() const;
virtual LayoutRect elementRect() const;
virtual AccessibilityObject* parentObject() const;
+ virtual AccessibilityObject* parentObjectIfExists() const;
AccessibilityObject* webAreaObject() const;
virtual AccessibilityObject* firstChild() const { return webAreaObject(); }
@@ -68,6 +70,7 @@
RefPtr<ScrollView> m_scrollView;
RefPtr<AccessibilityObject> m_horizontalScrollbar;
RefPtr<AccessibilityObject> m_verticalScrollbar;
+ bool m_childrenDirty;
};
inline AccessibilityScrollView* toAccessibilityScrollView(AccessibilityObject* object)