mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 391617 - CAccessibleText::scroll* methods are incorrect, r=aaronlev, a=dsicore
This commit is contained in:
parent
cb674c33c4
commit
adbfa3bec2
@ -45,7 +45,7 @@ typedef long nsAccessibleTextBoundary;
|
||||
|
||||
interface nsIAccessible;
|
||||
|
||||
[scriptable, uuid(948419b2-53f6-4a74-bb69-1345faf3e8e8)]
|
||||
[scriptable, uuid(caa4f543-070e-4705-8428-2e53575c41bb)]
|
||||
interface nsIAccessibleText : nsISupports
|
||||
{
|
||||
const nsAccessibleTextBoundary BOUNDARY_CHAR = 0;
|
||||
@ -180,15 +180,31 @@ interface nsIAccessibleText : nsISupports
|
||||
/**
|
||||
* Makes a specific part of string visible on screen.
|
||||
*
|
||||
* @param aStartIndex - 0-based character offset.
|
||||
* @param aEndIndex - 0-based character offset - the offset of the
|
||||
* @param startIndex 0-based character offset
|
||||
* @param endIndex 0-based character offset - the offset of the
|
||||
* character just past the last character of the
|
||||
* string.
|
||||
* @param aScrollType - defines how to scroll (see nsIAccessibleScrollType for
|
||||
* available constants).
|
||||
* string
|
||||
* @param scrollType defines how to scroll (see nsIAccessibleScrollType for
|
||||
* available constants)
|
||||
*/
|
||||
void scrollSubstringTo(in long aStartIndex, in long aEndIndex,
|
||||
in unsigned long aScrollType);
|
||||
void scrollSubstringTo(in long startIndex, in long endIndex,
|
||||
in unsigned long scrollType);
|
||||
|
||||
/**
|
||||
* Moves the top left of a substring to a specified location.
|
||||
*
|
||||
* @param startIndex 0-based character offset
|
||||
* @param endIndex 0-based character offset - the offset of the
|
||||
* character just past the last character of
|
||||
* the string
|
||||
* @param coordinateType specifies the coordinates origin (for available
|
||||
* constants refer to nsIAccessibleCoordinateType)
|
||||
* @param x defines the x coordinate
|
||||
* @param y defines the y coordinate
|
||||
*/
|
||||
void scrollSubstringToPoint(in long startIndex, in long endIndex,
|
||||
in unsigned long coordinateType,
|
||||
in long x, in long y);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -90,8 +90,7 @@ interface nsIAccessibleScrollType : nsISupports
|
||||
|
||||
|
||||
/**
|
||||
* These constants define which coordinate system a point is located in. Note,
|
||||
* keep them synchronized with IA2CoordinateType.
|
||||
* These constants define which coordinate system a point is located in.
|
||||
*/
|
||||
[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
|
||||
interface nsIAccessibleCoordinateType : nsISupports
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsPresContext.h"
|
||||
@ -441,71 +440,14 @@ nsAccessNode::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
|
||||
if (!frame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPresContext *presContext = frame->PresContext();
|
||||
|
||||
switch (aCoordinateType) {
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
|
||||
break;
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
|
||||
{
|
||||
nsIntPoint wndCoords = nsAccUtils::GetScreenCoordsForWindow(mDOMNode);
|
||||
aX += wndCoords.x;
|
||||
aY += wndCoords.y;
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
|
||||
{
|
||||
nsCOMPtr<nsPIAccessNode> parent;
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsresult rv = QueryInterface(NS_GET_IID(nsIAccessible),
|
||||
getter_AddRefs(accessible));
|
||||
if (NS_SUCCEEDED(rv) && accessible) {
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
accessible->GetParent(getter_AddRefs(parentAccessible));
|
||||
parent = do_QueryInterface(parentAccessible);
|
||||
} else {
|
||||
nsCOMPtr<nsIAccessNode> parentAccessNode;
|
||||
GetParentNode(getter_AddRefs(parentAccessNode));
|
||||
parent = do_QueryInterface(parentAccessNode);
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(parent);
|
||||
nsIFrame *parentFrame = parent->GetFrame();
|
||||
NS_ENSURE_STATE(parentFrame);
|
||||
|
||||
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
|
||||
aX += parentRect.x;
|
||||
aY += parentRect.y;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsIntPoint coords;
|
||||
nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
|
||||
this, &coords);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIFrame *parentFrame = frame;
|
||||
while (parentFrame = parentFrame->GetParent()) {
|
||||
nsIScrollableFrame *scrollableFrame = nsnull;
|
||||
CallQueryInterface(parentFrame, &scrollableFrame);
|
||||
if (scrollableFrame) {
|
||||
nsIntRect frameRect = frame->GetScreenRectExternal();
|
||||
PRInt32 devDeltaX = aX - frameRect.x;
|
||||
PRInt32 devDeltaY = aY - frameRect.y;
|
||||
|
||||
nsPoint deltaPoint;
|
||||
deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
|
||||
deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
|
||||
|
||||
nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
|
||||
|
||||
scrollPoint -= deltaPoint;
|
||||
|
||||
scrollableFrame->ScrollTo(scrollPoint);
|
||||
}
|
||||
}
|
||||
while (parentFrame = parentFrame->GetParent())
|
||||
nsAccUtils::ScrollFrameToPoint(parentFrame, frame, coords);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsPIAccessible.h"
|
||||
#include "nsPIAccessNode.h"
|
||||
#include "nsAccessibleEventData.h"
|
||||
|
||||
#include "nsAccessNode.h"
|
||||
@ -57,6 +58,7 @@
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionController.h"
|
||||
@ -286,6 +288,19 @@ nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRUint32 aScrollType)
|
||||
{
|
||||
PRInt16 vPercent, hPercent;
|
||||
ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
|
||||
|
||||
return ScrollSubstringTo(aFrame, aStartNode, aStartIndex, aEndNode, aEndIndex,
|
||||
vPercent, hPercent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRInt16 aVPercent, PRInt16 aHPercent)
|
||||
{
|
||||
if (!aFrame || !aStartNode || !aEndNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -311,10 +326,8 @@ nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(scrollToRange);
|
||||
|
||||
PRInt16 vPercent, hPercent;
|
||||
ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
|
||||
selection->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
|
||||
PR_TRUE, vPercent, hPercent);
|
||||
PR_TRUE, aVPercent, aHPercent);
|
||||
|
||||
selection->CollapseToStart();
|
||||
}
|
||||
@ -322,6 +335,32 @@ nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
|
||||
nsIFrame *aFrame,
|
||||
const nsIntPoint& aPoint)
|
||||
{
|
||||
nsIScrollableFrame *scrollableFrame = nsnull;
|
||||
CallQueryInterface(aScrollableFrame, &scrollableFrame);
|
||||
if (!scrollableFrame)
|
||||
return;
|
||||
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
|
||||
nsIntRect frameRect = aFrame->GetScreenRectExternal();
|
||||
PRInt32 devDeltaX = aPoint.x - frameRect.x;
|
||||
PRInt32 devDeltaY = aPoint.y - frameRect.y;
|
||||
|
||||
nsPoint deltaPoint;
|
||||
deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
|
||||
deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
|
||||
|
||||
nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
|
||||
scrollPoint -= deltaPoint;
|
||||
|
||||
scrollableFrame->ScrollTo(scrollPoint);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::ConvertScrollTypeToPercents(PRUint32 aScrollType,
|
||||
PRInt16 *aVPercent,
|
||||
@ -359,6 +398,67 @@ nsAccUtils::ConvertScrollTypeToPercents(PRUint32 aScrollType,
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode,
|
||||
nsIntPoint *aCoords)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCoords);
|
||||
|
||||
aCoords->MoveTo(aX, aY);
|
||||
|
||||
switch (aCoordinateType) {
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
|
||||
break;
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> DOMNode;
|
||||
aAccessNode->GetDOMNode(getter_AddRefs(DOMNode));
|
||||
NS_ENSURE_STATE(DOMNode);
|
||||
|
||||
nsIntPoint wndCoords = nsAccUtils::GetScreenCoordsForWindow(DOMNode);
|
||||
*aCoords += wndCoords;
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
|
||||
nsCOMPtr<nsPIAccessNode> parent;
|
||||
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(aAccessNode));
|
||||
if (accessible) {
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
accessible->GetParent(getter_AddRefs(parentAccessible));
|
||||
parent = do_QueryInterface(parentAccessible);
|
||||
} else {
|
||||
nsCOMPtr<nsIAccessNode> parentAccessNode;
|
||||
aAccessNode->GetParentNode(getter_AddRefs(parentAccessNode));
|
||||
parent = do_QueryInterface(parentAccessNode);
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
nsIFrame *parentFrame = parent->GetFrame();
|
||||
NS_ENSURE_STATE(parentFrame);
|
||||
|
||||
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
|
||||
aCoords->x += parentRect.x;
|
||||
aCoords->y += parentRect.y;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsAccUtils::GetScreenCoordsForWindow(nsIDOMNode *aNode)
|
||||
{
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessNode.h"
|
||||
#include "nsARIAMap.h"
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
@ -162,6 +163,33 @@ public:
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRUint32 aScrollType);
|
||||
|
||||
/** Helper method to scroll range into view, used for implementation of
|
||||
* nsIAccessibleText::scrollSubstringTo[Point]().
|
||||
*
|
||||
* @param aFrame the frame for accessible the range belongs to.
|
||||
* @param aStartNode start node of a range
|
||||
* @param aStartOffset an offset inside the start node
|
||||
* @param aEndNode end node of a range
|
||||
* @param aEndOffset an offset inside the end node
|
||||
* @param aVPercent how to align vertically, specified in percents
|
||||
* @param aHPercent how to align horizontally, specified in percents
|
||||
*/
|
||||
static nsresult ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRInt16 aVPercent, PRInt16 aHPercent);
|
||||
|
||||
/**
|
||||
* Scrolls the given frame to the point, used for implememntation of
|
||||
* nsIAccessNode::scrollToPoint and nsIAccessibleText::scrollSubstringToPoint.
|
||||
*
|
||||
* @param aScrollableFrame the scrollable frame
|
||||
* @param aFrame the frame to scroll
|
||||
* @param aPoint the point scroll to
|
||||
*/
|
||||
static void ScrollFrameToPoint(nsIFrame *aScrollableFrame,
|
||||
nsIFrame *aFrame, const nsIntPoint& aPoint);
|
||||
|
||||
/**
|
||||
* Converts scroll type constant defined in nsIAccessibleScrollType to
|
||||
* vertical and horizontal percents.
|
||||
@ -170,6 +198,22 @@ public:
|
||||
PRInt16 *aVPercent,
|
||||
PRInt16 *aHPercent);
|
||||
|
||||
/**
|
||||
* Converts the given coordinates to coordinates relative screen.
|
||||
*
|
||||
* @param aX [in] the given x coord
|
||||
* @param aY [in] the given y coord
|
||||
* @param aCoordinateType [in] specifies coordinates origin (refer to
|
||||
* nsIAccessibleCoordinateType)
|
||||
* @param aAccessNode [in] the accessible if coordinates are given
|
||||
* relative it.
|
||||
* @param aCoords [out] converted coordinates
|
||||
*/
|
||||
static nsresult ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode,
|
||||
nsIntPoint *aCoords);
|
||||
|
||||
/**
|
||||
* Returns coordinates relative screen for the top level window.
|
||||
*
|
||||
|
@ -61,6 +61,7 @@ REQUIRES = composer \
|
||||
necko \
|
||||
string \
|
||||
thebes \
|
||||
view \
|
||||
webshell \
|
||||
widget \
|
||||
xpcom \
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIPlaintextEditor.h"
|
||||
#include "nsISelection2.h"
|
||||
@ -665,6 +666,59 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
||||
PRInt32 aEndHTOffset,
|
||||
nsIDOMNode **aStartNode,
|
||||
PRInt32 *aStartOffset,
|
||||
nsIDOMNode **aEndNode,
|
||||
PRInt32 *aEndOffset)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStartNode);
|
||||
*aStartNode = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aStartOffset);
|
||||
*aStartOffset = -1;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aEndNode);
|
||||
*aEndNode = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aEndOffset);
|
||||
*aEndOffset = -1;
|
||||
|
||||
nsCOMPtr<nsIAccessible> startAcc, endAcc;
|
||||
PRInt32 startOffset = aStartHTOffset, endOffset = aEndHTOffset;
|
||||
nsIFrame *startFrame = nsnull, *endFrame = nsnull;
|
||||
|
||||
startFrame = GetPosAndText(startOffset, endOffset, nsnull, &endFrame, nsnull,
|
||||
getter_AddRefs(startAcc), getter_AddRefs(endAcc));
|
||||
if (!startAcc || !endAcc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
nsresult rv = GetDOMPointByFrameOffset(startFrame, startOffset, startAcc,
|
||||
getter_AddRefs(startNode),
|
||||
&startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aStartHTOffset != aEndHTOffset) {
|
||||
rv = GetDOMPointByFrameOffset(endFrame, endOffset, endAcc,
|
||||
getter_AddRefs(endNode), &endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
endNode = startNode;
|
||||
endOffset = startOffset;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aStartNode = startNode);
|
||||
*aStartOffset = startOffset;
|
||||
|
||||
NS_ADDREF(*aEndNode = endNode);
|
||||
*aEndOffset = endOffset;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsHyperTextAccessible::GetRelativeOffset(nsIPresShell *aPresShell,
|
||||
nsIFrame *aFromFrame,
|
||||
@ -1572,13 +1626,17 @@ NS_IMETHODIMP nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum, P
|
||||
/*
|
||||
* Changes the start and end offset of the specified selection.
|
||||
*/
|
||||
NS_IMETHODIMP nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum, PRInt32 aStartOffset, PRInt32 aEndOffset)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum,
|
||||
PRInt32 aStartOffset,
|
||||
PRInt32 aEndOffset)
|
||||
{
|
||||
nsCOMPtr<nsISelection> domSel;
|
||||
nsresult rv = GetSelections(nsnull, getter_AddRefs(domSel));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 isOnlyCaret = (aStartOffset == aEndOffset); // Caret is a collapsed selection
|
||||
// Caret is a collapsed selection
|
||||
PRBool isOnlyCaret = (aStartOffset == aEndOffset);
|
||||
|
||||
PRInt32 rangeCount;
|
||||
domSel->GetRangeCount(&rangeCount);
|
||||
@ -1595,78 +1653,20 @@ NS_IMETHODIMP nsHyperTextAccessible::SetSelectionBounds(PRInt32 aSelectionNum, P
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsIFrame *endFrame;
|
||||
nsCOMPtr<nsIAccessible> startAcc, endAcc;
|
||||
nsIFrame *startFrame = GetPosAndText(aStartOffset, aEndOffset, nsnull, &endFrame, nsnull,
|
||||
getter_AddRefs(startAcc), getter_AddRefs(endAcc));
|
||||
PRInt32 startOffset, endOffset;
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = GetPresShell();
|
||||
rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset,
|
||||
getter_AddRefs(startNode), &startOffset,
|
||||
getter_AddRefs(endNode), &endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!startFrame) { // past the end of the hyper text
|
||||
nsCOMPtr<nsIAccessNode> startAccessNode = do_QueryInterface(startAcc);
|
||||
NS_ENSURE_TRUE(startAccessNode, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
startAccessNode->GetDOMNode(getter_AddRefs(node));
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
rv = range->SetStartAfter(node);
|
||||
rv = range->SetStart(startNode, startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
nsIContent *startParentContent = startFrame->GetContent();
|
||||
PRInt32 startOffset;
|
||||
if (startFrame->GetType() != nsAccessibilityAtoms::textFrame) {
|
||||
nsIContent *newParent = startParentContent->GetParent();
|
||||
startOffset = newParent->IndexOf(startParentContent);
|
||||
startParentContent = newParent;
|
||||
}
|
||||
else {
|
||||
// We have a rendered offset into the text frame, and it needs to be
|
||||
// a content offset for us to set the caret
|
||||
nsIFrame *startPrimaryFrame =
|
||||
shell->GetPrimaryFrameFor(startFrame->GetContent());
|
||||
rv = RenderedToContentOffset(startPrimaryFrame, aStartOffset, &startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> startParentNode(do_QueryInterface(startParentContent));
|
||||
NS_ENSURE_TRUE(startParentNode, NS_ERROR_FAILURE);
|
||||
rv = range->SetStart(startParentNode, startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (isOnlyCaret) {
|
||||
rv = range->Collapse(PR_TRUE);
|
||||
rv = isOnlyCaret ? range->Collapse(PR_TRUE) :
|
||||
range->SetEnd(endNode, endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (!endFrame) { // past the end of the hyper text
|
||||
nsCOMPtr<nsIAccessNode> endAccessNode = do_QueryInterface(endAcc);
|
||||
NS_ENSURE_TRUE(endAccessNode, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
endAccessNode->GetDOMNode(getter_AddRefs(node));
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
rv = range->SetEndAfter(node);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
nsIContent *endParentContent = endFrame->GetContent();
|
||||
PRInt32 endOffset;
|
||||
if (endFrame->GetType() != nsAccessibilityAtoms::textFrame) {
|
||||
nsIContent *newParent = endParentContent->GetParent();
|
||||
endOffset = newParent->IndexOf(endParentContent);
|
||||
endParentContent = newParent;
|
||||
}
|
||||
else {
|
||||
// We have a rendered offset into the text frame, and it needs to be
|
||||
// a content offset for us to set the caret
|
||||
nsIFrame *endPrimaryFrame =
|
||||
shell->GetPrimaryFrameFor(endFrame->GetContent());
|
||||
rv = RenderedToContentOffset(endPrimaryFrame, aEndOffset, &endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> endParentNode(do_QueryInterface(endParentContent));
|
||||
NS_ENSURE_TRUE(endParentNode, NS_ERROR_FAILURE);
|
||||
rv = range->SetEnd(endParentNode, endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (aSelectionNum == rangeCount) { // Add successfully created new range
|
||||
return domSel->AddRange(range);
|
||||
@ -1708,56 +1708,96 @@ NS_IMETHODIMP nsHyperTextAccessible::RemoveSelection(PRInt32 aSelectionNum)
|
||||
return domSel->RemoveRange(range);
|
||||
}
|
||||
|
||||
// void nsIAccessibleText::
|
||||
// scrollSubstringTo(in long startIndex, in long endIndex,
|
||||
// in unsigned long scrollType);
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::ScrollSubstringTo(PRInt32 aStartIndex, PRInt32 aEndIndex,
|
||||
PRUint32 aScrollType)
|
||||
{
|
||||
PRInt32 startOffset = aStartIndex, endOffset = aEndIndex;
|
||||
nsIFrame *startFrame = nsnull, *endFrame = nsnull;
|
||||
nsCOMPtr<nsIAccessible> startAcc, endAcc;
|
||||
PRInt32 startOffset, endOffset;
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
|
||||
startFrame = GetPosAndText(startOffset, endOffset,
|
||||
nsnull, &endFrame, nsnull,
|
||||
getter_AddRefs(startAcc), getter_AddRefs(endAcc));
|
||||
if (!startFrame || !endFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
nsCOMPtr<nsIContent> startContent(startFrame->GetContent());
|
||||
|
||||
if (startFrame->GetType() == nsAccessibilityAtoms::textFrame) {
|
||||
nsresult rv = RenderedToContentOffset(startFrame, startOffset,
|
||||
&startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
startNode = do_QueryInterface(startContent);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> startParent(startContent->GetParent());
|
||||
NS_ENSURE_STATE(startParent);
|
||||
startOffset = startParent->IndexOf(startContent);
|
||||
startNode = do_QueryInterface(startParent);
|
||||
}
|
||||
NS_ENSURE_STATE(startNode);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> endNode;
|
||||
nsCOMPtr<nsIContent> endContent(endFrame->GetContent());
|
||||
|
||||
if (endFrame->GetType() == nsAccessibilityAtoms::textFrame) {
|
||||
nsresult rv = RenderedToContentOffset(endFrame, endOffset,
|
||||
nsresult rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex,
|
||||
getter_AddRefs(startNode),
|
||||
&startOffset,
|
||||
getter_AddRefs(endNode),
|
||||
&endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
endNode = do_QueryInterface(endContent);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> endParent(endContent->GetParent());
|
||||
NS_ENSURE_STATE(endParent);
|
||||
endOffset = endParent->IndexOf(endContent);
|
||||
endNode = do_QueryInterface(endParent);
|
||||
}
|
||||
NS_ENSURE_STATE(endNode);
|
||||
|
||||
return nsAccUtils::ScrollSubstringTo(GetFrame(), startNode, startOffset,
|
||||
endNode, endOffset, aScrollType);
|
||||
}
|
||||
|
||||
// void nsIAccessibleText::
|
||||
// scrollSubstringToPoint(in long startIndex, in long endIndex,
|
||||
// in unsigned long coordinateType,
|
||||
// in long x, in long y);
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::ScrollSubstringToPoint(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRUint32 aCoordinateType,
|
||||
PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntPoint coords;
|
||||
nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
|
||||
this, &coords);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 startOffset, endOffset;
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
|
||||
rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex,
|
||||
getter_AddRefs(startNode), &startOffset,
|
||||
getter_AddRefs(endNode), &endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsPresContext *presContext = frame->PresContext();
|
||||
|
||||
PRBool initialScrolled = PR_FALSE;
|
||||
nsIFrame *parentFrame = frame;
|
||||
while (parentFrame = parentFrame->GetParent()) {
|
||||
nsIScrollableFrame *scrollableFrame = nsnull;
|
||||
CallQueryInterface(parentFrame, &scrollableFrame);
|
||||
if (scrollableFrame) {
|
||||
if (!initialScrolled) {
|
||||
// Scroll substring to the given point. Turn the point into percents
|
||||
// relative scrollable area to use nsAccUtils::ScrollSubstringTo.
|
||||
nsIntRect frameRect = parentFrame->GetScreenRectExternal();
|
||||
PRInt32 devOffsetX = coords.x - frameRect.x;
|
||||
PRInt32 devOffsetY = coords.y - frameRect.y;
|
||||
|
||||
nsPoint offsetPoint(presContext->DevPixelsToAppUnits(devOffsetX),
|
||||
presContext->DevPixelsToAppUnits(devOffsetY));
|
||||
|
||||
nsSize size(parentFrame->GetSize());
|
||||
PRInt16 hPercent = offsetPoint.x * 100 / size.width;
|
||||
PRInt16 vPercent = offsetPoint.y * 100 / size.height;
|
||||
|
||||
rv = nsAccUtils::ScrollSubstringTo(GetFrame(), startNode, startOffset,
|
||||
endNode, endOffset,
|
||||
vPercent, hPercent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
initialScrolled = PR_TRUE;
|
||||
} else {
|
||||
// Substring was scrolled to the given point already inside its closest
|
||||
// scrollable area. If there are nested scrollable areas then make
|
||||
// sure we scroll lower areas to the given point inside currently
|
||||
// traversed scrollable area.
|
||||
nsAccUtils::ScrollFrameToPoint(parentFrame, frame, coords);
|
||||
}
|
||||
}
|
||||
frame = parentFrame;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsHyperTextAccessible::ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
|
||||
PRUint32 *aRenderedOffset)
|
||||
{
|
||||
@ -1803,4 +1843,58 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHyperTextAccessible::GetDOMPointByFrameOffset(nsIFrame *aFrame,
|
||||
PRInt32 aOffset,
|
||||
nsIAccessible *aAccessible,
|
||||
nsIDOMNode **aNode,
|
||||
PRInt32 *aNodeOffset)
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessible);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
|
||||
if (!aFrame) {
|
||||
// If the given frame is null then set offset after the DOM node of the
|
||||
// given accessible.
|
||||
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> DOMNode;
|
||||
accessNode->GetDOMNode(getter_AddRefs(DOMNode));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(DOMNode));
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsCOMPtr<nsIContent> parent(content->GetParent());
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
*aNodeOffset = parent->IndexOf(content) + 1;
|
||||
node = do_QueryInterface(parent);
|
||||
|
||||
} else if (aFrame->GetType() == nsAccessibilityAtoms::textFrame) {
|
||||
nsCOMPtr<nsIContent> content(aFrame->GetContent());
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell(GetPresShell());
|
||||
NS_ENSURE_STATE(shell);
|
||||
|
||||
nsIFrame *primaryFrame = shell->GetPrimaryFrameFor(content);
|
||||
nsresult rv = RenderedToContentOffset(primaryFrame, aOffset, aNodeOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
node = do_QueryInterface(content);
|
||||
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> content(aFrame->GetContent());
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsCOMPtr<nsIContent> parent(content->GetParent());
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
*aNodeOffset = parent->IndexOf(content);
|
||||
node = do_QueryInterface(parent);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aNode = node);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -123,6 +123,23 @@ public:
|
||||
nsIAccessible **aFinalAccessible = nsnull,
|
||||
PRBool aIsEndOffset = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Turn a start and end hypertext offsets into DOM range.
|
||||
*
|
||||
* @param aStartHTOffset [in] the given start hypertext offset
|
||||
* @param aEndHTOffset [in] the given end hypertext offset
|
||||
* @param aStartNode [out] start node of the range
|
||||
* @param aStartOffset [out] start offset of the range
|
||||
* @param aEndNode [out] end node of the range
|
||||
* @param aEndOffset [out] end offset of the range
|
||||
*/
|
||||
nsresult HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
||||
PRInt32 aEndHTOffset,
|
||||
nsIDOMNode **aStartNode,
|
||||
PRInt32 *aStartOffset,
|
||||
nsIDOMNode **aEndNode,
|
||||
PRInt32 *aEndOffset);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
|
||||
@ -203,6 +220,11 @@ protected:
|
||||
nsISelection **aDomSel = nsnull,
|
||||
nsCOMArray<nsIDOMRange>* aRanges = nsnull);
|
||||
nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);
|
||||
|
||||
// Helpers
|
||||
nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
|
||||
nsIAccessible *aAccessible,
|
||||
nsIDOMNode **aNode, PRInt32 *aNodeOffset);
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsHyperTextAccessible,
|
||||
|
@ -370,34 +370,18 @@ CAccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
|
||||
enum IA2CoordinateType aCoordinateType,
|
||||
enum IA2CoordinateType aCoordType,
|
||||
long aX, long aY)
|
||||
{
|
||||
GET_NSIACCESSIBLETEXT
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
PRInt32 startOffset = 0, endOffset = 0;
|
||||
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
|
||||
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
|
||||
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
|
||||
|
||||
// XXX: aEndIndex isn't used.
|
||||
textAcc->GetAttributeRange(aStartIndex, &startOffset, &endOffset,
|
||||
getter_AddRefs(accessible));
|
||||
if (!accessible)
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(accessible));
|
||||
if (!winAccessNode)
|
||||
return E_FAIL;
|
||||
|
||||
void **instancePtr = 0;
|
||||
winAccessNode->QueryNativeInterface(IID_IAccessible2, instancePtr);
|
||||
if (!instancePtr)
|
||||
return E_FAIL;
|
||||
|
||||
IAccessible2 *pAccessible2 = static_cast<IAccessible2*>(*instancePtr);
|
||||
HRESULT hr = pAccessible2->scrollToPoint(aCoordinateType, aX, aY);
|
||||
pAccessible2->Release();
|
||||
|
||||
return hr;
|
||||
nsresult rv = textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
|
||||
geckoCoordType, aX, aY);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
|
@ -1189,10 +1189,15 @@ nsAccessibleWrap::scrollTo(enum IA2ScrollType aScrollType)
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
nsAccessibleWrap::scrollToPoint(enum IA2CoordinateType coordinateType,
|
||||
long x, long y)
|
||||
nsAccessibleWrap::scrollToPoint(enum IA2CoordinateType aCoordType,
|
||||
long aX, long aY)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
|
||||
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
|
||||
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
|
||||
|
||||
return NS_SUCCEEDED(ScrollToPoint(geckoCoordType, aX, aY)) ?
|
||||
S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
|
Loading…
Reference in New Issue
Block a user