Bug 873358 - textarea claims bogus trailing \n (HTML br), r=tbsaunde

This commit is contained in:
Alexander Surkov 2013-05-23 12:57:04 +09:00
parent 9f0e15d929
commit 27eeac47c8
10 changed files with 77 additions and 143 deletions

View File

@ -12,6 +12,7 @@
#include "Relation.h"
#include "Role.h"
#include "States.h"
#include "TreeWalker.h"
#include "nsContentList.h"
#include "nsCxPusher.h"
@ -480,6 +481,22 @@ HTMLTextFieldAccessible::GetEditor() const
return editor.forget();
}
void
HTMLTextFieldAccessible::CacheChildren()
{
// XXX: textarea shouldn't contain anything but text leafs. Currently it may
// contain a trailing fake HTML br element added for layout needs. We don't
// need to expose it since it'd be confusing for AT.
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
while ((child = walker.NextChild())) {
if (child->IsTextLeaf())
AppendChild(child);
else
Document()->UnbindFromDocument(child);
}
}
////////////////////////////////////////////////////////////////////////////////
// HTMLTextFieldAccessible: Widgets

View File

@ -94,7 +94,8 @@ protected:
/**
* Accessible for HTML input@type="text" element.
* Accessible for HTML input@type="text", input@type="password", textarea and
* other HTML text controls.
*/
class HTMLTextFieldAccessible : public HyperTextAccessibleWrap
{
@ -129,6 +130,8 @@ public:
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
virtual void CacheChildren() MOZ_OVERRIDE;
};

View File

@ -58,9 +58,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
}, {
aAccOrElmOrID: "textarea",
expected: [[
"text area", "Test Text Area", "This is the text area text.", "\n"
"text area", "Test Text Area", "This is the text area text."
], [
"This is the text area text.", "\n", "Test Text Area", "text area"
"This is the text area text.", "Test Text Area", "text area"
]]
}, {
aAccOrElmOrID: "heading",
@ -181,4 +181,4 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
</table>
</div>
</body>
</html>
</html>

View File

@ -41,13 +41,13 @@
this.finalCheck = function moveToLastLineEnd_finalCheck()
{
testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
"textarea", kTodo, kOk, kTodo);
["textarea"]);
testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
"textarea", kTodo, kOk, kTodo);
"textarea", kOk, kTodo, kTodo);
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
"textarea", kTodo, kTodo, kTodo);
"textarea", kTodo, kTodo, kOk);
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
"textarea", kTodo, kTodo, kTodo);
@ -72,13 +72,13 @@
this.finalCheck = function moveToLastLineStart_finalCheck()
{
testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
"textarea", kTodo, kTodo, kTodo);
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
"textarea", kTodo, kTodo, kOk);
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
"textarea", kTodo, kOk, kTodo);
[ "textarea" ]);
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
"textarea", kTodo, kTodo, kTodo);
@ -224,7 +224,7 @@
var gQueue = null;
function doTest()
{
SimpleTest.expectAssertions(5);
SimpleTest.expectAssertions(7);
gQueue = new eventQueue();
gQueue.push(new moveToLastLineEnd());

View File

@ -30,15 +30,11 @@
testCharAtOffset(IDs, 0, "h", 0, 1);
testCharAtOffset(IDs, 1, "e", 1, 2);
testCharAtOffset(IDs, 14, "d", 14, 15);
testCharAtOffset([ "i1", "d1", "e1" ], 15, "", 15, 15);
testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
"t1", kOk, kTodo, kTodo);
testCharAtOffset(IDs, 15, "", 15, 15);
testCharAfterOffset(IDs, 0, "e", 1, 2);
testCharAfterOffset(IDs, 1, "l", 2, 3);
testCharAfterOffset([ "i1", "d1", "e1" ], 14, "", 15, 15);
testTextAfterOffset(14, BOUNDARY_CHAR, "", 15, 15,
"t1", kTodo, kOk, kTodo);
testCharAfterOffset(IDs, 14, "", 15, 15);
// 15 is out of range offset for get text after, keep todos until we
// decide how to handle out of range values (ATK and IA2 seems to have
@ -46,8 +42,7 @@
testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
"i1", kOk, kTodo, kTodo,
"d1", kOk, kTodo, kTodo,
"e1", kOk, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
"e1", kOk, kTodo, kTodo,
"t1", kOk, kTodo, kTodo);
//////////////////////////////////////////////////////////////////////////

View File

@ -22,15 +22,13 @@
var IDs = [ "i1", "d1", "e1", "t1" ];
testCharacterCount([ "i1", "d1", "e1" ], 15);
testCharacterCount("t1", 15, kTodo);
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([ "i1", "d1", "e1"], 0, -1, "hello my friend");
testText("t1", 0, -1, "hello my friend", kTodo);
testText(IDs, 0, -1, "hello my friend");
//////////////////////////////////////////////////////////////////////////
//
@ -39,16 +37,14 @@
IDs = [ "i2", "dpre2", "epre2", "t2" ];
testCharacterCount([ "i2", "dpre2", "epre2"], 22);
testCharacterCount("t2", 22, kTodo);
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([ "i2", "dpre2", "epre2" ], 0, -1, "Brave Sir Robin ran");
testText("t2", 0, -1, "Brave Sir Robin ran", kTodo);
testText(IDs, 0, -1, "Brave Sir Robin ran");
testCharacterCount(["d2", "e2"], 19);
testText(["d2", "e2"], 0, 19, "Brave Sir Robin ran");
@ -108,7 +104,8 @@ two words
<div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/></div>
<textarea id="t3" cols="300">oneword
two words</textarea>
two words
</textarea>
</pre>
</body>

View File

@ -16,7 +16,7 @@
function doTest()
{
SimpleTest.expectAssertions(44);
SimpleTest.expectAssertions(46);
// __o__n__e__w__o__r__d__\n
// 0 1 2 3 4 5 6 7
@ -25,9 +25,6 @@
// __t__w__o__ __w__o__r__d__s__\n
// 9 10 11 12 13 14 15 16 17 18
// Note: HTML textarea adds an extra "\n" at the end of the text at
// the layount/content level.
////////////////////////////////////////////////////////////////////////
// getText
@ -76,13 +73,13 @@
"divbr", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(19, BOUNDARY_LINE_START, "", 19, 19,
"div", kOk, kOk, kTodo,
"divbr", kOk, kOk, kOk,
"editable", kOk, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kOk, kOk, kTodo);
// BOUNDARY_LINE_END
testTextAfterOffset(0, BOUNDARY_LINE_END, "\n", 7, 8,
@ -102,7 +99,7 @@
"divbr", kOk, kOk, kOk,
"editable", kTodo, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(9, BOUNDARY_LINE_END, "\n", 18, 19,
"div", kTodo, kTodo, kTodo,
"divbr", kTodo, kTodo, kTodo,
@ -114,7 +111,7 @@
"divbr", kOk, kOk, kOk,
"editable", kTodo, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(19, BOUNDARY_LINE_END, "", 19, 19,
"div", kOk, kTodo, kTodo,
"divbr", kOk, kTodo, kTodo,
@ -157,7 +154,7 @@
"divbr", kTodo, kTodo, kTodo,
"editable", kOk, kOk, kOk,
"editablebr", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
"textarea", kOk, kOk, kOk);
// BOUNDARY_LINE_START
testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0,
@ -279,13 +276,13 @@
"divbr", kOk, kOk, kOk,
"editable", kTodo, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(13, BOUNDARY_LINE_START, "two words\n", 9, 19,
"div", kTodo, kOk, kTodo,
"divbr", kOk, kOk, kOk,
"editable", kTodo, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(18, BOUNDARY_LINE_START, "two words\n", 9, 19,
"div", kOk, kOk, kOk,
"divbr", kOk, kOk, kOk,
@ -297,7 +294,7 @@
"divbr", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kTodo,
"editablebr", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_LINE_END
testTextAtOffset(0, BOUNDARY_LINE_END, "oneword", 0, 7,
@ -323,7 +320,7 @@
"divbr", kOk, kOk, kOk,
"editable", kTodo, kOk, kTodo,
"editablebr", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(17, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
"div", kOk, kOk, kOk,
"divbr", kOk, kOk, kOk,
@ -383,7 +380,8 @@ two words
<div id="editablebr" contenteditable="true">oneword<br/><br/>two words<br/></div>
<textarea id="textarea" cols="300">oneword
two words</textarea>
two words
</textarea>
</pre>
</body>
</html>

View File

@ -12,9 +12,9 @@
src="../text.js"></script>
<script type="application/javascript">
if (navigator.platform.startsWith("Mac")) {
SimpleTest.expectAssertions(0, 14);
SimpleTest.expectAssertions(0, 16);
} else {
SimpleTest.expectAssertions(14);
SimpleTest.expectAssertions(16);
}
function doTest()
@ -57,22 +57,22 @@
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(1, BOUNDARY_LINE_START, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(14, BOUNDARY_LINE_START, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(15, BOUNDARY_LINE_START, "", 15, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
"textarea", kOk, kOk, kOk);
// BOUNDARY_LINE_END
testTextAfterOffset(0, BOUNDARY_LINE_END, "", 15, 15,
@ -94,7 +94,7 @@
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
"textarea", kOk, kTodo, kTodo);
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
@ -111,11 +111,7 @@
testTextBeforeOffset(9, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
testTextBeforeOffset(10, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
testTextBeforeOffset(14, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
testTextBeforeOffset(15, BOUNDARY_WORD_START, "my ", 6, 9,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(15, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
// BOUNDARY_WORD_END
testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
@ -167,11 +163,7 @@
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(15, BOUNDARY_LINE_END, "", 0, 0,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(15, BOUNDARY_LINE_END, "", 0, 0, IDs);
////////////////////////////////////////////////////////////////////////
// getTextAtOffset
@ -204,26 +196,10 @@
testTextAtOffset(15, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
// BOUNDARY_LINE_START
testTextAtOffset(0, BOUNDARY_LINE_START, "hello my friend", 0, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(1, BOUNDARY_LINE_START, "hello my friend", 0, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(14, BOUNDARY_LINE_START, "hello my friend", 0, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(15, BOUNDARY_LINE_START, "hello my friend", 0, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(0, BOUNDARY_LINE_START, "hello my friend", 0, 15, IDs);
testTextAtOffset(1, BOUNDARY_LINE_START, "hello my friend", 0, 15, IDs);
testTextAtOffset(14, BOUNDARY_LINE_START, "hello my friend", 0, 15, IDs);
testTextAtOffset(15, BOUNDARY_LINE_START, "hello my friend", 0, 15, IDs);
// BOUNDARY_LINE_END
testTextAtOffset(0, BOUNDARY_LINE_END, "hello my friend", 0, 15,

View File

@ -29,26 +29,10 @@
testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin ", 11, 19, IDs);
testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22, IDs);
// BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
@ -61,31 +45,11 @@
testTextAfterOffset(11, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(15, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(16, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22, IDs);
testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22, IDs);
testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22, IDs);
testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22, IDs);
testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22, IDs);
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
@ -186,21 +150,9 @@
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(19, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(21, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(22, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(19, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
testTextAtOffset(21, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
testTextAtOffset(22, BOUNDARY_WORD_START, "ran", 19, 22, IDs);
// BOUNDARY_WORD_END
testTextAtOffset(0, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
@ -218,8 +170,7 @@
testTextAtOffset(19, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAtOffset(20, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAtOffset(21, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
testTextAtOffset(22, BOUNDARY_WORD_END, " ran", 16, 22, ["input", "div", "editable"]);
testTextAtOffset(22, BOUNDARY_WORD_END, " ran\n", 16, 23, [ "textarea" ]);
testTextAtOffset(22, BOUNDARY_WORD_END, " ran", 16, 22, IDs);
SimpleTest.finish();
}

View File

@ -55,9 +55,6 @@
children: [
{
role: ROLE_TEXT_LEAF // hello1\nhello2 text
},
{
role: ROLE_WHITESPACE
}
]
};