Bug 750612 - Don't expose invisible property pages in a deck frame. r=tbsaunde
authorHub Figuière <hfiguiere@mozilla.com>
Thu, 28 Jun 2012 16:04:50 -0700
changeset 101180 5ca70d915a6705213216164158998f748d2d560d
parent 101179 57ae1fdbcfc561d44850655dbce2673ca880c7c9
child 101181 91e737d544c7a9979f90232a5ca38f9be8b59137
push idunknown
push userunknown
push dateunknown
reviewerstbsaunde
bugs750612
milestone16.0a1
Bug 750612 - Don't expose invisible property pages in a deck frame. r=tbsaunde
accessible/public/nsIAccessibleProvider.idl
accessible/src/base/nsAccessibilityService.cpp
accessible/src/generic/Accessible.h
accessible/src/mac/AccessibleWrap.mm
accessible/src/mac/Makefile.in
accessible/src/mac/mozAccessible.h
accessible/src/mac/mozAccessible.mm
accessible/src/mac/mozActionElements.h
accessible/src/mac/mozActionElements.mm
accessible/src/xul/XULTabAccessible.cpp
accessible/src/xul/XULTabAccessible.h
toolkit/content/widgets/tabbox.xml
--- a/accessible/public/nsIAccessibleProvider.idl
+++ b/accessible/public/nsIAccessibleProvider.idl
@@ -57,18 +57,18 @@ interface nsIAccessibleProvider : nsISup
   const long XULStatusBar = 0x00001014;
   const long XULRadioButton = 0x00001015;
   const long XULRadioGroup = 0x00001016;
 
   /** Used for XUL tab element */
   const long XULTab = 0x00001017;
   /** Used for XUL tabs element, a container for tab elements */
   const long XULTabs = 0x00001018;
-  /** Used for XUL tabpanels container element */
-  const long XULTabpanels = 0x00001019;
+  /** Used for XUL deck frame */
+  const long XULDeck = 0x00001019;
 
   const long XULText             = 0x0000101A;
   const long XULTextBox          = 0x0000101B;
   const long XULThumb            = 0x0000101C;
   const long XULTree             = 0x0000101D;
   const long XULTreeColumns      = 0x0000101E;
   const long XULTreeColumnItem   = 0x0000101F;
   const long XULToolbar          = 0x00001020;
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1148,21 +1148,24 @@ nsAccessibilityService::GetOrCreateAcces
 
   if (!newAcc) {
     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
     // say what kind of accessible to create.
     newAcc = CreateAccessibleByType(content, docAcc);
   }
 
   if (!newAcc) {
-    // Create generic accessibles for SVG and MathML nodes.
-    if (content->IsSVG(nsGkAtoms::svg)) {
+    // xul:deck does not have XBL and nsIFrame::CreateAccessible() is only called 
+    // on HTML elements
+    nsIAtom* tag = content->Tag();
+    if ((tag == nsGkAtoms::deck) || (tag == nsGkAtoms::tabpanels)) {
+      newAcc = new XULDeckAccessible(content, docAcc);
+    } else if (content->IsSVG(nsGkAtoms::svg)) {
       newAcc = new EnumRoleAccessible(content, docAcc, roles::DIAGRAM);
-    }
-    else if (content->IsMathML(nsGkAtoms::math)) {
+    } else if (content->IsMathML(nsGkAtoms::math)) {
       newAcc = new EnumRoleAccessible(content, docAcc, roles::EQUATION);
     }
   }
 
   if (!newAcc) {
     newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), content,
                                           docAcc);
   }
@@ -1321,16 +1324,20 @@ nsAccessibilityService::CreateAccessible
     case nsIAccessibleProvider::XULColorPickerTile:
       accessible = new XULColorPickerTileAccessible(aContent, aDoc);
       break;
 
     case nsIAccessibleProvider::XULCombobox:
       accessible = new XULComboboxAccessible(aContent, aDoc);
       break;
 
+    case nsIAccessibleProvider::XULDeck:
+      accessible = new XULDeckAccessible(aContent, aDoc);
+      break;
+
     case nsIAccessibleProvider::XULDropmarker:
       accessible = new XULDropmarkerAccessible(aContent, aDoc);
       break;
 
     case nsIAccessibleProvider::XULGroupbox:
       accessible = new XULGroupboxAccessible(aContent, aDoc);
       break;
 
@@ -1425,20 +1432,16 @@ nsAccessibilityService::CreateAccessible
     case nsIAccessibleProvider::XULTab:
       accessible = new XULTabAccessible(aContent, aDoc);
       break;
 
     case nsIAccessibleProvider::XULTabs:
       accessible = new XULTabsAccessible(aContent, aDoc);
       break;
 
-    case nsIAccessibleProvider::XULTabpanels:
-      accessible = new XULTabpanelsAccessible(aContent, aDoc);
-      break;
-
     case nsIAccessibleProvider::XULText:
       accessible = new XULLabelAccessible(aContent, aDoc);
       break;
 
     case nsIAccessibleProvider::XULTextBox:
       accessible = new XULTextFieldAccessible(aContent, aDoc);
       break;
 
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -503,16 +503,18 @@ public:
   mozilla::a11y::ImageAccessible* AsImage();
 
   bool IsImageMapAccessible() const { return mFlags & eImageMapAccessible; }
   mozilla::a11y::HTMLImageMapAccessible* AsImageMap();
 
   inline bool IsXULTree() const { return mFlags & eXULTreeAccessible; }
   mozilla::a11y::XULTreeAccessible* AsXULTree();
 
+  inline bool IsXULDeck() const { return mFlags & eXULDeckAccessible; }
+
   inline bool IsListControl() const { return mFlags & eListControlAccessible; }
 
   inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
 
   inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
 
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
   mozilla::a11y::RootAccessible* AsRoot();
@@ -761,17 +763,18 @@ protected:
     eHTMLListItemAccessible = 1 << 11,
     eImageAccessible = 1 << 12,
     eImageMapAccessible = 1 << 13,
     eListControlAccessible = 1 << 14,
     eMenuButtonAccessible = 1 << 15,
     eMenuPopupAccessible = 1 << 16,
     eRootAccessible = 1 << 17,
     eTextLeafAccessible = 1 << 18,
-    eXULTreeAccessible = 1 << 19
+    eXULDeckAccessible = 1 << 19,
+    eXULTreeAccessible = 1 << 20
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
--- a/accessible/src/mac/AccessibleWrap.mm
+++ b/accessible/src/mac/AccessibleWrap.mm
@@ -54,16 +54,19 @@ AccessibleWrap::GetNativeInterface (void
 
 // overridden in subclasses to create the right kind of object. by default we create a generic
 // 'mozAccessible' node.
 Class
 AccessibleWrap::GetNativeType () 
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
+  if (IsXULDeck())
+    return [mozPaneAccessible class];
+  
   roles::Role role = Role();
   switch (role) {
     case roles::PUSHBUTTON:
     case roles::SPLITBUTTON:
     case roles::TOGGLE_BUTTON:
     {
       // if this button may show a popup, let's make it of the popupbutton type.
       return HasPopup() ? [mozPopupButtonAccessible class] : 
@@ -76,17 +79,17 @@ AccessibleWrap::GetNativeType ()
     case roles::CHECKBUTTON:
       return [mozCheckboxAccessible class];
       
     case roles::HEADING:
       return [mozHeadingAccessible class];
 
     case roles::PAGETABLIST:
       return [mozTabsAccessible class];
-      
+
     case roles::ENTRY:
     case roles::STATICTEXT:
     case roles::CAPTION:
     case roles::ACCEL_LABEL:
     case roles::TEXT_LEAF:
     case roles::PASSWORD_TEXT:
       // normal textfield (static or editable)
       return [mozTextAccessible class]; 
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -43,10 +43,12 @@ include $(topsrcdir)/config/rules.mk
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../base \
   -I$(srcdir)/../generic \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xul \
   -I$(topsrcdir)/widget/cocoa \
   -I$(topsrcdir)/widget/xpwidgets \
+  -I$(topsrcdir)/layout/xul/base/src \
+  -I$(topsrcdir)/layout/generic \
   $(NULL)
 
--- a/accessible/src/mac/mozAccessible.h
+++ b/accessible/src/mac/mozAccessible.h
@@ -18,16 +18,24 @@
  * to give it the represented view, in the latter case.
  */
 inline id <mozAccessible>
 GetObjectOrRepresentedView(id <mozAccessible> aObject)
 {
   return [aObject hasRepresentedView] ? [aObject representedView] : aObject;
 }
 
+inline mozAccessible*
+GetNativeFromGeckoAccessible(nsIAccessible* aAccessible)
+{
+  mozAccessible* native = nil;
+  aAccessible->GetNativeInterface((void**)&native);
+  return native;
+}
+
 @interface mozAccessible : NSObject <mozAccessible>
 {
   /**
    * Weak reference; it owns us.
    */
   AccessibleWrap* mGeckoAccessible;
   
   /**
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -58,28 +58,16 @@ GetClosestInterestingAccessible(id anObj
   if ([unignoredObject respondsToSelector:@selector(hasRepresentedView)])
     return GetObjectOrRepresentedView(unignoredObject);
   
   return unignoredObject;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
-static inline mozAccessible* 
-GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
-
-  mozAccessible *native = nil;
-  anAccessible->GetNativeInterface ((void**)&native);
-  return native;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
-}
-
 #pragma mark -
 
 @implementation mozAccessible
  
 - (id)initWithAccessible:(AccessibleWrap*)geckoAccessible
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
--- a/accessible/src/mac/mozActionElements.h
+++ b/accessible/src/mac/mozActionElements.h
@@ -24,8 +24,15 @@
 
 /* Class for tabs - not individual tabs */
 @interface mozTabsAccessible : mozAccessible
 {
   NSMutableArray* mTabs;
 }
 -(id)tabs;
 @end
+
+/**
+ * Accessible for a PANE
+ */
+@interface mozPaneAccessible : mozAccessible
+
+@end
--- a/accessible/src/mac/mozActionElements.mm
+++ b/accessible/src/mac/mozActionElements.mm
@@ -2,18 +2,20 @@
 /* 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/. */
 
 #import "mozActionElements.h"
 
 #import "MacUtils.h"
 #include "Accessible-inl.h"
+#include "DocAccessible.h"
 #include "XULTabAccessible.h"
 
+#include "nsDeckFrame.h"
 #include "nsObjCExceptions.h"
 
 using namespace mozilla::a11y;
 
 enum CheckboxValue {
   // these constants correspond to the values in the OS
   kUnchecked = 0,
   kChecked = 1,
@@ -328,8 +330,35 @@ enum CheckboxValue {
 {
   [super invalidateChildren];
 
   [mTabs release];
   mTabs = nil;
 }
 
 @end
+
+@implementation mozPaneAccessible
+
+- (NSArray*)children
+{
+  if (!mGeckoAccessible)
+    return nil;
+
+  nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
+  nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nsnull;
+
+  Accessible* selectedAcc = nsnull;
+  if (selectedFrame) {
+    nsINode* node = selectedFrame->GetContent();
+    selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
+  }
+
+  if (selectedAcc) {
+    mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
+    if (curNative)
+      return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
+  }
+
+  return nil;
+}
+
+@end
--- a/accessible/src/xul/XULTabAccessible.cpp
+++ b/accessible/src/xul/XULTabAccessible.cpp
@@ -159,32 +159,25 @@ nsresult
 XULTabsAccessible::GetNameInternal(nsAString& aName)
 {
   // no name
   return NS_OK;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// XULTabpanelsAccessible
+// XULDeckAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-XULTabpanelsAccessible::
-  XULTabpanelsAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  AccessibleWrap(aContent, aDoc)
-{
-}
-
 role
-XULTabpanelsAccessible::NativeRole()
+XULDeckAccessible::NativeRole()
 {
   return roles::PANE;
 }
 
-
 ////////////////////////////////////////////////////////////////////////////////
 // XULTabpanelAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULTabpanelAccessible::
   XULTabpanelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
--- a/accessible/src/xul/XULTabAccessible.h
+++ b/accessible/src/xul/XULTabAccessible.h
@@ -51,23 +51,25 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 };
 
 
-/** 
+/**
  * A container of tab panels, xul:tabpanels element.
  */
-class XULTabpanelsAccessible : public AccessibleWrap
+class XULDeckAccessible : public AccessibleWrap
 {
 public:
-  XULTabpanelsAccessible(nsIContent* aContent, DocAccessible* aDoc);
+  XULDeckAccessible(nsIContent* aContent, DocAccessible* aDoc) :
+    AccessibleWrap(aContent, aDoc)
+    { mFlags |= eXULDeckAccessible; }
 
   // Accessible
   virtual a11y::role NativeRole();
 };
 
 
 /**
  * A tabpanel object, child elements of xul:tabpanels element. Note,the object
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -596,17 +596,17 @@
   <binding id="tabpanels"
            extends="chrome://global/content/bindings/tabbox.xml#tab-base">
     <implementation implements="nsIAccessibleProvider, nsIDOMXULRelatedElement">
 
       <!-- nsIAccessibleProvider -->
       <property name="accessibleType" readonly="true">
         <getter>
           <![CDATA[
-            return Components.interfaces.nsIAccessibleProvider.XULTabpanels;
+            return Components.interfaces.nsIAccessibleProvider.XULDeck;
           ]]>
         </getter>
       </property>
 
       <!-- nsIDOMXULRelatedElement -->
       <method name="getRelatedElement">
         <parameter name="aTabPanelElm"/>
         <body>