Bug 975065 - implement Text accessible text range methods, r=tbsaunde

This commit is contained in:
Alexander Surkov 2014-04-16 08:50:28 -04:00
parent a10ec8bc68
commit 710da7d2d2
9 changed files with 154 additions and 8 deletions

View File

@ -23,3 +23,15 @@ TextRange::Text(nsAString& aText) const
{
}
void
TextRange::Set(HyperTextAccessible* aRoot,
Accessible* aStartContainer, int32_t aStartOffset,
Accessible* aEndContainer, int32_t aEndOffset)
{
mRoot = aRoot;
mStartContainer = aStartContainer;
mEndContainer = aEndContainer;
mStartOffset = aStartOffset;
mEndOffset = aEndOffset;
}

View File

@ -31,6 +31,16 @@ public:
mEndContainer(Move(aRange.mEndContainer)),
mStartOffset(aRange.mStartOffset), mEndOffset(aRange.mEndOffset) {}
TextRange& operator= (TextRange&& aRange)
{
mRoot = Move(aRange.mRoot);
mStartContainer = Move(aRange.mStartContainer);
mEndContainer = Move(aRange.mEndContainer);
mStartOffset = aRange.mStartOffset;
mEndOffset = aRange.mEndOffset;
return *this;
}
Accessible* StartContainer() const { return mStartContainer; }
int32_t StartOffset() const { return mStartOffset; }
Accessible* EndContainer() const { return mEndContainer; }
@ -47,12 +57,17 @@ public:
bool IsValid() const { return mRoot; }
private:
TextRange(const TextRange& aRange) MOZ_DELETE;
TextRange& operator=(const TextRange& aRange) MOZ_DELETE;
friend class HyperTextAccessible;
friend class xpcAccessibleTextRange;
TextRange(const TextRange&) MOZ_DELETE;
TextRange& operator=(const TextRange&) MOZ_DELETE;
void Set(HyperTextAccessible* aRoot,
Accessible* aStartContainer, int32_t aStartOffset,
Accessible* aEndContainer, int32_t aEndOffset);
const nsRefPtr<HyperTextAccessible> mRoot;
nsRefPtr<HyperTextAccessible> mRoot;
nsRefPtr<Accessible> mStartContainer;
nsRefPtr<Accessible> mEndContainer;
int32_t mStartOffset;

View File

@ -1508,11 +1508,45 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
void
HyperTextAccessible::EnclosingRange(a11y::TextRange& aRange) const
{
if (IsTextField()) {
aRange.Set(mDoc, const_cast<HyperTextAccessible*>(this), 0,
const_cast<HyperTextAccessible*>(this), ChildCount());
} else {
aRange.Set(mDoc, mDoc, 0, mDoc, mDoc->ChildCount());
}
}
void
HyperTextAccessible::SelectionRanges(nsTArray<a11y::TextRange>* aRanges) const
{
NS_ASSERTION(aRanges->Length() != 0, "TextRange array supposed to be empty");
Selection* sel = DOMSelection();
if (!sel)
return;
aRanges->SetCapacity(sel->RangeCount());
for (uint32_t idx = 0; idx < sel->RangeCount(); idx++) {
nsRange* DOMRange = sel->GetRangeAt(idx);
HyperTextAccessible* startParent =
nsAccUtils::GetTextContainer(DOMRange->GetStartParent());
HyperTextAccessible* endParent =
nsAccUtils::GetTextContainer(DOMRange->GetEndParent());
if (!startParent || !endParent)
continue;
int32_t startOffset =
startParent->DOMPointToOffset(DOMRange->GetStartParent(),
DOMRange->StartOffset(), false);
int32_t endOffset =
endParent->DOMPointToOffset(DOMRange->GetEndParent(),
DOMRange->EndOffset(), true);
TextRange tr(IsTextField() ? const_cast<HyperTextAccessible*>(this) : mDoc,
startParent, startOffset, endParent, endOffset);
*(aRanges->AppendElement()) = Move(tr);
}
}
void
@ -1524,12 +1558,16 @@ void
HyperTextAccessible::RangeByChild(Accessible* aChild,
a11y::TextRange& aRange) const
{
aRange.Set(mDoc, aChild, 0, aChild, aChild->ChildCount());
}
void
HyperTextAccessible::RangeAtPoint(int32_t aX, int32_t aY,
a11y::TextRange& aRange) const
{
Accessible* child = mDoc->ChildAtPoint(aX, aY, eDeepestChild);
if (child)
aRange.Set(mDoc, child, 0, child, child->ChildCount());
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -12,8 +12,20 @@
using namespace mozilla;
using namespace mozilla::a11y;
// nsISupports
NS_IMPL_ISUPPORTS1(xpcAccessibleTextRange, nsIAccessibleTextRange)
// nsISupports and cycle collection
NS_IMPL_CYCLE_COLLECTION_3(xpcAccessibleTextRange,
mRange.mRoot,
mRange.mStartContainer,
mRange.mEndContainer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleTextRange)
NS_INTERFACE_MAP_ENTRY(nsIAccessibleTextRange)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleTextRange)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleTextRange)
NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleTextRange)
// nsIAccessibleTextRange
@ -21,7 +33,7 @@ NS_IMETHODIMP
xpcAccessibleTextRange::GetStartContainer(nsIAccessible** aAnchor)
{
NS_ENSURE_ARG_POINTER(aAnchor);
*aAnchor = static_cast<nsIAccessible*>(mRange.StartContainer());
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessible*>(mRange.StartContainer()));
return NS_OK;
}
@ -37,7 +49,7 @@ NS_IMETHODIMP
xpcAccessibleTextRange::GetEndContainer(nsIAccessible** aAnchor)
{
NS_ENSURE_ARG_POINTER(aAnchor);
*aAnchor = static_cast<nsIAccessible*>(mRange.EndContainer());
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessible*>(mRange.EndContainer()));
return NS_OK;
}

View File

@ -11,6 +11,7 @@
#include "TextRange.h"
#include "mozilla/Move.h"
#include "nsCycleCollectionParticipant.h"
namespace mozilla {
namespace a11y {
@ -20,7 +21,8 @@ class TextRange;
class xpcAccessibleTextRange MOZ_FINAL : public nsIAccessibleTextRange
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(xpcAccessibleTextRange)
NS_IMETHOD GetStartContainer(nsIAccessible** aAnchor) MOZ_FINAL MOZ_OVERRIDE;
NS_IMETHOD GetStartOffset(int32_t* aOffset) MOZ_FINAL MOZ_OVERRIDE;

View File

@ -34,5 +34,6 @@ DIRS += [
A11Y_MANIFESTS += [
'a11y.ini',
'events/a11y.ini',
'textrange/a11y.ini',
'tree/a11y.ini',
]

View File

@ -457,6 +457,19 @@ function testTextGetSelection(aID, aStartOffset, aEndOffset, aSelectionIndex)
aSelectionIndex + "'");
}
function testTextRange(aRange, aStartContainer, aStartOffset,
aEndContainer, aEndOffset)
{
is(aRange.startContainer, getAccessible(aStartContainer),
"Wrong start container");
is(aRange.startOffset, aStartOffset,
"Wrong start offset");
is(aRange.endContainer, getAccessible(aEndContainer),
"Wrong end container");
is(aRange.endOffset, aEndOffset,
"Wrong end offset");
}
////////////////////////////////////////////////////////////////////////////////
// Private

View File

@ -0,0 +1,3 @@
[DEFAULT]
[test_general.html]

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>Text Range 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()
{
var input = getAccessible("input", [ nsIAccessibleText ]);
testTextRange(input.enclosingRange, input, 0, input, 1);
var ta = getAccessible("textarea", [ nsIAccessibleText ]);
testTextRange(ta.enclosingRange, ta, 0, ta, 1);
var iframeDoc = getAccessible(getNode("iframe").contentDocument,
[ nsIAccessibleText ]);
testTextRange(iframeDoc.enclosingRange, iframeDoc, 0, iframeDoc, 1);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Implement Text accessible text range methods"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=975065">Bug 975065</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input id="input" value="hello">
<textarea id="textarea">hello</textarea>
<iframe id="iframe" src="data:text/html,<p>hello</p>"></iframe>
</body>
</html>