mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 686821 - expose offscreen state (no invisible state) for background tab accessibles, r=tbsaunde
This commit is contained in:
parent
eb24d5ccf0
commit
c5b0bb718a
@ -43,6 +43,7 @@
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
||||
#include "nsDeckFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIStringBundle.h"
|
||||
@ -606,26 +607,35 @@ Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
||||
uint64_t
|
||||
Accessible::VisibilityState()
|
||||
{
|
||||
uint64_t vstates = states::INVISIBLE | states::OFFSCREEN;
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return vstates;
|
||||
return states::INVISIBLE;
|
||||
|
||||
nsIPresShell* shell(mDoc->PresShell());
|
||||
if (!shell)
|
||||
return vstates;
|
||||
// Walk the parent frame chain to see if there's invisible parent or the frame
|
||||
// is in background tab.
|
||||
if (!frame->GetStyleVisibility()->IsVisible())
|
||||
return states::INVISIBLE;
|
||||
|
||||
// We need to know if at least a kMinPixels around the object is visible,
|
||||
// otherwise it will be marked states::OFFSCREEN.
|
||||
const uint16_t kMinPixels = 12;
|
||||
const nsSize frameSize = frame->GetSize();
|
||||
const nsRectVisibility rectVisibility =
|
||||
shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
|
||||
nsPresContext::CSSPixelsToAppUnits(kMinPixels));
|
||||
nsIFrame* curFrame = frame;
|
||||
do {
|
||||
nsIView* view = curFrame->GetView();
|
||||
if (view && view->GetVisibility() == nsViewVisibility_kHide)
|
||||
return states::INVISIBLE;
|
||||
|
||||
if (rectVisibility == nsRectVisibility_kVisible)
|
||||
vstates &= ~states::OFFSCREEN;
|
||||
// Offscreen state for background tab content.
|
||||
nsIFrame* parentFrame = curFrame->GetParent();
|
||||
nsDeckFrame* deckFrame = do_QueryFrame(parentFrame);
|
||||
if (deckFrame && deckFrame->GetSelectedBox() != curFrame)
|
||||
return states::OFFSCREEN;
|
||||
|
||||
if (!parentFrame) {
|
||||
parentFrame = nsLayoutUtils::GetCrossDocParentFrame(curFrame);
|
||||
if (parentFrame && !parentFrame->GetStyleVisibility()->IsVisible())
|
||||
return states::INVISIBLE;
|
||||
}
|
||||
|
||||
curFrame = parentFrame;
|
||||
} while (curFrame);
|
||||
|
||||
// Zero area rects can occur in the first frame of a multi-frame text flow,
|
||||
// in which case the rendered text is not empty and the frame should not be
|
||||
@ -638,16 +648,21 @@ Accessible::VisibilityState()
|
||||
nsAutoString renderedText;
|
||||
frame->GetRenderedText(&renderedText, nullptr, nullptr, 0, 1);
|
||||
if (renderedText.IsEmpty())
|
||||
return vstates;
|
||||
|
||||
return states::INVISIBLE;
|
||||
}
|
||||
|
||||
// XXX Do we really need to cross from content to chrome ancestor?
|
||||
if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY))
|
||||
return vstates;
|
||||
// We need to know if at least a kMinPixels around the object is visible,
|
||||
// otherwise it will be marked states::OFFSCREEN.
|
||||
const uint16_t kMinPixels = 12;
|
||||
const nsSize frameSize = frame->GetSize();
|
||||
const nsRectVisibility rectVisibility =
|
||||
mDoc->PresShell()->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
|
||||
nsPresContext::CSSPixelsToAppUnits(kMinPixels));
|
||||
|
||||
// Assume we are visible enough.
|
||||
return vstates &= ~states::INVISIBLE;
|
||||
if (rectVisibility != nsRectVisibility_kVisible)
|
||||
return states::OFFSCREEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
@ -16,27 +16,56 @@
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
function addTab(aURL)
|
||||
{
|
||||
testStates("div", 0, 0, STATE_INVISIBLE);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
|
||||
];
|
||||
|
||||
this.invoke = function addTab_invoke()
|
||||
{
|
||||
tabBrowser().loadOneTab(aURL, null, "", null, false);
|
||||
}
|
||||
|
||||
this.finalCheck = function addTab_finalCheck()
|
||||
{
|
||||
var tabDoc = tabDocumentAt(0);
|
||||
var input = getAccessible(tabDoc.getElementById("input"));
|
||||
testStates(input, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
|
||||
}
|
||||
|
||||
this.getID = function addTab_getID()
|
||||
{
|
||||
return "add tab: " + aURL;
|
||||
}
|
||||
}
|
||||
|
||||
var gInputDocURI = "data:text/html,<html><input id='input'></html>";
|
||||
|
||||
function doTests()
|
||||
{
|
||||
testStates("div", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
|
||||
testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
|
||||
testStates("div_abschild", 0, 0, STATE_INVISIBLE);
|
||||
testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
|
||||
|
||||
// Confirm destruction of accessibles.
|
||||
document.getElementById("div").style.visibility = "hidden";
|
||||
document.getElementById("div_off").style.visibility="hidden";
|
||||
document.getElementById("div_abschild").style.visibility="hidden";
|
||||
document.body.clientWidth; // flush layout
|
||||
testAccessibleTree("outer_div", {children:[]});
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Accessibles in background tab should have offscreen state and no
|
||||
// invisible state.
|
||||
gQueue.push(new addTab("about:blank"));
|
||||
|
||||
SimpleTest.finish();
|
||||
gQueue.onFinish = function() { closeBrowserWindow(); }
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
openBrowserWindow(doTests, gInputDocURI);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
Loading…
Reference in New Issue
Block a user