AX: Calls to AXObjectCache should prefer Node over Renderer
authordmazzoni@google.com <dmazzoni@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Aug 2012 21:31:35 +0000 (21:31 +0000)
committerdmazzoni@google.com <dmazzoni@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Aug 2012 21:31:35 +0000 (21:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91794

Reviewed by Chris Fleizach.

Source/WebCore:

Now that it's possible for nodes inside a canvas subtree to be focused and
represent accessible content, accessibility notifications should be triggered
with a Node* rather than with a RenderObject* whenever possible.

Every public API in AXObjectCache that took a RenderObject* before now either
takes a Node* instead, or has a parallel method that takes a Node*.

Tests: accessibility/accessibility-node-memory-management.html
       accessibility/accessibility-node-reparent.html
       accessibility/canvas-fallback-content.html

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::focusedImageMapUIElement):
(WebCore::AXObjectCache::focusedUIElementForPage):
(WebCore::AXObjectCache::get):
(WebCore::AXObjectCache::getOrCreate):
(WebCore::AXObjectCache::contentChanged):
(WebCore):
(WebCore::AXObjectCache::updateCacheAfterNodeIsAttached):
(WebCore::AXObjectCache::childrenChanged):
(WebCore::AXObjectCache::postNotification):
(WebCore::AXObjectCache::checkedStateChanged):
(WebCore::AXObjectCache::selectedChildrenChanged):
(WebCore::AXObjectCache::nodeTextChangeNotification):
(WebCore::AXObjectCache::handleAriaExpandedChange):
(WebCore::AXObjectCache::handleActiveDescendantChanged):
(WebCore::AXObjectCache::handleAriaRoleChanged):
(WebCore::AXObjectCache::textMarkerDataForVisiblePosition):
(WebCore::AXObjectCache::rootAXEditableElement):
(WebCore::AXObjectCache::nodeIsTextControl):
* accessibility/AXObjectCache.h:
(AXObjectCache):
(WebCore::AXObjectCache::setNodeInUse):
(WebCore::AXObjectCache::removeNodeForUse):
(WebCore::AXObjectCache::isNodeInUse):
(WebCore::AXObjectCache::checkedStateChanged):
(WebCore::AXObjectCache::childrenChanged):
(WebCore::AXObjectCache::contentChanged):
(WebCore::AXObjectCache::updateCacheAfterNodeIsAttached):
(WebCore::AXObjectCache::handleActiveDescendantChanged):
(WebCore::AXObjectCache::handleAriaExpandedChange):
(WebCore::AXObjectCache::handleAriaRoleChanged):
(WebCore::AXObjectCache::handleFocusedUIElementChanged):
(WebCore::AXObjectCache::nodeTextChangeNotification):
(WebCore::AXObjectCache::postNotification):
(WebCore::AXObjectCache::selectedChildrenChanged):
* accessibility/AccessibilityListBoxOption.cpp:
(WebCore::AccessibilityListBoxOption::parentObject):
* accessibility/AccessibilityObject.cpp:
(WebCore::appendAccessibilityObject):
(WebCore::replacedNodeNeedsCharacter):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::menuForMenuButton):
(WebCore::AccessibilityRenderObject::menuButtonForMenu):
(WebCore::AccessibilityRenderObject::checkboxOrRadioRect):
(WebCore::AccessibilityRenderObject::addRadioButtonGroupMembers):
(WebCore::AccessibilityRenderObject::titleUIElement):
(WebCore::AccessibilityRenderObject::isTabItemSelected):
(WebCore::AccessibilityRenderObject::accessibilityParentForImageMap):
(WebCore::AccessibilityRenderObject::nodeIsTextControl):
(WebCore::AccessibilityRenderObject::activeDescendant):
(WebCore::AccessibilityRenderObject::correspondingControlForLabelElement):
(WebCore::AccessibilityRenderObject::correspondingLabelForControlElement):
* accessibility/AccessibilityRenderObject.h:
(AccessibilityRenderObject):
* accessibility/AccessibilityScrollView.cpp:
(WebCore::AccessibilityScrollView::webAreaObject):
(WebCore::AccessibilityScrollView::parentObject):
(WebCore::AccessibilityScrollView::parentObjectIfExists):
* accessibility/chromium/AXObjectCacheChromium.cpp:
(WebCore::AXObjectCache::postPlatformNotification):
(WebCore::AXObjectCache::handleFocusedUIElementChanged):
* accessibility/gtk/AXObjectCacheAtk.cpp:
(WebCore::AXObjectCache::handleFocusedUIElementChanged):
* accessibility/mac/AXObjectCacheMac.mm:
(WebCore::AXObjectCache::handleFocusedUIElementChanged):
* accessibility/win/AXObjectCacheWin.cpp:
(WebCore::AXObjectCache::handleFocusedUIElementChanged):
* bindings/cpp/WebDOMCustomVoidCallback.cpp:
(toWebCore):
* dom/Document.cpp:
(WebCore::Document::setFocusedNode):
* dom/Element.cpp:
(WebCore::Element::attributeChanged):
* dom/Node.cpp:
(WebCore::Node::~Node):
(WebCore::Node::attach):
* editing/AppendNodeCommand.cpp:
(WebCore::sendAXTextChangedIgnoringLineBreaks):
* editing/DeleteFromTextNodeCommand.cpp:
(WebCore::DeleteFromTextNodeCommand::doApply):
(WebCore::DeleteFromTextNodeCommand::doUnapply):
* editing/Editor.cpp:
(WebCore::Editor::respondToChangedContents):
(WebCore::Editor::markAndReplaceFor):
* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doApply):
(WebCore::InsertIntoTextNodeCommand::doUnapply):
* editing/InsertNodeBeforeCommand.cpp:
(WebCore::InsertNodeBeforeCommand::doApply):
(WebCore::InsertNodeBeforeCommand::doUnapply):
* editing/chromium/FrameSelectionChromium.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::childrenChanged):
(WebCore::HTMLSelectElement::optionElementChildrenChanged):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::setInnerTextValue):
* html/InputType.cpp:
(WebCore::InputType::applyStep):
* html/RangeInputType.cpp:
(WebCore::RangeInputType::handleKeydownEvent):
* page/FocusController.cpp:
(WebCore::FocusController::setInitialFocus):

LayoutTests:

New tests:
- canvas-fallback-content tests that objects in a canvas subtree can be
  focused and then you can retrieve the role of the accessible object.
- accessibility-node-memory-management ensures that an AccessibilityNodeObject
  is detached when its node is destroyed.
- accessibility-node-reparent ensures that if an AccessibilityNodeObject is
  created for a node without a renderer, but the node later gets a renderer,
  the AccessibilityNodeObject is detached and an AccessibilityRenderObject is
  created instead.

* accessibility/accessibility-node-memory-management-expected.txt: Added.
* accessibility/accessibility-node-memory-management.html: Added.
* accessibility/accessibility-node-reparent-expected.txt: Added.
* accessibility/accessibility-node-reparent.html: Added.
* accessibility/canvas-fallback-content-expected.txt: Added.
* accessibility/canvas-fallback-content.html: Added.
* platform/gtk/TestExpectations:

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

36 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/accessibility-node-memory-management-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/accessibility-node-memory-management.html [new file with mode: 0644]
LayoutTests/accessibility/accessibility-node-reparent-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/accessibility-node-reparent.html [new file with mode: 0644]
LayoutTests/accessibility/canvas-fallback-content-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/canvas-fallback-content.html [new file with mode: 0644]
LayoutTests/platform/gtk/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AXObjectCache.cpp
Source/WebCore/accessibility/AXObjectCache.h
Source/WebCore/accessibility/AccessibilityListBoxOption.cpp
Source/WebCore/accessibility/AccessibilityNodeObject.h
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityScrollView.cpp
Source/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp
Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
Source/WebCore/accessibility/mac/AXObjectCacheMac.mm
Source/WebCore/accessibility/win/AXObjectCacheWin.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/editing/AppendNodeCommand.cpp
Source/WebCore/editing/DeleteFromTextNodeCommand.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
Source/WebCore/editing/InsertNodeBeforeCommand.cpp
Source/WebCore/editing/chromium/FrameSelectionChromium.cpp
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/HTMLTextFormControlElement.cpp
Source/WebCore/html/InputType.cpp
Source/WebCore/html/RangeInputType.cpp
Source/WebCore/page/FocusController.cpp

index 5be48f8..ad3b96b 100644 (file)
@@ -1,3 +1,28 @@
+2012-08-15  Dominic Mazzoni  <dmazzoni@google.com>
+
+        AX: Calls to AXObjectCache should prefer Node over Renderer
+        https://bugs.webkit.org/show_bug.cgi?id=91794
+
+        Reviewed by Chris Fleizach.
+
+        New tests:
+        - canvas-fallback-content tests that objects in a canvas subtree can be
+          focused and then you can retrieve the role of the accessible object.
+        - accessibility-node-memory-management ensures that an AccessibilityNodeObject
+          is detached when its node is destroyed.
+        - accessibility-node-reparent ensures that if an AccessibilityNodeObject is
+          created for a node without a renderer, but the node later gets a renderer,
+          the AccessibilityNodeObject is detached and an AccessibilityRenderObject is
+          created instead.
+
+        * accessibility/accessibility-node-memory-management-expected.txt: Added.
+        * accessibility/accessibility-node-memory-management.html: Added.
+        * accessibility/accessibility-node-reparent-expected.txt: Added.
+        * accessibility/accessibility-node-reparent.html: Added.
+        * accessibility/canvas-fallback-content-expected.txt: Added.
+        * accessibility/canvas-fallback-content.html: Added.
+        * platform/gtk/TestExpectations:
+
 2012-08-15  Zan Dobersek  <zandobersek@gmail.com>
 
         Unreviewed GTK gardening.
diff --git a/LayoutTests/accessibility/accessibility-node-memory-management-expected.txt b/LayoutTests/accessibility/accessibility-node-memory-management-expected.txt
new file mode 100644 (file)
index 0000000..116ba54
--- /dev/null
@@ -0,0 +1,12 @@
+This test makes sure that AccessibilityNodeObjects are properly detached when the node they point to is deleted.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS expectedButtonRole != expectedDetachedRole is true
+PASS canvasButtonRole is expectedButtonRole
+PASS detachedCanvasButtonRole is expectedDetachedRole
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/accessibility-node-memory-management.html b/LayoutTests/accessibility/accessibility-node-memory-management.html
new file mode 100644 (file)
index 0000000..39f4bfe
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+
+<canvas id="canvas" tabindex="-1"></canvas>
+
+<div id="console"></div>
+<script>
+description("This test makes sure that AccessibilityNodeObjects are properly detached when the node they point to is deleted.");
+
+if (window.testRunner && window.accessibilityController) {
+    window.testRunner.dumpAsText();
+
+    // Create an ordinary button on the page, focus it and get its accessibility role.
+    var button = document.createElement('button');
+    document.body.appendChild(button);
+    button.focus();
+    window.axElement = accessibilityController.focusedElement;
+    window.expectedButtonRole = axElement.role;
+
+    // Now remove the node from the tree and get the role of the detached accessibility object.
+    document.body.removeChild(button);
+    window.expectedDetachedRole = axElement.role;
+    shouldBeTrue("expectedButtonRole != expectedDetachedRole");
+
+    // This time create a button that's a child of a canvas element. It will be focusable but not rendered.
+    // In particular, this will create an AccessibilityNodeObject rather than an AccessibilityRenderObject.
+    var canvas = document.getElementById('canvas');
+    (function() {
+        var button = document.createElement('button');
+        canvas.appendChild(button);
+
+        // Note: focusing the button and using that to get its accessibility object creates an extra
+        // reference to the button and it won't get deleted when we want it to. So instead we focus the
+        // canvas and get its first child.
+        canvas.focus();
+        window.axElement = accessibilityController.focusedElement.childAtIndex(0);
+
+        window.canvasButtonRole = axElement.role;
+        shouldBe("canvasButtonRole", "expectedButtonRole");
+
+        // Now delete the node.
+        canvas.removeChild(button);
+    })();
+
+    // Explicitly run garbage collection now; since there are no more references to the button,
+    // the node will be destroyed.
+    gc();
+
+    // Ensure that the accessibility object is detached by checking its role.
+    window.detachedCanvasButtonRole = axElement.role;
+    shouldBe("detachedCanvasButtonRole", "expectedDetachedRole");
+}
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/accessibility/accessibility-node-reparent-expected.txt b/LayoutTests/accessibility/accessibility-node-reparent-expected.txt
new file mode 100644 (file)
index 0000000..3583f6c
--- /dev/null
@@ -0,0 +1,14 @@
+
+This test makes sure that AccessibilityNodeObjects are properly detached when the node they point to is reparented to a location that allows them to have a renderer.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS expectedButtonRole != expectedDetachedRole is true
+PASS canvasButtonRole is expectedButtonRole
+PASS detachedCanvasButtonRole is expectedDetachedRole
+PASS reparentedButtonRole is expectedButtonRole
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/accessibility-node-reparent.html b/LayoutTests/accessibility/accessibility-node-reparent.html
new file mode 100644 (file)
index 0000000..36e950c
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+
+<div id="container" tabindex="-1"></div>
+
+<canvas id="canvas" tabindex="-1"></canvas>
+
+<div id="console"></div>
+<script>
+description("This test makes sure that AccessibilityNodeObjects are properly detached when the node they point to is reparented to a location that allows them to have a renderer.");
+
+if (window.testRunner && window.accessibilityController) {
+    window.testRunner.dumpAsText();
+
+    // Create an ordinary button on the page, focus it and get its accessibility role.
+    var button = document.createElement('button');
+    document.body.appendChild(button);
+    button.focus();
+    window.axElement = accessibilityController.focusedElement;
+    window.expectedButtonRole = axElement.role;
+
+    // Now remove the node from the tree and get the role of the detached accessibility object.
+    document.body.removeChild(button);
+    window.expectedDetachedRole = axElement.role;
+    shouldBeTrue("expectedButtonRole != expectedDetachedRole");
+
+    // This time create a button that's a child of a canvas element. It will be focusable but not rendered.
+    // In particular, this will create an AccessibilityNodeObject rather than an AccessibilityRenderObject.
+    var canvas = document.getElementById('canvas');
+    (function() {
+        var button = document.createElement('button');
+        canvas.appendChild(button);
+
+        // Note: focusing the button and using that to get its accessibility object creates an extra
+        // reference to the button and it won't get deleted when we want it to. So instead we focus the
+        // canvas and get its first child.
+        canvas.focus();
+        window.axElement = accessibilityController.focusedElement.childAtIndex(0);
+
+        window.canvasButtonRole = axElement.role;
+        shouldBe("canvasButtonRole", "expectedButtonRole");
+
+        // Now reparent the node to a container that's not a canvas.
+        var container = document.getElementById('container');
+        container.appendChild(button);
+        container.focus();
+        window.axReparentedElement = accessibilityController.focusedElement.childAtIndex(0);
+    })();
+
+    // Ensure that the old accessibility object is detached by checking its role.
+    window.detachedCanvasButtonRole = axElement.role;
+    shouldBe("detachedCanvasButtonRole", "expectedDetachedRole");
+
+    // Ensure that the new accessibility object for the now-reparented node has the correct role.
+    window.reparentedButtonRole = axReparentedElement.role;
+    shouldBe("reparentedButtonRole", "expectedButtonRole");
+}
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/accessibility/canvas-fallback-content-expected.txt b/LayoutTests/accessibility/canvas-fallback-content-expected.txt
new file mode 100644 (file)
index 0000000..b2b1ffa
--- /dev/null
@@ -0,0 +1,101 @@
+Link  Button          
+Focusable
+ARIA button
+ARIA link
+This test makes sure that focusable elements in canvas fallback content are accessible.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+link1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXLink"
+
+button1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+text1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXTextField"
+
+checkbox1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXCheckBox"
+
+radio1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXRadioButton"
+
+submit1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+combobox1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXPopUpButton"
+
+focusable1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXGroup"
+
+aria-button1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+aria-link1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXLink"
+
+link2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXLink"
+
+button2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+text2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXTextField"
+
+checkbox2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXCheckBox"
+
+radio2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXRadioButton"
+
+submit2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+combobox2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXPopUpButton"
+
+focusable2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXGroup"
+
+aria-button2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+aria-link2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXLink"
+
+focusable1
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+focusable2
+PASS document.activeElement == element is true
+PASS axElement.role is "AXRole: AXButton"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/canvas-fallback-content.html b/LayoutTests/accessibility/canvas-fallback-content.html
new file mode 100644 (file)
index 0000000..9de67d0
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+
+<div>
+  <a id="link1" href="#">Link</a>
+  <button id="button1">Button</button>
+  <input id="text1" type="text">
+  <input id="checkbox1" type="checkbox">
+  <input id="radio1" type="radio">
+  <input id="submit1" type="submit">
+  <select id="combobox1"><option>1<option>2</select>
+  <div id="focusable1" tabindex="0">Focusable</div>
+  <div id="aria-button1" tabindex="0" role="button">ARIA button</div>
+  <div id="aria-link1" tabindex="0" role="link">ARIA link</div>
+</div>
+
+<canvas id="myCanvas" width="300" height="300">
+  <a id="link2" href="#">Link</a>
+  <button id="button2">Button</button>
+  <input id="text2" type="text">
+  <input id="checkbox2" type="checkbox">
+  <input id="radio2" type="radio">
+  <input id="submit2" type="submit">
+  <select id="combobox2"><option>1<option>2</select>
+  <div id="focusable2" tabindex="0">Focusable</div>
+  <div id="aria-button2" tabindex="0" role="button">ARIA button</div>
+  <div id="aria-link2" tabindex="0" role="link">ARIA link</div>
+</canvas>
+
+<div id="console"></div>
+<script>
+description("This test makes sure that focusable elements in canvas fallback content are accessible.");
+
+if (window.testRunner && window.accessibilityController) {
+    window.testRunner.dumpAsText();
+
+    function check(id, expectedRole) {
+        debug(id);
+        window.element = document.getElementById(id);
+        element.focus();
+        shouldBe("document.activeElement == element", "true");
+        window.axElement = accessibilityController.focusedElement;
+        shouldBe("axElement.role", "\"" + expectedRole + "\"");
+        debug("");
+    }
+
+    // Check rendered controls.
+    check("link1", "AXRole: AXLink");
+    check("button1", "AXRole: AXButton");
+    check("text1", "AXRole: AXTextField");
+    check("checkbox1", "AXRole: AXCheckBox");
+    check("radio1", "AXRole: AXRadioButton");
+    check("submit1", "AXRole: AXButton");
+    check("combobox1", "AXRole: AXPopUpButton");
+    check("focusable1", "AXRole: AXGroup");
+    check("aria-button1", "AXRole: AXButton");
+    check("aria-link1", "AXRole: AXLink");
+
+    // Check unrendered controls inside a canvas.
+    check("link2", "AXRole: AXLink");
+    check("button2", "AXRole: AXButton");
+    check("text2", "AXRole: AXTextField");
+    check("checkbox2", "AXRole: AXCheckBox");
+    check("radio2", "AXRole: AXRadioButton");
+    check("submit2", "AXRole: AXButton");
+    check("combobox2", "AXRole: AXPopUpButton");
+    check("focusable2", "AXRole: AXGroup");
+    check("aria-button2", "AXRole: AXButton");
+    check("aria-link2", "AXRole: AXLink");
+
+    // Check that the role is updated when the element changes.
+    document.getElementById('focusable1').setAttribute('role', 'button');
+    check("focusable1", "AXRole: AXButton");
+    document.getElementById('focusable2').setAttribute('role', 'button');
+    check("focusable2", "AXRole: AXButton");
+}
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 0741c7d..32a0c30 100644 (file)
@@ -613,6 +613,7 @@ BUGWKGTK : accessibility/aria-text-role.html = TEXT
 BUGWKGTK : accessibility/aria-used-on-image-maps.html = TEXT
 BUGWKGTK : accessibility/button-press-action.html = TEXT
 BUGWKGTK : accessibility/canvas.html = TEXT
+BUGWKGTK : accessibility/canvas-fallback-content.html = TEXT
 BUGWKGTK : accessibility/editable-webarea-context-menu-point.html = TEXT
 BUGWKGTK : accessibility/ellipsis-text.html = TEXT
 BUGWKGTK : accessibility/ignore-spacer-elements.html = TEXT
index b8d60db..0fc7352 100644 (file)
@@ -1,3 +1,127 @@
+2012-08-15  Dominic Mazzoni  <dmazzoni@google.com>
+
+        AX: Calls to AXObjectCache should prefer Node over Renderer
+        https://bugs.webkit.org/show_bug.cgi?id=91794
+
+        Reviewed by Chris Fleizach.
+
+        Now that it's possible for nodes inside a canvas subtree to be focused and
+        represent accessible content, accessibility notifications should be triggered
+        with a Node* rather than with a RenderObject* whenever possible.
+
+        Every public API in AXObjectCache that took a RenderObject* before now either
+        takes a Node* instead, or has a parallel method that takes a Node*.
+
+        Tests: accessibility/accessibility-node-memory-management.html
+               accessibility/accessibility-node-reparent.html
+               accessibility/canvas-fallback-content.html
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::focusedImageMapUIElement):
+        (WebCore::AXObjectCache::focusedUIElementForPage):
+        (WebCore::AXObjectCache::get):
+        (WebCore::AXObjectCache::getOrCreate):
+        (WebCore::AXObjectCache::contentChanged):
+        (WebCore):
+        (WebCore::AXObjectCache::updateCacheAfterNodeIsAttached):
+        (WebCore::AXObjectCache::childrenChanged):
+        (WebCore::AXObjectCache::postNotification):
+        (WebCore::AXObjectCache::checkedStateChanged):
+        (WebCore::AXObjectCache::selectedChildrenChanged):
+        (WebCore::AXObjectCache::nodeTextChangeNotification):
+        (WebCore::AXObjectCache::handleAriaExpandedChange):
+        (WebCore::AXObjectCache::handleActiveDescendantChanged):
+        (WebCore::AXObjectCache::handleAriaRoleChanged):
+        (WebCore::AXObjectCache::textMarkerDataForVisiblePosition):
+        (WebCore::AXObjectCache::rootAXEditableElement):
+        (WebCore::AXObjectCache::nodeIsTextControl):
+        * accessibility/AXObjectCache.h:
+        (AXObjectCache):
+        (WebCore::AXObjectCache::setNodeInUse):
+        (WebCore::AXObjectCache::removeNodeForUse):
+        (WebCore::AXObjectCache::isNodeInUse):
+        (WebCore::AXObjectCache::checkedStateChanged):
+        (WebCore::AXObjectCache::childrenChanged):
+        (WebCore::AXObjectCache::contentChanged):
+        (WebCore::AXObjectCache::updateCacheAfterNodeIsAttached):
+        (WebCore::AXObjectCache::handleActiveDescendantChanged):
+        (WebCore::AXObjectCache::handleAriaExpandedChange):
+        (WebCore::AXObjectCache::handleAriaRoleChanged):
+        (WebCore::AXObjectCache::handleFocusedUIElementChanged):
+        (WebCore::AXObjectCache::nodeTextChangeNotification):
+        (WebCore::AXObjectCache::postNotification):
+        (WebCore::AXObjectCache::selectedChildrenChanged):
+        * accessibility/AccessibilityListBoxOption.cpp:
+        (WebCore::AccessibilityListBoxOption::parentObject):
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::appendAccessibilityObject):
+        (WebCore::replacedNodeNeedsCharacter):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::menuForMenuButton):
+        (WebCore::AccessibilityRenderObject::menuButtonForMenu):
+        (WebCore::AccessibilityRenderObject::checkboxOrRadioRect):
+        (WebCore::AccessibilityRenderObject::addRadioButtonGroupMembers):
+        (WebCore::AccessibilityRenderObject::titleUIElement):
+        (WebCore::AccessibilityRenderObject::isTabItemSelected):
+        (WebCore::AccessibilityRenderObject::accessibilityParentForImageMap):
+        (WebCore::AccessibilityRenderObject::nodeIsTextControl):
+        (WebCore::AccessibilityRenderObject::activeDescendant):
+        (WebCore::AccessibilityRenderObject::correspondingControlForLabelElement):
+        (WebCore::AccessibilityRenderObject::correspondingLabelForControlElement):
+        * accessibility/AccessibilityRenderObject.h:
+        (AccessibilityRenderObject):
+        * accessibility/AccessibilityScrollView.cpp:
+        (WebCore::AccessibilityScrollView::webAreaObject):
+        (WebCore::AccessibilityScrollView::parentObject):
+        (WebCore::AccessibilityScrollView::parentObjectIfExists):
+        * accessibility/chromium/AXObjectCacheChromium.cpp:
+        (WebCore::AXObjectCache::postPlatformNotification):
+        (WebCore::AXObjectCache::handleFocusedUIElementChanged):
+        * accessibility/gtk/AXObjectCacheAtk.cpp:
+        (WebCore::AXObjectCache::handleFocusedUIElementChanged):
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXObjectCache::handleFocusedUIElementChanged):
+        * accessibility/win/AXObjectCacheWin.cpp:
+        (WebCore::AXObjectCache::handleFocusedUIElementChanged):
+        * bindings/cpp/WebDOMCustomVoidCallback.cpp:
+        (toWebCore):
+        * dom/Document.cpp:
+        (WebCore::Document::setFocusedNode):
+        * dom/Element.cpp:
+        (WebCore::Element::attributeChanged):
+        * dom/Node.cpp:
+        (WebCore::Node::~Node):
+        (WebCore::Node::attach):
+        * editing/AppendNodeCommand.cpp:
+        (WebCore::sendAXTextChangedIgnoringLineBreaks):
+        * editing/DeleteFromTextNodeCommand.cpp:
+        (WebCore::DeleteFromTextNodeCommand::doApply):
+        (WebCore::DeleteFromTextNodeCommand::doUnapply):
+        * editing/Editor.cpp:
+        (WebCore::Editor::respondToChangedContents):
+        (WebCore::Editor::markAndReplaceFor):
+        * editing/InsertIntoTextNodeCommand.cpp:
+        (WebCore::InsertIntoTextNodeCommand::doApply):
+        (WebCore::InsertIntoTextNodeCommand::doUnapply):
+        * editing/InsertNodeBeforeCommand.cpp:
+        (WebCore::InsertNodeBeforeCommand::doApply):
+        (WebCore::InsertNodeBeforeCommand::doUnapply):
+        * editing/chromium/FrameSelectionChromium.cpp:
+        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::setChecked):
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::childrenChanged):
+        (WebCore::HTMLSelectElement::optionElementChildrenChanged):
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::setInnerTextValue):
+        * html/InputType.cpp:
+        (WebCore::InputType::applyStep):
+        * html/RangeInputType.cpp:
+        (WebCore::RangeInputType::handleKeydownEvent):
+        * page/FocusController.cpp:
+        (WebCore::FocusController::setInitialFocus):
+
 2012-08-15  Andreas Kling  <kling@webkit.org>
 
         NinePieceImage: Avoid unnecessary duplication of default data in assignment operator.
index dad4c84..6c08be2 100644 (file)
@@ -112,7 +112,7 @@ AccessibilityObject* AXObjectCache::focusedImageMapUIElement(HTMLAreaElement* ar
     if (!imageElement)
         return 0;
     
-    AccessibilityObject* axRenderImage = areaElement->document()->axObjectCache()->getOrCreate(imageElement->renderer());
+    AccessibilityObject* axRenderImage = areaElement->document()->axObjectCache()->getOrCreate(imageElement);
     if (!axRenderImage)
         return 0;
     
@@ -144,12 +144,10 @@ AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page* page)
     if (focusedNode->hasTagName(areaTag))
         return focusedImageMapUIElement(static_cast<HTMLAreaElement*>(focusedNode));
     
-    RenderObject* focusedNodeRenderer = focusedNode->renderer();
-    if (!focusedNodeRenderer)
+    AccessibilityObject* obj = focusedNode->document()->axObjectCache()->getOrCreate(focusedNode);
+    if (!obj)
         return 0;
 
-    AccessibilityObject* obj = focusedNodeRenderer->document()->axObjectCache()->getOrCreate(focusedNodeRenderer);
-
     if (obj->shouldFocusActiveDescendant()) {
         if (AccessibilityObject* descendant = obj->activeDescendant())
             obj = descendant;
@@ -193,16 +191,27 @@ AccessibilityObject* AXObjectCache::get(Node* node)
     if (!node)
         return 0;
 
-    // Always prefer building the AccessibilityObject from the renderer if there is one.
-    if (node->renderer())
-        return get(node->renderer());
+    AXID renderID = node->renderer() ? m_renderObjectMapping.get(node->renderer()) : 0;
+    ASSERT(!HashTraits<AXID>::isDeletedValue(renderID));
 
-    AXID axID = m_nodeObjectMapping.get(node);
-    ASSERT(!HashTraits<AXID>::isDeletedValue(axID));
-    if (!axID)
+    AXID nodeID = m_nodeObjectMapping.get(node);
+    ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID));
+
+    if (node->renderer() && nodeID && !renderID) {
+        // This can happen if an AccessibilityNodeObject is created for a node that's not
+        // rendered, but later something changes and it gets a renderer (like if it's
+        // reparented).
+        remove(nodeID);
+        return 0;
+    }
+
+    if (renderID)
+        return m_objects.get(renderID).get();
+
+    if (!nodeID)
         return 0;
 
-    return m_objects.get(axID).get();
+    return m_objects.get(nodeID).get();
 }
 
 // FIXME: This probably belongs on Node.
@@ -512,24 +521,34 @@ void AXObjectCache::removeAXID(AccessibilityObject* object)
     m_idsInUse.remove(objID);
 }
 
+void AXObjectCache::contentChanged(Node* node)
+{
+    if (AccessibilityObject* object = getOrCreate(node))
+        object->contentChanged(); 
+}
+
 void AXObjectCache::contentChanged(RenderObject* renderer)
 {
-    AccessibilityObject* object = getOrCreate(renderer);
-    if (object)
+    if (AccessibilityObject* object = getOrCreate(renderer))
         object->contentChanged(); 
 }
 
+void AXObjectCache::updateCacheAfterNodeIsAttached(Node* node)
+{
+    // Calling get() will update the AX object if we had an AccessibilityNodeObject but now we need
+    // an AccessibilityRenderObject, because it was reparented to a location outside of a canvas.
+    get(node);
+}
+
+void AXObjectCache::childrenChanged(Node* node)
+{
+    if (AccessibilityObject* obj = get(node))
+        obj->childrenChanged();
+}
+
 void AXObjectCache::childrenChanged(RenderObject* renderer)
 {
-    if (!renderer)
-        return;
-    AXID axID = m_renderObjectMapping.get(renderer);
-    if (!axID)
-        return;
-    
-    AccessibilityObject* obj = m_objects.get(axID).get();
-    if (obj)
+    if (AccessibilityObject* obj = get(renderer))
         obj->childrenChanged();
 }
     
@@ -559,8 +578,6 @@ void AXObjectCache::notificationPostTimerFired(Timer<AXObjectCache>*)
     
 void AXObjectCache::postNotification(RenderObject* renderer, AXNotification notification, bool postToElement, PostType postType)
 {
-    // Notifications for text input objects are sent to that object.
-    // All others are sent to the top WebArea.
     if (!renderer)
         return;
     
@@ -578,6 +595,25 @@ void AXObjectCache::postNotification(RenderObject* renderer, AXNotification noti
     postNotification(object.get(), renderer->document(), notification, postToElement, postType);
 }
 
+void AXObjectCache::postNotification(Node* node, AXNotification notification, bool postToElement, PostType postType)
+{
+    if (!node)
+        return;
+    
+    // Get an accessibility object that already exists. One should not be created here
+    // because a render update may be in progress and creating an AX object can re-trigger a layout
+    RefPtr<AccessibilityObject> object = get(node);
+    while (!object && node) {
+        node = node->parentNode();
+        object = get(node);
+    }
+    
+    if (!node)
+        return;
+    
+    postNotification(object.get(), node->document(), notification, postToElement, postType);
+}
+
 void AXObjectCache::postNotification(AccessibilityObject* object, Document* document, AXNotification notification, bool postToElement, PostType postType)
 {
     if (object && !postToElement)
@@ -597,9 +633,16 @@ void AXObjectCache::postNotification(AccessibilityObject* object, Document* docu
         postPlatformNotification(object, notification);
 }
 
-void AXObjectCache::checkedStateChanged(RenderObject* renderer)
+void AXObjectCache::checkedStateChanged(Node* node)
 {
-    postNotification(renderer, AXObjectCache::AXCheckedStateChanged, true);
+    postNotification(node, AXObjectCache::AXCheckedStateChanged, true);
+}
+
+void AXObjectCache::selectedChildrenChanged(Node* node)
+{
+    // postToElement is false so that you can pass in any child of an element and it will go up the parent tree
+    // to find the container which should send out the notification.
+    postNotification(node, AXSelectedChildrenChanged, false);
 }
 
 void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
@@ -609,13 +652,13 @@ void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
     postNotification(renderer, AXSelectedChildrenChanged, false);
 }
 
-void AXObjectCache::nodeTextChangeNotification(RenderObject* renderer, AXTextChange textChange, unsigned offset, const String& text)
+void AXObjectCache::nodeTextChangeNotification(Node* node, AXTextChange textChange, unsigned offset, const String& text)
 {
-    if (!renderer)
+    if (!node)
         return;
 
     // Delegate on the right platform
-    AccessibilityObject* obj = getOrCreate(renderer);
+    AccessibilityObject* obj = getOrCreate(node);
     nodeTextChangePlatformNotification(obj, textChange, offset, text);
 }
 
@@ -639,36 +682,26 @@ void AXObjectCache::handleScrollbarUpdate(ScrollView* view)
         return;
     
     // We don't want to create a scroll view from this method, only update an existing one.
-    AccessibilityObject* scrollViewObject = get(view);
-    if (scrollViewObject)
+    if (AccessibilityObject* scrollViewObject = get(view))
         scrollViewObject->updateChildrenIfNecessary();
 }
     
-void AXObjectCache::handleAriaExpandedChange(RenderObject *renderer)
+void AXObjectCache::handleAriaExpandedChange(Node* node)
 {
-    if (!renderer)
-        return;
-    AccessibilityObject* obj = getOrCreate(renderer);
-    if (obj)
+    if (AccessibilityObject* obj = getOrCreate(node))
         obj->handleAriaExpandedChanged();
 }
     
-void AXObjectCache::handleActiveDescendantChanged(RenderObject* renderer)
+void AXObjectCache::handleActiveDescendantChanged(Node* node)
 {
-    if (!renderer)
-        return;
-    AccessibilityObject* obj = getOrCreate(renderer);
-    if (obj)
+    if (AccessibilityObject* obj = getOrCreate(node))
         obj->handleActiveDescendantChanged();
 }
 
-void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer)
+void AXObjectCache::handleAriaRoleChanged(Node* node)
 {
-    if (!renderer)
-        return;
-    AccessibilityObject* obj = getOrCreate(renderer);
-    if (obj && obj->isAccessibilityRenderObject())
-        static_cast<AccessibilityRenderObject*>(obj)->updateAccessibilityRole();
+    if (AccessibilityObject* obj = getOrCreate(node))
+        obj->updateAccessibilityRole();
 }
 
 VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData)
@@ -717,13 +750,9 @@ void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerD
             return;
     }
     
-    // locate the renderer, which must exist for a visible dom node
-    RenderObject* renderer = domNode->renderer();
-    ASSERT(renderer);
-    
-    // find or create an accessibility object for this renderer
-    AXObjectCache* cache = renderer->document()->axObjectCache();
-    RefPtr<AccessibilityObject> obj = cache->getOrCreate(renderer);
+    // find or create an accessibility object for this node
+    AXObjectCache* cache = domNode->document()->axObjectCache();
+    RefPtr<AccessibilityObject> obj = cache->getOrCreate(domNode);
     
     textMarkerData.axID = obj.get()->axObjectID();
     textMarkerData.node = domNode;
@@ -751,7 +780,7 @@ bool AXObjectCache::nodeIsTextControl(const Node* node)
     if (!node)
         return false;
 
-    const AccessibilityObject* axObject = getOrCreate(node->renderer());
+    const AccessibilityObject* axObject = getOrCreate(const_cast<Node*>(node));
     return axObject && axObject->isTextControl();
 }
 
index 603fce0..1001cf2 100644 (file)
@@ -87,17 +87,22 @@ public:
 
     void detachWrapper(AccessibilityObject*);
     void attachWrapper(AccessibilityObject*);
+    void childrenChanged(Node*);
     void childrenChanged(RenderObject*);
-    void checkedStateChanged(RenderObject*);
+    void checkedStateChanged(Node*);
+    void selectedChildrenChanged(Node*);
     void selectedChildrenChanged(RenderObject*);
     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
+    void contentChanged(Node*);
     void contentChanged(RenderObject*);
-    
-    void handleActiveDescendantChanged(RenderObject*);
-    void handleAriaRoleChanged(RenderObject*);
-    void handleFocusedUIElementChanged(RenderObject* oldFocusedRenderer, RenderObject* newFocusedRenderer);
+    // Called when a node has just been attached, so we can make sure we have the right subclass of AccessibilityObject.
+    void updateCacheAfterNodeIsAttached(Node*);
+
+    void handleActiveDescendantChanged(Node*);
+    void handleAriaRoleChanged(Node*);
+    void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
     void handleScrolledToAnchor(const Node* anchorNode);
-    void handleAriaExpandedChange(RenderObject*);
+    void handleAriaExpandedChange(Node*);
     void handleScrollbarUpdate(ScrollView*);
 
 #if HAVE(ACCESSIBILITY)
@@ -124,11 +129,6 @@ public:
     AXID platformGenerateAXID() const;
     AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); }
 
-    // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
-    void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
-    void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
-    bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
-    
     // Text marker utilities.
     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
@@ -155,6 +155,7 @@ public:
     };
 
     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
+    void postNotification(Node*, AXNotification, bool postToElement, PostType = PostAsynchronously);
     void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
 
     enum AXTextChange {
@@ -162,7 +163,7 @@ public:
         AXTextDeleted,
     };
 
-    void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, const String&);
+    void nodeTextChangeNotification(Node*, AXTextChange, unsigned offset, const String&);
 
     enum AXLoadingEvent {
         AXLoadingStarted,
@@ -180,6 +181,11 @@ protected:
     void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, const String&);
     void frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent);
 
+    // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
+    void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
+    void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
+    bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
+
 private:
     Document* m_document;
     HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
@@ -220,28 +226,33 @@ inline Element* AXObjectCache::rootAXEditableElement(Node*) { return 0; }
 inline bool nodeHasRole(Node*, const String&) { return false; }
 inline const Element* AXObjectCache::rootAXEditableElement(const Node*) { return 0; }
 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
-inline void AXObjectCache::checkedStateChanged(RenderObject*) { }
+inline void AXObjectCache::checkedStateChanged(Node*) { }
 inline void AXObjectCache::childrenChanged(RenderObject*) { }
+inline void AXObjectCache::childrenChanged(Node*) { }
 inline void AXObjectCache::contentChanged(RenderObject*) { }
+inline void AXObjectCache::contentChanged(Node*) { }
+inline void AXObjectCache::updateCacheAfterNodeIsAttached(Node*) { }
 inline void AXObjectCache::detachWrapper(AccessibilityObject*) { }
 inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent) { }
-inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { }
-inline void AXObjectCache::handleAriaExpandedChange(RenderObject*) { }
-inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { }
-inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { }
+inline void AXObjectCache::handleActiveDescendantChanged(Node*) { }
+inline void AXObjectCache::handleAriaExpandedChange(Node*) { }
+inline void AXObjectCache::handleAriaRoleChanged(Node*) { }
+inline void AXObjectCache::handleFocusedUIElementChanged(Node*, Node*) { }
 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
-inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, const String&) { }
+inline void AXObjectCache::nodeTextChangeNotification(Node*, AXTextChange, unsigned, const String&) { }
 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&) { }
 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { }
 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { }
+inline void AXObjectCache::postNotification(Node*, AXNotification, bool postToElement, PostType) { }
 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
 inline void AXObjectCache::remove(AXID) { }
 inline void AXObjectCache::remove(RenderObject*) { }
 inline void AXObjectCache::remove(Node*) { }
 inline void AXObjectCache::remove(Widget*) { }
 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
+inline void AXObjectCache::selectedChildrenChanged(Node*) { }
 #endif
 
 }
index 6cc10ff..e66649a 100644 (file)
@@ -172,7 +172,7 @@ AccessibilityObject* AccessibilityListBoxOption::parentObject() const
     if (!parentNode)
         return 0;
     
-    return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode->renderer());
+    return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode);
 }
 
 void AccessibilityListBoxOption::setSelected(bool selected)
index b0e1f1f..e0a2cad 100644 (file)
@@ -81,7 +81,7 @@ public:
 
     virtual void detach();
     virtual void childrenChanged();
-    void updateAccessibilityRole();
+    virtual void updateAccessibilityRole();
 
     virtual LayoutRect elementRect() const;
 
index 793b54a..737cc6b 100644 (file)
@@ -384,7 +384,7 @@ static void appendAccessibilityObject(AccessibilityObject* object, Accessibility
         if (!doc || !doc->renderer())
             return;
         
-        object = object->axObjectCache()->getOrCreate(doc->renderer());
+        object = object->axObjectCache()->getOrCreate(doc);
     }
 
     if (object)
@@ -779,7 +779,7 @@ static bool replacedNodeNeedsCharacter(Node* replacedNode)
         return false;
 
     // create an AX object, but skip it if it is not supposed to be seen
-    AccessibilityObject* object = replacedNode->renderer()->document()->axObjectCache()->getOrCreate(replacedNode->renderer());
+    AccessibilityObject* object = replacedNode->renderer()->document()->axObjectCache()->getOrCreate(replacedNode);
     if (object->accessibilityIsIgnored())
         return false;
 
index 264781a..1e36a2c 100644 (file)
@@ -557,6 +557,7 @@ public:
 
     virtual void childrenChanged() { }
     virtual void contentChanged() { }
+    virtual void updateAccessibilityRole() { }
     const AccessibilityChildrenVector& children();
     virtual void addChildren() { }
     virtual bool canHaveChildren() const { return true; }
index 3fff2fa..5b63998 100644 (file)
@@ -998,7 +998,7 @@ AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const
 {
     Element* menu = menuElementForMenuButton();
     if (menu && menu->renderer())
-        return axObjectCache()->getOrCreate(menu->renderer());
+        return axObjectCache()->getOrCreate(menu);
     return 0;
 }
 
@@ -1016,7 +1016,7 @@ AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const
 
     if (menuItem && menuItem->renderer()) {
         // ARIA just has generic menu items.  AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem
-        AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem->renderer());
+        AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem);
         if (menuItemAX->isMenuButton())
             return menuItemAX;
     }
@@ -1552,7 +1552,7 @@ LayoutRect AccessibilityRenderObject::checkboxOrRadioRect() const
     if (!label || !label->renderer())
         return boundingBoxRect();
     
-    LayoutRect labelRect = axObjectCache()->getOrCreate(label->renderer())->elementRect();
+    LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementRect();
     labelRect.unite(boundingBoxRect());
     return labelRect;
 }
@@ -1640,7 +1640,7 @@ void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildren
         unsigned len = formElements.size();
         for (unsigned i = 0; i < len; ++i) {
             Node* associateElement = formElements[i].get();
-            if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement->renderer()))
+            if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement))
                 linkedUIElements.append(object);        
         } 
     } else {
@@ -1650,7 +1650,7 @@ void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildren
             if (list->item(i)->hasTagName(inputTag)) {
                 HTMLInputElement* associateElement = static_cast<HTMLInputElement*>(list->item(i));
                 if (associateElement->isRadioButton() && associateElement->name() == input->name()) {
-                    if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement->renderer()))
+                    if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement))
                         linkedUIElements.append(object);
                 }
             }
@@ -1703,7 +1703,7 @@ void AccessibilityRenderObject::ariaFlowToElements(AccessibilityChildrenVector&
     unsigned count = elements.size();
     for (unsigned k = 0; k < count; ++k) {
         Element* element = elements[k];
-        AccessibilityObject* flowToElement = cache->getOrCreate(element->renderer());
+        AccessibilityObject* flowToElement = cache->getOrCreate(element);
         if (flowToElement)
             flowTo.append(flowToElement);
     }
@@ -1777,7 +1777,7 @@ AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
         return 0;
     HTMLLabelElement* label = labelForElement(static_cast<Element*>(element));
     if (label && label->renderer())
-        return axObjectCache()->getOrCreate(label->renderer());
+        return axObjectCache()->getOrCreate(label);
 
     return 0;   
 }
@@ -2271,7 +2271,7 @@ bool AccessibilityRenderObject::isTabItemSelected() const
     unsigned count = elements.size();
     for (unsigned k = 0; k < count; ++k) {
         Element* element = elements[k];
-        AccessibilityObject* tabPanel = axObjectCache()->getOrCreate(element->renderer());
+        AccessibilityObject* tabPanel = axObjectCache()->getOrCreate(element);
 
         // A tab item should only control tab panels.
         if (!tabPanel || tabPanel->roleValue() != TabPanelRole)
@@ -2470,7 +2470,7 @@ AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(H
     if (!imageElement)
         return 0;
     
-    return axObjectCache()->getOrCreate(imageElement->renderer());
+    return axObjectCache()->getOrCreate(imageElement);
 }
     
 void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& result)
@@ -2661,7 +2661,7 @@ bool AccessibilityRenderObject::nodeIsTextControl(const Node* node) const
     if (!node)
         return false;
 
-    const AccessibilityObject* axObjectForNode = axObjectCache()->getOrCreate(node->renderer());
+    const AccessibilityObject* axObjectForNode = axObjectCache()->getOrCreate(const_cast<Node*>(node));
     if (!axObjectForNode)
         return false;
 
@@ -2998,7 +2998,7 @@ AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
     if (!target)
         return 0;
     
-    AccessibilityObject* obj = axObjectCache()->getOrCreate(target->renderer());
+    AccessibilityObject* obj = axObjectCache()->getOrCreate(target);
     if (obj && obj->isAccessibilityRenderObject())
     // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
         return obj;
@@ -3063,7 +3063,7 @@ AccessibilityObject* AccessibilityRenderObject::correspondingControlForLabelElem
     if (!correspondingControl)
         return 0;
     
-    return axObjectCache()->getOrCreate(correspondingControl->renderer());     
+    return axObjectCache()->getOrCreate(correspondingControl);     
 }
 
 AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElement() const
@@ -3075,7 +3075,7 @@ AccessibilityObject* AccessibilityRenderObject::correspondingLabelForControlElem
     if (node && node->isHTMLElement()) {
         HTMLLabelElement* label = labelForElement(static_cast<Element*>(node));
         if (label)
-            return axObjectCache()->getOrCreate(label->renderer());
+            return axObjectCache()->getOrCreate(label);
     }
 
     return 0;
index dc3abb8..6d13aad 100644 (file)
@@ -160,7 +160,7 @@ AccessibilityObject* AccessibilityScrollView::webAreaObject() const
     if (!doc || !doc->renderer())
         return 0;
 
-    return axObjectCache()->getOrCreate(doc->renderer());
+    return axObjectCache()->getOrCreate(doc);
 }
 
 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
@@ -197,7 +197,7 @@ AccessibilityObject* AccessibilityScrollView::parentObject() const
     
     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
     if (owner && owner->renderer())
-        return axObjectCache()->getOrCreate(owner->renderer());
+        return axObjectCache()->getOrCreate(owner);
 
     return 0;
 }
@@ -209,7 +209,7 @@ AccessibilityObject* AccessibilityScrollView::parentObjectIfExists() const
     
     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
     if (owner && owner->renderer())
-        return axObjectCache()->get(owner->renderer());
+        return axObjectCache()->get(owner);
     
     return 0;
 }
index f8afecf..a95e044 100644 (file)
@@ -80,7 +80,7 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
 
         // Calling handleFocusedUIElementChanged will focus the new active
         // descendant and send the AXFocusedUIElementChanged notification.
-        handleFocusedUIElementChanged(0, obj->document()->focusedNode()->renderer());
+        handleFocusedUIElementChanged(0, obj->document()->focusedNode());
         break;
     case AXAutocorrectionOccured:
     case AXCheckedStateChanged:
@@ -113,12 +113,12 @@ void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*,
 {
 }
 
-void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject* newFocusedRenderer)
+void AXObjectCache::handleFocusedUIElementChanged(Node*, Node* newFocusedNode)
 {
-    if (!newFocusedRenderer)
+    if (!newFocusedNode)
         return;
 
-    Page* page = newFocusedRenderer->document()->page();
+    Page* page = newFocusedNode->document()->page();
     if (!page)
         return;
 
index db8ae23..0054f16 100644 (file)
@@ -238,14 +238,14 @@ void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* o
     }
 }
 
-void AXObjectCache::handleFocusedUIElementChanged(RenderObject* oldFocusedRender, RenderObject* newFocusedRender)
+void AXObjectCache::handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode)
 {
-    RefPtr<AccessibilityObject> oldObject = getOrCreate(oldFocusedRender);
+    RefPtr<AccessibilityObject> oldObject = getOrCreate(oldFocusedNode);
     if (oldObject) {
         g_signal_emit_by_name(oldObject->wrapper(), "focus-event", false);
         g_signal_emit_by_name(oldObject->wrapper(), "state-change", "focused", false);
     }
-    RefPtr<AccessibilityObject> newObject = getOrCreate(newFocusedRender);
+    RefPtr<AccessibilityObject> newObject = getOrCreate(newFocusedNode);
     if (newObject) {
         g_signal_emit_by_name(newObject->wrapper(), "focus-event", true);
         g_signal_emit_by_name(newObject->wrapper(), "state-change", "focused", true);
index 3608d21..72d54fa 100644 (file)
@@ -139,7 +139,7 @@ void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*,
 {
 }
 
-void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*)
+void AXObjectCache::handleFocusedUIElementChanged(Node*, Node*)
 {
     wkAccessibilityHandleFocusChanged();
 }
index 7ad7ae6..8db73de 100644 (file)
@@ -134,12 +134,12 @@ AXID AXObjectCache::platformGenerateAXID() const
     return objID;
 }
 
-void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject* newFocusedRenderer)
+void AXObjectCache::handleFocusedUIElementChanged(Node*, Node* newFocusedNode)
 {
-    if (!newFocusedRenderer)
+    if (!newFocusedNode)
         return;
 
-    Page* page = newFocusedRenderer->document()->page();
+    Page* page = newFocusedNode->document()->page();
     if (!page || !page->chrome()->platformPageClient())
         return;
 
index a34cd1a..af9fc48 100644 (file)
@@ -3858,17 +3858,8 @@ bool Document::setFocusedNode(PassRefPtr<Node> prpNewFocusedNode)
     }
 
 #if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
-    if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled()) {
-        RenderObject* oldFocusedRenderer = 0;
-        RenderObject* newFocusedRenderer = 0;
-
-        if (oldFocusedNode)
-            oldFocusedRenderer = oldFocusedNode->renderer();
-        if (newFocusedNode)
-            newFocusedRenderer = newFocusedNode->renderer();
-
-        axObjectCache()->handleFocusedUIElementChanged(oldFocusedRenderer, newFocusedRenderer);
-    }
+    if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
+        axObjectCache()->handleFocusedUIElementChanged(oldFocusedNode.get(), newFocusedNode.get());
 #endif
     if (!focusChangeBlocked)
         page()->chrome()->focusedNodeChanged(m_focusedNode.get());
index 2877802..3c1b4b7 100644 (file)
@@ -724,26 +724,26 @@ void Element::attributeChanged(const Attribute& attribute)
     const QualifiedName& attrName = attribute.name();
     if (attrName == aria_activedescendantAttr) {
         // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
-        document()->axObjectCache()->handleActiveDescendantChanged(renderer());
+        document()->axObjectCache()->handleActiveDescendantChanged(this);
     } else if (attrName == roleAttr) {
         // the role attribute can change at any time, and the AccessibilityObject must pick up these changes
-        document()->axObjectCache()->handleAriaRoleChanged(renderer());
+        document()->axObjectCache()->handleAriaRoleChanged(this);
     } else if (attrName == aria_valuenowAttr) {
         // If the valuenow attribute changes, AX clients need to be notified.
-        document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
+        document()->axObjectCache()->postNotification(this, AXObjectCache::AXValueChanged, true);
     } else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == altAttr || attrName == titleAttr) {
         // If the content of an element changes due to an attribute change, notify accessibility.
-        document()->axObjectCache()->contentChanged(renderer());
+        document()->axObjectCache()->contentChanged(this);
     } else if (attrName == aria_checkedAttr)
-        document()->axObjectCache()->checkedStateChanged(renderer());
+        document()->axObjectCache()->checkedStateChanged(this);
     else if (attrName == aria_selectedAttr)
-        document()->axObjectCache()->selectedChildrenChanged(renderer());
+        document()->axObjectCache()->selectedChildrenChanged(this);
     else if (attrName == aria_expandedAttr)
-        document()->axObjectCache()->handleAriaExpandedChange(renderer());
+        document()->axObjectCache()->handleAriaExpandedChange(this);
     else if (attrName == aria_hiddenAttr)
-        document()->axObjectCache()->childrenChanged(renderer());
+        document()->axObjectCache()->childrenChanged(this);
     else if (attrName == aria_invalidAttr)
-        document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXInvalidStatusChanged, true);
+        document()->axObjectCache()->postNotification(this, AXObjectCache::AXInvalidStatusChanged, true);
 }
 
 // Returns true is the given attribute is an event handler.
index 3841e0c..360f239 100644 (file)
@@ -414,7 +414,7 @@ Node::~Node()
 
     Document* doc = m_document;
     if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists())
-        doc->axObjectCache()->removeNodeForUse(this);
+        doc->axObjectCache()->remove(this);
     
     if (m_previous)
         m_previous->setNextSibling(0);
@@ -1283,6 +1283,10 @@ void Node::attach()
 
     setAttached();
     clearNeedsStyleRecalc();
+
+    Document* doc = m_document;
+    if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists())
+        doc->axObjectCache()->updateCacheAfterNodeIsAttached(this);
 }
 
 #ifndef NDEBUG
index eedb4b5..4db5e1a 100644 (file)
@@ -51,7 +51,7 @@ static void sendAXTextChangedIgnoringLineBreaks(Node* node, AXObjectCache::AXTex
     if (nodeValue == "\n")
       return;
 
-    node->document()->axObjectCache()->nodeTextChangeNotification(node->renderer(), textChange, 0, nodeValue);
+    node->document()->axObjectCache()->nodeTextChangeNotification(node, textChange, 0, nodeValue);
 }
 
 void AppendNodeCommand::doApply()
index 786d61f..5708c86 100644 (file)
@@ -57,7 +57,7 @@ void DeleteFromTextNodeCommand::doApply()
     
     // Need to notify this before actually deleting the text
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_text);
+        document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
 
     m_node->deleteData(m_offset, m_count, ec);
 }
@@ -73,7 +73,7 @@ void DeleteFromTextNodeCommand::doUnapply()
     m_node->insertData(m_offset, m_text, ec);
 
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_text);
+        document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
 }
 
 #ifndef NDEBUG
index b307f46..41985d6 100644 (file)
@@ -494,7 +494,7 @@ void Editor::respondToChangedContents(const VisibleSelection& endingSelection)
     if (AXObjectCache::accessibilityEnabled()) {
         Node* node = endingSelection.start().deprecatedNode();
         if (node)
-            m_frame->document()->axObjectCache()->postNotification(node->renderer(), AXObjectCache::AXValueChanged, false);
+            m_frame->document()->axObjectCache()->postNotification(node, AXObjectCache::AXValueChanged, false);
     }
 
     updateMarkersForWordsAffectedByEditing(true);
@@ -2130,7 +2130,7 @@ void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect
                 
                 if (AXObjectCache::accessibilityEnabled()) {
                     if (Element* root = m_frame->selection()->selection().rootEditableElement())
-                        m_frame->document()->axObjectCache()->postNotification(root->renderer(), AXObjectCache::AXAutocorrectionOccured, true);
+                        m_frame->document()->axObjectCache()->postNotification(root, AXObjectCache::AXAutocorrectionOccured, true);
                 }
 
                 selectionChanged = true;
index e0965e0..a888f4c 100644 (file)
@@ -60,7 +60,7 @@ void InsertIntoTextNodeCommand::doApply()
     m_node->insertData(m_offset, m_text, ec);
 
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_text);
+        document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
 }
 
 void InsertIntoTextNodeCommand::doUnapply()
@@ -70,7 +70,7 @@ void InsertIntoTextNodeCommand::doUnapply()
         
     // Need to notify this before actually deleting the text
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_text);
+        document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
 
     ExceptionCode ec;
     m_node->deleteData(m_offset, m_text.length(), ec);
index 93213cc..bef4011 100644 (file)
@@ -55,7 +55,7 @@ void InsertNodeBeforeCommand::doApply()
     parent->insertBefore(m_insertChild.get(), m_refChild.get(), ec);
 
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue());
+        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue());
 }
 
 void InsertNodeBeforeCommand::doUnapply()
@@ -65,7 +65,7 @@ void InsertNodeBeforeCommand::doUnapply()
         
     // Need to notify this before actually deleting the text
     if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue());
+        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue());
 
     ExceptionCode ec;
     m_insertChild->remove(ec);
index 6bea6ee..eb201f7 100644 (file)
@@ -42,7 +42,7 @@ void FrameSelection::notifyAccessibilityForSelectionChange()
     // FIXME: Support editable text in chromium.
     if (AXObjectCache::accessibilityEnabled() && m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
         Document* document = m_frame->document();
-        document->axObjectCache()->postNotification(m_selection.start().deprecatedNode()->renderer(), AXObjectCache::AXSelectedTextChanged, false);
+        document->axObjectCache()->postNotification(m_selection.start().deprecatedNode(), AXObjectCache::AXSelectedTextChanged, false);
     }
 }
 
index d87cfe8..cfd2bf6 100644 (file)
@@ -849,7 +849,7 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
     // RenderTextView), but it's not possible to do it at the moment
     // because of the way the code is structured.
     if (renderer() && AXObjectCache::accessibilityEnabled())
-        renderer()->document()->axObjectCache()->checkedStateChanged(renderer());
+        renderer()->document()->axObjectCache()->checkedStateChanged(this);
 
     // Only send a change event for items in the document (avoid firing during
     // parsing) and don't send a change event for a radio button that's getting
index d4e1f54..9261d52 100644 (file)
@@ -378,7 +378,7 @@ void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange
     HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
     
     if (AXObjectCache::accessibilityEnabled() && renderer())
-        renderer()->document()->axObjectCache()->childrenChanged(renderer());
+        renderer()->document()->axObjectCache()->childrenChanged(this);
 }
 
 void HTMLSelectElement::optionElementChildrenChanged()
@@ -387,7 +387,7 @@ void HTMLSelectElement::optionElementChildrenChanged()
     setNeedsValidityCheck();
 
     if (AXObjectCache::accessibilityEnabled() && renderer())
-        renderer()->document()->axObjectCache()->childrenChanged(renderer());
+        renderer()->document()->axObjectCache()->childrenChanged(this);
 }
 
 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents)
index 9092de7..2ec5f09 100644 (file)
@@ -484,7 +484,7 @@ void HTMLTextFormControlElement::setInnerTextValue(const String& value)
     bool textIsChanged = value != innerTextValue();
     if (textIsChanged || !innerTextElement()->hasChildNodes()) {
         if (textIsChanged && document() && renderer() && AXObjectCache::accessibilityEnabled())
-            document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, false);
+            document()->axObjectCache()->postNotification(this, AXObjectCache::AXValueChanged, false);
 
         ExceptionCode ec = 0;
         innerTextElement()->setInnerText(value, ec);
index ec93a76..0942e9a 100644 (file)
@@ -968,7 +968,7 @@ void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldE
     setValueAsDecimal(newValue, eventBehavior, ec);
 
     if (AXObjectCache::accessibilityEnabled())
-         element()->document()->axObjectCache()->postNotification(element()->renderer(), AXObjectCache::AXValueChanged, true);
+         element()->document()->axObjectCache()->postNotification(element(), AXObjectCache::AXValueChanged, true);
 }
 
 bool InputType::getAllowedValueStep(Decimal* step) const
index ae696e6..f2cce17 100644 (file)
@@ -239,7 +239,7 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
         setValueAsDecimal(newValue, eventBehavior, ec);
 
         if (AXObjectCache::accessibilityEnabled())
-            element()->document()->axObjectCache()->postNotification(element()->renderer(), AXObjectCache::AXValueChanged, true);
+            element()->document()->axObjectCache()->postNotification(element(), AXObjectCache::AXValueChanged, true);
         element()->dispatchFormControlChangeEvent();
     }
 
index bf9512b..41e9ffd 100644 (file)
@@ -285,7 +285,7 @@ bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* e
     // into the web area again, even if focus did not change within WebCore. PostNotification is called instead
     // of handleFocusedUIElementChanged, because this will send the notification even if the element is the same.
     if (AXObjectCache::accessibilityEnabled())
-        focusedOrMainFrame()->document()->axObjectCache()->postNotification(focusedOrMainFrame()->document()->renderer(), AXObjectCache::AXFocusedUIElementChanged, true);
+        focusedOrMainFrame()->document()->axObjectCache()->postNotification(focusedOrMainFrame()->document(), AXObjectCache::AXFocusedUIElementChanged, true);
 
     return didAdvanceFocus;
 }