Bug 676267 - expose stale state on accessibles unattached from tree, r=tbsaunde
authorAlexander Surkov <surkov.alexander@gmail.com>
Thu, 04 Aug 2011 18:54:06 +0900
changeset 73849 dd38dafe931bf15332057edd46a96ad8c1b28602
parent 73848 7b917981c44dfa8cd6869fc42c54496dc54a8a3d
child 73850 d201bfd052b397f6213dbc2266664e024aae5ba9
push id20923
push usermak77@bonardo.net
push dateFri, 05 Aug 2011 15:10:34 +0000
treeherdermozilla-central@c7931e07dd4d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs676267
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 676267 - expose stale state on accessibles unattached from tree, r=tbsaunde
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/tests/mochitest/states/Makefile.in
accessible/tests/mochitest/states/test_stale.html
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -658,16 +658,21 @@ nsAccessible::IsVisible(PRBool* aIsOffsc
   }
   return isVisible;
 }
 
 PRUint64
 nsAccessible::NativeState()
 {
   PRUint64 state = 0;
+
+  nsDocAccessible* document = GetDocAccessible();
+  if (!document || !document->IsInDocument(this))
+    state |= states::STALE;
+
   PRBool disabled = PR_FALSE;
   if (mContent->IsElement()) {
     nsEventStates elementState = mContent->AsElement()->State();
 
     if (elementState.HasState(NS_EVENT_STATE_INVALID))
       state |= states::INVALID;
 
     if (elementState.HasState(NS_EVENT_STATE_REQUIRED))
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -230,19 +230,29 @@ public:
    *
    * @return the accessible object
    */
   nsAccessible* GetAccessible(nsINode* aNode) const;
 
   /**
    * Return whether the given DOM node has an accessible or not.
    */
-  inline bool HasAccessible(nsINode* aNode)
+  inline bool HasAccessible(nsINode* aNode) const
+    { return GetAccessible(aNode); }
+
+  /**
+   * Return true if the given accessible is in document.
+   */
+  inline bool IsInDocument(nsAccessible* aAccessible) const
   {
-    return GetAccessible(aNode);
+    nsAccessible* acc = aAccessible;
+    while (acc && !acc->IsPrimaryForNode())
+      acc = acc->Parent();
+
+    return acc ? mNodeToAccessibleMap.Get(acc->GetNode()) : false;
   }
 
   /**
    * Return the cached accessible by the given unique ID within this document.
    *
    * @note   the unique ID matches with the uniqueID() of nsAccessNode
    *
    * @param  aUniqueID  [in] the unique ID used to cache the node.
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -53,16 +53,17 @@ include $(topsrcdir)/config/rules.mk
 		test_doc.html \
 		test_docarticle.html \
 		test_editablebody.html \
 		test_frames.html \
 		test_inputs.html \
 		test_inputs.xul \
 		test_link.html \
 		test_popup.xul \
+		test_stale.html \
 		test_textbox.xul \
 		test_tree.xul \
 		z_frames.html \
 		z_frames_article.html \
 		z_frames_checkbox.html \
 		z_frames_textbox.html \
 		z_frames_update.html \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_stale.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Stale state testing</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+    function addChild(aContainerID)
+    {
+      this.containerNode = getNode(aContainerID);
+      this.childNode = null;
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, this.containerNode)
+      ];
+
+      this.invoke = function addChild_invoke()
+      {
+        this.childNode = document.createElement("div");
+        this.containerNode.appendChild(this.childNode);
+      }
+
+      this.finalCheck = function addChild_finalCheck()
+      {
+        // no stale state should be set
+        testStates(this.childNode, 0, 0, 0, EXT_STATE_STALE);
+      }
+
+      this.getID = function addChild_getID()
+      {
+        return "add child for " + prettyName(aContainerID);
+      }
+    }
+
+    function removeChildChecker(aInvoker)
+    {
+      this.type = EVENT_HIDE;
+      this.__defineGetter__("target", function() { return aInvoker.child; });
+
+      this.check = function removeChildChecker_check()
+      {
+        // stale state should be set
+        testStates(aInvoker.child, 0, EXT_STATE_STALE);
+      }
+    }
+
+    function removeChild(aContainerID)
+    {
+      this.containerNode = getNode(aContainerID);
+      this.child = null;
+
+      this.eventSeq = [
+        new removeChildChecker(this)
+      ];
+
+      this.invoke = function removeChild_invoke()
+      {
+        var childNode = this.containerNode.firstChild;
+        this.child = getAccessible(childNode);
+
+        this.containerNode.removeChild(childNode);
+      }
+
+      this.getID = function removeChild_getID()
+      {
+        return "remove child from " + prettyName(aContainerID);
+      }
+    }
+
+    //gA11yEventDumpToConsole = true; //debugging
+
+    var gQueue = null;
+    function doTest()
+    {
+      gQueue = new eventQueue();
+
+      gQueue.push(new addChild("container"));
+      gQueue.push(new removeChild("container"));
+
+      gQueue.invoke(); // will call SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+
+<body role="">
+
+  <a target="_blank"
+     title="Expose stale state on accessibles unattached from tree"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=676267">Mozilla Bug 676267</a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="container"></div>
+
+</body>
+</html>