Last Comment Bug 814836 - <xul:deck> element messes up screen readers
: <xul:deck> element messes up screen readers
Status: RESOLVED FIXED
: access, regression
Product: Core
Classification: Components
Component: Disability Access APIs (show other bugs)
: Trunk
: All All
: -- normal (vote)
: mozilla20
Assigned To: alexander :surkov
:
: alexander :surkov
Mentors:
Depends on: 924915
Blocks: xula11y abp
  Show dependency treegraph
 
Reported: 2012-11-24 02:54 PST by Wladimir Palant
Modified: 2014-03-24 12:17 PDT (History)
6 users (show)
surkov.alexander: in‑testsuite+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Testcase (389 bytes, text/plain)
2012-11-24 02:54 PST, Wladimir Palant
no flags Details
patch (21.01 KB, patch)
2012-12-06 08:50 PST, alexander :surkov
no flags Details | Diff | Splinter Review
patch2 (22.15 KB, patch)
2012-12-06 10:40 PST, alexander :surkov
tbsaunde+mozbugs: review+
roc: superreview+
Details | Diff | Splinter Review

Description Wladimir Palant 2012-11-24 02:54:36 PST
Created attachment 684838 [details]
Testcase

It seems that Firefox is reporting wrong structure for XUL documents to screen readers if a <xul:deck> element is present. I attached a testcase, it needs to be downloaded and added to some chrome namespace (won't open otherwise due to remote XUL restrictions). That testcase shows four strings:

test1
test2
test3
test4

The second and third string are inside a <deck> element, the others are just regular <description> elements. A screen reader should normally read all of them nevertheless. However, when I test it with a Firefox 20.0a1 nightly (2012-11-23) on Linux with the Orca screen reader only test1 and test4 are being read. With more complicated examples I get more complicated failures, e.g. in the Filter Preferences dialog of Adblock Plus 2.2.1 (<richlistbox> with items containing a <deck> along with several other elements) some elements inside the items are being read when the dialog window opens and others when the selection changes - I couldn't figure out the system behind it. It all stops as soon as I remove the <deck> element.

This is apparently a cross-platform issue, the original report referred to JAWS which is Windows-only. And it is a regression, the regression range I found is:

Last good nightly: 2012-07-06
First bad nightly: 2012-07-08

Pushlog:
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=4b1249ae1906&tochange=1751d97cc9e4

Unfortunately, I couldn't find any obvious candidates in the push log, accessibility changes seems to touch only Windows and Mac specific code.
Comment 1 alexander :surkov 2012-11-24 19:09:45 PST
(In reply to Wladimir Palant from comment #0)

> It seems that Firefox is reporting wrong structure for XUL documents to
> screen readers if a <xul:deck> element is present. 
> The second and third string are inside a <deck> element, the others are just
> regular <description> elements. A screen reader should normally read all of
> them nevertheless. However, when I test it with a Firefox 20.0a1 nightly
> (2012-11-23) on Linux with the Orca screen reader only test1 and test4 are
> being read.

Did you compare hierarchy between builds just in case? (DOMi, Accerciser)

> With more complicated examples I get more complicated failures,
> e.g. in the Filter Preferences dialog of Adblock Plus 2.2.1 (<richlistbox>
> with items containing a <deck> along with several other elements) 

That may be different issue, AT might not expect to see deck inside listboxes.

> This is apparently a cross-platform issue, the original report referred to
> JAWS which is Windows-only.

That's interesting. Afaik screen readers feel well with Option Dialog which uses deck element as well.
Comment 2 alexander :surkov 2012-11-24 19:11:17 PST
(In reply to alexander :surkov from comment #1)

> That's interesting. Afaik screen readers feel well with Option Dialog which
> uses deck element as well.

sorry, About Dialog
Comment 3 Wladimir Palant 2012-11-25 02:46:23 PST
(In reply to alexander :surkov from comment #1)
> Did you compare hierarchy between builds just in case? (DOMi, Accerciser)

No, I forgot that DOMi could show accessibility nodes - never used that feature before.

> That may be different issue, AT might not expect to see deck inside
> listboxes.

I would also suspect that it is a different issue - but it has exactly the same regression range.
Comment 4 alexander :surkov 2012-11-25 20:17:18 PST
the difference between those builds: 06 June's one doesn't have an accessible for XUL deck. Extra grouping role (MSAA role) shouldn't confuse JAWS, perhaps pane role (ATK role) might confuse Orca. Extra grouping accessible inside listbox can confuse JAWS I guess.

In bug 810260 I guessed that we don't need an accessible for xul:deck in general so might be it's time to get rid it.
Comment 5 alexander :surkov 2012-11-26 01:20:41 PST
and then in bug bug 750612 we "legalized" an accessible xul:deck
Comment 6 alexander :surkov 2012-12-06 08:50:14 PST
Created attachment 689226 [details] [diff] [review]
patch

1) Do not create an accessible for deck (partial back out of bug 750612). As a rule deck is not part of UI and used to show/hide UI elements (analogue of HTML display style technique), for example, it's used inside listboxes for that propose.
2) Do not create an accessible for deck panel (partial backout of bug 357969). Tabpanels have semantics, deck panels don't.
3) Do not create accessibles for children of not selected deck panel (fall into usual tree update procedure when selected panel is changed).
4) Do not touch tabpanels.

3 and 4 guarantee we don't regress bug 750612.
4 guarantees us we don't regress bug 357969.

Note, Firefox option dialog uses deck for top level tabs (like 'general', 'tabs' and etc) but those tabpanels aren't connected with those buttons. It doesn't seem we regress user experience on this.
Comment 7 alexander :surkov 2012-12-06 10:40:53 PST
Created attachment 689288 [details] [diff] [review]
patch2
Comment 8 Trevor Saunders (:tbsaunde) 2012-12-10 05:47:44 PST
Comment on attachment 689288 [details] [diff] [review]
patch2

>diff --git a/accessible/public/nsIAccessibleProvider.idl b/accessible/public/nsIAccessibleProvider.idl
>--- 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 deck frame */
>-  const long XULDeck = 0x00001019;
>+  /** Used for XUL tabpanels element */
>+  const long XULTabpanels = 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;
>diff --git a/accessible/src/base/AccTypes.h b/accessible/src/base/AccTypes.h
>--- a/accessible/src/base/AccTypes.h
>+++ b/accessible/src/base/AccTypes.h
>@@ -47,17 +47,17 @@ enum AccType {
>   /**
>    * Other accessible types.
>    */
>   eApplication = 25,
>   eImageMap = 26,
>   eMenuPopup = 27,
>   eProgress = 28,
>   eRoot = 29,
>-  eXULDeck = 30,
T>+  eXULTabpanels = 30,
>   eXULTree = 31
> };
> 
> /**
>  * Generic accessible type, different accessible classes can share the same
>  * type, the same accessible class can have several types.
>  */
> enum AccGenericType {
>diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp
>--- a/accessible/src/base/nsAccessibilityService.cpp
>+++ b/accessible/src/base/nsAccessibilityService.cpp
>@@ -54,16 +54,17 @@
> #include "nsIObserverService.h"
> #include "nsLayoutUtils.h"
> #include "nsNPAPIPluginInstance.h"
> #include "nsObjectFrame.h"
> #include "mozilla/dom/Element.h"
> #include "mozilla/Preferences.h"
> #include "mozilla/Services.h"
> #include "mozilla/Util.h"
>+#include "nsDeckFrame.h"
> 
> #ifdef MOZ_XUL
> #include "XULAlertAccessible.h"
> #include "XULColorPickerAccessible.h"
> #include "XULComboboxAccessible.h"
> #include "XULElementAccessibles.h"
> #include "XULFormControlAccessible.h"
> #include "XULListboxAccessibleWrap.h"
>@@ -249,16 +250,57 @@ nsAccessibilityService::CreatePluginAcce
> #endif
>   }
> #endif
> 
>   return nullptr;
> }
> 
> void
>+nsAccessibilityService::DeckPanelSwitched(nsIPresShell* aPresShell,
>+                                          nsIContent* aDeckNode,
>+                                          nsIFrame* aPrevBoxFrame,
>+                                          nsIFrame* aCurrentBoxFrame)
>+{

I think I'd prefer this was a method on DocAccessible

>+  // Ignore tabpanels elements (a deck having an accessible) since their
>+  // children are accessible not depending on selected tab.
>+  DocAccessible* document = GetDocAccessible(aPresShell);

why not just do aPresShell->GetDocAccessible() we know the pres shell is non null so we don't need the branching in that method.

>+    if (!newAcc && aContext->IsXULTabpanels() &&
>+      content->GetParent() == aContext->GetContent() &&
>+      (frame->GetType() == nsGkAtoms::boxFrame ||
>+        frame->GetType() == nsGkAtoms::scrollFrame)) {

I wonder if it would be a good idea to put the result of frame->GetType() in a variable since its virtual (I'm not hope the compiler is smart enough to do it itself but...)
Comment 9 alexander :surkov 2012-12-10 20:41:36 PST
(In reply to Trevor Saunders (:tbsaunde) from comment #8)

> >+nsAccessibilityService::DeckPanelSwitched(nsIPresShell* aPresShell,
> >+                                          nsIContent* aDeckNode,
> >+                                          nsIFrame* aPrevBoxFrame,
> >+                                          nsIFrame* aCurrentBoxFrame)
> >+{
> 
> I think I'd prefer this was a method on DocAccessible

I would leave that to the bug we have about moving the methods out of the service.


> why not just do aPresShell->GetDocAccessible() we know the pres shell is non
> null so we don't need the branching in that method.

technically they have a difference. I think I'd like to keep notifications the same way, i.e. they are allowed to trigger document creation.

> I wonder if it would be a good idea to put the result of frame->GetType() in
> a variable since its virtual (I'm not hope the compiler is smart enough to
> do it itself but...)

ok
Comment 10 Trevor Saunders (:tbsaunde) 2012-12-19 22:29:24 PST
(In reply to alexander :surkov from comment #9)
> (In reply to Trevor Saunders (:tbsaunde) from comment #8)
> 
> > >+nsAccessibilityService::DeckPanelSwitched(nsIPresShell* aPresShell,
> > >+                                          nsIContent* aDeckNode,
> > >+                                          nsIFrame* aPrevBoxFrame,
> > >+                                          nsIFrame* aCurrentBoxFrame)
> > >+{
> > 
> > I think I'd prefer this was a method on DocAccessible
> 
> I would leave that to the bug we have about moving the methods out of the
> service.

only because you like to keep them here, but I guess that bug is a better place to convince you ;/)

> > why not just do aPresShell->GetDocAccessible() we know the pres shell is non
> > null so we don't need the branching in that method.
> 
> technically they have a difference. I think I'd like to keep notifications
> the same way, i.e. they are allowed to trigger document creation.

they could in theory sure, but is it actually possible? if doc existed before a11y starts then code in ApplicationAccessible::CacheChildren() should create it otherwise normal doc creation logic should no?
Comment 11 alexander :surkov 2012-12-20 20:10:38 PST
(In reply to Trevor Saunders (:tbsaunde) from comment #10)

> > I would leave that to the bug we have about moving the methods out of the
> > service.
> 
> only because you like to keep them here, but I guess that bug is a better
> place to convince you ;/)

you're right, I'm no sure what is best

> > > why not just do aPresShell->GetDocAccessible() we know the pres shell is non
> > > null so we don't need the branching in that method.
> > 
> > technically they have a difference. I think I'd like to keep notifications
> > the same way, i.e. they are allowed to trigger document creation.
> 
> they could in theory sure, but is it actually possible? if doc existed
> before a11y starts then code in ApplicationAccessible::CacheChildren()
> should create it otherwise normal doc creation logic should no?

true, AppAcc creates root accessibles and its trees, OuterDocAccessible creates underlying documents and so on. But I really would prefer to change them all together separately. If you like I can file a bug.
Comment 12 Trevor Saunders (:tbsaunde) 2012-12-24 01:47:45 PST
> > > > why not just do aPresShell->GetDocAccessible() we know the pres shell is non
> > > > null so we don't need the branching in that method.
> > > 
> > > technically they have a difference. I think I'd like to keep notifications
> > > the same way, i.e. they are allowed to trigger document creation.
> > 
> > they could in theory sure, but is it actually possible? if doc existed
> > before a11y starts then code in ApplicationAccessible::CacheChildren()
> > should create it otherwise normal doc creation logic should no?
> 
> true, AppAcc creates root accessibles and its trees, OuterDocAccessible
> creates underlying documents and so on. But I really would prefer to change
> them all together separately. If you like I can file a bug.

I'm not sure I see a point in doing them all together, but sure file a bug if you prefer.
Comment 13 alexander :surkov 2012-12-24 02:14:43 PST
(In reply to Trevor Saunders (:tbsaunde) from comment #12)

there's a small risk, if we missed something, and since these are unrelated things then I prefer to deal with them separately.
Comment 15 Graeme McCutcheon [:graememcc] 2012-12-29 04:31:51 PST
https://hg.mozilla.org/mozilla-central/rev/57c3756c0705

Note You need to log in before you can comment on or make changes to this bug.