Bug 630001 - Stop usage of nsIFrame::GetRenderedText in GetTextAt/Before/After for boundary char, r=fer, a=betaN

This commit is contained in:
Alexander Surkov 2011-02-03 22:29:12 +08:00
parent 1621463125
commit 5cdd07e1fa
5 changed files with 202 additions and 173 deletions

View File

@ -483,21 +483,13 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
if (IsDefunct())
return NS_ERROR_FAILURE;
if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
aStartOffset = CharacterCount();
else if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
GetCaretOffset(&aStartOffset);
if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
aEndOffset = CharacterCount();
else if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
GetCaretOffset(&aEndOffset);
PRInt32 startChildIdx = GetChildIndexAtOffset(aStartOffset);
PRInt32 startOffset = ConvertMagicOffset(aStartOffset);
PRInt32 startChildIdx = GetChildIndexAtOffset(startOffset);
if (startChildIdx == -1)
return NS_ERROR_INVALID_ARG;
PRInt32 endChildIdx = GetChildIndexAtOffset(aEndOffset);
PRInt32 endOffset = ConvertMagicOffset(aEndOffset);
PRInt32 endChildIdx = GetChildIndexAtOffset(endOffset);
if (endChildIdx == -1)
return NS_ERROR_INVALID_ARG;
@ -506,8 +498,8 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(childOffset != -1);
nsAccessible* child = GetChildAt(startChildIdx);
child->AppendTextTo(aText, aStartOffset - childOffset,
aEndOffset - aStartOffset);
child->AppendTextTo(aText, startOffset - childOffset,
endOffset - startOffset);
return NS_OK;
}
@ -516,7 +508,7 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(startChildOffset != -1);
nsAccessible* startChild = GetChildAt(startChildIdx);
startChild->AppendTextTo(aText, aStartOffset - startChildOffset);
startChild->AppendTextTo(aText, startOffset - startChildOffset);
for (PRInt32 childIdx = startChildIdx + 1; childIdx < endChildIdx; childIdx++) {
nsAccessible* child = GetChildAt(childIdx);
@ -527,7 +519,7 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(endChildOffset != -1);
nsAccessible* endChild = GetChildAt(endChildIdx);
endChild->AppendTextTo(aText, 0, aEndOffset - endChildOffset);
endChild->AppendTextTo(aText, 0, endOffset - endChildOffset);
return NS_OK;
}
@ -552,20 +544,19 @@ NS_IMETHODIMP nsHyperTextAccessible::GetCharacterCount(PRInt32 *aCharacterCount)
*/
NS_IMETHODIMP nsHyperTextAccessible::GetCharacterAtOffset(PRInt32 aOffset, PRUnichar *aCharacter)
{
NS_ENSURE_ARG_POINTER(aCharacter);
*aCharacter = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsAutoString text;
nsresult rv = GetText(aOffset, aOffset + 1, text);
if (NS_FAILED(rv)) {
return rv;
nsAutoString character;
if (GetCharAt(aOffset, eGetAt, character)) {
*aCharacter = character.First();
return NS_OK;
}
if (text.IsEmpty()) {
return NS_ERROR_FAILURE;
}
*aCharacter = text.First();
return NS_OK;
return NS_ERROR_INVALID_ARG;
}
nsAccessible*
@ -1092,18 +1083,33 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
NS_IMETHODIMP nsHyperTextAccessible::GetTextBeforeOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetBefore, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
NS_IMETHODIMP nsHyperTextAccessible::GetTextAtOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetAt, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
NS_IMETHODIMP nsHyperTextAccessible::GetTextAfterOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
@ -2164,6 +2170,29 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
////////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible public
bool
nsHyperTextAccessible::GetCharAt(PRInt32 aOffset, EGetTextType aShift,
nsAString& aChar, PRInt32* aStartOffset,
PRInt32* aEndOffset)
{
aChar.Truncate();
PRInt32 offset = ConvertMagicOffset(aOffset) + static_cast<PRInt32>(aShift);
PRInt32 childIdx = GetChildIndexAtOffset(offset);
if (childIdx == -1)
return false;
nsAccessible* child = GetChildAt(childIdx);
child->AppendTextTo(aChar, offset - GetChildOffset(childIdx), 1);
if (aStartOffset)
*aStartOffset = offset;
if (aEndOffset)
*aEndOffset = aChar.IsEmpty() ? offset : offset + 1;
return true;
}
PRInt32
nsHyperTextAccessible::GetChildOffset(PRUint32 aChildIndex,
PRBool aInvalidateAfter)

View File

@ -210,6 +210,20 @@ public:
return GetChildOffset(GetChildCount());
}
/**
* Get a character before/at/after the given offset.
*
* @param aOffset [in] the given offset
* @param aShift [in] specifies whether to get a char before/at/after
* offset
* @param aChar [out] the character
* @param aStartOffset [out, optional] the start offset of the character
* @param aEndOffset [out, optional] the end offset of the character
* @return false if offset at the given shift is out of range
*/
bool GetCharAt(PRInt32 aOffset, EGetTextType aShift, nsAString& aChar,
PRInt32* aStartOffset = nsnull, PRInt32* aEndOffset = nsnull);
/**
* Return text offset of the given child accessible within hypertext
* accessible.
@ -251,6 +265,23 @@ public:
protected:
// nsHyperTextAccessible
/**
* Transform magic offset into text offset.
*/
inline PRInt32 ConvertMagicOffset(PRInt32 aOffset)
{
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
return CharacterCount();
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
PRInt32 caretOffset = -1;
GetCaretOffset(&caretOffset);
return caretOffset;
}
return aOffset;
}
/*
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
* @param aType, eGetBefore, eGetAt, eGetAfter

View File

@ -43,6 +43,28 @@ function testText(aIDs, aStartOffset, aEndOffset, aText)
}
}
/**
* Test getTextAtOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character at it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharAtOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextAtOffset, "getTextAtOffset ");
}
}
/**
* Test getTextAtOffset function over different elements
*
@ -75,6 +97,28 @@ function testTextAtOffset(aOffset, aBoundaryType, aText,
}
}
/**
* Test getTextAfterOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character after it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharAfterOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextAfterOffset, "getTextAfterOffset ");
}
}
/**
* Test getTextAfterOffset function over different elements
*
@ -88,7 +132,6 @@ function testTextAtOffset(aOffset, aBoundaryType, aText,
* kTodo or kOk for returned text
* kTodo or kOk for returned start offset
* kTodo or kOk for returned offset result
*
*/
function testTextAfterOffset(aOffset, aBoundaryType,
aText, aStartOffset, aEndOffset)
@ -107,6 +150,28 @@ function testTextAfterOffset(aOffset, aBoundaryType,
}
}
/**
* Test getTextBeforeOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character before it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharBeforeOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextBeforeOffset, "getTextBeforeOffset ");
}
}
/**
* Test getTextBeforeOffset function over different elements
*

View File

@ -37,27 +37,23 @@
////////////////////////////////////////////////////////////////////////
// getTextAfterOffset
var IDs = [ "input", "div", "editable", "textarea" ];
var regularIDs = [ "input", "div", "editable" ];
// BOUNDARY_CHAR
testTextAfterOffset(0, BOUNDARY_CHAR, "e", 1, 2,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(1, BOUNDARY_CHAR, "l", 2, 3,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(14, BOUNDARY_CHAR, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testCharAfterOffset(IDs, 0, "e", 1, 2);
testCharAfterOffset(IDs, 1, "l", 2, 3);
testCharAfterOffset(regularIDs, 14, "", 15, 15);
testCharAfterOffset("textarea", 14, "\n", 15, 16);
// XXX: why are 15/15 expected? there's no 16 offset we are trying to
// get an offset for?
testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
"editable", kOk, kTodo, kTodo);
testCharAfterOffset("textarea", 15, "", 16, 16);
// BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9,
@ -210,27 +206,13 @@
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextBeforeOffset(0, BOUNDARY_CHAR, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_CHAR, "h", 0, 1,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(14, BOUNDARY_CHAR, "n", 13, 14,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(15, BOUNDARY_CHAR, "d", 14, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharBeforeOffset(IDs, 0, "", 0, 0);
testCharBeforeOffset(IDs, 1, "h", 0, 1);
testCharBeforeOffset(IDs, 14, "n", 13, 14);
testCharBeforeOffset(IDs, 15, "d", 14, 15);
// BOUNDARY_WORD_START
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
@ -383,27 +365,17 @@
////////////////////////////////////////////////////////////////////////
// getTextAtOffset
IDs = [ "input", "div", "editable", "textarea" ];
regularIDs = [ "input", "div", "editable" ];
// BOUNDARY_CHAR
testTextAtOffset(0, BOUNDARY_CHAR, "h", 0, 1,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(1, BOUNDARY_CHAR, "e", 1, 2,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(14, BOUNDARY_CHAR, "d", 14, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(15, BOUNDARY_CHAR, "", 15, 15,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharAtOffset(IDs, 0, "h", 0, 1);
testCharAtOffset(IDs, 1, "e", 1, 2);
testCharAtOffset(IDs, 14, "d", 14, 15);
testCharAtOffset(regularIDs, 15, "", 15, 15);
testCharAtOffset("textarea", 15, "\n", 15, 16);
testCharAtOffset("textarea", 16, "", 16, 16);
// BOUNDARY_WORD_START
testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6,

View File

@ -41,62 +41,20 @@
////////////////////////////////////////////////////////////////////////
// getTextAfterOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextAfterOffset(0, BOUNDARY_CHAR, "r", 1, 2,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(1, BOUNDARY_CHAR, "a", 2, 3,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(4, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_CHAR, "S", 6, 7,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_CHAR, " ", 10, 11,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(10, BOUNDARY_CHAR, "R", 11, 12,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_CHAR, " ", 17, 18,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(17, BOUNDARY_CHAR, " ", 18, 19,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(18, BOUNDARY_CHAR, "r", 19, 20,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testCharAfterOffset(IDs, 0, "r", 1, 2);
testCharAfterOffset(IDs, 1, "a", 2, 3);
testCharAfterOffset(IDs, 4, " ", 5, 6);
testCharAfterOffset(IDs, 5, "S", 6, 7);
testCharAfterOffset(IDs, 8, " ", 9, 10);
testCharAfterOffset(IDs, 9, " ", 10, 11);
testCharAfterOffset(IDs, 10, "R", 11, 12);
testCharAfterOffset(IDs, 15, " ", 16, 17);
testCharAfterOffset(IDs, 16, " ", 17, 18);
testCharAfterOffset(IDs, 17, " ", 18, 19);
testCharAfterOffset(IDs, 18, "r", 19, 20);
// BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11,
@ -225,42 +183,16 @@
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextBeforeOffset(0, BOUNDARY_CHAR, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_CHAR, "B", 0, 1,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(6, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(10, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(11, BOUNDARY_CHAR, " ", 10, 11,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(17, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(19, BOUNDARY_CHAR, " ", 18, 19,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharBeforeOffset(IDs, 0, "", 0, 0);
testCharBeforeOffset(IDs, 1, "B", 0, 1);
testCharBeforeOffset(IDs, 6, " ", 5, 6);
testCharBeforeOffset(IDs, 10, " ", 9, 10);
testCharBeforeOffset(IDs, 11, " ", 10, 11);
testCharBeforeOffset(IDs, 17, " ", 16, 17);
testCharBeforeOffset(IDs, 19, " ", 18, 19);
// BOUNDARY_WORD_START
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,