--- a/accessible/public/nsIAccessibleText.idl
+++ b/accessible/public/nsIAccessibleText.idl
@@ -40,17 +40,17 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
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;
const nsAccessibleTextBoundary BOUNDARY_WORD_START = 1;
const nsAccessibleTextBoundary BOUNDARY_WORD_END = 2;
const nsAccessibleTextBoundary BOUNDARY_SENTENCE_START = 3; // don't use, deprecated
const nsAccessibleTextBoundary BOUNDARY_SENTENCE_END = 4; // don't use, deprecated
const nsAccessibleTextBoundary BOUNDARY_LINE_START = 5;
@@ -175,25 +175,41 @@ interface nsIAccessibleText : nsISupport
void addSelection (in long startOffset, in long endOffset);
void removeSelection (in long selectionNum);
/**
* 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
- * character just past the last character of the
- * string.
- * @param aScrollType - defines how to scroll (see nsIAccessibleScrollType for
- * available constants).
+ * @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 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);
};
/*
Assumptions:
Using wstring (UCS2) instead of string encoded in UTF-8.
Multibyte encodings (or at least potentially multi-byte
encodings) would be preferred for the reasons cited above.
--- a/accessible/public/nsIAccessibleTypes.idl
+++ b/accessible/public/nsIAccessibleTypes.idl
@@ -85,18 +85,17 @@ interface nsIAccessibleScrollType : nsIS
* Scroll an object the minimum amount necessary in order for the entire
* frame to be visible (if possible).
*/
const unsigned long SCROLL_TYPE_ANYWHERE = 0x06;
};
/**
- * 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
{
/**
* The coordinates are relative to the screen.
*/
const unsigned long COORDTYPE_SCREEN_RELATIVE = 0x00;
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -56,17 +56,16 @@
#include "nsIDOMHTMLElement.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMViewCSS.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIFrame.h"
-#include "nsIScrollableFrame.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsITimer.h"
#include "nsRootAccessible.h"
@@ -436,81 +435,24 @@ nsAccessNode::ScrollTo(PRUint32 aScrollT
NS_IMETHODIMP
nsAccessNode::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
{
nsIFrame *frame = GetFrame();
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;
}
nsresult
nsAccessNode::MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode)
{
*aAccessNode = nsnull;
--- a/accessible/src/base/nsAccessibilityUtils.cpp
+++ b/accessible/src/base/nsAccessibilityUtils.cpp
@@ -35,16 +35,17 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsAccessibilityUtils.h"
#include "nsIAccessibleTypes.h"
#include "nsPIAccessible.h"
+#include "nsPIAccessNode.h"
#include "nsAccessibleEventData.h"
#include "nsAccessNode.h"
#include "nsARIAMap.h"
#include "nsIDocument.h"
#include "nsIDOMAbstractView.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentView.h"
@@ -52,16 +53,17 @@
#include "nsIDOMNodeList.h"
#include "nsIDOMRange.h"
#include "nsIDOMXULSelectCntrlEl.h"
#include "nsIDOMXULSelectCntrlItemEl.h"
#include "nsIDOMWindowInternal.h"
#include "nsIEventListenerManager.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
+#include "nsIScrollableFrame.h"
#include "nsIEventStateManager.h"
#include "nsISelection2.h"
#include "nsISelectionController.h"
#include "nsContentCID.h"
#include "nsComponentManagerUtils.h"
#include "nsIInterfaceRequestorUtils.h"
@@ -282,16 +284,29 @@ nsAccUtils::GetAncestorWithRole(nsIAcces
}
nsresult
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;
nsPresContext *presContext = aFrame->PresContext();
nsCOMPtr<nsIDOMRange> scrollToRange = do_CreateInstance(kRangeCID);
NS_ENSURE_TRUE(scrollToRange, NS_ERROR_FAILURE);
@@ -306,28 +321,52 @@ nsAccUtils::ScrollSubstringTo(nsIFrame *
selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY,
getter_AddRefs(selection1));
nsCOMPtr<nsISelection2> selection(do_QueryInterface(selection1));
if (selection) {
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();
}
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,
PRInt16 *aHPercent)
{
switch (aScrollType)
{
case nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT:
*aVPercent = NS_PRESSHELL_SCROLL_TOP;
@@ -354,16 +393,77 @@ nsAccUtils::ConvertScrollTypeToPercents(
*aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
break;
default:
*aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
*aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
}
}
+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)
{
nsIntPoint coords(0, 0);
nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
if (!treeItem)
return coords;
--- a/accessible/src/base/nsAccessibilityUtils.h
+++ b/accessible/src/base/nsAccessibilityUtils.h
@@ -36,16 +36,17 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsAccessibilityUtils_h_
#define nsAccessibilityUtils_h_
#include "nsAccessibilityAtoms.h"
#include "nsIAccessible.h"
+#include "nsIAccessNode.h"
#include "nsARIAMap.h"
#include "nsIDOMNode.h"
#include "nsIPersistentProperties2.h"
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsIDocShellTreeItem.h"
#include "nsPoint.h"
@@ -157,25 +158,68 @@ public:
* @param aEndOffset an offset inside the end node
* @param aScrollType the place a range should be scrolled to
*/
static nsresult ScrollSubstringTo(nsIFrame *aFrame,
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
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.
*/
static void ConvertScrollTypeToPercents(PRUint32 aScrollType,
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.
*
* @param - aNode - the DOM node hosted in the window.
*/
static nsIntPoint GetScreenCoordsForWindow(nsIDOMNode *aNode);
/**
* Return document shell tree item for the given DOM node.
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -56,16 +56,17 @@ REQUIRES = composer \
imglib2 \
intl \
js \
layout \
locale \
necko \
string \
thebes \
+ view \
webshell \
widget \
xpcom \
xpconnect \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
REQUIRES += editor
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -51,16 +51,17 @@
#include "nsIDOMDocumentView.h"
#include "nsIDOMRange.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMXULDocument.h"
#include "nsIEditingSession.h"
#include "nsIEditor.h"
#include "nsIFontMetrics.h"
#include "nsIFrame.h"
+#include "nsIScrollableFrame.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPlaintextEditor.h"
#include "nsISelection2.h"
#include "nsIServiceManager.h"
#include "nsTextFragment.h"
#include "gfxSkipChars.h"
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
@@ -660,16 +661,69 @@ nsresult nsHyperTextAccessible::DOMPoint
// If not at end of last text node, we will return the accessible we were in
NS_ADDREF(*aFinalAccessible = childAccessible);
}
}
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,
PRInt32 aFromOffset,
nsIAccessible *aFromAccessible,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRBool aNeedsStart)
@@ -1567,111 +1621,57 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
}
return DOMPointToHypertextOffset(endNode, endOffset, aEndOffset, nsnull, PR_TRUE);
}
/*
* 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);
nsCOMPtr<nsIDOMRange> range;
if (aSelectionNum == rangeCount) { // Add a range
range = do_CreateInstance(kRangeCID);
NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
}
else if (aSelectionNum < 0 || aSelectionNum > rangeCount) {
return NS_ERROR_INVALID_ARG;
}
else {
domSel->GetRangeAt(aSelectionNum, getter_AddRefs(range));
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));
-
- nsCOMPtr<nsIPresShell> shell = GetPresShell();
+ PRInt32 startOffset, endOffset;
+ nsCOMPtr<nsIDOMNode> startNode, endNode;
- 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);
- 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);
- }
+ rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset,
+ getter_AddRefs(startNode), &startOffset,
+ getter_AddRefs(endNode), &endOffset);
+ NS_ENSURE_SUCCESS(rv, rv);
- if (isOnlyCaret) {
- rv = range->Collapse(PR_TRUE);
- 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);
- }
+ rv = range->SetStart(startNode, startOffset);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = isOnlyCaret ? range->Collapse(PR_TRUE) :
+ range->SetEnd(endNode, endOffset);
+ NS_ENSURE_SUCCESS(rv, rv);
if (aSelectionNum == rangeCount) { // Add successfully created new range
return domSel->AddRange(range);
}
return NS_OK;
}
/*
@@ -1703,66 +1703,106 @@ NS_IMETHODIMP nsHyperTextAccessible::Rem
if (aSelectionNum < 0 || aSelectionNum >= rangeCount)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIDOMRange> range;
domSel->GetRangeAt(aSelectionNum, getter_AddRefs(range));
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;
-
- 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());
+ PRInt32 startOffset, endOffset;
+ nsCOMPtr<nsIDOMNode> startNode, endNode;
- 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,
- &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);
+ nsresult rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex,
+ getter_AddRefs(startNode),
+ &startOffset,
+ getter_AddRefs(endNode),
+ &endOffset);
+ NS_ENSURE_SUCCESS(rv, rv);
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)
{
NS_ASSERTION(aFrame->GetType() == nsAccessibilityAtoms::textFrame,
"Need text frame for offset conversion");
NS_ASSERTION(aFrame->GetPrevContinuation() == nsnull,
"Call on primary frame only");
@@ -1798,9 +1838,63 @@ nsresult nsHyperTextAccessible::Rendered
PRUint32 ourRenderedStart = iter.GetSkippedOffset();
PRInt32 ourContentStart = iter.GetOriginalOffset();
*aContentOffset = iter.ConvertSkippedToOriginal(aRenderedOffset + ourRenderedStart) - ourContentStart;
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;
+}
+
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -118,16 +118,33 @@ public:
* by the offset returned is at [offset]. If the passed-in offset in inside a
* descendant, then the returned offset will be on the relevant embedded object char.
*/
nsresult DOMPointToHypertextOffset(nsIDOMNode* aNode, PRInt32 aNodeOffset,
PRInt32 *aHypertextOffset,
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
* @param aType, eGetBefore, eGetAt, eGetAfter
* @param aBoundaryType, char/word-start/word-end/line-start/line-end/paragraph/attribute
* @param aOffset, offset into the hypertext to start from
* @param *aStartOffset, the resulting start offset for the returned substring
* @param *aEndOffset, the resulting end offset for the returned substring
@@ -198,15 +215,20 @@ protected:
* @param aSelCon The selection controller for the current hyper text, or nsnull if not needed
* @param aDomSel The selection interface for the current hyper text, or nsnull if not needed
* @param aRanges The selected ranges within the current subtree, or nsnull if not needed
*/
nsresult GetSelections(nsISelectionController **aSelCon,
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,
NS_HYPERTEXTACCESSIBLE_IMPL_CID)
#endif // _nsHyperTextAccessible_H_
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/CAccessibleText.cpp
@@ -365,44 +365,28 @@ CAccessibleText::scrollSubstringTo(long
GET_NSIACCESSIBLETEXT
nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
return NS_FAILED(rv) ? E_FAIL : S_OK;
}
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;
-
- // XXX: aEndIndex isn't used.
- textAcc->GetAttributeRange(aStartIndex, &startOffset, &endOffset,
- getter_AddRefs(accessible));
- if (!accessible)
- return E_FAIL;
+ PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
+ nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
+ nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
- 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
CAccessibleText::get_newText(IA2TextSegment *aNewText)
{
return GetModifiedText(PR_TRUE, aNewText);
}
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1184,20 +1184,25 @@ STDMETHODIMP
nsAccessibleWrap::scrollTo(enum IA2ScrollType aScrollType)
{
if (NS_SUCCEEDED(ScrollTo(aScrollType)))
return S_OK;
return E_FAIL;
}
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
nsAccessibleWrap::get_groupPosition(long *aGroupLevel,
long *aSimilarItemsInGroup,
long *aPositionInGroup)
{
PRInt32 groupLevel = 0;