Closed Bug 371955 Opened 17 years ago Closed 17 years ago

Calling grabFocus a link with "a:focus { overflow:hidden }" makes the text disappear

Categories

(Core :: Disability Access APIs, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: wwalker, Assigned: evan.yan)

References

(Blocks 2 open bugs, )

Details

(Keywords: access)

User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a3pre) Gecko/20070222 Minefield/3.0a3pre
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a3pre) Gecko/20070222 Minefield/3.0a3pre

If one calls getText(0, -1) on an at-spi object that's for a link with the "a:focus { overflow:hidden }", the text for the link shrinks to an empty string.


Reproducible: Always

Steps to Reproduce:
1. Run Firefox.  Open http://svn.gnome.org/viewcvs/orca/trunk/test/html/slash-test.html?view=co
2. Run Orca v2.17.92 and give the Firefox window focus.  
3. Press Insert+F12 until you hear Orca say "Orca is controlling the caret"
4. Press Ctrl+Home.
5. Press 'h' to navigate header by header.


1. Run Firefox
2. Run Orca v2.17.92
3.
Actual Results:  
When you reach the "Science" link, Orca will not speak the text, "Science".

Expected Results:  
Orca should be able to obtain and read the text for the link.

I did some debugging in Orca, and it turns out that the call to component.grabFocus() on the link is making the text disappear.  That is, when I call obj.text.getText(0, -1) before the call to grabFocus, the text is there.  When I call obj.text.getText(0, -1) immediately afterwards, the text disappears.

This problem doesn't happen on things that do not have the overflow:hidden stylesheet attribute.
Keywords: access
Blocks: keya11y
Blocks: orca
Is the object DEFUNCT at this point?
Assignee: nobody → aaronleventhal
Blocks: focusnav
Component: Disability Access → Disability Access APIs
Product: Firefox → Core
QA Contact: disability.access → accessibility-apis
I'm not sure we're seeing this, should it be DEFUNCT immediately upon the return of the call to grabFocus, or does it happen asynchronously?  BTW, just for reference, the understanding here is that a call to grabFocus on a Gecko object currently does something very strange: Gecko kills the object and creates a brand new one.  I have a few questions about this:

1) Is it just the object that Gecko kills, or does Gecko delete the known world and create new objects across the board?

2) Are there any other kinds of AT-SPI calls that will cause this bizarre "go kill yourself" behavior?

3) Is there any chance of getting Gecko to not do this?  :-)

Thanks!
Gecko doesn't typically kill the object, but if the author does something funky with the style for :focus, it may cause the layout engine to need to change the layout object type, which can cause the accessibility object to be invalidated.

If it's not defunct than the theory may be incorrect and we'll need to do some deeper debugging.

#1 -- just the object
#2 -- anything that makes Gecko do something -- so I believe setting text attributes, inserting text and doing actions could make weird things happen. You just never know what the CSS or especially the JS will do. The JS is especially dangerous, because it can respond to an event handler and do whatever it wants.
#3 -- after you make it grabFocus you really need to find out what really got focus from your focus listener. We can't tell get Gecko not to pay attention to things like Javascript, and the Javascript could haved changed the focus to something else. You really should be doing the safe thing whenever you any of the items in #2. Accessibility APIs are not really read-only, and any time you do something that isn't, the web page may do something funky with that.

That said, in this particular case, it may be overkill that Gecko is wiping out the accessibility object, but that doesn't change what the safe thing is for you to do.
Assignee: aaronleventhal → Evan.Yan
Evan, do you mind taking a look?
I'm afraid I won't have time to look at this one until the end of this week.
Evan, when you get a chance, please let me know.  Thanks!
From some initial testing I can see that it is in fact correct that the a11y object is getting destroyed. Setting the DEFUNCT state, and perhaps even the destruction of the object, may be async.

While it may seem a bit extreme to destroy the a11y object for this, imagine an onfocus in a web page that does something like redirect focus somewhere else, or on focus it wants to show an image link with a larger icon, and thus destroys the current focus and creates a new node. Authors can and will do any crazy thing.

Therefore, I really think the solution I proposed at CSUN is correct: go ahead and set focus as you do now, but use your focus listener to do any other focus-related caching or other work. This will fix this problem and potentially many others. Listening to focus is the only way to ensure you get the real focus.
Will, I'd like to mark this as WONTFIX. If we start carefully sorting what they layout engine does and invalidating less often, there will still be legitimate times that you need to follow the suggestions in comment 7. Trying to split hairs and second guess the layout engine will cause a lot of work and potentially more bugs.
Another concern is security. Some malicious authors may try to create crashes by doing strange things in their apps. We need to handle it gracefully.

Any time you set focus, do an action or change text via an interface, a web page author can listen to that and change the web page underneath you. It's just better to not assume your objects are valid anymore after you do one of those things.

The web is a bit wild, and Mozilla really can't insulate the AT from all these things, unless the a11y APIs were "read only".
Will, did you find a workaround? My finger is hovering over WONTFIX.
I actually happen to be working away at this right this second.  One thing I think I see happening is that we're getting a focus event for an object of role "unknown".  Bizarre.
I remember that links are currently exposed with the correct role but there was an issue on the AT-SPI side (bridge or tools?) which made the role appear unknown. Are you seeing it for all links or are you only seeing it for this testcase?
Only for this test case.  I believe the thing that was showing "unknown" was at-poke.  Everything else should be getting the rolename string just fine.

Do you have a handle on exactly what's going on when grabFocus is called in these cases?  Is a focus event actually issued for the old object, or does the old object get destroyed immediately and a new one created?
The focus event should be issues for the thing that actually gets focus. We have a very tiny delay before we fire most event, so that we get the final accessible object for the DOM node after all processing is done. We use that final accessible to fire the events.
I think we've been able to workaround this bug, so I guess you can feel free to discard it if you wish.  :-)  Thanks!
Was the workaround similar to what I recommended? We might want to add the workaround to our docs. If you don't mind sharing anything you learned it would be great.
Status: UNCONFIRMED → RESOLVED
Closed: 17 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.