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 dateMon, 20 Oct 2014 17:29:22 +0000
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;
 }