diff --git a/accessible/src/html/nsHyperTextAccessible.cpp b/accessible/src/html/nsHyperTextAccessible.cpp index 1e664f666b51..e65d4b91f1f8 100644 --- a/accessible/src/html/nsHyperTextAccessible.cpp +++ b/accessible/src/html/nsHyperTextAccessible.cpp @@ -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(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) diff --git a/accessible/src/html/nsHyperTextAccessible.h b/accessible/src/html/nsHyperTextAccessible.h index 81ac7fefe7cf..be04ae5209c4 100644 --- a/accessible/src/html/nsHyperTextAccessible.h +++ b/accessible/src/html/nsHyperTextAccessible.h @@ -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 diff --git a/accessible/tests/mochitest/text.js b/accessible/tests/mochitest/text.js index 3734ff25574e..ec20bf84254e 100644 --- a/accessible/tests/mochitest/text.js +++ b/accessible/tests/mochitest/text.js @@ -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 * diff --git a/accessible/tests/mochitest/text/test_singleline.html b/accessible/tests/mochitest/text/test_singleline.html index d16b548a20c1..6c10b6fa4d78 100644 --- a/accessible/tests/mochitest/text/test_singleline.html +++ b/accessible/tests/mochitest/text/test_singleline.html @@ -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, diff --git a/accessible/tests/mochitest/text/test_whitespaces.html b/accessible/tests/mochitest/text/test_whitespaces.html index 98e61d02491b..e6fa5b6110ed 100644 --- a/accessible/tests/mochitest/text/test_whitespaces.html +++ b/accessible/tests/mochitest/text/test_whitespaces.html @@ -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,