AXObjectCache cleared unnecessarily when non-top Document is detached.
https://bugs.webkit.org/show_bug.cgi?id=68636
Patch by Dominic Mazzoni <dmazzoni@google.com> on 2011-09-27
Reviewed by Chris Fleizach.
Source/WebCore:
Test: accessibility/deleting-iframe-destroys-axcache.html
* dom/Document.cpp:
(WebCore::Document::attach):
(WebCore::Document::detach):
LayoutTests:
* accessibility/deleting-iframe-destroys-axcache.html: Added.
* platform/mac/accessibility/deleting-iframe-destroys-axcache-expected.txt: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96127 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 55aa34e..6399959 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2011-09-27 Dominic Mazzoni <dmazzoni@google.com>
+
+ AXObjectCache cleared unnecessarily when non-top Document is detached.
+ https://bugs.webkit.org/show_bug.cgi?id=68636
+
+ Reviewed by Chris Fleizach.
+
+ * accessibility/deleting-iframe-destroys-axcache.html: Added.
+ * platform/mac/accessibility/deleting-iframe-destroys-axcache-expected.txt: Added.
+
2011-09-26 Ryosuke Niwa <rniwa@webkit.org>
dump-as-markup conversion: editing/pasteboard/merge-end-list.html and merge-end-table.html
diff --git a/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html b/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html
new file mode 100644
index 0000000..87563e2
--- /dev/null
+++ b/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html
@@ -0,0 +1,107 @@
+<html>
+<head>
+<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.waitUntilDone();
+
+ function buildAccessibilityTree(accessibilityObject, indent) {
+ var str = "";
+ for (var i = 0; i < indent; i++)
+ str += " ";
+ str += accessibilityObject.role;
+ str += " " + accessibilityObject.stringValue;
+
+ if (accessibilityObject.role == '')
+ str += accessibilityObject.allAttributes();
+
+ str += "\n";
+ document.getElementById("console").innerText += str;
+
+ if (accessibilityObject.stringValue.indexOf('End of test') >= 0)
+ return false;
+
+ var count = accessibilityObject.childrenCount;
+ for (var i = 0; i < count; ++i) {
+ if (!buildAccessibilityTree(accessibilityObject.childAtIndex(i), indent + 1))
+ return false;
+ }
+
+ return true;
+ }
+
+ function runTest()
+ {
+ description("This tests that deleting an iframe doesn't cause the accessibility cache to be destroyed and recreated.");
+
+ if (window.accessibilityController) {
+ window.root = accessibilityController.rootElement;
+ window.body = root.childAtIndex(0);
+ window.before = body.childAtIndex(0).childAtIndex(0);
+ window.iframe = body.childAtIndex(1).childAtIndex(0);
+ window.after = body.childAtIndex(2).childAtIndex(0);
+
+ window.frameBody = window.iframe.childAtIndex(0);
+ window.frameBodyRole = window.frameBody.role;
+ window.frameGroup = window.frameBody.childAtIndex(0);
+ window.frameGroupRole = window.frameGroup.role;
+ window.frameButton = window.frameGroup.childAtIndex(0);
+ window.frameButtonRole = window.frameButton.role;
+
+ document.getElementById("console").innerText += "\nBefore:\n";
+ buildAccessibilityTree(root, 0);
+
+ // Remove the iframe.
+ document.body.removeChild(document.getElementById("iframe"));
+
+ window.newRoot = accessibilityController.rootElement;
+ window.newBody = newRoot.childAtIndex(0);
+ window.newBefore = newBody.childAtIndex(0).childAtIndex(0);
+ window.newAfter = newBody.childAtIndex(1).childAtIndex(0);
+
+ document.getElementById("console").innerText += "\nAfter:\n";
+ buildAccessibilityTree(newRoot, 0);
+ document.getElementById("console").innerText += "\n";
+
+ // Make sure that the accessibility objects from the iframe's nodes
+ // are now invalid by checking that their role is changed - this
+ // is because they've been deleted.
+ shouldBeFalse("frameBodyRole == frameBody.role");
+ shouldBeFalse("frameGroupRole == frameGroup.role");
+ shouldBeFalse("frameButtonRole == frameButton.role");
+
+ // Make sure that the other nodes are unchanged.
+ shouldBeTrue("root.isEqual(newRoot)");
+ shouldBeTrue("body.isEqual(newBody)");
+ shouldBeTrue("before.isEqual(newBefore)");
+ shouldBeTrue("after.isEqual(newAfter)");
+ }
+
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ }
+
+ window.addEventListener('load', function() {
+ setTimeout(runTest, 10);
+ }, false);
+
+ </script>
+</head>
+<body>
+
+<p>Before</p>
+
+<iframe id="iframe" src="data:text/html,<body><button>Click me</button></body>"></iframe>
+
+<p>After</p>
+
+<p>End of test</p>
+
+<p id="description"></p>
+<div id="console"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/accessibility/deleting-iframe-destroys-axcache-expected.txt b/LayoutTests/platform/mac/accessibility/deleting-iframe-destroys-axcache-expected.txt
new file mode 100644
index 0000000..5a36718
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/deleting-iframe-destroys-axcache-expected.txt
@@ -0,0 +1,47 @@
+Before
+
+After
+
+End of test
+
+This tests that deleting an iframe doesn't cause the accessibility cache to be destroyed and recreated.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Before:
+AXRole: AXScrollArea
+ AXRole: AXWebArea AXValue:
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: Before
+ AXRole: AXGroup AXValue:
+ AXRole: AXScrollArea
+ AXRole: AXWebArea AXValue:
+ AXRole: AXGroup AXValue:
+ AXRole: AXButton AXValue:
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: After
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: End of test
+
+After:
+AXRole: AXScrollArea
+ AXRole: AXWebArea AXValue:
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: Before
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: After
+ AXRole: AXGroup AXValue:
+ AXRole: AXStaticText AXValue: End of test
+
+PASS frameBodyRole == frameBody.role is false
+PASS frameGroupRole == frameGroup.role is false
+PASS frameButtonRole == frameButton.role is false
+PASS root.isEqual(newRoot) is true
+PASS body.isEqual(newBody) is true
+PASS before.isEqual(newBefore) is true
+PASS after.isEqual(newAfter) is true
+
+TEST COMPLETE
+
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 5ca35ed..a9ed907 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,16 @@
+2011-09-27 Dominic Mazzoni <dmazzoni@google.com>
+
+ AXObjectCache cleared unnecessarily when non-top Document is detached.
+ https://bugs.webkit.org/show_bug.cgi?id=68636
+
+ Reviewed by Chris Fleizach.
+
+ Test: accessibility/deleting-iframe-destroys-axcache.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::attach):
+ (WebCore::Document::detach):
+
2011-09-27 Sheriff Bot <webkit.review.bot@gmail.com>
Unreviewed, rolling out r96108, r96111, r96113, and r96116.
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index aec22b0..1483cf0 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -1801,7 +1801,7 @@
{
ASSERT(!attached());
ASSERT(!m_inPageCache);
- ASSERT(!m_axObjectCache);
+ ASSERT(!m_axObjectCache || this != topDocument());
if (!m_renderArena)
m_renderArena = adoptPtr(new RenderArena);
@@ -1827,7 +1827,9 @@
ASSERT(attached());
ASSERT(!m_inPageCache);
- clearAXObjectCache();
+ if (this == topDocument())
+ clearAXObjectCache();
+
stopActiveDOMObjects();
m_eventQueue->close();
#if ENABLE(FULLSCREEN_API)