summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/text
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/text')
-rw-r--r--accessible/tests/mochitest/text/a11y.ini16
-rw-r--r--accessible/tests/mochitest/text/doc.html9
-rw-r--r--accessible/tests/mochitest/text/test_atcaretoffset.html455
-rw-r--r--accessible/tests/mochitest/text/test_charboundary.html140
-rw-r--r--accessible/tests/mochitest/text/test_doc.html42
-rw-r--r--accessible/tests/mochitest/text/test_dynamic.html88
-rw-r--r--accessible/tests/mochitest/text/test_general.xul80
-rw-r--r--accessible/tests/mochitest/text/test_gettext.html112
-rw-r--r--accessible/tests/mochitest/text/test_hypertext.html147
-rw-r--r--accessible/tests/mochitest/text/test_lineboundary.html265
-rw-r--r--accessible/tests/mochitest/text/test_passwords.html60
-rw-r--r--accessible/tests/mochitest/text/test_selection.html101
-rw-r--r--accessible/tests/mochitest/text/test_wordboundary.html291
-rw-r--r--accessible/tests/mochitest/text/test_words.html133
14 files changed, 1939 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/text/a11y.ini b/accessible/tests/mochitest/text/a11y.ini
new file mode 100644
index 000000000..96283a736
--- /dev/null
+++ b/accessible/tests/mochitest/text/a11y.ini
@@ -0,0 +1,16 @@
+[DEFAULT]
+support-files = doc.html
+ !/accessible/tests/mochitest/*.js
+
+[test_atcaretoffset.html]
+[test_charboundary.html]
+[test_doc.html]
+[test_dynamic.html]
+[test_general.xul]
+[test_gettext.html]
+[test_hypertext.html]
+[test_lineboundary.html]
+[test_passwords.html]
+[test_selection.html]
+[test_wordboundary.html]
+[test_words.html]
diff --git a/accessible/tests/mochitest/text/doc.html b/accessible/tests/mochitest/text/doc.html
new file mode 100644
index 000000000..d57406c22
--- /dev/null
+++ b/accessible/tests/mochitest/text/doc.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="application/javascript">
+ document.documentElement.appendChild(document.createTextNode("outbody"));
+ </script>
+</head>
+<body>inbody</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_atcaretoffset.html b/accessible/tests/mochitest/text/test_atcaretoffset.html
new file mode 100644
index 000000000..330298a62
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Test: nsIAccessibleText getText* functions at caret offset</title>
+
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../role.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ //gA11yEventDumpToConsole = true; // debugging
+
+ function traverseTextByLines(aQueue, aID, aLines)
+ {
+ var wholeText = "";
+ for (var i = 0; i < aLines.length ; i++)
+ wholeText += aLines[i][0] + aLines[i][1];
+
+ var baseInvokerFunc = synthClick;
+ var charIter = new charIterator(wholeText, aLines);
+ //charIter.debugOffset = 10; // enable to run tests at given offset only
+
+ while (charIter.next()) {
+ aQueue.push(new tmpl_moveTo(aID, baseInvokerFunc, wholeText, charIter));
+ baseInvokerFunc = synthRightKey;
+ }
+ }
+
+ /**
+ * Used to get test list for each traversed character.
+ */
+ function charIterator(aWholeText, aLines)
+ {
+ this.next = function charIterator_next()
+ {
+ // Don't increment offset if we are at end of the wrapped line
+ // (offset is shared between end of this line and start of next line).
+ if (this.mAtWrappedLineEnd) {
+ this.mAtWrappedLineEnd = false;
+ this.mLine = this.mLine.nextLine;
+ return true;
+ }
+
+ this.mOffset++;
+ if (this.mOffset > aWholeText.length)
+ return false;
+
+ var nextLine = this.mLine.nextLine;
+ if (!nextLine.isFakeLine() && this.mOffset == nextLine.start) {
+ if (nextLine.start == this.mLine.end)
+ this.mAtWrappedLineEnd = true;
+ else
+ this.mLine = nextLine;
+ }
+
+ return true;
+ }
+
+ Object.defineProperty(this, "offset", { get: function()
+ { return this.mOffset; }
+ });
+
+ Object.defineProperty(this, "offsetDescr", { get: function()
+ {
+ return this.mOffset + " offset (" + this.mLine.number + " line, " +
+ (this.mOffset - this.mLine.start) + " offset on the line)";
+ }
+ });
+
+ Object.defineProperty(this, "tests", { get: function()
+ {
+ // Line boundary tests.
+ var cLine = this.mLine;
+ var pLine = cLine.prevLine;
+ var ppLine = pLine.prevLine;
+ var nLine = cLine.nextLine;
+ var nnLine = nLine.nextLine;
+
+ var lineTests = [
+ [ testTextBeforeOffset, BOUNDARY_LINE_START, pLine.start, cLine.start],
+ [ testTextBeforeOffset, BOUNDARY_LINE_END, ppLine.end, pLine.end],
+ [ testTextAtOffset, BOUNDARY_LINE_START, cLine.start, nLine.start],
+ [ testTextAtOffset, BOUNDARY_LINE_END, pLine.end, cLine.end],
+ [ testTextAfterOffset, BOUNDARY_LINE_START, nLine.start, nnLine.start],
+ [ testTextAfterOffset, BOUNDARY_LINE_END, cLine.end, nLine.end]
+ ];
+
+ // Word boundary tests.
+ var cWord = this.mLine.firstWord;
+ var nWord = cWord.nextWord, pWord = cWord.prevWord;
+
+ // The current word is a farthest word starting at or after the offset.
+ if (this.mOffset >= nWord.start) {
+ while (this.mOffset >= nWord.start && !this.mLine.isLastWord(cWord)) {
+ cWord = nWord;
+ nWord = nWord.nextWord;
+ }
+ pWord = cWord.prevWord;
+
+ } else if (this.mOffset < cWord.start) {
+ while (this.mOffset < cWord.start) {
+ cWord = pWord;
+ pWord = pWord.prevWord;
+ }
+ nWord = cWord.nextWord;
+ }
+
+ var nnWord = nWord.nextWord, ppWord = pWord.prevWord;
+
+ var isAfterWordEnd =
+ this.mOffset > cWord.end || cWord.line != this.mLine;
+ var isAtOrAfterWordEnd = (this.mOffset >= cWord.end);
+ var useNextWordForAtWordEnd =
+ isAtOrAfterWordEnd && this.mOffset != aWholeText.length;
+
+ var wordTests = [
+ [ testTextBeforeOffset, BOUNDARY_WORD_START,
+ pWord.start, cWord.start ],
+ [ testTextBeforeOffset, BOUNDARY_WORD_END,
+ (isAfterWordEnd ? pWord : ppWord).end,
+ (isAfterWordEnd ? cWord : pWord).end ],
+ [ testTextAtOffset, BOUNDARY_WORD_START,
+ cWord.start, nWord.start ],
+ [ testTextAtOffset, BOUNDARY_WORD_END,
+ (useNextWordForAtWordEnd ? cWord : pWord).end,
+ (useNextWordForAtWordEnd ? nWord : cWord).end ],
+ [ testTextAfterOffset, BOUNDARY_WORD_START,
+ nWord.start, nnWord.start ],
+ [ testTextAfterOffset, BOUNDARY_WORD_END,
+ (isAfterWordEnd ? nWord : cWord).end,
+ (isAfterWordEnd ? nnWord : nWord).end ]
+ ];
+
+ // Character boundary tests.
+ var prevOffset = this.offset > 1 ? this.offset - 1 : 0;
+ var nextOffset = this.offset >= aWholeText.length ?
+ this.offset : this.offset + 1;
+ var nextAfterNextOffset = nextOffset >= aWholeText.length ?
+ nextOffset : nextOffset + 1;
+
+ var charTests = [
+ [ testTextBeforeOffset, BOUNDARY_CHAR,
+ prevOffset, this.offset ],
+ [ testTextAtOffset, BOUNDARY_CHAR,
+ this.offset,
+ this.mAtWrappedLineEnd ? this.offset : nextOffset ],
+ [ testTextAfterOffset, BOUNDARY_CHAR,
+ this.mAtWrappedLineEnd ? this.offset : nextOffset,
+ this.mAtWrappedLineEnd ? nextOffset : nextAfterNextOffset ]
+ ];
+
+ return lineTests.concat(wordTests.concat(charTests));
+ }
+ });
+
+ Object.defineProperty(this, "failures", { get: function()
+ {
+ if (this.mOffset == this.mLine.start)
+ return this.mLine.lineStartFailures;
+ if (this.mOffset == this.mLine.end)
+ return this.mLine.lineEndFailures;
+ return [];
+ }
+ });
+
+ this.mOffset = -1;
+ this.mLine = new line(aWholeText, aLines, 0);
+ this.mAtWrappedLineEnd = false;
+ this.mWord = this.mLine.firstWord;
+ }
+
+ /**
+ * A line object. Allows to navigate by lines and by words.
+ */
+ function line(aWholeText, aLines, aIndex)
+ {
+ Object.defineProperty(this, "prevLine", { get: function()
+ {
+ return new line(aWholeText, aLines, aIndex - 1);
+ }
+ });
+ Object.defineProperty(this, "nextLine", { get: function()
+ {
+ return new line(aWholeText, aLines, aIndex + 1);
+ }
+ });
+
+ Object.defineProperty(this, "start", { get: function()
+ {
+ if (aIndex < 0)
+ return 0;
+
+ if (aIndex >= aLines.length)
+ return aWholeText.length;
+
+ return aLines[aIndex][2];
+ }
+ });
+ Object.defineProperty(this, "end", { get: function()
+ {
+ if (aIndex < 0)
+ return 0;
+
+ if (aIndex >= aLines.length)
+ return aWholeText.length;
+
+ return aLines[aIndex][3];
+ }
+ });
+
+ Object.defineProperty(this, "number", { get: function()
+ { return aIndex; }
+ });
+ Object.defineProperty(this, "wholeText", { get: function()
+ { return aWholeText; }
+ });
+ this.isFakeLine = function line_isFakeLine()
+ {
+ return aIndex < 0 || aIndex >= aLines.length;
+ }
+
+ Object.defineProperty(this, "lastWord", { get: function()
+ {
+ if (aIndex < 0)
+ return new word(this, [], -1);
+ if (aIndex >= aLines.length)
+ return new word(this, [], 0);
+
+ var words = aLines[aIndex][4].words;
+ return new word(this, words, words.length - 2);
+ }
+ });
+ Object.defineProperty(this, "firstWord", { get: function()
+ {
+ if (aIndex < 0)
+ return new word(this, [], -1);
+ if (aIndex >= aLines.length)
+ return new word(this, [], 0);
+
+ var words = aLines[aIndex][4].words;
+ return new word(this, words, 0);
+ }
+ });
+
+ this.isLastWord = function line_isLastWord(aWord)
+ {
+ var lastWord = this.lastWord;
+ return lastWord.start == aWord.start && lastWord.end == aWord.end;
+ }
+
+ Object.defineProperty(this, "lineStartFailures", { get: function()
+ {
+ if (aIndex < 0 || aIndex >= aLines.length)
+ return [];
+
+ return aLines[aIndex][4].lsf || [];
+ }
+ });
+ Object.defineProperty(this, "lineEndFailures", { get: function()
+ {
+ if (aIndex < 0 || aIndex >= aLines.length)
+ return [];
+
+ return aLines[aIndex][4].lef || [];
+ }
+ });
+ }
+
+ /**
+ * A word object. Allows to navigate by words.
+ */
+ function word(aLine, aWords, aIndex)
+ {
+ Object.defineProperty(this, "prevWord", { get: function()
+ {
+ if (aIndex >= 2)
+ return new word(aLine, aWords, aIndex - 2);
+
+ var prevLineLastWord = aLine.prevLine.lastWord;
+ if (this.start == prevLineLastWord.start && !this.isFakeStartWord())
+ return prevLineLastWord.prevWord;
+ return prevLineLastWord;
+ }
+ });
+ Object.defineProperty(this, "nextWord", { get: function()
+ {
+ if (aIndex + 2 < aWords.length)
+ return new word(aLine, aWords, aIndex + 2);
+
+ var nextLineFirstWord = aLine.nextLine.firstWord;
+ if (this.end == nextLineFirstWord.end && !this.isFakeEndWord())
+ return nextLineFirstWord.nextWord;
+ return nextLineFirstWord;
+ }
+ });
+
+ Object.defineProperty(this, "line", { get: function() { return aLine; } });
+
+ Object.defineProperty(this, "start", { get: function()
+ {
+ if (this.isFakeStartWord())
+ return 0;
+
+ if (this.isFakeEndWord())
+ return aLine.end;
+ return aWords[aIndex];
+ }
+ });
+ Object.defineProperty(this, "end", { get: function()
+ {
+ if (this.isFakeStartWord())
+ return 0;
+
+ return this.isFakeEndWord() ? aLine.end : aWords[aIndex + 1];
+ }
+ });
+
+ this.toString = function word_toString()
+ {
+ var start = this.start, end = this.end;
+ return "'" + aLine.wholeText.substring(start, end) +
+ "' at [" + start + ", " + end + "]";
+ }
+
+ this.isFakeStartWord = function() { return aIndex < 0; }
+ this.isFakeEndWord = function() { return aIndex >= aWords.length; }
+ }
+
+ /**
+ * A template invoker to move through the text.
+ */
+ function tmpl_moveTo(aID, aInvokerFunc, aWholeText, aCharIter)
+ {
+ this.offset = aCharIter.offset;
+
+ var checker = new caretMoveChecker(this.offset, aID);
+ this.__proto__ = new (aInvokerFunc)(aID, checker);
+
+ this.finalCheck = function genericMoveTo_finalCheck()
+ {
+ if (this.noTests())
+ return;
+
+ for (var i = 0; i < this.tests.length; i++) {
+ var func = this.tests[i][0];
+ var boundary = this.tests[i][1];
+ var startOffset = this.tests[i][2];
+ var endOffset = this.tests[i][3];
+ var text = aWholeText.substring(startOffset, endOffset);
+
+ var isOk1 = kOk, isOk2 = kOk, isOk3 = kOk;
+ for (var fIdx = 0; fIdx < this.failures.length; fIdx++) {
+ var failure = this.failures[fIdx];
+ if (func.name.indexOf(failure[0]) != -1 && boundary == failure[1]) {
+ isOk1 = failure[2];
+ isOk2 = failure[3];
+ isOk3 = failure[4];
+ }
+ }
+
+ func.call(null, kCaretOffset, boundary, text, startOffset, endOffset,
+ aID, isOk1, isOk2, isOk3);
+ }
+ }
+
+ this.getID = function genericMoveTo_getID()
+ {
+ return "move to " + this.offsetDescr;
+ }
+
+ this.noTests = function tmpl_moveTo_noTests()
+ {
+ return ("debugOffset" in aCharIter) &&
+ (aCharIter.debugOffset != this.offset);
+ }
+
+ this.offsetDescr = aCharIter.offsetDescr;
+ this.tests = this.noTests() ? null : aCharIter.tests;
+ this.failures = aCharIter.failures;
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ gQueue = new eventQueue();
+
+ // __a__w__o__r__d__\n
+ // 0 1 2 3 4 5
+ // __t__w__o__ (soft line break)
+ // 6 7 8 9
+ // __w__o__r__d__s
+ // 10 11 12 13 14 15
+
+ traverseTextByLines(gQueue, "textarea",
+ [ [ "aword", "\n", 0, 5, { words: [ 0, 5 ] } ],
+ [ "two ", "", 6, 10, { words: [ 6, 9 ] } ],
+ [ "words", "", 10, 15, { words: [ 10, 15 ] } ]
+ ] );
+
+ var line4 = [ // "riend "
+ [ "TextBeforeOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ],
+ [ "TextAfterOffset", BOUNDARY_WORD_END, kTodo, kTodo, kTodo ]
+ ];
+ traverseTextByLines(gQueue, "ta_wrapped",
+ [ [ "hi ", "", 0, 3, { words: [ 0, 2 ] } ],
+ [ "hello ", "", 3, 9, { words: [ 3, 8 ] } ],
+ [ "my ", "", 9, 12, { words: [ 9, 11 ] } ],
+ [ "longf", "", 12, 17, { words: [ 12, 17 ] } ],
+ [ "riend ", "", 17, 23, { words: [ 17, 22 ], lsf: line4 } ],
+ [ "t sq ", "", 23, 28, { words: [ 23, 24, 25, 27 ] } ],
+ [ "t", "", 28, 29, { words: [ 28, 29 ] } ]
+ ] );
+
+ gQueue.invoke(); // will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="nsIAccessibleText getText related functions tests at caret offset"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=852021">
+ Bug 852021
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+
+ <textarea id="textarea" cols="5">aword
+two words</textarea>
+
+ <textarea id="ta_wrapped" cols="5">hi hello my longfriend t sq t</textarea>
+ </pre>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_charboundary.html b/accessible/tests/mochitest/text/test_charboundary.html
new file mode 100644
index 000000000..2fddcb5be
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_charboundary.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Char boundary text tests</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
+ var IDs = [ "i1", "d1", "e1", "t1" ];
+
+ testCharBeforeOffset(IDs, 0, "", 0, 0);
+ testCharBeforeOffset(IDs, 1, "h", 0, 1);
+ testCharBeforeOffset(IDs, 14, "n", 13, 14);
+ testCharBeforeOffset(IDs, 15, "d", 14, 15);
+
+ testCharAtOffset(IDs, 0, "h", 0, 1);
+ testCharAtOffset(IDs, 1, "e", 1, 2);
+ testCharAtOffset(IDs, 14, "d", 14, 15);
+ testCharAtOffset(IDs, 15, "", 15, 15);
+
+ testCharAfterOffset(IDs, 0, "e", 1, 2);
+ testCharAfterOffset(IDs, 1, "l", 2, 3);
+ testCharAfterOffset(IDs, 14, "", 15, 15);
+ testCharAfterOffset(IDs, 15, "", 15, 15);
+
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+
+ IDs = [ "i2", "d2", "e2", "t2" ];
+
+ 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);
+
+ testCharAtOffset(IDs, 0, "B", 0, 1);
+ testCharAtOffset(IDs, 1, "r", 1, 2);
+ testCharAtOffset(IDs, 5, " ", 5, 6);
+ testCharAtOffset(IDs, 9, " ", 9, 10);
+ testCharAtOffset(IDs, 10, " ", 10, 11);
+ testCharAtOffset(IDs, 17, " ", 17, 18);
+
+ 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);
+
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __o__n__e__w__o__r__d__\n
+ // 0 1 2 3 4 5 6 7
+ // __\n
+ // 8
+ // __t__w__o__ __w__o__r__d__s__\n
+ // 9 10 11 12 13 14 15 16 17 18
+
+ IDs = ["d3", "dbr3", "e3", "ebr3", "t3"];
+
+ testCharBeforeOffset(IDs, 8, "\n", 7, 8);
+ testCharBeforeOffset(IDs, 9, "\n", 8, 9);
+ testCharBeforeOffset(IDs, 10, "t", 9, 10);
+
+ testCharAtOffset(IDs, 7, "\n", 7, 8);
+ testCharAtOffset(IDs, 8, "\n", 8, 9);
+ testCharAtOffset(IDs, 9, "t", 9, 10);
+
+ testCharAfterOffset(IDs, 6, "\n", 7, 8);
+ testCharAfterOffset(IDs, 7, "\n", 8, 9);
+ testCharAfterOffset(IDs, 8, "t", 9, 10);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <input id="i1" value="hello my friend"/>
+ <div id="d1">hello my friend</div>
+ <div id="e1" contenteditable="true">hello my friend</div>
+ <textarea id="t1" contenteditable="true">hello my friend</textarea>
+
+ <input id="i2" value="Brave Sir Robin ran"/>
+ <pre>
+ <div id="d2">Brave Sir Robin ran</div>
+ <div id="e2" contenteditable="true">Brave Sir Robin ran</div>
+ </pre>
+ <textarea id="t2" cols="300">Brave Sir Robin ran</textarea>
+
+ <pre>
+ <div id="d3">oneword
+
+two words
+</div>
+ <div id="dbr3">oneword<br/><br/>two words<br/></div>
+ <div id="e3" contenteditable="true">oneword
+
+two words
+</div>
+ <div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/></div>
+ <textarea id="t3" cols="300">oneword
+
+two words</textarea>
+ </pre>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_doc.html b/accessible/tests/mochitest/text/test_doc.html
new file mode 100644
index 000000000..9c6788275
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_doc.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>nsIAccessibleText getText related function tests for document accessible</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+ <script type="application/javascript">
+
+ function doTest()
+ {
+ var iframeDoc = [ getNode("iframe").contentDocument ];
+ testCharacterCount(iframeDoc, 15);
+ testText(iframeDoc, 0, 15, "outbody inbody ");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="Elements appended outside the body aren't accessible"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <iframe id="iframe" src="doc.html"></iframe>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_dynamic.html b/accessible/tests/mochitest/text/test_dynamic.html
new file mode 100644
index 000000000..0e5d4394a
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_dynamic.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>nsIAccessibleText getText related function tests for tree mutations</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+
+ <script type="application/javascript">
+ function insertBefore(aId, aEl, aTextBefore, aTextAfter, aStartIdx, aEndIdx)
+ {
+ this.eventSeq = [
+ new invokerChecker(EVENT_REORDER, aId)
+ ];
+
+ this.invoke = function insertBefore_invoke()
+ {
+ testText(aId, 0, -1, aTextBefore);
+ getNode(aId).insertBefore(aEl, getNode(aId).firstChild);
+ }
+
+ this.finalCheck = function insertBefore_finalCheck()
+ {
+ testText(aId, aStartIdx, aEndIdx, aTextAfter);
+ }
+
+ this.getID = function insertTextBefore_getID() {
+ return "insert " + prettyName(aEl) + " before";
+ }
+ }
+
+ function insertTextBefore(aId, aTextBefore, aText)
+ {
+ var el = document.createTextNode(aText);
+ this.__proto__ = new insertBefore(aId, el, aTextBefore,
+ aText + aTextBefore, 0, -1)
+ }
+
+ function insertImgBefore(aId, aTextBefore)
+ {
+ var el = document.createElement("img");
+ el.setAttribute("src", "../moz.png");
+ el.setAttribute("alt", "mozilla");
+
+ this.__proto__ = new insertBefore(aId, el, aTextBefore,
+ kEmbedChar + aTextBefore, 0, -1)
+ }
+
+ function insertTextBefore2(aId)
+ {
+ var el = document.createTextNode("hehe");
+ this.__proto__ = new insertBefore(aId, el, "ho", "ho", 4, -1)
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ gQueue = new eventQueue();
+ gQueue.push(new insertTextBefore("c1", "ho", "ha"));
+ gQueue.push(new insertImgBefore("c1", "haho"));
+ gQueue.push(new insertImgBefore("c2", kEmbedChar));
+ gQueue.push(new insertTextBefore2("c3"));
+ gQueue.invoke(); // will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="c1">ho</div>
+ <div id="c2"><img src="../moz.png" alt="mozilla"></div>
+ <div id="c3">ho</div>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_general.xul b/accessible/tests/mochitest/text/test_general.xul
new file mode 100644
index 000000000..0bd720e28
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_general.xul
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Tests: XUL label text interface">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../role.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing
+
+ var gQueue = null;
+ function doTests()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ // XUL label
+
+ var ids = ["label1", "label2"];
+
+ testCharacterCount(ids, 5);
+
+ testText(ids, 0, -1, "Hello");
+ testText(ids, 0, 1, "H");
+
+ testCharAfterOffset(ids, 0, "e", 1, 2);
+ testCharBeforeOffset(ids, 1, "H", 0, 1);
+ testCharAtOffset(ids, 1, "e", 1, 2);
+
+ //////////////////////////////////////////////////////////////////////////
+ // XUL textbox
+
+ testTextAtOffset([ getNode("tbox1").inputField ], BOUNDARY_LINE_START,
+ [ [ 0, 4, "test", 0, 4 ] ]);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTests);
+ ]]>
+ </script>
+
+ <vbox flex="1" style="overflow: auto;">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=396166"
+ title="xul:label@value accessible should implement nsIAccessibleText">
+ Bug 396166
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=899433"
+ title="Accessibility returns empty line for last line in certain cases">
+ Bug 899433
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+ <label id="label1" value="Hello"/>
+ <label id="label2">Hello</label>
+
+ <textbox id="tbox1" value="test" multiline="true"/>
+ </vbox>
+</window>
diff --git a/accessible/tests/mochitest/text/test_gettext.html b/accessible/tests/mochitest/text/test_gettext.html
new file mode 100644
index 000000000..303edc58a
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_gettext.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Get text between offsets tests</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
+ var IDs = [ "i1", "d1", "e1", "t1" ];
+
+ testCharacterCount(IDs, 15);
+
+ testText(IDs, 0, 1, "h");
+ testText(IDs, 1, 3, "el");
+ testText(IDs, 14, 15, "d");
+ testText(IDs, 0, 15, "hello my friend");
+ testText(IDs, 0, -1, "hello my friend");
+
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
+
+ IDs = [ "i2", "dpre2", "epre2", "t2" ];
+
+ testCharacterCount(IDs, 22);
+
+ testText(IDs, 0, 1, "B");
+ testText(IDs, 5, 6, " ");
+ testText(IDs, 9, 11, " ");
+ testText(IDs, 16, 19, " ");
+ testText(IDs, 0, 22, "Brave Sir Robin ran");
+ testText(IDs, 0, -1, "Brave Sir Robin ran");
+
+ testCharacterCount(["d2", "e2"], 19);
+ testText(["d2", "e2"], 0, 19, "Brave Sir Robin ran");
+
+ //////////////////////////////////////////////////////////////////////////
+ //
+ // __o__n__e__w__o__r__d__\n
+ // 0 1 2 3 4 5 6 7
+ // __\n
+ // 8
+ // __t__w__o__ __w__o__r__d__s__\n
+ // 9 10 11 12 13 14 15 16 17 18
+
+ var IDs = ["d3", "dbr3", "e3", "ebr3", "t3"];
+
+ testCharacterCount(IDs, 19);
+
+ testText(IDs, 0, 19, "oneword\n\ntwo words\n");
+ testText(IDs, 0, -1, "oneword\n\ntwo words\n");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <input id="i1" value="hello my friend"/>
+ <div id="d1">hello my friend</div>
+ <div id="e1" contenteditable="true">hello my friend</div>
+ <textarea id="t1">hello my friend</textarea>
+
+ <input id="i2" value="Brave Sir Robin ran"/>
+ <pre><div id="dpre2">Brave Sir Robin ran</div></pre>
+ <pre><div id="epre2" contenteditable="true">Brave Sir Robin ran</div></pre>
+ <textarea id="t2" cols="300">Brave Sir Robin ran</textarea>
+ <div id="d2">Brave Sir Robin ran</div>
+ <div id="e2" contenteditable="true">Brave Sir Robin ran</div>
+
+ <pre>
+ <div id="d3">oneword
+
+two words
+</div>
+ <div id="dbr3">oneword<br/><br/>two words<br/><br/></div>
+ <div id="e3" contenteditable="true">oneword
+
+two words
+</div>
+ <div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
+ <textarea id="t3" cols="300">oneword
+
+two words
+</textarea>
+ </pre>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_hypertext.html b/accessible/tests/mochitest/text/test_hypertext.html
new file mode 100644
index 000000000..2d71e11a9
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_hypertext.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>nsIAccessibleText getText related function tests for rich text</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <style>
+ #listitemnone {
+ list-style-type: none;
+ }
+ h6.gencontent:before {
+ content: "aga"
+ }
+ </style>
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ // null getText
+ //////////////////////////////////////////////////////////////////////////
+
+ var emptyTextAcc = getAccessible("nulltext", [nsIAccessibleText]);
+ is(emptyTextAcc.getText(0, -1), "", "getText() END_OF_TEXT with null string");
+ is(emptyTextAcc.getText(0, 0), "", "getText() Len==0 with null string");
+
+ //////////////////////////////////////////////////////////////////////////
+ // hypertext
+ //////////////////////////////////////////////////////////////////////////
+
+ // ! - embedded object char
+ // __h__e__l__l__o__ __!__ __s__e__e__ __!__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+
+ var IDs = [ "hypertext", "hypertext2" ];
+
+ ////////////////////////////////////////////////////////////////////////
+ // characterCount
+
+ testCharacterCount(IDs, 13);
+
+ ////////////////////////////////////////////////////////////////////////
+ // getText
+
+ testText(IDs, 0, 1, "h");
+ testText(IDs, 5, 7, " " + kEmbedChar);
+ testText(IDs, 10, 13, "e " + kEmbedChar);
+ testText(IDs, 0, 13, "hello " + kEmbedChar + " see " + kEmbedChar);
+
+ ////////////////////////////////////////////////////////////////////////
+ // getTextAtOffset line boundary
+
+ testTextAtOffset(0, BOUNDARY_LINE_START, "line ", 0, 5,
+ "hypertext3", kOk, kOk, kOk);
+
+ // XXX: see bug 634202.
+ testTextAtOffset(0, BOUNDARY_LINE_START, "line ", 0, 5,
+ "hypertext4", kTodo, kOk, kTodo);
+
+ //////////////////////////////////////////////////////////////////////////
+ // list
+ //////////////////////////////////////////////////////////////////////////
+
+ IDs = [ "list" ];
+ testCharacterCount(IDs, 2);
+ testText(IDs, 0, 2, kEmbedChar + kEmbedChar);
+
+ IDs = [ "listitem" ];
+ testCharacterCount(IDs, 6);
+ testText(IDs, 0, 6, "1. foo");
+
+ IDs = [ "listitemnone" ];
+ testCharacterCount(IDs, 3);
+ testText(IDs, 0, 3, "bar");
+
+ testText(["testbr"], 0, 3, "foo");
+
+ testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr",
+ kOk, kOk, kOk);
+ testTextAtOffset(2, nsIAccessibleText.BOUNDARY_WORD_START, "foo\n", 0, 4,
+ "testbr", kTodo, kOk, kTodo);
+ testTextBeforeOffset(2, nsIAccessibleText.BOUNDARY_LINE_START, "foo\n",
+ 0, 4, "testbr", kTodo, kOk, kTodo);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="Fix getText"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=630001">
+ Bug 630001, part3
+ </a>
+ <a target="_blank"
+ title="getTextAtOffset line boundary may return more than one line"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=638326">
+ Bug 638326
+ </a>
+ <a target="_blank"
+ title="getText(0, -1) fails with empty text"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=749810">
+ Bug 749810
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="nulltext"></div>
+
+ <div id="hypertext">hello <a>friend</a> see <img src="about:blank"></div>
+ <div id="hypertext2">hello <a>friend</a> see <input></div>
+ <ol id="list">
+ <li id="listitem">foo</li>
+ <li id="listitemnone">bar</li>
+ </ol>
+
+ <div id="hypertext3">line
+<!-- haha -->
+<!-- hahaha -->
+<h6>heading</h6>
+ </div>
+
+ <div id="hypertext4">line
+<!-- haha -->
+<!-- hahaha -->
+<h6 role="presentation" class="gencontent">heading</h6>
+ </div>
+
+ <div id="testbr">foo<br/></div>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_lineboundary.html b/accessible/tests/mochitest/text/test_lineboundary.html
new file mode 100644
index 000000000..8370d25d0
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_lineboundary.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Line boundary getText* functions tests</title>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+ <script type="application/javascript">
+ function doTest()
+ {
+ testTextAtOffset("line_test_1", BOUNDARY_LINE_START,
+ [[0, 6, "Line 1 ", 0, 7],
+ [7, 7, "", 7, 7],
+ [8, 15, "Line 3 ", 8, 15]]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
+ var IDs = [ "input", "div", "editable", "textarea",
+ getNode("ta", getNode("ta_cntr").contentDocument) ];
+
+ testTextBeforeOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 15, "", 0, 0 ] ]);
+ testTextBeforeOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 15, "", 0, 0 ] ]);
+
+ testTextAtOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 15, "hello my friend", 0, 15 ] ]);
+ testTextAtOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 15, "hello my friend", 0, 15 ] ]);
+
+ testTextAfterOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 15, "", 15, 15 ] ]);
+ testTextAfterOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 15, "", 15, 15 ] ]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // __o__n__e__w__o__r__d__\n
+ // 0 1 2 3 4 5 6 7
+ // __\n
+ // 8
+ // __t__w__o__ __w__o__r__d__s__\n
+ // 9 10 11 12 13 14 15 16 17 18
+
+ IDs = [ "ml_div", "ml_divbr", "ml_editable", "ml_editablebr", "ml_textarea"];
+
+ testTextBeforeOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 7, "", 0, 0 ],
+ [ 8, 8, "oneword\n", 0, 8 ],
+ [ 9, 18, "\n", 8, 9 ],
+ [ 19, 19, "two words\n", 9, 19 ]]);
+
+ testTextBeforeOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 7, "", 0, 0 ],
+ [ 8, 8, "oneword", 0, 7 ],
+ [ 9, 18, "\n", 7, 8 ],
+ [ 19, 19, "\ntwo words", 8, 18 ]]);
+
+ testTextAtOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 7, "oneword\n", 0, 8 ],
+ [ 8, 8, "\n", 8, 9 ],
+ [ 9, 18, "two words\n", 9, 19 ],
+ [ 19, 19, "", 19, 19 ]]);
+ testTextAtOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 7, "oneword", 0, 7 ],
+ [ 8, 8, "\n", 7, 8 ],
+ [ 9, 18, "\ntwo words", 8, 18 ],
+ [ 19, 19, "\n", 18, 19 ]]);
+
+ testTextAfterOffset(IDs, BOUNDARY_LINE_START,
+ [ [ 0, 7, "\n", 8, 9 ],
+ [ 8, 8, "two words\n", 9, 19 ],
+ [ 9, 19, "", 19, 19 ]]);
+ testTextAfterOffset(IDs, BOUNDARY_LINE_END,
+ [ [ 0, 7, "\n", 7, 8 ],
+ [ 8, 8, "\ntwo words", 8, 18 ],
+ [ 9, 18, "\n", 18, 19 ],
+ [ 19, 19, "", 19, 19 ]]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // a * b (* is embedded char for link)
+ testTextBeforeOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_START,
+ [ [ 0, 5, "", 0, 0 ] ]);
+
+ testTextBeforeOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END,
+ [ [ 0, 5, "", 0, 0 ] ]);
+
+ testTextAtOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_START,
+ [ [ 0, 5, "a " + kEmbedChar + " c", 0, 5 ] ]);
+
+ testTextAtOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END,
+ [ [ 0, 5, "a " + kEmbedChar + " c", 0, 5 ] ]);
+
+ testTextAfterOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_START,
+ [ [ 0, 5, "", 5, 5 ] ]);
+
+ testTextAfterOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END,
+ [ [ 0, 5, "", 5, 5 ] ]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // foo<br> and foo<br><br>
+
+ testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
+ BOUNDARY_LINE_START,
+ [ [ 0, 3, "foo", 0, 3 ] ]);
+ testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
+ BOUNDARY_LINE_START,
+ [ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // 'Hello world ' (\n is rendered as space)
+
+ testTextAtOffset([ "ht_4" ], BOUNDARY_LINE_START,
+ [ [ 0, 12, "Hello world ", 0, 12 ] ]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // list items
+
+ testTextAtOffset([ "li1" ], BOUNDARY_LINE_START,
+ [ [ 0, 6, kDiscBulletText + "Item", 0, 6 ] ]);
+ testTextAtOffset([ "li2" ], BOUNDARY_LINE_START,
+ [ [ 0, 2, kDiscBulletText, 0, 2 ] ]);
+ testTextAtOffset([ "li3" ], BOUNDARY_LINE_START,
+ [ [ 0, 8, kDiscBulletText + "a long ", 0, 9 ],
+ [ 9, 12, "and ", 9, 13 ] ]);
+ testTextAtOffset([ "li4" ], BOUNDARY_LINE_START,
+ [ [ 0, 7, kDiscBulletText + "a " + kEmbedChar + " c", 0, 7 ] ]);
+ testTextAtOffset([ "li5" ], BOUNDARY_LINE_START,
+ [ [ 0, 2, kDiscBulletText + "\n", 0, 3 ],
+ [ 3, 7, "hello", 3, 8 ] ]);
+ testTextAtOffset([ "ul1" ], BOUNDARY_LINE_START,
+ [ [ 0, 0, kEmbedChar, 0, 1 ],
+ [ 1, 1, kEmbedChar, 1, 2 ],
+ [ 2, 2, kEmbedChar, 2, 3 ],
+ [ 3, 3, kEmbedChar, 3, 4 ],
+ [ 4, 5, kEmbedChar, 4, 5 ] ]);
+
+ testTextAtOffset([ "li6" ], BOUNDARY_LINE_START,
+ [ [ 0, 7, "1. Item", 0, 7 ] ]);
+ testTextAtOffset([ "li7" ], BOUNDARY_LINE_START,
+ [ [ 0, 3, "2. ", 0, 3 ] ]);
+ testTextAtOffset([ "li8" ], BOUNDARY_LINE_START,
+ [ [ 0, 9, "3. a long ", 0, 10 ],
+ [ 10, 13, "and ", 10, 14 ] ]);
+ testTextAtOffset([ "li9" ], BOUNDARY_LINE_START,
+ [ [ 0, 8, "4. a " + kEmbedChar + " c", 0, 8 ] ]);
+ testTextAtOffset([ "li10" ], BOUNDARY_LINE_START,
+ [ [ 0, 3, "5. \n", 0, 4 ],
+ [ 4, 8, "hello", 4, 9 ] ]);
+ testTextAtOffset([ "ol1" ], BOUNDARY_LINE_START,
+ [ [ 0, 0, kEmbedChar, 0, 1 ],
+ [ 1, 1, kEmbedChar, 1, 2 ],
+ [ 2, 2, kEmbedChar, 2, 3 ],
+ [ 3, 3, kEmbedChar, 3, 4 ],
+ [ 4, 5, kEmbedChar, 4, 5 ] ]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // Nested hypertexts
+
+ testTextAtOffset(["ht_5" ], BOUNDARY_LINE_START,
+ [ [ 0, 0, kEmbedChar, 0, 1 ] ]);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="getTextAtOffset for word boundaries: beginning of a new life"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
+ Bug 853340
+ </a>
+ <a target="_blank"
+ title="getTextBeforeOffset for word boundaries: evolving"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
+ Bug 855732
+ </a>
+ <a target="_blank"
+ title=" getTextAfterOffset for line boundary on new rails"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=882292">
+ Bug 882292
+ </a>
+ <a target="_blank"
+ title="getTextAtOffset broken for last object when closing tag is preceded by newline char"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=947170">
+ Bug 947170
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <input id="input" value="hello my friend"/>
+ <div id="div">hello my friend</div>
+ <div id="editable" contenteditable="true">hello my friend</div>
+ <textarea id="textarea">hello my friend</textarea>
+ <iframe id="ta_cntr"
+ src="data:text/html,<html><body><textarea id='ta'>hello my friend</textarea></body></html>"></iframe>
+
+ <pre>
+ <div id="ml_div" style="border-style:outset;">oneword
+
+two words
+</div>
+ <div id="ml_divbr" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div>
+ <div id="ml_editable" style="border-style:outset;" contenteditable="true">oneword
+
+two words
+</div>
+ <div id="ml_editablebr" contenteditable="true" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div>
+ <textarea id="ml_textarea" cols="300">oneword
+
+two words
+</textarea>
+ </pre>
+
+ <iframe id="ht_1" src="data:text/html,<html><body>a <a href=''>b</a> c</body></html>"></iframe>
+
+ <iframe id="ht_2" src="data:text/html,<div contentEditable='true'>foo<br/></div>"></iframe>
+ <iframe id="ht_3" src="data:text/html,<div contentEditable='true'>foo<br/><br/></div>"></iframe>
+
+ <p id="ht_4">Hello world
+</p>
+
+ <ul id="ul1">
+ <li id="li1">Item</li>
+ <li id="li2"></li>
+ <li id="li3" style="font-family:monospace; font-size:10pt; width:8ch;">a long and winding road that lead me to your door</li>
+ <li id="li4">a <a href=''>b</a> c</li>
+ <li id="li5"><br>hello</li>
+ </ul>
+
+ <ol id="ol1">
+ <li id="li6">Item</li>
+ <li id="li7"></li>
+ <li id="li8" style="font-family:monospace; font-size:10pt; width:8ch;">a long and winding road that lead me to your door</li>
+ <li id="li9">a <a href=''>b</a> c</li>
+ <li id="li10"><br>hello</li>
+ </ol>
+
+ <div id="ht_5">
+ <div>
+ <p>sectiounus</p>
+ <p>seciofarus</p>
+ </div>
+ </div>
+ <div id="line_test_1">
+ Line 1
+ <center><input type="TEXT"><input value="Button" type="SUBMIT"></center>
+ Line 3
+ </div>
+ </body>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_passwords.html b/accessible/tests/mochitest/text/test_passwords.html
new file mode 100644
index 000000000..8a47b5944
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_passwords.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>nsIAccessibleText getText related function tests for text and password inputs</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ // regular text and password inputs
+ //////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////
+ // characterCount and getText for regular text field
+
+ var IDs = [ "username" ];
+ testCharacterCount(IDs, 4);
+ testText(IDs, 0, 4, "test");
+
+ ////////////////////////////////////////////////////////////////////////
+ // characterCount and getText for password field
+
+ IDs = [ "password" ];
+ testCharacterCount(IDs, 4);
+ testPasswordText(IDs, 0, 4, "test");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="mochitest for getText for password fields"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=415943">Mozilla Bug 415943</a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <form action="post.php" method="post">
+ <label for="username">User name:</label>
+ <input id="username" value="test"><br />
+ <label for="password">Password:</label>
+ <input type="password" id="password" value="test"/>
+ </form>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_selection.html b/accessible/tests/mochitest/text/test_selection.html
new file mode 100644
index 000000000..b832231cf
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_selection.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Test text selection functions</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+
+ function doTest()
+ {
+ // Test selection count: clean selection / check count.
+ testTextAddSelection("div0", 0, 2, 1); // |Test selection...
+ cleanTextSelections("div0");
+ testTextSelectionCount("div0", 0);
+
+ // Test addition: adding two equal selections, the second one should
+ // not be added.
+ testTextAddSelection("div1", 7, 9, 1); // Test ad|di|ng two...
+ testTextAddSelection("div1", 7, 9, 1); // Test ad|di|ng two...
+ testTextGetSelection("div1", 7, 9, 0);
+
+ // Test overlapping selections: adding three selections, one adjacent.
+ testTextAddSelection("div2", 0, 3, 1); // |Tes|t adding 3...
+ testTextAddSelection("div2", 7, 9, 2); // |Tes|t ad|di|ng 3...
+ testTextAddSelection("div2", 3, 4, 3); // |Tes||t| ad|di|ng 3...
+ testTextGetSelection("div2", 0, 3, 0);
+ testTextGetSelection("div2", 3, 4, 1);
+ testTextGetSelection("div2", 7, 9, 2);
+
+ // Test selection re-ordering: adding two selections.
+ // NOTE: removeSelections aSelectionIndex is from start of document.
+ testTextAddSelection("div3", 0, 3, 1); // |Tes|t adding 2...
+ testTextAddSelection("div3", 7, 9, 2); // |Tes|t ad|di|ng 2...
+ testTextRemoveSelection("div3", 4, 1); // Test ad|di|ng 2...
+
+ // Test extending existing selection.
+ // NOTE: setSelectionBounds aSelectionIndex is from start of document.
+ testTextAddSelection("div4", 4, 5, 1); // Test| |extending...
+ testTextSetSelection("div4", 4, 9, 6, 1); // Test| exte|nding...
+
+ // Test moving an existing selection.
+ // NOTE: setSelectionBounds aSelectionIndex is from start of document.
+ testTextAddSelection("div5", 1, 3, 1); // T|es|t moving...
+ testTextSetSelection("div5", 5, 9, 6, 1); // Test |movi|ng...
+
+ // Test adding selections to multiple inner elements.
+ testTextAddSelection("div71", 0, 3, 1); // |Tes|t adding...
+ testTextAddSelection("div71", 7, 8, 2); // |Tes|t ad|d|ing...
+ testTextAddSelection("div72", 4, 6, 1); // Test| a|dding...
+ testTextAddSelection("div72", 7, 8, 2); // Test| a|d|d|ing...
+
+ // Test adding selection to parent element.
+ // NOTE: If inner elements are represented as embedded chars
+ // we count their internal selections.
+ testTextAddSelection("div7", 7, 8, 5); // Test ad|d|ing...
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+
+</script>
+</head>
+
+<body>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="div0">Test selection count</div>
+ </br>
+ <div id="div1">Test adding two equal selections </div>
+ <div id="div2">Test adding 3 selections one adjacent </div>
+ <div id="div3">Test adding 2 selections, remove first one </div>
+ <div id="div4">Test extending a selection </div>
+ <div id="div5">Test moving a selection </div>
+ </br>
+ <div id="div7">Test adding selections to parent element
+ <div id="div71">Test adding selections to inner element1 </div>
+ <div id="div72">Test adding selections to inner element2 </div>
+ </div>
+
+</body>
+
+</html>
diff --git a/accessible/tests/mochitest/text/test_wordboundary.html b/accessible/tests/mochitest/text/test_wordboundary.html
new file mode 100644
index 000000000..6d3c09e8c
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_wordboundary.html
@@ -0,0 +1,291 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Word boundary text tests</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ // "hello"
+ // __h__e__l__l__o__
+ // 0 1 2 3 4 5
+ var ids = [ "i1", "d1", "e1", "t1" ];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "", 0, 0 ] ]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 0, 0 ] ]);
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "hello", 0, 5 ] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "hello", 0, 5 ] ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "", 5, 5 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 5, 5 ] ]);
+
+ // "hello "
+ // __h__e__l__l__o__ __
+ // 0 1 2 3 4 5 6
+ var ids = [ "i2", "d2", "e2", "t2" ];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 6, "", 0, 0 ] ]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 6, "hello", 0, 5 ]
+ ]);
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 6, "hello ", 0, 6 ] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 4, "hello", 0, 5 ],
+ [ 5, 6, " ", 5, 6 ]
+ ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 6, "", 6, 6 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, " ", 5, 6 ],
+ [ 6, 6, "", 6, 6 ]
+ ]);
+
+ // "hello all"
+ // __h__e__l__l__o__ __a__l__l__
+ // 0 1 2 3 4 5 6 7 8 9
+ ids = [ "i6", "d6", "e6", "t6" ];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 9, "hello ", 0, 6 ]]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 9, "hello", 0, 5 ] ]);
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "hello ", 0, 6 ],
+ [ 6, 9, "all", 6, 9 ] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 4, "hello", 0, 5 ],
+ [ 5, 9, " all", 5, 9 ] ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "all", 6, 9 ],
+ [ 6, 9, "", 9, 9 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, " all", 5, 9 ],
+ [ 6, 9, "", 9, 9 ] ]);
+
+ // "hello my friend"
+ // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ ids = [ "i7", "d7", "e7", "t7" ];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 8, "hello ", 0, 6 ],
+ [ 9, 15, "my ", 6, 9 ] ]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 8, "hello", 0, 5 ],
+ [ 9, 15, " my", 5, 8 ] ]);
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "hello ", 0, 6 ],
+ [ 6, 8, "my ", 6, 9 ],
+ [ 9, 15, "friend", 9, 15] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 4, "hello", 0, 5 ],
+ [ 5, 7, " my", 5, 8 ],
+ [ 8, 15, " friend", 8, 15] ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "my ", 6, 9 ],
+ [ 6, 8, "friend", 9, 15 ],
+ [ 9, 15, "", 15, 15 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, " my", 5, 8 ],
+ [ 6, 8, " friend", 8, 15 ],
+ [ 9, 15, "", 15, 15 ] ]);
+
+ // "Brave Sir Robin ran"
+ // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n__
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
+ ids = [ "i8", "d8", "e8", "t8" ];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 10, "Brave ", 0, 6 ],
+ [ 11, 18, "Sir ", 6, 11 ],
+ [ 19, 22, "Robin ", 11, 19 ] ]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, "", 0, 0 ],
+ [ 6, 9, "Brave", 0, 5 ],
+ [ 10, 16, " Sir", 5, 9 ],
+ [ 17, 22, " Robin", 9, 16 ] ]);
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "Brave ", 0, 6 ],
+ [ 6, 10, "Sir ", 6, 11 ],
+ [ 11, 18, "Robin ", 11, 19 ],
+ [ 19, 22, "ran", 19, 22 ] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 4, "Brave", 0, 5 ],
+ [ 5, 8, " Sir", 5, 9 ],
+ [ 9, 15, " Robin", 9, 16 ],
+ [ 16, 22, " ran", 16, 22 ] ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 5, "Sir ", 6, 11 ],
+ [ 6, 10, "Robin ", 11, 19 ],
+ [ 11, 18, "ran", 19, 22 ],
+ [ 19, 22, "", 22, 22 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 5, " Sir", 5, 9 ],
+ [ 6, 9, " Robin", 9, 16 ],
+ [ 10, 16, " ran", 16, 22 ],
+ [ 17, 22, "", 22, 22 ] ]);
+
+ // 'oneword
+ // '
+ // 'two words
+ // '
+ // __o__n__e__w__o__r__d__\n
+ // 0 1 2 3 4 5 6 7
+ // __\n
+ // 8
+ // __t__w__o__ __w__o__r__d__s__\n__
+ // 9 10 11 12 13 14 15 16 17 18 19
+
+ ids = ["ml_div1", "ml_divbr1", "ml_ediv1", "ml_edivbr1", "ml_t1"];
+ testTextBeforeOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 8, "", 0, 0 ],
+ [ 9, 12, "oneword\n\n", 0, 9 ],
+ [ 13, 19, "two ", 9, 13 ] ]);
+ testTextBeforeOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 7, "", 0, 0 ],
+ [ 8, 12, "oneword", 0, 7,
+ [ [ 8, "ml_divbr1", kTodo, kOk, kTodo ],
+ [ 8, "ml_edivbr1", kTodo, kOk, kTodo ],
+ [ 9, "ml_divbr1", kTodo, kOk, kTodo ],
+ [ 9, "ml_edivbr1", kTodo, kOk, kTodo ] ] ],
+ [ 13, 18, "\n\ntwo", 7, 12 ],
+ [ 19, 19, " words", 12, 18,
+ [ [ 19, "ml_divbr1", kTodo, kTodo, kTodo, ],
+ [ 19, "ml_edivbr1", kTodo, kTodo, kTodo, ] ] ]
+ ] );
+
+ testTextAtOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 8, "oneword\n\n", 0, 9,
+ [ [ 7, "ml_divbr1", kTodo, kTodo, kTodo ],
+ [ 7, "ml_edivbr1", kTodo, kTodo, kTodo ],
+ [ 8, "ml_divbr1", kTodo, kTodo, kTodo ],
+ [ 8, "ml_edivbr1", kTodo, kTodo, kTodo ] ] ],
+ [ 9, 12, "two ", 9, 13 ],
+ [ 13, 19, "words\n", 13, 19 ] ]);
+ testTextAtOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 6, "oneword", 0, 7 ],
+ [ 7, 11, "\n\ntwo", 7, 12 ],
+ [ 12, 17, " words", 12, 18 ],
+ [ 18, 19, "\n", 18, 19,
+ [ [ 18, "ml_divbr1", kTodo, kTodo, kOk ],
+ [ 18, "ml_edivbr1", kTodo, kTodo, kOk ],
+ [ 19, "ml_divbr1", kTodo, kTodo, kOk ],
+ [ 19, "ml_edivbr1", kTodo, kTodo, kOk ] ] ] ]);
+
+ testTextAfterOffset(ids, BOUNDARY_WORD_START,
+ [ [ 0, 8, "two ", 9, 13,
+ [ [ 7, "ml_divbr1", kTodo, kTodo, kTodo ],
+ [ 7, "ml_edivbr1", kTodo, kTodo, kTodo ],
+ [ 8, "ml_divbr1", kTodo, kTodo, kTodo ],
+ [ 8, "ml_edivbr1", kTodo, kTodo, kTodo ] ] ],
+ [ 9, 12, "words\n", 13, 19 ],
+ [ 13, 19, "", 19, 19 ] ]);
+ testTextAfterOffset(ids, BOUNDARY_WORD_END,
+ [ [ 0, 7, "\n\ntwo", 7, 12 ],
+ [ 8, 12, " words", 12, 18 ],
+ [ 13, 18, "\n", 18, 19,
+ [ [ 18, "ml_divbr1", kTodo, kTodo, kOk ],
+ [ 18, "ml_edivbr1", kTodo, kTodo, kOk ] ] ],
+ [ 19, 19, "", 19, 19 ] ]);
+
+ // a <a href="#">b</a>
+ // a *
+ testTextBeforeOffset("cntr_1", BOUNDARY_WORD_START,
+ [ [ 0, 1, "", 0, 0 ],
+ [ 2, 3, "a ", 0, 2 ] ]);
+
+ testTextAtOffset("cntr_1", BOUNDARY_WORD_START,
+ [ [ 0, 1, "a ", 0, 2 ],
+ [ 2, 3, kEmbedChar, 2, 3 ] ]);
+ testTextAfterOffset("cntr_1", BOUNDARY_WORD_START,
+ [ [ 0, 1, kEmbedChar, 2, 3 ],
+ [ 2, 3, "", 3, 3 ] ]);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <input id="i1" value="hello"/>
+ <div id="d1">hello</div>
+ <div id="e1" contenteditable="true">hello</div>
+ <textarea id="t1">hello</textarea>
+
+ <input id="i2" value="hello "/>
+ <pre><div id="d2">hello </div></pre>
+ <div id="e2" contenteditable="true" style='white-space:pre'>hello </div>
+ <textarea id="t2">hello </textarea>
+
+ <input id="i6" value="hello all"/>
+ <div id="d6">hello all</div>
+ <div id="e6" contenteditable="true">hello all</div>
+ <textarea id="t6">hello all</textarea>
+
+ <input id="i7" value="hello my friend"/>
+ <div id="d7">hello my friend</div>
+ <div id="e7" contenteditable="true">hello my friend</div>
+ <textarea id="t7">hello my friend</textarea>
+
+ <input id="i8" value="Brave Sir Robin ran"/>
+ <pre>
+ <div id="d8">Brave Sir Robin ran</div>
+ <div id="e8" contenteditable="true">Brave Sir Robin ran</div>
+ </pre>
+ <textarea id="t8" cols="300">Brave Sir Robin ran</textarea>
+
+ <pre>
+<div id="ml_div1">oneword
+
+two words
+</div>
+<div id="ml_divbr1">oneword<br/><br/>two words<br/><br/></div>
+<div id="ml_ediv1" contenteditable="true">oneword
+
+two words
+</div>
+<div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
+<textarea id="ml_t1" cols="300">oneword
+
+two words
+</textarea>
+ </pre>
+
+ <div id="cntr_1">a <a href="#">b</a></div>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/text/test_words.html b/accessible/tests/mochitest/text/test_words.html
new file mode 100644
index 000000000..dff90bfea
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_words.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>nsIAccessibleText getText related function tests for html:input,html:div and html:textarea</title>
+ <meta charset="utf-8" />
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../text.js"></script>
+ <script type="application/javascript">
+ if (navigator.platform.startsWith("Mac")) {
+ SimpleTest.expectAssertions(0, 1);
+ } else {
+ SimpleTest.expectAssertions(0, 1);
+ }
+
+ function doTest()
+ {
+ // "one two"
+ testWords("div1", ["one", "two"]);
+
+ // "one two"
+ testWords("div2", ["one", "two"]);
+
+ // "one,two"
+ testWordCount("div3", 2, kOk);
+ testWordAt("div3", 0, "one", kTodo);
+ testWordAt("div3", 1, "two", kOk);
+
+ // "one, two"
+ testWordCount("div4", 2, kOk);
+ testWordAt("div4", 0, "one", kTodo);
+ testWordAt("div4", 1, "two", kOk);
+
+ // "one+two"
+ testWordCount("div5", 2, kOk);
+ testWordAt("div5", 0, "one", kTodo);
+ testWordAt("div5", 1, "two", kOk);
+
+ // "one+two "
+ testWordCount("div6", 2, kOk);
+ testWordAt("div6", 0, "one", kTodo);
+ testWordAt("div6", 1, "two", kOk);
+
+ // "one\ntwo"
+ testWordCount("div7", 2, kOk);
+ testWordAt("div7", 0, "one", kOk);
+ testWordAt("div7", 1, "two", kTodo);
+
+ // "one.two"
+ testWordCount("div8", 2, kOk);
+ testWordAt("div8", 0, "one", kTodo);
+ testWordAt("div8", 1, "two", kOk);
+
+ // "345"
+ testWords("div9", ["345"]);
+
+ // "3a A4"
+ testWords("div10", ["3a", "A4"]);
+
+ // "3.1416"
+ testWords("div11", ["3.1416"], kTodo);
+
+ // "4,261.01"
+ testWords("div12", ["4,261.01"], kTodo);
+
+ // "カタカナ"
+ testWords("div13", ["カタカナ"], kOk);
+
+ // "Peter's car"
+ testWords("div14", ["Peter's", "car"], kTodo);
+
+ // "N.A.T.O."
+ testWords("div15", ["N.A.T.O."], kTodo);
+
+ // "3+4*5=23"
+ testWordCount("div16", 4, kOk);
+ testWordAt("div15", 0, "3", kTodo);
+ testWordAt("div15", 1, "4", kTodo);
+ testWordAt("div15", 2, "5", kTodo);
+ testWordAt("div15", 3, "23", kTodo);
+
+ // "Hello. Friend, are you here?!"
+ testWordCount("div17", 5, kOk);
+ testWordAt("div17", 0, "Hello", kTodo);
+ testWordAt("div17", 1, "Friend", kTodo);
+ testWordAt("div17", 2, "are", kOk);
+ testWordAt("div17", 3, "you", kOk);
+ testWordAt("div17", 4, "here", kTodo);
+
+ testWords("input_1", ["foo", "bar"]);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ title="nsIAccessibleText test word boundaries"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=452769">Mozilla Bug 452769</a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ <div id="div1">one two</div>
+ <div id="div2">one two</div>
+ <div id="div3">one,two</div>
+ <div id="div4">one, two</div>
+ <div id="div5">one+two</div>
+ <div id="div6">one+two </div>
+ <div id="div7">one<br/>two</div>
+ <div id="div8">one.two</div>
+ <div id="div9">345</div>
+ <div id="div10">3a A4</div>
+ <div id="div11">3.1416</div>
+ <div id="div12">4,261.01</div>
+ <div id="div13">カタカナ</div>
+ <div id="div14">Peter's car</div>
+ <div id="div15">N.A.T.O.</div>
+ <div id="div16">3+4*5=23</div>
+ <div id="div17">Hello. Friend, are you here?!</div>
+ </pre>
+ <input id="input_1" type="text" value="foo bar" placeholder="something or other">
+
+</body>
+</html>