Bug 741408 - figure out a way to deal with accessibles with no content, r=tbsaunde
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 13 Oct 2012 15:34:21 +0900
changeset 118080 4ee4e3aa9ea6d133e9e29af1668ce21a5f98876c
parent 118079 97a10c2ac350a9981d88634fb53aab7845f98d36
child 118081 b8970531e93ee8b034c6e55650145ff43424f6e5
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs741408
milestone19.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 741408 - figure out a way to deal with accessibles with no content, r=tbsaunde
accessible/src/atk/RootAccessibleWrap.cpp
accessible/src/atk/RootAccessibleWrap.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsCoreUtils.cpp
accessible/src/generic/Accessible.cpp
accessible/src/generic/Accessible.h
accessible/src/generic/ApplicationAccessible.cpp
accessible/src/generic/ApplicationAccessible.h
accessible/src/generic/BaseAccessibles.cpp
accessible/src/generic/BaseAccessibles.h
accessible/src/generic/DocAccessible.cpp
accessible/src/html/HTMLImageMapAccessible.cpp
accessible/src/msaa/HTMLWin32ObjectAccessible.cpp
accessible/src/msaa/HTMLWin32ObjectAccessible.h
accessible/src/msaa/Makefile.in
accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
--- a/accessible/src/atk/RootAccessibleWrap.cpp
+++ b/accessible/src/atk/RootAccessibleWrap.cpp
@@ -5,24 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RootAccessibleWrap.h"
 
 #include "nsMai.h"
 
 using namespace mozilla::a11y;
 
-NativeRootAccessibleWrap::NativeRootAccessibleWrap(AtkObject* aAccessible):
-  RootAccessible(nullptr, nullptr, nullptr)
+GtkWindowAccessible::GtkWindowAccessible(AtkObject* aAccessible) :
+  DummyAccessible()
 {
-  // XXX: mark the object as defunct to ensure no single internal method is
-  // running on it.
-  mFlags |= eIsDefunct;
-
   g_object_ref(aAccessible);
   mAtkObject = aAccessible;
 }
 
-NativeRootAccessibleWrap::~NativeRootAccessibleWrap()
+GtkWindowAccessible::~GtkWindowAccessible()
 {
   g_object_unref(mAtkObject);
   mAtkObject = nullptr;
 }
--- a/accessible/src/atk/RootAccessibleWrap.h
+++ b/accessible/src/atk/RootAccessibleWrap.h
@@ -2,32 +2,33 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_RootAccessibleWrap_h__
 #define mozilla_a11y_RootAccessibleWrap_h__
 
+#include "BaseAccessibles.h"
 #include "RootAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
 typedef RootAccessible RootAccessibleWrap;
 
-/* NativeRootAccessibleWrap is the accessible class for gtk+ native window.
- * The instance of NativeRootAccessibleWrap is a child of MaiAppRoot instance.
+/* GtkWindowAccessible is the accessible class for gtk+ native window.
+ * The instance of GtkWindowAccessible is a child of MaiAppRoot instance.
  * It is added into root when the toplevel window is created, and removed
  * from root when the toplevel window is destroyed.
  */
-class NativeRootAccessibleWrap : public RootAccessible
+class GtkWindowAccessible MOZ_FINAL : public DummyAccessible
 {
 public:
-  NativeRootAccessibleWrap(AtkObject* aAccessible);
-  virtual ~NativeRootAccessibleWrap();
+  GtkWindowAccessible(AtkObject* aAccessible);
+  virtual ~GtkWindowAccessible();
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif   /* mozilla_a11y_Root_Accessible_Wrap_h__ */
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -4,19 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAccessibilityService.h"
 
 // NOTE: alphabetically ordered
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "ARIAGridAccessibleWrap.h"
-#ifdef MOZ_ACCESSIBILITY_ATK
-#include "AtkSocketAccessible.h"
-#endif
 #include "DocAccessible-inl.h"
 #include "FocusManager.h"
 #include "HTMLCanvasAccessible.h"
 #include "HTMLElementAccessibles.h"
 #include "HTMLImageMapAccessible.h"
 #include "HTMLLinkAccessible.h"
 #include "HTMLListAccessible.h"
 #include "HTMLSelectAccessible.h"
@@ -29,20 +26,25 @@
 #include "nsIAccessibleProvider.h"
 #include "nsXFormsFormControlsAccessible.h"
 #include "nsXFormsWidgetsAccessible.h"
 #include "OuterDocAccessible.h"
 #include "Role.h"
 #include "RootAccessibleWrap.h"
 #include "States.h"
 #include "Statistics.h"
+#include "TextLeafAccessibleWrap.h"
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AtkSocketAccessible.h"
+#endif
+
 #ifdef XP_WIN
-#include "nsHTMLWin32ObjectAccessible.h"
+#include "HTMLWin32ObjectAccessible.h"
 #endif
-#include "TextLeafAccessibleWrap.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
@@ -328,19 +330,18 @@ nsAccessibilityService::CreateHTMLObject
   if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
       pluginInstance) {
 #ifdef XP_WIN
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nullptr;
     aFrame->GetPluginPort(&pluginPort);
 
     Accessible* accessible =
-      new nsHTMLWin32ObjectOwnerAccessible(aContent,
-                                           GetDocAccessible(aPresShell),
-                                           pluginPort);
+      new HTMLWin32ObjectOwnerAccessible(aContent, GetDocAccessible(aPresShell),
+                                         pluginPort);
     NS_ADDREF(accessible);
     return accessible;
 
 #elif MOZ_ACCESSIBILITY_ATK
     if (!AtkSocketAccessible::gCanEmbed)
       return nullptr;
 
     nsCString plugId;
@@ -1664,23 +1665,21 @@ nsAccessibilityService::CreateHTMLAccess
 Accessible*
 nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
   ApplicationAccessible* applicationAcc = ApplicationAcc();
   if (!applicationAcc)
     return nullptr;
 
-  nsRefPtr<NativeRootAccessibleWrap> nativeRootAcc =
-    new NativeRootAccessibleWrap(static_cast<AtkObject*>(aAtkAccessible));
-  if (!nativeRootAcc)
-    return nullptr;
+  GtkWindowAccessible* nativeWnd =
+    new GtkWindowAccessible(static_cast<AtkObject*>(aAtkAccessible));
 
-  if (applicationAcc->AppendChild(nativeRootAcc))
-    return nativeRootAcc;
+  if (applicationAcc->AppendChild(nativeWnd))
+    return nativeWnd;
 #endif
 
   return nullptr;
 }
 
 void
 nsAccessibilityService::RemoveNativeRootAccessible(Accessible* aAccessible)
 {
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -159,21 +159,18 @@ nsCoreUtils::DispatchMouseEvent(uint32_t
   event.button = nsMouseEvent::eLeftButton;
   event.time = PR_IntervalNow();
 
   nsEventStatus status = nsEventStatus_eIgnore;
   aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
 }
 
 uint32_t
-nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
+nsCoreUtils::GetAccessKeyFor(nsIContent* aContent)
 {
-  if (!aContent)
-    return 0;
-
   // Accesskeys are registered by @accesskey attribute only. At first check
   // whether it is presented on the given element to avoid the slow
   // nsEventStateManager::GetRegisteredAccessKey() method.
   if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
     return 0;
 
   nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
   if (!presShell)
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -254,17 +254,20 @@ Accessible::GetName(nsAString& aName)
   return NS_OK;
 }
 
 ENameValueFlag
 Accessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  GetARIAName(aName);
+  if (!HasOwnContent())
+    return eNameOK;
+
+  ARIAName(aName);
   if (!aName.IsEmpty())
     return eNameOK;
 
   nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mContent));
   if (xblAccessible) {
     xblAccessible->GetAccessibleName(aName);
     if (!aName.IsEmpty())
       return eNameOK;
@@ -312,17 +315,17 @@ void
 Accessible::Description(nsString& aDescription)
 {
   // There are 4 conditions that make an accessible have no accDescription:
   // 1. it's a text node; or
   // 2. It has no DHTML describedby property
   // 3. it doesn't have an accName; or
   // 4. its title attribute already equals to its accName nsAutoString name; 
 
-  if (mContent->IsNodeOfType(nsINode::eTEXT))
+  if (!HasOwnContent() || mContent->IsNodeOfType(nsINode::eTEXT))
     return;
 
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
 
   if (aDescription.IsEmpty()) {
     bool isXUL = mContent->IsXUL();
@@ -361,16 +364,19 @@ Accessible::GetAccessKey(nsAString& aAcc
 
   AccessKey().ToString(aAccessKey);
   return NS_OK;
 }
 
 KeyBinding
 Accessible::AccessKey() const
 {
+  if (!HasOwnContent())
+    return KeyBinding();
+
   uint32_t key = nsCoreUtils::GetAccessKeyFor(mContent);
   if (!key && mContent->IsElement()) {
     Accessible* label = nullptr;
 
     // Copy access key from label node.
     if (mContent->IsHTML()) {
       // Unless it is labeled via an ancestor <label>, in which case that would
       // be redundant.
@@ -673,17 +679,17 @@ Accessible::VisibilityState()
 uint64_t
 Accessible::NativeState()
 {
   uint64_t state = 0;
 
   if (!IsInDocument())
     state |= states::STALE;
 
-  if (mContent->IsElement()) {
+  if (HasOwnContent() && mContent->IsElement()) {
     nsEventStates elementState = mContent->AsElement()->State();
 
     if (elementState.HasState(NS_EVENT_STATE_INVALID))
       state |= states::INVALID;
 
     if (elementState.HasState(NS_EVENT_STATE_REQUIRED))
       state |= states::REQUIRED;
 
@@ -697,32 +703,32 @@ Accessible::NativeState()
 
   nsIFrame *frame = GetFrame();
   if (frame) {
     if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
       state |= states::FLOATING;
 
     // XXX we should look at layout for non XUL box frames, but need to decide
     // how that interacts with ARIA.
-    if (mContent->IsXUL() && frame->IsBoxFrame()) {
+    if (HasOwnContent() && mContent->IsXUL() && frame->IsBoxFrame()) {
       const nsStyleXUL* xulStyle = frame->GetStyleXUL();
       if (xulStyle && frame->IsBoxFrame()) {
         // In XUL all boxes are either vertical or horizontal
         if (xulStyle->mBoxOrient == NS_STYLE_BOX_ORIENT_VERTICAL)
           state |= states::VERTICAL;
         else
           state |= states::HORIZONTAL;
       }
     }
   }
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
-      if (mContent->IsXUL() && mContent->HasAttr(kNameSpaceID_None,
-                                                 nsGkAtoms::popup))
-        state |= states::HASPOPUP;
+  if (HasOwnContent() && mContent->IsXUL() &&
+      mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
+    state |= states::HASPOPUP;
 
   // Bypass the link states specialization for non links.
   if (!mRoleMapEntry || mRoleMapEntry->roleRule == kUseNativeRole ||
       mRoleMapEntry->role == roles::LINK)
     state |= NativeLinkState();
 
   return state;
 }
@@ -938,30 +944,28 @@ Accessible::GetBounds(int32_t* aX, int32
   NS_ENSURE_ARG_POINTER(aWidth);
   *aWidth = 0;
   NS_ENSURE_ARG_POINTER(aHeight);
   *aHeight = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsIPresShell* presShell = mDoc->PresShell();
-
   // This routine will get the entire rectangle for all the frames in this node.
   // -------------------------------------------------------------------------
   //      Primary Frame for node
   //  Another frame, same node                <- Example
   //  Another frame, same node
 
   nsRect unionRectTwips;
   nsIFrame* boundingFrame = nullptr;
   GetBoundsRect(unionRectTwips, &boundingFrame);   // Unions up all primary frames for this node and all siblings after it
   NS_ENSURE_STATE(boundingFrame);
 
-  nsPresContext* presContext = presShell->GetPresContext();
+  nsPresContext* presContext = mDoc->PresContext();
   *aX = presContext->AppUnitsToDevPixels(unionRectTwips.x);
   *aY = presContext->AppUnitsToDevPixels(unionRectTwips.y);
   *aWidth = presContext->AppUnitsToDevPixels(unionRectTwips.width);
   *aHeight = presContext->AppUnitsToDevPixels(unionRectTwips.height);
 
   // We have the union of the rectangle, now we need to put it in absolute screen coords
   nsIntRect orgRectPixels = boundingFrame->GetScreenRectInAppUnits().
     ToNearestPixels(presContext->AppUnitsPerDevPixel());
@@ -972,16 +976,19 @@ Accessible::GetBounds(int32_t* aX, int32
 }
 
 NS_IMETHODIMP
 Accessible::SetSelected(bool aSelect)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
+  if (!HasOwnContent())
+    return NS_OK;
+
   Accessible* select = nsAccUtils::GetSelectableContainer(this, State());
   if (select) {
     if (select->State() & states::MULTISELECTABLE) {
       if (mRoleMapEntry) {
         if (aSelect) {
           return mContent->SetAttr(kNameSpaceID_None,
                                    nsGkAtoms::aria_selected,
                                    NS_LITERAL_STRING("true"), true);
@@ -1219,18 +1226,17 @@ Accessible::GetAttributes(nsIPersistentP
     attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
   }
   
   nsAutoString xmlRoles;
   if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::role, xmlRoles)) {
     attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),  xmlRoles, oldValueUnused);          
   }
 
-  nsCOMPtr<nsIAccessibleValue> supportsValue = do_QueryInterface(static_cast<nsIAccessible*>(this));
-  if (supportsValue) {
+  if (HasNumericValue()) {
     // We support values, so expose the string value as well, via the valuetext object attribute
     // We test for the value interface because we don't want to expose traditional get_accValue()
     // information such as URL's on links and documents, or text in an input
     nsAutoString valuetext;
     GetValue(valuetext);
     attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext, oldValueUnused);
   }
 
@@ -1265,17 +1271,17 @@ Accessible::GetAttributes(nsIPersistentP
   return NS_OK;
 }
 
 nsresult
 Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   // If the accessible isn't primary for its node (such as list item bullet or
   // xul tree item then don't calculate content based attributes.
-  if (!IsPrimaryForNode())
+  if (!HasOwnContent())
     return NS_OK;
 
   // Attributes set by this method will not be used to override attributes on a sub-document accessible
   // when there is a <frame>/<iframe> element that spawned the sub-document
 
   nsEventShell::GetEventAttributes(GetNode(), aAttributes);
  
   // Expose class because it may have useful microformat information
@@ -2425,18 +2431,19 @@ Accessible::Shutdown()
     mParent->RemoveChild(this);
 
   nsAccessNodeWrap::Shutdown();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible public methods
 
-nsresult
-Accessible::GetARIAName(nsAString& aName)
+// Accessible protected
+void
+Accessible::ARIAName(nsAString& aName)
 {
   nsAutoString label;
 
   // aria-labelledby now takes precedence over aria-label
   nsresult rv = nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, label);
   if (NS_SUCCEEDED(rv)) {
     label.CompressWhitespace();
@@ -2444,18 +2451,16 @@ Accessible::GetARIAName(nsAString& aName
   }
 
   if (label.IsEmpty() &&
       mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label,
                         label)) {
     label.CompressWhitespace();
     aName = label;
   }
-  
-  return NS_OK;
 }
 
 nsresult
 Accessible::GetNameInternal(nsAString& aName)
 {
   if (mContent->IsHTML())
     return GetHTMLName(aName);
 
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -142,21 +142,16 @@ public:
   {
     nsIDOMNode *DOMNode = nullptr;
     if (GetNode())
       CallQueryInterface(GetNode(), &DOMNode);
     return DOMNode;
   }
 
   /**
-   * Returns the accessible name specified by ARIA.
-   */
-  nsresult GetARIAName(nsAString& aName);
-
-  /**
    * Maps ARIA state attributes to state of accessible. Note the given state
    * argument should hold states for accessible before you pass it into this
    * method.
    *
    * @param  [in/out] where to fill the states into.
    */
   virtual void ApplyARIAState(uint64_t* aState) const;
 
@@ -688,23 +683,25 @@ public:
   bool IsDefunct() const { return mFlags & eIsDefunct; }
 
   /**
    * Return true if the accessible is no longer in the document.
    */
   bool IsInDocument() const { return !(mFlags & eIsNotInDocument); }
 
   /**
-  * Return true if the accessible is primary accessible for the given DOM node.
-  *
-  * Accessible hierarchy may be complex for single DOM node, in this case
-  * these accessibles share the same DOM node. The primary accessible "owns"
-  * that DOM node in terms it gets stored in the accessible to node map.
-  */
-  bool IsPrimaryForNode() const { return !(mFlags & eSharedNode); }
+   * Return true if the accessible should be contained by document node map.
+   */
+  bool IsNodeMapEntry() const
+    { return HasOwnContent() && !(mFlags & eNotNodeMapEntry); }
+
+  /**
+   * Return true if the accessible has associated DOM content.
+   */
+  bool HasOwnContent() const { return mContent && !(mFlags & eSharedNode); }
 
   /**
   * Return true if the accessible has a numeric value.
   */
   bool HasNumericValue() const;
 
 protected:
 
@@ -752,55 +749,61 @@ protected:
   /**
    * Flags used to describe the state of this accessible.
    * @note keep these flags in sync with ChildrenFlags
    */
   enum StateFlags {
     eIsDefunct = 1 << 2, // accessible is defunct
     eIsNotInDocument = 1 << 3, // accessible is not in document
     eSharedNode = 1 << 4, // accessible shares DOM node from another accessible
-    eHasNumericValue = 1 << 5 // accessible has a numeric value
+    eNotNodeMapEntry = 1 << 5, // accessible shouldn't be in document node map
+    eHasNumericValue = 1 << 6 // accessible has a numeric value
   };
 
   /**
    * Flags describing the type of this accessible.
    * @note keep these flags in sync with ChildrenFlags and StateFlags
    */
   enum AccessibleTypes {
-    eApplicationAccessible = 1 << 6,
-    eAutoCompleteAccessible = 1 << 7,
-    eAutoCompletePopupAccessible = 1 << 8,
-    eComboboxAccessible = 1 << 9,
-    eDocAccessible = 1 << 10,
-    eHyperTextAccessible = 1 << 11,
-    eHTMLFileInputAccessible = 1 << 12,
-    eHTMLListItemAccessible = 1 << 13,
-    eImageAccessible = 1 << 14,
-    eImageMapAccessible = 1 << 15,
-    eListControlAccessible = 1 << 16,
-    eMenuButtonAccessible = 1 << 17,
-    eMenuPopupAccessible = 1 << 18,
-    eRootAccessible = 1 << 19,
-    eTextLeafAccessible = 1 << 20,
-    eXULDeckAccessible = 1 << 21,
-    eXULTreeAccessible = 1 << 22
+    eApplicationAccessible = 1 << 7,
+    eAutoCompleteAccessible = 1 << 8,
+    eAutoCompletePopupAccessible = 1 << 9,
+    eComboboxAccessible = 1 << 10,
+    eDocAccessible = 1 << 11,
+    eHyperTextAccessible = 1 << 12,
+    eHTMLFileInputAccessible = 1 << 13,
+    eHTMLListItemAccessible = 1 << 14,
+    eImageAccessible = 1 << 15,
+    eImageMapAccessible = 1 << 16,
+    eListControlAccessible = 1 << 17,
+    eMenuButtonAccessible = 1 << 18,
+    eMenuPopupAccessible = 1 << 19,
+    eRootAccessible = 1 << 20,
+    eTextLeafAccessible = 1 << 21,
+    eXULDeckAccessible = 1 << 22,
+    eXULTreeAccessible = 1 << 23
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
   mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole);
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
+   * Returns the accessible name specified by ARIA.
+   */
+  void ARIAName(nsAString& aName);
+
+  /**
    * Compute the name of HTML node.
    */
   nsresult GetHTMLName(nsAString& aName);
 
   /**
    * Compute the name for XUL node.
    */
   nsresult GetXULName(nsAString& aName);
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -21,17 +21,17 @@
 #include "mozilla/Services.h"
 #include "nsIStringBundle.h"
 
 using namespace mozilla::a11y;
 
 ApplicationAccessible::ApplicationAccessible() :
   AccessibleWrap(nullptr, nullptr)
 {
-  mFlags |= (eApplicationAccessible | eSharedNode);
+  mFlags |= eApplicationAccessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_ISUPPORTS_INHERITED1(ApplicationAccessible, Accessible,
                              nsIAccessibleApplication)
 
@@ -366,32 +366,16 @@ ApplicationAccessible::GetSiblingAtOffse
 
   return nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
 NS_IMETHODIMP
-ApplicationAccessible::GetDOMNode(nsIDOMNode** aDOMNode)
-{
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-  *aDOMNode = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ApplicationAccessible::GetDocument(nsIAccessibleDocument** aDocument)
-{
-  NS_ENSURE_ARG_POINTER(aDocument);
-  *aDocument = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 ApplicationAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
   *aRootDocument = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -23,28 +23,26 @@ namespace a11y {
  * And this one should be created when Mozilla Startup (if accessibility
  * feature has been enabled) and destroyed when Mozilla Shutdown.
  *
  * All the accessibility objects for toplevel windows are direct children of
  * the ApplicationAccessible instance.
  */
 
 class ApplicationAccessible : public AccessibleWrap,
-                             public nsIAccessibleApplication
+                              public nsIAccessibleApplication
 {
 public:
 
   ApplicationAccessible();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
-  NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
-  NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
   NS_IMETHOD ScrollTo(uint32_t aScrollType);
   NS_IMETHOD ScrollToPoint(uint32_t aCoordinateType, int32_t aX, int32_t aY);
   NS_IMETHOD GetLanguage(nsAString& aLanguage);
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
--- a/accessible/src/generic/BaseAccessibles.cpp
+++ b/accessible/src/generic/BaseAccessibles.cpp
@@ -232,8 +232,35 @@ EnumRoleAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED0(EnumRoleAccessible, Accessible)
 
 role
 EnumRoleAccessible::NativeRole()
 {
   return mRole;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// DummyAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+uint64_t
+DummyAccessible::NativeState()
+{
+  return 0;
+}
+uint64_t
+DummyAccessible::NativeInteractiveState() const
+{
+  return 0;
+}
+
+uint64_t
+DummyAccessible::NativeLinkState() const
+{
+  return 0;
+}
+
+bool
+DummyAccessible::NativelyUnavailable() const
+{
+  return false;
+}
--- a/accessible/src/generic/BaseAccessibles.h
+++ b/accessible/src/generic/BaseAccessibles.h
@@ -102,12 +102,29 @@ public:
 
   // Accessible
   virtual a11y::role NativeRole();
 
 protected:
   a11y::role mRole;
 };
 
+
+/**
+ * A wrapper accessible around native accessible to connect it with
+ * crossplatform accessible tree.
+ */
+class DummyAccessible : public AccessibleWrap
+{
+public:
+  DummyAccessible() : AccessibleWrap(nullptr, nullptr) { }
+  virtual ~DummyAccessible() { }
+
+  virtual uint64_t NativeState() MOZ_OVERRIDE MOZ_FINAL;
+  virtual uint64_t NativeInteractiveState() const MOZ_OVERRIDE MOZ_FINAL;
+  virtual uint64_t NativeLinkState() const MOZ_OVERRIDE MOZ_FINAL;
+  virtual bool NativelyUnavailable() const MOZ_OVERRIDE MOZ_FINAL;
+};
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -79,17 +79,17 @@ DocAccessible::
   DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                   nsIPresShell* aPresShell) :
   HyperTextAccessibleWrap(aRootContent, this),
   mDocument(aDocument), mScrollPositionChangedTicks(0),
   mLoadState(eTreeConstructionPending), mLoadEventType(0),
   mVirtualCursor(nullptr),
   mPresShell(aPresShell)
 {
-  mFlags |= eDocAccessible;
+  mFlags |= eDocAccessible | eNotNodeMapEntry;
   if (mPresShell)
     mPresShell->SetAccDocument(this);
 
   mDependentIDsHash.Init();
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessibleCache.Init(kDefaultCacheSize);
   mNodeToAccessibleMap.Init(kDefaultCacheSize);
 
@@ -266,20 +266,21 @@ DocAccessible::SetRoleMapEntry(nsRoleMap
 }
 
 void
 DocAccessible::Description(nsString& aDescription)
 {
   if (mParent)
     mParent->Description(aDescription);
 
-  if (aDescription.IsEmpty())
+  if (HasOwnContent() && aDescription.IsEmpty()) {
     nsTextEquivUtils::
       GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                              aDescription);
+  }
 }
 
 // Accessible public method
 uint64_t
 DocAccessible::NativeState()
 {
   // The root content of the document might be removed so that mContent is
   // out of date.
@@ -1385,17 +1386,17 @@ DocAccessible::GetAccessibleOrContainer(
 bool
 DocAccessible::BindToDocument(Accessible* aAccessible,
                               nsRoleMapEntry* aRoleMapEntry)
 {
   if (!aAccessible)
     return false;
 
   // Put into DOM node cache.
-  if (aAccessible->IsPrimaryForNode())
+  if (aAccessible->IsNodeMapEntry())
     mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible);
 
   // Put into unique ID cache.
   mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
   // Initialize the accessible.
   aAccessible->Init();
 
@@ -1418,17 +1419,17 @@ DocAccessible::UnbindFromDocument(Access
     FocusMgr()->ActiveItemChanged(nullptr);
 #ifdef A11Y_LOG
           if (logging::IsEnabled(logging::eFocus))
             logging::ActiveItemChangeCausedBy("tree shutdown", aAccessible);
 #endif
   }
 
   // Remove an accessible from node-to-accessible map if it exists there.
-  if (aAccessible->IsPrimaryForNode() &&
+  if (aAccessible->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
     mNodeToAccessibleMap.Remove(aAccessible->GetNode());
 
   void* uniqueID = aAccessible->UniqueID();
 
   NS_ASSERTION(!aAccessible->IsDefunct(), "Shutdown the shutdown accessible!");
   aAccessible->Shutdown();
 
@@ -2042,17 +2043,17 @@ DocAccessible::UncacheChildrenInSubtree(
 
   if (aRoot->IsElement())
     RemoveDependentIDsFor(aRoot);
 
   uint32_t count = aRoot->ContentChildCount();
   for (uint32_t idx = 0; idx < count; idx++)
     UncacheChildrenInSubtree(aRoot->ContentChildAt(idx));
 
-  if (aRoot->IsPrimaryForNode() &&
+  if (aRoot->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aRoot->GetNode()) == aRoot)
     mNodeToAccessibleMap.Remove(aRoot->GetNode());
 }
 
 void
 DocAccessible::ShutdownChildrenInSubtree(Accessible* aAccessible)
 {
   // Traverse through children and shutdown them before this accessible. When
--- a/accessible/src/html/HTMLImageMapAccessible.cpp
+++ b/accessible/src/html/HTMLImageMapAccessible.cpp
@@ -147,19 +147,19 @@ HTMLImageMapAccessible::CacheChildren()
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLAreaAccessible::
   HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HTMLLinkAccessible(aContent, aDoc)
 {
-  // Make HTML area DOM element not accessible. HTML image map accessible			
+  // Make HTML area DOM element not accessible. HTML image map accessible
   // manages its tree itself.
-  mFlags |= eSharedNode;
+  mFlags |= eNotNodeMapEntry;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible: nsIAccessible
 
 nsresult
 HTMLAreaAccessible::GetNameInternal(nsAString& aName)
 {
rename from accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
rename to accessible/src/msaa/HTMLWin32ObjectAccessible.cpp
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
+++ b/accessible/src/msaa/HTMLWin32ObjectAccessible.cpp
@@ -1,99 +1,93 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsHTMLWin32ObjectAccessible.h"
+#include "HTMLWin32ObjectAccessible.h"
 
 #include "Role.h"
 #include "States.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible
+// HTMLWin32ObjectOwnerAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLWin32ObjectOwnerAccessible::
-  nsHTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc, void* aHwnd) :
+HTMLWin32ObjectOwnerAccessible::
+  HTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
+                                 DocAccessible* aDoc, void* aHwnd) :
   AccessibleWrap(aContent, aDoc), mHwnd(aHwnd)
 {
-  // Our only child is a nsHTMLWin32ObjectAccessible object.
-  mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd);
+  // Our only child is a HTMLWin32ObjectAccessible object.
+  mNativeAccessible = new HTMLWin32ObjectAccessible(mHwnd);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: nsAccessNode implementation
+// HTMLWin32ObjectOwnerAccessible: nsAccessNode implementation
 
 void
-nsHTMLWin32ObjectOwnerAccessible::Shutdown()
+HTMLWin32ObjectOwnerAccessible::Shutdown()
 {
   AccessibleWrap::Shutdown();
   mNativeAccessible = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: Accessible implementation
+// HTMLWin32ObjectOwnerAccessible: Accessible implementation
 
 role
-nsHTMLWin32ObjectOwnerAccessible::NativeRole()
+HTMLWin32ObjectOwnerAccessible::NativeRole()
 {
   return roles::EMBEDDED_OBJECT;
 }
 
 bool
-nsHTMLWin32ObjectOwnerAccessible::NativelyUnavailable() const
+HTMLWin32ObjectOwnerAccessible::NativelyUnavailable() const
 {
   // XXX: No HWND means this is windowless plugin which is not accessible in
   // the meantime.
   return !mHwnd;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: Accessible protected implementation
+// HTMLWin32ObjectOwnerAccessible: Accessible protected implementation
 
 void
-nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
+HTMLWin32ObjectOwnerAccessible::CacheChildren()
 {
   if (mNativeAccessible)
     AppendChild(mNativeAccessible);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectAccessible
+// HTMLWin32ObjectAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd) :
-  LeafAccessible(nullptr, nullptr)
+HTMLWin32ObjectAccessible::HTMLWin32ObjectAccessible(void* aHwnd) :
+  DummyAccessible()
 {
-  // XXX: Mark it as defunct to make sure no single Accessible method is
-  // running on it. We need to allow accessible without DOM nodes.
-  mFlags |= eIsDefunct;
-
   mHwnd = aHwnd;
   if (mHwnd) {
     // The plugin is not windowless. In this situation we use 
     // use its inner child owned by the plugin so that we don't get
     // in an infinite loop, where the WM_GETOBJECT's get forwarded
-    // back to us and create another nsHTMLWin32ObjectAccessible
+    // back to us and create another HTMLWin32ObjectAccessible
     HWND childWnd = ::GetWindow((HWND)aHwnd, GW_CHILD);
     if (childWnd) {
       mHwnd = childWnd;
     }
   }
 }
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLWin32ObjectAccessible, Accessible)
-
 NS_IMETHODIMP 
-nsHTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
+HTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
 {
   if (mHwnd) {
     ::AccessibleObjectFromWindow(static_cast<HWND>(mHwnd),
                                  OBJID_WINDOW, IID_IAccessible,
                                  aNativeAccessible);
   }
   return NS_OK;
 }
rename from accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
rename to accessible/src/msaa/HTMLWin32ObjectAccessible.h
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
+++ b/accessible/src/msaa/HTMLWin32ObjectAccessible.h
@@ -1,32 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef _nsHTMLWin32ObjectAccessible_H_
-#define _nsHTMLWin32ObjectAccessible_H_
+#ifndef mozilla_a11y_HTMLWin32ObjectAccessible_h_
+#define mozilla_a11y_HTMLWin32ObjectAccessible_h_
 
 #include "BaseAccessibles.h"
 
 struct IAccessible;
 
-class nsHTMLWin32ObjectOwnerAccessible : public AccessibleWrap
+namespace mozilla {
+namespace a11y {
+
+class HTMLWin32ObjectOwnerAccessible : public AccessibleWrap
 {
 public:
-  // This will own the nsHTMLWin32ObjectAccessible. We create this where the
+  // This will own the HTMLWin32ObjectAccessible. We create this where the
   // <object> or <embed> exists in the tree, so that get_accNextSibling() etc.
   // will still point to Gecko accessible sibling content. This is necessary
   // because the native plugin accessible doesn't know where it exists in the
   // Mozilla tree, and returns null for previous and next sibling. This would
   // have the effect of cutting off all content after the plugin.
-  nsHTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
+  HTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
                                    DocAccessible* aDoc, void* aHwnd);
-  virtual ~nsHTMLWin32ObjectOwnerAccessible() {}
+  virtual ~HTMLWin32ObjectOwnerAccessible() {}
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
   virtual bool NativelyUnavailable() const;
 
@@ -43,24 +46,24 @@ protected:
   * This class is used only internally, we never! send out an IAccessible linked
   *   back to this object. This class is used to represent a plugin object when
   *   referenced as a child or sibling of another Accessible node. We need only
   *   a limited portion of the nsIAccessible interface implemented here. The
   *   in depth accessible information will be returned by the actual IAccessible
   *   object returned by us in Accessible::NewAccessible() that gets the IAccessible
   *   from the windows system from the window handle.
   */
-class nsHTMLWin32ObjectAccessible : public mozilla::a11y::LeafAccessible
+class HTMLWin32ObjectAccessible : public DummyAccessible
 {
 public:
-
-  nsHTMLWin32ObjectAccessible(void* aHwnd);
-  virtual ~nsHTMLWin32ObjectAccessible() {}
-
-  NS_DECL_ISUPPORTS_INHERITED
+  HTMLWin32ObjectAccessible(void* aHwnd);
+  virtual ~HTMLWin32ObjectAccessible() {}
 
   NS_IMETHOD GetNativeInterface(void** aNativeAccessible) MOZ_OVERRIDE;
 
 protected:
   void* mHwnd;
 };
 
-#endif  
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -16,20 +16,20 @@ LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccessibleWrap.cpp \
   ApplicationAccessibleWrap.cpp \
   ARIAGridAccessibleWrap.cpp \
   DocAccessibleWrap.cpp \
   HTMLTableAccessibleWrap.cpp \
+  HTMLWin32ObjectAccessible.cpp \
   HyperTextAccessibleWrap.cpp \
   ImageAccessibleWrap.cpp \
   nsAccessNodeWrap.cpp \
-  nsHTMLWin32ObjectAccessible.cpp \
   nsWinUtils.cpp \
   Compatibility.cpp \
   EnumVariant.cpp \
   RootAccessibleWrap.cpp \
   TextLeafAccessibleWrap.cpp \
   $(NULL)
 
 ifdef MOZ_XUL