Bug 1251712 - propagate a context flag for alerts, r=davdib
authorAlexander Surkov <surkov.alexander@gmail.com>
Mon, 29 Feb 2016 10:08:40 -0500
changeset 322443 5ff87fac5346cecc9118046c39418feca73e4cce
parent 322442 e6977e56333235951c15448a0c7cb4aa044514c6
child 322444 f282f0355f9e5b5c6f806b02405412bd2ee11690
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavdib
bugs1251712
milestone47.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 1251712 - propagate a context flag for alerts, r=davdib
accessible/base/ARIAMap.cpp
accessible/base/AccTypes.h
accessible/generic/Accessible.cpp
accessible/generic/Accessible.h
accessible/generic/DocAccessible.cpp
accessible/xul/XULAlertAccessible.cpp
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -38,17 +38,17 @@ static nsRoleMapEntry sWAIRoleMaps[] =
 {
   { // alert
     &nsGkAtoms::alert,
     roles::ALERT,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
-    kGenericAccType,
+    eAlert,
     kNoReqStates
   },
   { // alertdialog
     &nsGkAtoms::alertdialog,
     roles::DIALOG,
     kUseMapRole,
     eNoValue,
     eNoAction,
--- a/accessible/base/AccTypes.h
+++ b/accessible/base/AccTypes.h
@@ -63,30 +63,31 @@ enum AccType {
   eLastAccType = eXULTreeType
 };
 
 /**
  * Generic accessible type, different accessible classes can share the same
  * type, the same accessible class can have several types.
  */
 enum AccGenericType {
-  eAutoComplete = 1 << 0,
-  eAutoCompletePopup = 1 << 1,
-  eButton = 1 << 2,
-  eCombobox = 1 << 3,
-  eDocument = 1 << 4,
-  eHyperText = 1 << 5,
-  eLandmark = 1 << 6,
-  eList = 1 << 7,
-  eListControl = 1 << 8,
-  eMenuButton = 1 << 9,
-  eSelect = 1 << 10,
-  eTable = 1 << 11,
-  eTableCell = 1 << 12,
-  eTableRow = 1 << 13,
+  eAlert = 1 << 0,
+  eAutoComplete = 1 << 1,
+  eAutoCompletePopup = 1 << 2,
+  eButton = 1 << 3,
+  eCombobox = 1 << 4,
+  eDocument = 1 << 5,
+  eHyperText = 1 << 6,
+  eLandmark = 1 << 7,
+  eList = 1 << 8,
+  eListControl = 1 << 9,
+  eMenuButton = 1 << 10,
+  eSelect = 1 << 11,
+  eTable = 1 << 12,
+  eTableCell = 1 << 13,
+  eTableRow = 1 << 14,
 
   eLastAccGenericType = eTableRow
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_AccTypes_h
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1977,16 +1977,20 @@ Accessible::BindToParent(Accessible* aPa
   // Note: this is currently only used for richlistitems and their children.
   if (mParent->HasNameDependentParent() || mParent->IsXULListItem())
     mContextFlags |= eHasNameDependentParent;
   else
     mContextFlags &= ~eHasNameDependentParent;
 
   if (mParent->IsARIAHidden() || aria::HasDefinedARIAHidden(mContent))
     SetARIAHidden(true);
+
+  mContextFlags |=
+    static_cast<uint32_t>((mParent->IsAlert() ||
+                           mParent->IsInsideAlert())) & eInsideAlert;
 }
 
 // Accessible protected
 void
 Accessible::UnbindFromParent()
 {
 #ifdef DEBUG
   AssertInMutatingSubtree();
@@ -1994,17 +1998,17 @@ Accessible::UnbindFromParent()
   mParent = nullptr;
   mIndexInParent = -1;
   mInt.mIndexOfEmbeddedChild = -1;
   if (IsProxy())
     MOZ_CRASH("this should never be called on proxy wrappers");
 
   delete mBits.groupInfo;
   mBits.groupInfo = nullptr;
-  mContextFlags &= ~eHasNameDependentParent;
+  mContextFlags &= ~eHasNameDependentParent & ~eInsideAlert;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible public methods
 
 RootAccessible*
 Accessible::RootAccessible() const
 {
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -563,16 +563,18 @@ public:
   //////////////////////////////////////////////////////////////////////////////
   // Downcasting and types
 
   inline bool IsAbbreviation() const
   {
     return mContent->IsAnyOfHTMLElements(nsGkAtoms::abbr, nsGkAtoms::acronym);
   }
 
+  bool IsAlert() const { return HasGenericType(eAlert); }
+
   bool IsApplication() const { return mType == eApplicationType; }
   ApplicationAccessible* AsApplication();
 
   bool IsAutoComplete() const { return HasGenericType(eAutoComplete); }
 
   bool IsAutoCompletePopup() const
     { return HasGenericType(eAutoCompletePopup); }
 
@@ -941,16 +943,21 @@ public:
 
   /**
    * Return true if aria-hidden="true" is applied to the accessible or inherited
    * from the parent.
    */
   bool IsARIAHidden() const { return mContextFlags & eARIAHidden; }
   void SetARIAHidden(bool aIsDefined);
 
+  /**
+   * Return true if the element is inside an alert.
+   */
+  bool IsInsideAlert() const { return mContextFlags & eInsideAlert; }
+
 protected:
   virtual ~Accessible();
 
   /**
    * Return the accessible name provided by native markup. It doesn't take
    * into account ARIA markup used to specify the name.
    */
   virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
@@ -1029,18 +1036,19 @@ protected:
   };
 
   /**
    * Flags used for contextual information about the accessible.
    */
   enum ContextFlags {
     eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
     eARIAHidden = 1 << 1,
+    eInsideAlert = 1 << 2,
 
-    eLastContextFlag = eARIAHidden
+    eLastContextFlag = eInsideAlert
   };
 
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
@@ -1136,19 +1144,19 @@ protected:
   DocAccessible* mDoc;
 
   RefPtr<Accessible> mParent;
   nsTArray<RefPtr<Accessible> > mChildren;
   int32_t mIndexInParent;
 
   static const uint8_t kChildrenFlagsBits = 2;
   static const uint8_t kStateFlagsBits = 11;
-  static const uint8_t kContextFlagsBits = 2;
+  static const uint8_t kContextFlagsBits = 3;
   static const uint8_t kTypeBits = 6;
-  static const uint8_t kGenericTypesBits = 14;
+  static const uint8_t kGenericTypesBits = 15;
 
   /**
    * Keep in sync with ChildrenFlags, StateFlags, ContextFlags, and AccTypes.
    */
   uint32_t mChildrenFlags : kChildrenFlagsBits;
   uint32_t mStateFlags : kStateFlagsBits;
   uint32_t mContextFlags : kContextFlagsBits;
   uint32_t mType : kTypeBits;
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1759,32 +1759,26 @@ DocAccessible::UpdateTreeOnInsertion(Acc
   }
 
   // Content insertion/removal is not cause of accessible tree change.
   if (updateFlags == eNoAccessible)
     return;
 
   // Check to see if change occurred inside an alert, and fire an EVENT_ALERT
   // if it did.
-  if (!(updateFlags & eAlertAccessible)) {
-    // XXX: tree traversal is perf issue, accessible should know if they are
-    // children of alert accessible to avoid this.
+  if (!(updateFlags & eAlertAccessible) &&
+      (aContainer->IsAlert() || aContainer->IsInsideAlert())) {
     Accessible* ancestor = aContainer;
-    while (ancestor) {
-      if (ancestor->ARIARole() == roles::ALERT) {
+    do {
+      if (ancestor->IsAlert()) {
         FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor);
         break;
       }
-
-      // Don't climb above this document.
-      if (ancestor == this)
-        break;
-
-      ancestor = ancestor->Parent();
     }
+    while ((ancestor = ancestor->Parent()));
   }
 
   MaybeNotifyOfValueChange(aContainer);
   FireDelayedEvent(reorderEvent);
 }
 
 void
 DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode)
--- a/accessible/xul/XULAlertAccessible.cpp
+++ b/accessible/xul/XULAlertAccessible.cpp
@@ -14,16 +14,17 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // XULAlertAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULAlertAccessible::
   XULAlertAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
+  mGenericTypes |= eAlert;
 }
 
 XULAlertAccessible::~XULAlertAccessible()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(XULAlertAccessible, Accessible)