Bug 403794. GetState() cleanup to fix some crashes on defunct objects and some incorrect states, and remove some code that is no longer necessary. r=surkov, a=dsicore
authoraaronleventhal@moonset.net
Thu, 15 Nov 2007 11:53:40 -0800
changeset 8052 85e8ae4514b6a9530f97bda0e5ed5faff89f4bbc
parent 8051 f2a0f2dc264274a53e68471b5b17ed65c7b80877
child 8053 1ec2a1489a3600d9d79a1dc2166cf02caddff5b1
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssurkov, dsicore
bugs403794
milestone1.9b2pre
Bug 403794. GetState() cleanup to fix some crashes on defunct objects and some incorrect states, and remove some code that is no longer necessary. r=surkov, a=dsicore
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsBaseWidgetAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsRootAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.cpp
accessible/src/html/nsHTMLLinkAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.h
accessible/src/html/nsHTMLTextAccessible.cpp
accessible/src/html/nsHTMLTextAccessible.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
accessible/src/xul/nsXULAlertAccessible.cpp
accessible/src/xul/nsXULColorPickerAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.h
accessible/src/xul/nsXULMenuAccessible.cpp
accessible/src/xul/nsXULSelectAccessible.cpp
accessible/src/xul/nsXULTabAccessible.cpp
accessible/src/xul/nsXULTabAccessible.h
accessible/src/xul/nsXULTreeAccessible.cpp
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -990,24 +990,26 @@ PRBool nsAccessible::IsVisible(PRBool *a
   return isVisible;
 }
 
 nsresult
 nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   *aState = 0;
 
+  if (!mDOMNode) {
+    if (aExtraState) {
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    }
+    return NS_OK; // Node shut down
+  }
+
   if (aExtraState)
     *aExtraState = 0;
 
-  if (!mDOMNode && aExtraState) {
-    *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
-    return NS_OK; // Node shut down
-  }
-
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content) {
     return NS_OK;  // On document, this is not an error
   }
 
   // Set STATE_UNAVAILABLE state based on disabled attribute
   // The disabled attribute is mostly used in XUL elements and HTML forms, but
   // if someone sets it on another attribute, 
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -116,16 +116,18 @@ NS_IMETHODIMP nsLinkableAccessible::Take
 }
 
 /* long GetState (); */
 NS_IMETHODIMP
 nsLinkableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   if (mIsLink) {
     *aState |= nsIAccessibleStates::STATE_LINKED;
     nsCOMPtr<nsILink> link = do_QueryInterface(mActionContent);
     if (link) {
       nsLinkState linkState;
       link->GetLinkState(linkState);
       if (linkState == eLinkState_Visited) {
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -230,16 +230,18 @@ nsDocAccessible::GetDescription(nsAStrin
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // nsAccessible::GetState() always fail for document accessible.
   nsAccessible::GetState(aState, aExtraState);
+  if (!mDOMNode)
+    return NS_OK;
 
 #ifdef MOZ_XUL
   nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
   if (!xulDoc)
 #endif
   {
     // XXX Need to invent better check to see if doc is focusable,
     // which it should be if it is scrollable. A XUL document could be focusable.
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -207,16 +207,18 @@ PRUint32 nsRootAccessible::GetChromeFlag
 }
 #endif
 
 NS_IMETHODIMP
 nsRootAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsDocAccessibleWrap::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
 #ifdef MOZ_XUL
   PRUint32 chromeFlags = GetChromeFlags();
   if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) {
     *aState |= nsIAccessibleStates::STATE_SIZEABLE;
   }
   if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR) {
     // If it has a titlebar it's movable
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -89,16 +89,18 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImage
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The state is a bitfield, get our inherited state, then logically OR it with
   // STATE_ANIMATED if this is an animated image.
 
   nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
   nsCOMPtr<imgIRequest> imageRequest;
 
   if (content)
     content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                         getter_AddRefs(imageRequest));
 
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/nsHTMLLinkAccessible.cpp
@@ -65,16 +65,18 @@ NS_IMETHODIMP nsHTMLLinkAccessible::GetR
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   *aState  &= ~nsIAccessibleStates::STATE_READONLY;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (content && content->HasAttr(kNameSpaceID_None,
                                   nsAccessibilityAtoms::name)) {
     // This is how we indicate it is a named anchor
     // In other words, this anchor can be selected as a location :)
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -325,16 +325,18 @@ nsHTMLSelectListAccessible::nsHTMLSelect
   *     nsIAccessibleStates::STATE_MULTISELECTABLE
   *     nsIAccessibleStates::STATE_EXTSELECTABLE
   */
 NS_IMETHODIMP
 nsHTMLSelectListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsHTMLSelectableAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsCOMPtr<nsIDOMHTMLSelectElement> select (do_QueryInterface(mDOMNode));
   if (select) {
     if (*aState | nsIAccessibleStates::STATE_FOCUSED) {
       // Treat first focusable option node as actual focus, in order
       // to avoid confusing JAWS, which needs focus on the option
       nsCOMPtr<nsIDOMNode> focusedOption;
       nsHTMLSelectOptionAccessible::GetFocusedOptionNode(mDOMNode, 
@@ -609,19 +611,19 @@ nsIFrame* nsHTMLSelectOptionAccessible::
   *     STATE_OFFSCREEN
   */
 NS_IMETHODIMP
 nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Upcall to nsAccessible, but skip nsHyperTextAccessible impl
   // because we don't want EXT_STATE_EDITABLE or EXT_STATE_SELECTABLE_TEXT
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  NS_ENSURE_TRUE(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRUint32 selectState, selectExtState;
   nsCOMPtr<nsIContent> selectContent = GetSelectState(&selectState,
                                                       &selectExtState);
   if (selectState & nsIAccessibleStates::STATE_INVISIBLE) {
     return NS_OK;
   }
 
@@ -1070,16 +1072,18 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::
   *     STATE_COLLAPSED
   */
 NS_IMETHODIMP
 nsHTMLComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsIFrame *frame = GetBoundsFrame();
   nsIComboboxControlFrame *comboFrame = nsnull;
   if (frame) {
     frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
   }
 
   if (comboFrame && comboFrame->IsDroppedDown()) {
@@ -1388,16 +1392,18 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccess
   *     STATE_INVISIBLE
   */
 NS_IMETHODIMP
 nsHTMLComboboxButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsIFrame *boundsFrame = GetBoundsFrame();
   nsIComboboxControlFrame* comboFrame = nsnull;
   if (boundsFrame)
     boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
 
   if (!comboFrame) {
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
@@ -1445,16 +1451,18 @@ nsIFrame *nsHTMLComboboxListAccessible::
   *     STATE_FLOATING
   */
 NS_IMETHODIMP
 nsHTMLComboboxListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsIFrame *boundsFrame = GetBoundsFrame();
   nsIComboboxControlFrame* comboFrame = nsnull;
   if (boundsFrame)
     boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
 
   if (comboFrame && comboFrame->IsDroppedDown())
     *aState |= nsIAccessibleStates::STATE_FLOATING;
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -69,28 +69,16 @@ nsHyperTextAccessibleWrap(aDomNode, aShe
 
 /* unsigned long getRole (); */
 NS_IMETHODIMP nsHTMLTableCellAccessible::GetRole(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_CELL;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsHTMLTableCellAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  nsresult rv = nsAccessible::GetState(aState, aExtraState);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Inherit all states except focusable state since table cells cannot be
-  // focused.
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
-  return NS_OK;
-}
-
 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLTableAccessible, nsAccessible, nsIAccessibleTable)
 
 nsHTMLTableAccessible::nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
 nsAccessibleWrap(aDomNode, aShell)
 { 
 }
 
 void nsHTMLTableAccessible::CacheChildren()
@@ -141,20 +129,17 @@ NS_IMETHODIMP nsHTMLTableAccessible::Get
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv= nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
   *aState |= nsIAccessibleStates::STATE_READONLY;
-  // Inherit all states except focusable state since tables cannot be focused.
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLTableAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();  // Default name is blank
 
   nsAccessible::GetName(aName);
--- a/accessible/src/html/nsHTMLTableAccessible.h
+++ b/accessible/src/html/nsHTMLTableAccessible.h
@@ -44,17 +44,16 @@
 
 class nsHTMLTableCellAccessible : public nsHyperTextAccessibleWrap
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aResult); 
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsITableLayout;
 
 // To turn on table debugging descriptions define SHOW_LAYOUT_HEURISTIC
 // This allow release trunk builds to be used by testers to refine the
 // data vs. layout heuristic
 // #define SHOW_LAYOUT_HEURISTIC
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -72,16 +72,18 @@ NS_IMETHODIMP nsHTMLTextAccessible::GetR
   return nsTextAccessible::GetRole(aRole);
 }
 
 NS_IMETHODIMP
 nsHTMLTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsCOMPtr<nsIAccessible> docAccessible = 
     do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
   if (docAccessible) {
      PRUint32 state, extState;
      docAccessible->GetFinalState(&state, &extState);
      if (0 == (extState & nsIAccessibleStates::EXT_STATE_EDITABLE)) {
        *aState |= nsIAccessibleStates::STATE_READONLY; // Links not focusable in editor
@@ -115,41 +117,34 @@ nsLeafAccessible(aDomNode, aShell)
 }
 
 NS_IMETHODIMP nsHTMLHRAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_SEPARATOR;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsHTMLHRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
-  return NS_OK;
-}
-
 nsHTMLBRAccessible::nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
 nsLeafAccessible(aDomNode, aShell)
 { 
 }
 
 NS_IMETHODIMP nsHTMLBRAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_WHITESPACE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLBRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   *aState = nsIAccessibleStates::STATE_READONLY;
+  if (aExtraState) {
+    *aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLBRAccessible::GetName(nsAString& aName)
 {
   aName = static_cast<PRUnichar>('\n');    // Newline char
   return NS_OK;
 }
@@ -183,19 +178,20 @@ NS_IMETHODIMP nsHTMLLabelAccessible::Get
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLLabelAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= (nsIAccessibleStates::STATE_LINKED |
-              nsIAccessibleStates::STATE_TRAVERSED);  // Only use link states
+  if (mDOMNode) {
+    *aState &= (nsIAccessibleStates::STATE_LINKED |
+                nsIAccessibleStates::STATE_TRAVERSED); // Only use link states
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLLabelAccessible::GetFirstChild(nsIAccessible **aFirstChild) 
 {  
   // A <label> is not necessarily a leaf!
   return nsAccessible::GetFirstChild(aFirstChild);
 }
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -58,17 +58,16 @@ public:
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 };
 
 class nsHTMLHRAccessible : public nsLeafAccessible
 {
 public:
   nsHTMLHRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsHTMLBRAccessible : public nsLeafAccessible
 {
 public:
   nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
   NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -161,18 +161,17 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHyperTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessibleWrap::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!aExtraState)
+  if (!mDOMNode || !aExtraState)
     return NS_OK;
 
   nsCOMPtr<nsIEditor> editor;
   GetAssociatedEditor(getter_AddRefs(editor));
   if (editor) {
     PRUint32 flags;
     editor->GetFlags(&flags);
     if (0 == (flags & nsIPlaintextEditor::eEditorReadonlyMask)) {
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -170,16 +170,24 @@ nsXFormsAccessible::GetValue(nsAString& 
   return sXFormsService->GetValue(mDOMNode, aValue);
 }
 
 NS_IMETHODIMP
 nsXFormsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
   *aState = 0;
+  if (!mDOMNode) {
+    if (aExtraState) {
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    }
+    return NS_OK;
+  }
+  if (aExtraState)
+    *aExtraState = 0;
 
   NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
 
   PRBool isRelevant = PR_FALSE;
   nsresult rv = sXFormsService->IsRelevant(mDOMNode, &isRelevant);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isReadonly = PR_FALSE;
@@ -303,18 +311,17 @@ nsXFormsEditableAccessible::
 
 NS_IMETHODIMP
 nsXFormsEditableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!aExtraState)
+  if (!mDOMNode || !aExtraState)
     return NS_OK;
 
   PRBool isReadonly = PR_FALSE;
   rv = sXFormsService->IsReadonly(mDOMNode, &isReadonly);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!isReadonly) {
     PRBool isRelevant = PR_FALSE;
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -206,16 +206,18 @@ nsXFormsInputBooleanAccessible::GetRole(
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsInputBooleanAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   nsAutoString value;
   rv = sXFormsService->GetValue(mDOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (value.EqualsLiteral("true"))
     *aState |= nsIAccessibleStates::STATE_CHECKED;
 
@@ -292,16 +294,18 @@ nsXFormsSecretAccessible::GetRole(PRUint
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsSecretAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsInputAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_PROTECTED;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsSecretAccessible::GetValue(nsAString& aValue)
 {
@@ -326,16 +330,18 @@ nsXFormsRangeAccessible::GetRole(PRUint3
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsRangeAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRUint32 isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
   rv = sXFormsService->IsInRange(mDOMNode, &isInRange);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
     *aState |= nsIAccessibleStates::STATE_INVALID;
 
@@ -407,16 +413,18 @@ nsXFormsSelectAccessible::
 {
 }
 
 NS_IMETHODIMP
 nsXFormsSelectAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsContainerAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRUint32 isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
   rv = sXFormsService->IsInRange(mDOMNode, &isInRange);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
     *aState |= nsIAccessibleStates::STATE_INVALID;
 
@@ -498,16 +506,18 @@ nsXFormsItemCheckgroupAccessible::GetRol
 }
 
 NS_IMETHODIMP
 nsXFormsItemCheckgroupAccessible::GetState(PRUint32 *aState,
                                            PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_CHECKED;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -543,16 +553,18 @@ nsXFormsItemRadiogroupAccessible::GetRol
 }
 
 NS_IMETHODIMP
 nsXFormsItemRadiogroupAccessible::GetState(PRUint32 *aState,
                                            PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_CHECKED;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -584,16 +596,18 @@ nsXFormsSelectComboboxAccessible::GetRol
 }
 
 NS_IMETHODIMP
 nsXFormsSelectComboboxAccessible::GetState(PRUint32 *aState,
                                            PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsSelectableAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRBool isOpen = PR_FALSE;
   rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOpen)
     *aState = nsIAccessibleStates::STATE_EXPANDED;
   else
@@ -632,18 +646,17 @@ nsXFormsItemComboboxAccessible::GetRole(
 }
 
 NS_IMETHODIMP
 nsXFormsItemComboboxAccessible::GetState(PRUint32 *aState,
                                          PRUint32 *aExtraState)
 {
   nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  if (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)
+  if (!mDOMNode || (*aState & nsIAccessibleStates::STATE_UNAVAILABLE))
     return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_SELECTABLE;
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_SELECTED;
 
   return NS_OK;
 }
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -55,18 +55,24 @@ nsXFormsDropmarkerWidgetAccessible::GetR
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsDropmarkerWidgetAccessible::GetState(PRUint32 *aState,
                                              PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
+  *aState = 0;
+  if (!mDOMNode) {
+    if (aExtraState) {
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    }
+    return NS_OK;
+  }
 
-  *aState = 0;
   if (aExtraState)
     *aExtraState = 0;
 
   PRBool isOpen = PR_FALSE;
   nsresult rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOpen)
@@ -151,16 +157,18 @@ nsXFormsComboboxPopupWidgetAccessible::G
 NS_IMETHODIMP
 nsXFormsComboboxPopupWidgetAccessible::GetState(PRUint32 *aState,
                                                 PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRBool isOpen = PR_FALSE;
   rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   if (isOpen)
--- a/accessible/src/xul/nsXULAlertAccessible.cpp
+++ b/accessible/src/xul/nsXULAlertAccessible.cpp
@@ -53,14 +53,14 @@ NS_IMETHODIMP nsXULAlertAccessible::GetR
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULAlertAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
-  *aState |= nsIAccessibleStates::STATE_ALERT_MEDIUM; // XUL has no markup for low, medium or high
+  if (mDOMNode) {
+    *aState |= nsIAccessibleStates::STATE_ALERT_MEDIUM; // XUL has no markup for low, medium or high
+  }
   return NS_OK;
 }
 
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -66,16 +66,18 @@ NS_IMETHODIMP nsXULColorPickerTileAccess
   * Possible states: focused, focusable, selected
   */
 NS_IMETHODIMP
 nsXULColorPickerTileAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
   nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   // Focused?
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   NS_ASSERTION(element, "No XUL Element for colorpicker");
   PRBool isFocused = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("hover"), &isFocused);
@@ -121,16 +123,18 @@ nsXULColorPickerTileAccessible(aNode, aS
   * Possible states: focused, focusable, unavailable(disabled)
   */
 NS_IMETHODIMP
 nsXULColorPickerAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
   nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE |
              nsIAccessibleStates::STATE_HASPOPUP;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULColorPickerAccessible::GetRole(PRUint32 *_retval)
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -115,16 +115,18 @@ NS_IMETHODIMP nsXULButtonAccessible::Get
   * Possible states: focused, focusable, unavailable(disabled)
   */
 NS_IMETHODIMP
 nsXULButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   PRBool disabled = PR_FALSE;
   nsCOMPtr<nsIDOMXULControlElement> xulFormElement(do_QueryInterface(mDOMNode));
   if (xulFormElement) {
     xulFormElement->GetDisabled(&disabled);
     if (disabled)
       *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
     else 
@@ -288,16 +290,22 @@ NS_IMETHODIMP nsXULDropmarkerAccessible:
   *aResult = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULDropmarkerAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   *aState = 0;
+  if (!mDOMNode) {
+    if (aExtraState) {
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    }
+    return NS_OK;
+  }
   if (aExtraState)
     *aExtraState = 0;
 
   if (DropmarkerOpen(PR_FALSE))
     *aState = nsIAccessibleStates::STATE_PRESSED;
 
   return NS_OK;
 }
@@ -367,16 +375,18 @@ NS_IMETHODIMP nsXULCheckboxAccessible::D
   * Possible states: focused, focusable, unavailable(disabled), checked
   */
 NS_IMETHODIMP
 nsXULCheckboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus and disable status from base class
   nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
   
   *aState |= nsIAccessibleStates::STATE_CHECKABLE;
   
   // Determine Checked state
   nsCOMPtr<nsIDOMXULCheckboxElement> xulCheckboxElement(do_QueryInterface(mDOMNode));
   if (xulCheckboxElement) {
     PRBool checked = PR_FALSE;
     xulCheckboxElement->GetChecked(&checked);
@@ -468,26 +478,16 @@ nsFormControlAccessible(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULProgressMeterAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PROGRESSBAR;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsXULProgressMeterAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  nsresult rv = nsAccessible::GetState(aState, aExtraState);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE; // Progress meters are not focusable
-  return NS_OK;
-}
-
 NS_IMETHODIMP nsXULProgressMeterAccessible::GetValue(nsAString& aValue)
 {
   aValue.Truncate();
   nsAccessible::GetValue(aValue);
   if (!aValue.IsEmpty()) {
     return NS_OK;
   }
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
@@ -552,16 +552,18 @@ nsRadioButtonAccessible(aNode, aShell)
 }
 
 /** We are Focusable and can be Checked and focused */
 NS_IMETHODIMP
 nsXULRadioButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode)
+    return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_CHECKABLE;
   
   PRBool selected = PR_FALSE;   // Radio buttons can be selected
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton(do_QueryInterface(mDOMNode));
   if (radioButton) {
     radioButton->GetSelected(&selected);
@@ -611,19 +613,20 @@ NS_IMETHODIMP nsXULRadioGroupAccessible:
 NS_IMETHODIMP
 nsXULRadioGroupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The radio group is not focusable.
   // Sometimes the focus controller will report that it is focused.
   // That means that the actual selected radio button should be considered focused
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
-               nsIAccessibleStates::STATE_FOCUSED);
+  if (mDOMNode) {
+    *aState &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
+                 nsIAccessibleStates::STATE_FOCUSED);
+  }
 
   return NS_OK;
 }
 /**
   * XUL StatusBar: can contain arbitrary HTML content
   */
 
 /**
@@ -714,26 +717,16 @@ nsAccessibleWrap(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULToolbarAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_TOOLBAR;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsXULToolbarAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  nsresult rv = nsAccessible::GetState(aState, aExtraState);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;  // toolbar is not focusable
-  return NS_OK;
-}
-
 /**
   * XUL Toolbar Separator
   */
 
 nsXULToolbarSeparatorAccessible::nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsLeafAccessible(aNode, aShell)
 { 
 }
@@ -744,19 +737,19 @@ NS_IMETHODIMP nsXULToolbarSeparatorAcces
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULToolbarSeparatorAccessible::GetState(PRUint32 *aState,
                                           PRUint32 *aExtraState)
 {
   *aState = 0;  // no special state flags for toolbar separator
-  if (aExtraState)
-    *aExtraState = 0;
-
+  if (aExtraState) {
+    *aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT;
+  }
   return NS_OK;
 }
 
 /**
   * XUL Textfield
   */
 
 nsXULTextFieldAccessible::nsXULTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -99,17 +99,16 @@ public:
 class nsXULProgressMeterAccessible : public nsFormControlAccessible
 {
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLEVALUE
 
 public:
   nsXULProgressMeterAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString &aValue);
 };
 
 class nsXULRadioButtonAccessible : public nsRadioButtonAccessible
 {
 
 public:
   nsXULRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
@@ -140,17 +139,16 @@ public:
   static PRBool IsSeparator(nsIAccessible *aAccessible);
 };
 
 class nsXULToolbarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsXULToolbarSeparatorAccessible : public nsLeafAccessible
 {
 public:
   nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -270,16 +270,19 @@ NS_IMETHODIMP nsXULMenuitemAccessible::I
   return rv;
 }
 
 NS_IMETHODIMP
 nsXULMenuitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
   // Focused?
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   if (!element)
     return NS_ERROR_FAILURE;
   PRBool isFocused = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("_moz-menuactive"), &isFocused); 
   if (isFocused)
@@ -544,16 +547,19 @@ nsXULMenuitemAccessible(aDOMNode, aShell
 }
 
 NS_IMETHODIMP
 nsXULMenuSeparatorAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Isn't focusable, but can be offscreen/invisible -- only copy those states
   nsresult rv = nsXULMenuitemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
   *aState &= (nsIAccessibleStates::STATE_OFFSCREEN | 
               nsIAccessibleStates::STATE_INVISIBLE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetName(nsAString& _retval)
@@ -593,16 +599,19 @@ nsXULMenupopupAccessible::nsXULMenupopup
   mSelectControl = do_QueryInterface(parentNode);
 }
 
 NS_IMETHODIMP
 nsXULMenupopupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
 #ifdef DEBUG_A11Y
   // We are onscreen if our parent is active
   PRBool isActive = PR_FALSE;
 
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   element->HasAttribute(NS_LITERAL_STRING("menuactive"), &isActive);
   if (!isActive) {
@@ -707,16 +716,19 @@ nsXULMenubarAccessible::nsXULMenubarAcce
 { 
 }
 
 NS_IMETHODIMP
 nsXULMenubarAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
   // Menu bar iteself is not actually focusable
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return rv;
 }
 
 
 NS_IMETHODIMP nsXULMenubarAccessible::GetName(nsAString& _retval)
--- a/accessible/src/xul/nsXULSelectAccessible.cpp
+++ b/accessible/src/xul/nsXULSelectAccessible.cpp
@@ -65,21 +65,20 @@ nsXULColumnsAccessible::GetRole(PRUint32
   *aRole = nsIAccessibleRole::ROLE_LIST;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULColumnsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
-
-  if (aExtraState)
-    *aExtraState = 0;
-
   *aState = nsIAccessibleStates::STATE_READONLY;
+  if (aExtraState) {
+    *aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT ;
+  }
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColumnItemAccessible
 
 nsXULColumnItemAccessible::
   nsXULColumnItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
@@ -95,21 +94,20 @@ nsXULColumnItemAccessible::GetRole(PRUin
   *aRole = nsIAccessibleRole::ROLE_COLUMNHEADER;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULColumnItemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
-
-  if (aExtraState)
-    *aExtraState = 0;
-
   *aState = nsIAccessibleStates::STATE_READONLY;
+  if (aExtraState) {
+    *aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT ;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULColumnItemAccessible::GetName(nsAString& aName)
 {
   return GetXULName(aName);
 }
@@ -158,16 +156,19 @@ nsXULSelectableAccessible(aDOMNode, aShe
   *     nsIAccessibleStates::STATE_FOCUSABLE
   */
 NS_IMETHODIMP
 nsXULListboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
 // see if we are multiple select if so set ourselves as such
   nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mDOMNode));
   if (element) {
     nsAutoString selType;
     element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
     if (!selType.IsEmpty() && selType.EqualsLiteral("multiple"))
       *aState |= nsIAccessibleStates::STATE_MULTISELECTABLE |
@@ -256,19 +257,28 @@ NS_IMETHODIMP nsXULListitemAccessible::G
 
 /**
   *
   */
 NS_IMETHODIMP
 nsXULListitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   if (mIsCheckbox) {
-    nsXULMenuitemAccessible::GetState(aState, aExtraState);
+    return nsXULMenuitemAccessible::GetState(aState, aExtraState);
+  }
+
+  *aState = 0;
+  if (!mDOMNode) {
+    if (aExtraState) {
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    }
     return NS_OK;
   }
+  if (aExtraState)
+    *aExtraState = 0;
 
   *aState = nsIAccessibleStates::STATE_FOCUSABLE |
             nsIAccessibleStates::STATE_SELECTABLE;
   nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem (do_QueryInterface(mDOMNode));
   if (listItem) {
     PRBool isSelected;
     listItem->GetSelected(&isSelected);
     if (isSelected)
@@ -352,16 +362,19 @@ NS_IMETHODIMP nsXULComboboxAccessible::G
   *     STATE_COLLAPSED
   */
 NS_IMETHODIMP
 nsXULComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
   if (menuList) {
     PRBool isOpen;
     menuList->GetOpen(&isOpen);
     if (isOpen) {
       *aState |= nsIAccessibleStates::STATE_EXPANDED;
     }
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -96,16 +96,19 @@ NS_IMETHODIMP nsXULTabAccessible::GetRol
 /**
   * Possible states: focused, focusable, unavailable(disabled), offscreen
   */
 NS_IMETHODIMP
 nsXULTabAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
   nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
+  if (!mDOMNode) {
+    return NS_OK;
+  }
   NS_ENSURE_SUCCESS(rv, rv);
 
   // In the past, tabs have been focusable in classic theme
   // They may be again in the future
   // Check style for -moz-user-focus: normal to see if it's focusable
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
@@ -249,27 +252,16 @@ nsAccessibleWrap(aNode, aShell)
 
 /** We are a window*/
 NS_IMETHODIMP nsXULTabBoxAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PANE;
   return NS_OK;
 }
 
-/** Possible states: normal */
-NS_IMETHODIMP
-nsXULTabBoxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  nsresult rv = nsAccessible::GetState(aState, aExtraState);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
-  return NS_OK;
-}
-
 #ifdef NEVER
 /** 2 children, tabs, tabpanels */
 NS_IMETHODIMP nsXULTabBoxAccessible::GetChildCount(PRInt32 *_retval)
 {
   *_retval = 2;
   return NS_OK;
 }
 #endif
@@ -293,23 +285,16 @@ NS_IMETHODIMP nsXULTabsAccessible::GetRo
 
 /** no actions */
 NS_IMETHODIMP nsXULTabsAccessible::GetNumActions(PRUint8 *_retval)
 {
   *_retval = 0;
   return NS_OK;
 }
 
-/** no state -- normal */
-NS_IMETHODIMP
-nsXULTabsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
-{
-  return nsAccessible::GetState(aState, aExtraState);
-}
-
 /** no value */
 NS_IMETHODIMP nsXULTabsAccessible::GetValue(nsAString& _retval)
 {
   return NS_OK;
 }
 
 /** no name*/
 NS_IMETHODIMP nsXULTabsAccessible::GetName(nsAString& _retval)
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -71,30 +71,27 @@ public:
   *    entity with relationships between tabs and content to
   *    be displayed in the tabpanels object
   */
 class nsXULTabBoxAccessible : public nsAccessibleWrap
 {
 public:
   nsXULTabBoxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
-  //NS_IMETHOD GetChildCount(PRInt32 *_retval); // aaronl remove this?
 };
 
 /**
  * A container of tab obejcts, xul:tabs element.
  */
 class nsXULTabsAccessible : public nsXULSelectableAccessible
 {
 public:
   nsXULTabsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD GetName(nsAString& _retval);
 };
 
 /**
  * A tabpanel object, child elements of xul:tabpanels element. Note,the object
  * is created from nsAccessibilityService::GetAccessibleForDeckChildren()
  * method and we do not use nsIAccessibleProvider interface here because
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -172,17 +172,19 @@ void nsXULTreeAccessible::GetTreeBoxObje
 }
 
 NS_IMETHODIMP
 nsXULTreeAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
-
+  if (!mDOMNode)
+    return NS_OK;
+  
   // see if we are multiple select if so set ourselves as such
   nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mDOMNode));
   if (element) {
     // the default selection type is multiple
     nsAutoString selType;
     element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
     if (selType.IsEmpty() || !selType.EqualsLiteral("single"))
       *aState |= nsIAccessibleStates::STATE_MULTISELECTABLE;
@@ -596,19 +598,19 @@ NS_IMETHODIMP nsXULTreeitemAccessible::S
 }
 
 NS_IMETHODIMP nsXULTreeitemAccessible::GetName(nsAString& aName)
 {
   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
   mTreeView->GetCellText(mRow, mColumn, aName);
   
   // If there is still no name try the cell value:
-  // This is for graphical cells. We need tree/table view implementors to implement
-  // FooView::GetCellValue to return a meaningful string for cases where there is
-  // something shown in the cell (non-text) such as a star icon; in which case
+  // This is for graphical cells. We need tree/table view implementors to implement
+  // FooView::GetCellValue to return a meaningful string for cases where there is
+  // something shown in the cell (non-text) such as a star icon; in which case
   // GetCellValue for that cell would return "starred" or "flagged" for example.
   if (aName.IsEmpty()) {
     mTreeView->GetCellValue(mRow, mColumn, aName);
   }
   
   return NS_OK;
 }