mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Bug 756296 - Introduce pivot moveToPoint(). r=davidb
This commit is contained in:
parent
c5138de0ee
commit
43020f808e
@ -122,6 +122,20 @@ interface nsIAccessiblePivot : nsISupports
|
||||
*/
|
||||
boolean movePreviousByText(in TextBoundaryType aBoundary);
|
||||
|
||||
/**
|
||||
* Move pivot to given coordinate in screen pixels.
|
||||
*
|
||||
* @param aRule [in] raversal rule to use.
|
||||
* @param aX [in] screen's x coordinate
|
||||
* @param aY [in] screen's y coordinate
|
||||
* @param aIgnoreNoMatch [in] don't unset position if no object was found at
|
||||
* point.
|
||||
* @return true on success, false if the pivot has not been moved.
|
||||
*/
|
||||
boolean moveToPoint(in nsIAccessibleTraversalRule aRule,
|
||||
in long aX, in long aY,
|
||||
in boolean aIgnoreNoMatch);
|
||||
|
||||
/**
|
||||
* Add an observer for pivot changes.
|
||||
*
|
||||
|
@ -305,6 +305,51 @@ nsAccessiblePivot::MovePreviousByText(TextBoundaryType aBoundary, bool* aResult)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessiblePivot::MoveToPoint(nsIAccessibleTraversalRule* aRule,
|
||||
PRInt32 aX, PRInt32 aY, bool aIgnoreNoMatch,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG_POINTER(aRule);
|
||||
|
||||
*aResult = false;
|
||||
|
||||
if (mRoot && mRoot->IsDefunct())
|
||||
return NS_ERROR_NOT_IN_TREE;
|
||||
|
||||
RuleCache cache(aRule);
|
||||
Accessible* match = nsnull;
|
||||
Accessible* child = mRoot->ChildAtPoint(aX, aY, Accessible::eDeepestChild);
|
||||
while (child && mRoot != child) {
|
||||
PRUint16 filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
nsresult rv = cache.ApplyFilter(child, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Ignore any matching nodes that were below this one
|
||||
if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE)
|
||||
match = nsnull;
|
||||
|
||||
// Match if no node below this is a match
|
||||
if ((filtered & nsIAccessibleTraversalRule::FILTER_MATCH) && !match) {
|
||||
PRInt32 childX, childY, childWidth, childHeight;
|
||||
child->GetBounds(&childX, &childY, &childWidth, &childHeight);
|
||||
// Double-check child's bounds since the deepest child may have been out
|
||||
// of bounds. This assures we don't return a false positive.
|
||||
if (aX >= childX && aX < childX + childWidth &&
|
||||
aY >= childY && aY < childY + childHeight)
|
||||
match = child;
|
||||
}
|
||||
|
||||
child = child->Parent();
|
||||
}
|
||||
|
||||
if (match || !aIgnoreNoMatch)
|
||||
*aResult = MovePivotInternal(match);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Observer functions
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -86,9 +86,8 @@ function VCChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||
}
|
||||
|
||||
var position = aDocAcc.virtualCursor.position;
|
||||
|
||||
var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
|
||||
var nameMatches = position.name == aIdOrNameOrAcc;
|
||||
var idMatches = position && position.DOMNode.id == aIdOrNameOrAcc;
|
||||
var nameMatches = position && position.name == aIdOrNameOrAcc;
|
||||
var accMatches = position == aIdOrNameOrAcc;
|
||||
|
||||
SimpleTest.ok(idMatches || nameMatches || accMatches, "id or name matches",
|
||||
@ -170,26 +169,70 @@ function setVCRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
* @param aDocAcc [in] document that manages the virtual cursor
|
||||
* @param aPivotMoveMethod [in] method to test (ie. "moveNext", "moveFirst", etc.)
|
||||
* @param aRule [in] traversal rule object
|
||||
* @param aIdOrNameOrAcc [in] id, accessivle or accessible name to expect
|
||||
* @param aIdOrNameOrAcc [in] id, accessible or accessible name to expect
|
||||
* virtual cursor to land on after performing move method.
|
||||
* false if no move is expected.
|
||||
*/
|
||||
function setVCPosInvoker(aDocAcc, aPivotMoveMethod, aRule, aIdOrNameOrAcc)
|
||||
{
|
||||
var expectMove = (aIdOrNameOrAcc != false);
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
VCChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
|
||||
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
|
||||
SimpleTest.ok((expectMove && moved) || (!expectMove && !moved),
|
||||
"moved pivot");
|
||||
};
|
||||
|
||||
this.getID = function setVCPosInvoker_getID()
|
||||
{
|
||||
return "Do " + (aIdOrNameOrAcc ? "" : "no-op ") + aPivotMoveMethod;
|
||||
return "Do " + (expectMove ? "" : "no-op ") + aPivotMoveMethod;
|
||||
};
|
||||
|
||||
if (aIdOrNameOrAcc) {
|
||||
if (expectMove) {
|
||||
this.eventSeq = [ new VCChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
||||
} else {
|
||||
this.eventSeq = [];
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the pivot to the position under the point.
|
||||
*
|
||||
* @param aDocAcc [in] document that manages the virtual cursor
|
||||
* @param aX [in] screen x coordinate
|
||||
* @param aY [in] screen y coordinate
|
||||
* @param aIgnoreNoMatch [in] don't unset position if no object was found at
|
||||
* point.
|
||||
* @param aRule [in] traversal rule object
|
||||
* @param aIdOrNameOrAcc [in] id, accessible or accessible name to expect
|
||||
* virtual cursor to land on after performing move method.
|
||||
* false if no move is expected.
|
||||
*/
|
||||
function moveVCCoordInvoker(aDocAcc, aX, aY, aIgnoreNoMatch,
|
||||
aRule, aIdOrNameOrAcc)
|
||||
{
|
||||
var expectMove = (aIdOrNameOrAcc != false);
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
VCChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
var moved = aDocAcc.virtualCursor.moveToPoint(aRule, aX, aY,
|
||||
aIgnoreNoMatch);
|
||||
SimpleTest.ok((expectMove && moved) || (!expectMove && !moved),
|
||||
"moved pivot");
|
||||
};
|
||||
|
||||
this.getID = function setVCPosInvoker_getID()
|
||||
{
|
||||
return "Do " + (expectMove ? "" : "no-op ") + "moveToPoint " + aIdOrNameOrAcc;
|
||||
};
|
||||
|
||||
if (expectMove) {
|
||||
this.eventSeq = [ new VCChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
||||
} else {
|
||||
this.eventSeq = [];
|
||||
@ -220,7 +263,7 @@ function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
||||
}
|
||||
|
||||
// No further more matches for given rule, expect no virtual cursor changes.
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, null));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, false));
|
||||
|
||||
for (var i = aSequence.length-2; i >= 0; i--) {
|
||||
var invoker =
|
||||
@ -229,18 +272,18 @@ function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
||||
}
|
||||
|
||||
// No previous more matches for given rule, expect no virtual cursor changes.
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, false));
|
||||
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveLast", aRule,
|
||||
aSequence[aSequence.length - 1]));
|
||||
|
||||
// No further more matches for given rule, expect no virtual cursor changes.
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, null));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, false));
|
||||
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveFirst", aRule, aSequence[0]));
|
||||
|
||||
// No previous more matches for given rule, expect no virtual cursor changes.
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
<script type="application/javascript" src="../states.js"></script>
|
||||
<script type="application/javascript" src="../pivot.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
var gBrowserWnd = null;
|
||||
@ -76,6 +77,22 @@
|
||||
gQueue.push(new removeVCRootInvoker(
|
||||
doc.getElementById('links')));
|
||||
|
||||
var [x, y] = getBounds(getAccessible(doc.getElementById('heading-1-1')));
|
||||
gQueue.push(new moveVCCoordInvoker(docAcc, x + 1, y + 1, true,
|
||||
HeadersTraversalRule, 'heading-1-1'));
|
||||
|
||||
// Already on the point, so we should not get a move event.
|
||||
gQueue.push(new moveVCCoordInvoker(docAcc, x + 1, y + 1, true,
|
||||
HeadersTraversalRule, false));
|
||||
|
||||
// Attempting a coordinate outside any header, should not move.
|
||||
gQueue.push(new moveVCCoordInvoker(docAcc, x - 1, y - 1, true,
|
||||
HeadersTraversalRule, false));
|
||||
|
||||
// Attempting a coordinate outside any header, should move to null
|
||||
gQueue.push(new moveVCCoordInvoker(docAcc, x - 1, y - 1, false,
|
||||
HeadersTraversalRule, null));
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user