Bug 899433 - Accessibility returns empty line for last line in certain cases, r=tbsaunde

This commit is contained in:
Alexander Surkov 2013-09-11 12:56:01 -04:00
parent 3e78316af2
commit 6f0d3fa785
12 changed files with 59 additions and 31 deletions

View File

@ -481,6 +481,7 @@ public:
bool IsHyperText() const { return HasGenericType(eHyperText); } bool IsHyperText() const { return HasGenericType(eHyperText); }
HyperTextAccessible* AsHyperText(); HyperTextAccessible* AsHyperText();
bool IsHTMLBr() const { return mType == eHTMLBRType; }
bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; } bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; }
bool IsHTMLListItem() const { return mType == eHTMLLiType; } bool IsHTMLListItem() const { return mType == eHTMLLiType; }

View File

@ -13,6 +13,7 @@
#include "Role.h" #include "Role.h"
#include "States.h" #include "States.h"
#include "TextAttrs.h" #include "TextAttrs.h"
#include "TreeWalker.h"
#include "nsIClipboard.h" #include "nsIClipboard.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
@ -2062,6 +2063,31 @@ HyperTextAccessible::RemoveChild(Accessible* aAccessible)
return Accessible::RemoveChild(aAccessible); return Accessible::RemoveChild(aAccessible);
} }
void
HyperTextAccessible::CacheChildren()
{
// Trailing HTML br element don't play any difference. We don't need to expose
// it to AT (see bug https://bugzilla.mozilla.org/show_bug.cgi?id=899433#c16
// for details).
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
Accessible* lastChild = nullptr;
while ((child = walker.NextChild())) {
if (lastChild)
AppendChild(lastChild);
lastChild = child;
}
if (lastChild) {
if (lastChild->IsHTMLBr())
Document()->UnbindFromDocument(lastChild);
else
AppendChild(lastChild);
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// HyperTextAccessible public static // HyperTextAccessible public static

View File

@ -273,6 +273,7 @@ public:
protected: protected:
// Accessible // Accessible
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE; virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
virtual void CacheChildren() MOZ_OVERRIDE;
// HyperTextAccessible // HyperTextAccessible

View File

@ -33,7 +33,10 @@ class HTMLBRAccessible : public LeafAccessible
{ {
public: public:
HTMLBRAccessible(nsIContent* aContent, DocAccessible* aDoc) : HTMLBRAccessible(nsIContent* aContent, DocAccessible* aDoc) :
LeafAccessible(aContent, aDoc) {} LeafAccessible(aContent, aDoc)
{
mType = eHTMLBRType;
}
// Accessible // Accessible
virtual a11y::role NativeRole(); virtual a11y::role NativeRole();

View File

@ -464,22 +464,6 @@ HTMLTextFieldAccessible::GetEditor() const
return editor.forget(); 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 // HTMLTextFieldAccessible: Widgets

View File

@ -142,8 +142,6 @@ public:
protected: protected:
// Accessible // Accessible
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE; virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
virtual void CacheChildren() MOZ_OVERRIDE;
}; };

View File

@ -70,7 +70,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452161
var testRun = new editableTextTestRun(); var testRun = new editableTextTestRun();
addTestEditable("input", testRun); addTestEditable("input", testRun);
addTestEditable("div", testRun, '\n'); addTestEditable("div", testRun);
addTestEditable(getNode("frame").contentDocument, testRun, '\n'); addTestEditable(getNode("frame").contentDocument, testRun, '\n');
testRun.run(); // Will call SimpleTest.finish(); testRun.run(); // Will call SimpleTest.finish();

View File

@ -1298,7 +1298,8 @@
<p>This is a quotation taken from the Mozilla Developer Center.</p> <p>This is a quotation taken from the Mozilla Developer Center.</p>
</blockquote> </blockquote>
<p id="br_container"><br></p> <!-- two BRs, one will be eaten -->
<p id="br_container"><br><br></p>
<button id="button">button</button> <button id="button">button</button>
<form> <form>

View File

@ -96,12 +96,12 @@
two words two words
</div> </div>
<div id="dbr3">oneword<br/><br/>two words<br/></div> <div id="dbr3">oneword<br/><br/>two words<br/><br/></div>
<div id="e3" contenteditable="true">oneword <div id="e3" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/></div> <div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
<textarea id="t3" cols="300">oneword <textarea id="t3" cols="300">oneword
two words two words

View File

@ -74,7 +74,7 @@
testCharacterCount(IDs, 5); testCharacterCount(IDs, 5);
testText(IDs, 0, 5, "1.foo"); testText(IDs, 0, 5, "1.foo");
testText(["testbr"], 0, 4, "foo\n"); testText(["testbr"], 0, 3, "foo");
testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr", testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr",
kOk, kOk, kOk); kOk, kOk, kOk);

View File

@ -50,6 +50,7 @@
[ 8, 8, "oneword\n", 0, 8 ], [ 8, 8, "oneword\n", 0, 8 ],
[ 9, 18, "\n", 8, 9 ], [ 9, 18, "\n", 8, 9 ],
[ 19, 19, "two words\n", 9, 19 ]]); [ 19, 19, "two words\n", 9, 19 ]]);
testTextBeforeOffset(IDs, BOUNDARY_LINE_END, testTextBeforeOffset(IDs, BOUNDARY_LINE_END,
[ [ 0, 7, "", 0, 0 ], [ [ 0, 7, "", 0, 0 ],
[ 8, 8, "oneword", 0, 7 ], [ 8, 8, "oneword", 0, 7 ],
@ -96,7 +97,17 @@
testTextAfterOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END, testTextAfterOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END,
[ [ 0, 5, "", 5, 5 ] ]); [ [ 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 ] ]);
SimpleTest.finish(); SimpleTest.finish();
} }
@ -135,16 +146,16 @@
src="data:text/html,<html><body><textarea id='ta'>hello my friend</textarea></body></html>"></iframe> src="data:text/html,<html><body><textarea id='ta'>hello my friend</textarea></body></html>"></iframe>
<pre> <pre>
<div id="ml_div">oneword <div id="ml_div" style="border-style:outset;">oneword
two words two words
</div> </div>
<div id="ml_divbr">oneword<br/><br/>two words<br/></div> <div id="ml_divbr" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div>
<div id="ml_editable" contenteditable="true">oneword <div id="ml_editable" style="border-style:outset;" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ml_editablebr" contenteditable="true">oneword<br/><br/>two words<br/></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 <textarea id="ml_textarea" cols="300">oneword
two words two words
@ -152,5 +163,8 @@ two words
</pre> </pre>
<iframe id="ht_1" src="data:text/html,<html><body>a <a href=''>b</a> c</body></html>"></iframe> <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>
</body> </body>
</html> </html>

View File

@ -268,12 +268,12 @@
two words two words
</div> </div>
<div id="ml_divbr1">oneword<br/><br/>two words<br/></div> <div id="ml_divbr1">oneword<br/><br/>two words<br/><br/></div>
<div id="ml_ediv1" contenteditable="true">oneword <div id="ml_ediv1" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/></div> <div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
<textarea id="ml_t1" cols="300">oneword <textarea id="ml_t1" cols="300">oneword
two words two words