зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1011496 - complete the TextRange interface design, r=davidb
This commit is contained in:
Родитель
ce84878818
Коммит
c17e4c94f4
|
@ -6,20 +6,149 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIAccessible;
|
||||
interface nsIAccessibleText;
|
||||
interface nsIArray;
|
||||
interface nsIVariant;
|
||||
|
||||
/**
|
||||
* A range representing a piece of text in the document.
|
||||
*/
|
||||
[scriptable, uuid(6fe17c33-6709-4d7a-9ba0-3d448c4b3ef4)]
|
||||
[scriptable, uuid(525b3401-8a67-4822-b35d-661065767cd8)]
|
||||
interface nsIAccessibleTextRange : nsISupports
|
||||
{
|
||||
readonly attribute nsIAccessible startContainer;
|
||||
readonly attribute nsIAccessibleText startContainer;
|
||||
readonly attribute long startOffset;
|
||||
readonly attribute nsIAccessible endContainer;
|
||||
readonly attribute nsIAccessibleText endContainer;
|
||||
readonly attribute long endOffset;
|
||||
|
||||
/**
|
||||
* Return an accessible containing the whole range
|
||||
*/
|
||||
readonly attribute nsIAccessible container;
|
||||
|
||||
/**
|
||||
* Return embedded children within the range.
|
||||
*/
|
||||
readonly attribute nsIArray embeddedChildren;
|
||||
|
||||
/**
|
||||
* Return true if this range has the same end points of the given range.
|
||||
*/
|
||||
boolean compare(in nsIAccessibleTextRange aOtherRange);
|
||||
|
||||
/**
|
||||
* The two endpoints of the range (starting and ending).
|
||||
*/
|
||||
const unsigned long EndPoint_Start = 1;
|
||||
const unsigned long EndPoint_End = 2;
|
||||
|
||||
/**
|
||||
* Compare this and given ranges end points.
|
||||
*
|
||||
* @return -1/0/1 if this range end point is before/equal/after the given
|
||||
* range end point.
|
||||
*/
|
||||
long compareEndPoints(in unsigned long aEndPoint,
|
||||
in nsIAccessibleTextRange aOtherRange,
|
||||
in unsigned long aOtherRangeEndPoint);
|
||||
|
||||
/**
|
||||
* Return text within the range.
|
||||
*/
|
||||
readonly attribute AString text;
|
||||
|
||||
/**
|
||||
* Return list of rects of the range.
|
||||
*/
|
||||
readonly attribute nsIArray bounds;
|
||||
|
||||
const unsigned long FormatUnit = 0;
|
||||
const unsigned long WordUnit = 1;
|
||||
const unsigned long LineUnit = 2;
|
||||
const unsigned long ParagraphUnit = 3;
|
||||
const unsigned long PageUnit = 4;
|
||||
const unsigned long DocumentUnit = 5;
|
||||
|
||||
/**
|
||||
* Move the boundary(ies) by the given number of the unit.
|
||||
*/
|
||||
void move(in unsigned long aUnit, in long aCount);
|
||||
void moveStart(in unsigned long aUnit, in long aCount);
|
||||
void moveEnd(in unsigned long aUnit, in long aCount);
|
||||
|
||||
/**
|
||||
* Normalize the range to the closest unit of the given type.
|
||||
*/
|
||||
void normalize(in unsigned long aUnit);
|
||||
|
||||
/**
|
||||
* Return range enclosing the found text.
|
||||
*/
|
||||
nsIAccessibleTextRange findText(in AString aText, in boolean aIsBackward,
|
||||
in boolean aIsIgnoreCase);
|
||||
|
||||
/**
|
||||
* Text attributes. Used in conjunction with findAttrs().
|
||||
*/
|
||||
const unsigned long AnimationStyleAttr = 0;
|
||||
const unsigned long AnnotationObjectsAttr = 1;
|
||||
const unsigned long AnnotationTypesAttr = 2;
|
||||
const unsigned long BackgroundColorAttr = 3;
|
||||
const unsigned long BulletStyleAttr = 4;
|
||||
const unsigned long CapStyleAttr = 5;
|
||||
const unsigned long CaretBidiModeAttr = 6;
|
||||
const unsigned long CaretPositionAttr = 7;
|
||||
const unsigned long CultureAttr = 8;
|
||||
const unsigned long FontNameAttr = 9;
|
||||
const unsigned long FontSizeAttr = 10;
|
||||
const unsigned long FontWeightAttr = 11;
|
||||
const unsigned long ForegroundColorAttr = 12;
|
||||
const unsigned long HorizontalTextAlignmentAttr = 13;
|
||||
const unsigned long IndentationFirstLineAttr = 14;
|
||||
const unsigned long IndentationLeadingAttr = 15;
|
||||
const unsigned long IndentationTrailingAttr = 16;
|
||||
const unsigned long IsActiveAttr = 17;
|
||||
const unsigned long IsHiddenAttr = 18;
|
||||
const unsigned long IsItalicAttr = 19;
|
||||
const unsigned long IsReadOnlyAttr = 20;
|
||||
const unsigned long IsSubscriptAttr = 21;
|
||||
const unsigned long IsSuperscriptAttr = 22;
|
||||
const unsigned long LinkAttr = 23;
|
||||
const unsigned long MarginBottomAttr = 24;
|
||||
const unsigned long MarginLeadingAttr = 25;
|
||||
const unsigned long MarginTopAttr = 26;
|
||||
const unsigned long MarginTrailingAttr = 27;
|
||||
const unsigned long OutlineStylesAttr = 28;
|
||||
const unsigned long OverlineColorAttr = 29;
|
||||
const unsigned long OverlineStyleAttr = 30;
|
||||
const unsigned long SelectionActiveEndAttr = 31;
|
||||
const unsigned long StrikethroughColorAttr = 32;
|
||||
const unsigned long StrikethroughStyleAttr = 33;
|
||||
const unsigned long StyleIdAttr = 34;
|
||||
const unsigned long StyleNameAttr = 35;
|
||||
const unsigned long TabsAttr = 36;
|
||||
const unsigned long TextFlowDirectionsAttr = 37;
|
||||
const unsigned long UnderlineColorAttr = 38;
|
||||
const unsigned long UnderlineStyleAttr = 39;
|
||||
|
||||
/**
|
||||
* Return range enslosing the text having requested attribute.
|
||||
*/
|
||||
nsIAccessibleTextRange findAttr(in unsigned long aAttr, in nsIVariant aValue,
|
||||
in boolean aIsBackward);
|
||||
|
||||
/**
|
||||
* Add/remove the text range from selection.
|
||||
*/
|
||||
void addToSelection();
|
||||
void removeFromSelection();
|
||||
void select();
|
||||
|
||||
const unsigned long AlignToTop = 0;
|
||||
const unsigned long AlignToBottom = 1;
|
||||
|
||||
/**
|
||||
* Scroll the range into view.
|
||||
*/
|
||||
void scrollIntoView(in unsigned long aHow);
|
||||
};
|
||||
|
|
|
@ -7,27 +7,237 @@
|
|||
#include "TextRange.h"
|
||||
|
||||
#include "HyperTextAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TextPoint
|
||||
|
||||
bool
|
||||
TextPoint::operator <(const TextPoint& aPoint) const
|
||||
{
|
||||
if (mContainer == aPoint.mContainer)
|
||||
return mOffset < aPoint.mOffset;
|
||||
|
||||
// Build the chain of parents
|
||||
Accessible* p1 = mContainer;
|
||||
Accessible* p2 = aPoint.mContainer;
|
||||
nsAutoTArray<Accessible*, 30> parents1, parents2;
|
||||
do {
|
||||
parents1.AppendElement(p1);
|
||||
p1 = p1->Parent();
|
||||
} while (p1);
|
||||
do {
|
||||
parents2.AppendElement(p2);
|
||||
p2 = p2->Parent();
|
||||
} while (p2);
|
||||
|
||||
// Find where the parent chain differs
|
||||
uint32_t pos1 = parents1.Length(), pos2 = parents2.Length();
|
||||
for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
|
||||
Accessible* child1 = parents1.ElementAt(--pos1);
|
||||
Accessible* child2 = parents2.ElementAt(--pos2);
|
||||
if (child1 != child2)
|
||||
return child1->IndexInParent() < child2->IndexInParent();
|
||||
}
|
||||
|
||||
NS_ERROR("Broken tree?!");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TextRange
|
||||
|
||||
TextRange::TextRange(HyperTextAccessible* aRoot,
|
||||
Accessible* aStartContainer, int32_t aStartOffset,
|
||||
Accessible* aEndContainer, int32_t aEndOffset) :
|
||||
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||
HyperTextAccessible* aEndContainer, int32_t aEndOffset) :
|
||||
mRoot(aRoot), mStartContainer(aStartContainer), mEndContainer(aEndContainer),
|
||||
mStartOffset(aStartOffset), mEndOffset(aEndOffset)
|
||||
{
|
||||
}
|
||||
|
||||
Accessible*
|
||||
TextRange::Container() const
|
||||
{
|
||||
if (mStartContainer == mEndContainer)
|
||||
return mStartContainer;
|
||||
|
||||
// Build the chain of parents
|
||||
Accessible* p1 = mStartContainer;
|
||||
Accessible* p2 = mEndContainer;
|
||||
nsAutoTArray<Accessible*, 30> parents1, parents2;
|
||||
do {
|
||||
parents1.AppendElement(p1);
|
||||
p1 = p1->Parent();
|
||||
} while (p1);
|
||||
do {
|
||||
parents2.AppendElement(p2);
|
||||
p2 = p2->Parent();
|
||||
} while (p2);
|
||||
|
||||
// Find where the parent chain differs
|
||||
uint32_t pos1 = parents1.Length();
|
||||
uint32_t pos2 = parents2.Length();
|
||||
Accessible* parent = nullptr;
|
||||
uint32_t len = 0;
|
||||
for (len = std::min(pos1, pos2); len > 0; --len) {
|
||||
Accessible* child1 = parents1.ElementAt(--pos1);
|
||||
Accessible* child2 = parents2.ElementAt(--pos2);
|
||||
if (child1 != child2)
|
||||
break;
|
||||
|
||||
parent = child1;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::EmbeddedChildren(nsTArray<Accessible*>* aChildren) const
|
||||
{
|
||||
if (mStartContainer == mEndContainer) {
|
||||
int32_t startIdx = mStartContainer->GetChildIndexAtOffset(mStartOffset);
|
||||
int32_t endIdx = mStartContainer->GetChildIndexAtOffset(mEndOffset);
|
||||
for (int32_t idx = startIdx; idx <= endIdx; idx++) {
|
||||
Accessible* child = mStartContainer->GetChildAt(idx);
|
||||
if (nsAccUtils::IsEmbeddedObject(child))
|
||||
aChildren->AppendElement(child);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Accessible* p1 = mStartContainer->GetChildAtOffset(mStartOffset);
|
||||
Accessible* p2 = mEndContainer->GetChildAtOffset(mEndOffset);
|
||||
nsAutoTArray<Accessible*, 30> parents1, parents2;
|
||||
do {
|
||||
parents1.AppendElement(p1);
|
||||
p1 = p1->Parent();
|
||||
} while (p1);
|
||||
do {
|
||||
parents2.AppendElement(p2);
|
||||
p2 = p2->Parent();
|
||||
} while (p2);
|
||||
|
||||
// Find deepest common container.
|
||||
uint32_t pos1 = parents1.Length();
|
||||
uint32_t pos2 = parents2.Length();
|
||||
Accessible* container = nullptr;
|
||||
for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
|
||||
Accessible* child1 = parents1.ElementAt(--pos1);
|
||||
Accessible* child2 = parents2.ElementAt(--pos2);
|
||||
if (child1 != child2)
|
||||
break;
|
||||
|
||||
container = child1;
|
||||
}
|
||||
|
||||
// Traverse the tree up to the container and collect embedded objects.
|
||||
for (uint32_t idx = 0; idx < pos1 - 1; idx++) {
|
||||
Accessible* parent = parents1[idx + 1];
|
||||
Accessible* child = parents1[idx];
|
||||
uint32_t childCount = parent->ChildCount();
|
||||
for (uint32_t childIdx = child->IndexInParent(); childIdx < childCount; childIdx++) {
|
||||
Accessible* next = parent->GetChildAt(childIdx);
|
||||
if (nsAccUtils::IsEmbeddedObject(next))
|
||||
aChildren->AppendElement(next);
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse through direct children in the container.
|
||||
int32_t endIdx = parents2[pos2 - 1]->IndexInParent();
|
||||
int32_t childIdx = parents1[pos1 - 1]->IndexInParent() + 1;
|
||||
for (; childIdx < endIdx; childIdx++) {
|
||||
Accessible* next = container->GetChildAt(childIdx);
|
||||
if (nsAccUtils::IsEmbeddedObject(next))
|
||||
aChildren->AppendElement(next);
|
||||
}
|
||||
|
||||
// Traverse down from the container to end point.
|
||||
for (int32_t idx = pos2 - 2; idx > 0; idx--) {
|
||||
Accessible* parent = parents2[idx];
|
||||
Accessible* child = parents2[idx - 1];
|
||||
int32_t endIdx = child->IndexInParent();
|
||||
for (int32_t childIdx = 0; childIdx < endIdx; childIdx++) {
|
||||
Accessible* next = parent->GetChildAt(childIdx);
|
||||
if (nsAccUtils::IsEmbeddedObject(next))
|
||||
aChildren->AppendElement(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::Text(nsAString& aText) const
|
||||
{
|
||||
Accessible* current = mStartContainer->GetChildAtOffset(mStartOffset);
|
||||
uint32_t startIntlOffset =
|
||||
mStartOffset - mStartContainer->GetChildOffset(current);
|
||||
|
||||
while (current && TextInternal(aText, current, startIntlOffset)) {
|
||||
current = current->Parent();
|
||||
if (!current)
|
||||
break;
|
||||
|
||||
current = current->NextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::Bounds(nsTArray<nsIntRect> aRects) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::Normalize(ETextUnit aUnit)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::FindText(const nsAString& aText, EDirection aDirection,
|
||||
nsCaseTreatment aCaseSensitive, TextRange* aFoundRange) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::FindAttr(EAttr aAttr, nsIVariant* aValue, EDirection aDirection,
|
||||
TextRange* aFoundRange) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::AddToSelection() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::RemoveFromSelection() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::Select() const
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TextRange::ScrollIntoView(EHowToAlign aHow) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// pivate
|
||||
|
||||
void
|
||||
TextRange::Set(HyperTextAccessible* aRoot,
|
||||
Accessible* aStartContainer, int32_t aStartOffset,
|
||||
Accessible* aEndContainer, int32_t aEndOffset)
|
||||
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||
HyperTextAccessible* aEndContainer, int32_t aEndOffset)
|
||||
{
|
||||
mRoot = aRoot;
|
||||
mStartContainer = aStartContainer;
|
||||
|
@ -35,3 +245,51 @@ TextRange::Set(HyperTextAccessible* aRoot,
|
|||
mStartOffset = aStartOffset;
|
||||
mEndOffset = aEndOffset;
|
||||
}
|
||||
|
||||
bool
|
||||
TextRange::TextInternal(nsAString& aText, Accessible* aCurrent,
|
||||
uint32_t aStartIntlOffset) const
|
||||
{
|
||||
bool moveNext = true;
|
||||
int32_t endIntlOffset = -1;
|
||||
if (aCurrent->Parent() == mEndContainer &&
|
||||
mEndContainer->GetChildAtOffset(mEndOffset) == aCurrent) {
|
||||
|
||||
uint32_t currentStartOffset = mEndContainer->GetChildOffset(aCurrent);
|
||||
endIntlOffset = mEndOffset - currentStartOffset;
|
||||
if (endIntlOffset == 0)
|
||||
return false;
|
||||
|
||||
moveNext = false;
|
||||
}
|
||||
|
||||
if (aCurrent->IsTextLeaf()) {
|
||||
aCurrent->AppendTextTo(aText, aStartIntlOffset,
|
||||
endIntlOffset - aStartIntlOffset);
|
||||
if (!moveNext)
|
||||
return false;
|
||||
}
|
||||
|
||||
Accessible* next = aCurrent->FirstChild();
|
||||
if (next) {
|
||||
if (!TextInternal(aText, next, 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
next = aCurrent->NextSibling();
|
||||
if (next) {
|
||||
if (!TextInternal(aText, next, 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
return moveNext;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TextRange::MoveInternal(ETextUnit aUnit, int32_t aCount,
|
||||
HyperTextAccessible& aContainer, int32_t aOffset,
|
||||
HyperTextAccessible* aStopContainer, int32_t aStopOffset)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIVariant;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
@ -16,6 +21,24 @@ namespace a11y {
|
|||
class Accessible;
|
||||
class HyperTextAccessible;
|
||||
|
||||
/**
|
||||
* A text point (hyper text + offset), represents a boundary of text range.
|
||||
*/
|
||||
struct TextPoint MOZ_FINAL
|
||||
{
|
||||
TextPoint(HyperTextAccessible* aContainer, int32_t aOffset) :
|
||||
mContainer(aContainer), mOffset(aOffset) { }
|
||||
TextPoint(const TextPoint& aPoint) :
|
||||
mContainer(aPoint.mContainer), mOffset(aPoint.mOffset) { }
|
||||
|
||||
HyperTextAccessible* mContainer;
|
||||
int32_t mOffset;
|
||||
|
||||
bool operator ==(const TextPoint& aPoint) const
|
||||
{ return mContainer == aPoint.mContainer && mOffset == aPoint.mOffset; }
|
||||
bool operator <(const TextPoint& aPoint) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a text range within the text control or document.
|
||||
*/
|
||||
|
@ -23,39 +46,177 @@ class TextRange MOZ_FINAL
|
|||
{
|
||||
public:
|
||||
TextRange(HyperTextAccessible* aRoot,
|
||||
Accessible* aStartContainer, int32_t aStartOffset,
|
||||
Accessible* aEndContainer, int32_t aEndOffset);
|
||||
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||
HyperTextAccessible* aEndContainer, int32_t aEndOffset);
|
||||
TextRange() {}
|
||||
TextRange(TextRange&& aRange) :
|
||||
mRoot(Move(aRange.mRoot)), mStartContainer(Move(aRange.mStartContainer)),
|
||||
mEndContainer(Move(aRange.mEndContainer)),
|
||||
mRoot(mozilla::Move(aRange.mRoot)),
|
||||
mStartContainer(mozilla::Move(aRange.mStartContainer)),
|
||||
mEndContainer(mozilla::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);
|
||||
mRoot = mozilla::Move(aRange.mRoot);
|
||||
mStartContainer = mozilla::Move(aRange.mStartContainer);
|
||||
mEndContainer = mozilla::Move(aRange.mEndContainer);
|
||||
mStartOffset = aRange.mStartOffset;
|
||||
mEndOffset = aRange.mEndOffset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Accessible* StartContainer() const { return mStartContainer; }
|
||||
HyperTextAccessible* StartContainer() const { return mStartContainer; }
|
||||
int32_t StartOffset() const { return mStartOffset; }
|
||||
Accessible* EndContainer() const { return mEndContainer; }
|
||||
HyperTextAccessible* EndContainer() const { return mEndContainer; }
|
||||
int32_t EndOffset() const { return mEndOffset; }
|
||||
|
||||
bool operator ==(const TextRange& aRange) const
|
||||
{
|
||||
return mStartContainer == aRange.mStartContainer &&
|
||||
mStartOffset == aRange.mStartOffset &&
|
||||
mEndContainer == aRange.mEndContainer && mEndOffset == aRange.mEndOffset;
|
||||
}
|
||||
|
||||
TextPoint StartPoint() const { return TextPoint(mStartContainer, mStartOffset); }
|
||||
TextPoint EndPoint() const { return TextPoint(mEndContainer, mEndOffset); }
|
||||
|
||||
/**
|
||||
* Return a container containing both start and end points.
|
||||
*/
|
||||
Accessible* Container() const;
|
||||
|
||||
/**
|
||||
* Return a list of embedded objects enclosed by the text range (includes
|
||||
* partially overlapped objects).
|
||||
*/
|
||||
void EmbeddedChildren(nsTArray<Accessible*>* aChildren) const;
|
||||
|
||||
/**
|
||||
* Return text enclosed by the range.
|
||||
*/
|
||||
void Text(nsAString& aText) const;
|
||||
|
||||
/**
|
||||
* Return list of bounding rects of the text range by lines.
|
||||
*/
|
||||
void Bounds(nsTArray<nsIntRect> aRects) const;
|
||||
|
||||
enum ETextUnit {
|
||||
eFormat,
|
||||
eWord,
|
||||
eLine,
|
||||
eParagraph,
|
||||
ePage,
|
||||
eDocument
|
||||
};
|
||||
|
||||
/**
|
||||
* Move the range or its points on specified amount of given units.
|
||||
*/
|
||||
void Move(ETextUnit aUnit, int32_t aCount)
|
||||
{
|
||||
MoveEnd(aUnit, aCount);
|
||||
MoveStart(aUnit, aCount);
|
||||
}
|
||||
void MoveStart(ETextUnit aUnit, int32_t aCount)
|
||||
{
|
||||
MoveInternal(aUnit, aCount, *mStartContainer, mStartOffset,
|
||||
mEndContainer, mEndOffset);
|
||||
}
|
||||
void MoveEnd(ETextUnit aUnit, int32_t aCount)
|
||||
{ MoveInternal(aUnit, aCount, *mEndContainer, mEndOffset); }
|
||||
|
||||
/**
|
||||
* Move the range points to the closest unit boundaries.
|
||||
*/
|
||||
void Normalize(ETextUnit aUnit);
|
||||
|
||||
enum EDirection {
|
||||
eBackward,
|
||||
eForward
|
||||
};
|
||||
|
||||
/**
|
||||
* Return range enclosing the found text.
|
||||
*/
|
||||
void FindText(const nsAString& aText, EDirection aDirection,
|
||||
nsCaseTreatment aCaseSensitive, TextRange* aFoundRange) const;
|
||||
|
||||
enum EAttr {
|
||||
eAnimationStyleAttr,
|
||||
eAnnotationObjectsAttr,
|
||||
eAnnotationTypesAttr,
|
||||
eBackgroundColorAttr,
|
||||
eBulletStyleAttr,
|
||||
eCapStyleAttr,
|
||||
eCaretBidiModeAttr,
|
||||
eCaretPositionAttr,
|
||||
eCultureAttr,
|
||||
eFontNameAttr,
|
||||
eFontSizeAttr,
|
||||
eFontWeightAttr,
|
||||
eForegroundColorAttr,
|
||||
eHorizontalTextAlignmentAttr,
|
||||
eIndentationFirstLineAttr,
|
||||
eIndentationLeadingAttr,
|
||||
eIndentationTrailingAttr,
|
||||
eIsActiveAttr,
|
||||
eIsHiddenAttr,
|
||||
eIsItalicAttr,
|
||||
eIsReadOnlyAttr,
|
||||
eIsSubscriptAttr,
|
||||
eIsSuperscriptAttr,
|
||||
eLinkAttr,
|
||||
eMarginBottomAttr,
|
||||
eMarginLeadingAttr,
|
||||
eMarginTopAttr,
|
||||
eMarginTrailingAttr,
|
||||
eOutlineStylesAttr,
|
||||
eOverlineColorAttr,
|
||||
eOverlineStyleAttr,
|
||||
eSelectionActiveEndAttr,
|
||||
eStrikethroughColorAttr,
|
||||
eStrikethroughStyleAttr,
|
||||
eStyleIdAttr,
|
||||
eStyleNameAttr,
|
||||
eTabsAttr,
|
||||
eTextFlowDirectionsAttr,
|
||||
eUnderlineColorAttr,
|
||||
eUnderlineStyleAttr
|
||||
};
|
||||
|
||||
/**
|
||||
* Return range enclosing text having requested attribute.
|
||||
*/
|
||||
void FindAttr(EAttr aAttr, nsIVariant* aValue, EDirection aDirection,
|
||||
TextRange* aFoundRange) const;
|
||||
|
||||
/**
|
||||
* Add/remove the text range from selection.
|
||||
*/
|
||||
void AddToSelection() const;
|
||||
void RemoveFromSelection() const;
|
||||
void Select() const;
|
||||
|
||||
/**
|
||||
* Scroll the text range into view.
|
||||
*/
|
||||
enum EHowToAlign {
|
||||
eAlignToTop,
|
||||
eAlignToBottom
|
||||
};
|
||||
void ScrollIntoView(EHowToAlign aHow) const;
|
||||
|
||||
/**
|
||||
* Return true if this TextRange object represents an actual range of text.
|
||||
*/
|
||||
bool IsValid() const { return mRoot; }
|
||||
|
||||
void SetStartPoint(HyperTextAccessible* aContainer, int32_t aOffset)
|
||||
{ mStartContainer = aContainer; mStartOffset = aOffset; }
|
||||
void SetEndPoint(HyperTextAccessible* aContainer, int32_t aOffset)
|
||||
{ mStartContainer = aContainer; mStartOffset = aOffset; }
|
||||
|
||||
private:
|
||||
TextRange(const TextRange& aRange) MOZ_DELETE;
|
||||
TextRange& operator=(const TextRange& aRange) MOZ_DELETE;
|
||||
|
@ -64,12 +225,27 @@ private:
|
|||
friend class xpcAccessibleTextRange;
|
||||
|
||||
void Set(HyperTextAccessible* aRoot,
|
||||
Accessible* aStartContainer, int32_t aStartOffset,
|
||||
Accessible* aEndContainer, int32_t aEndOffset);
|
||||
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||
HyperTextAccessible* aEndContainer, int32_t aEndOffset);
|
||||
|
||||
/**
|
||||
* Text() method helper.
|
||||
* @param aText [in,out] calculated text
|
||||
* @param aCurrent [in] currently traversed node
|
||||
* @param aStartIntlOffset [in] start offset if current node is a text node
|
||||
* @return true if calculation is not finished yet
|
||||
*/
|
||||
bool TextInternal(nsAString& aText, Accessible* aCurrent,
|
||||
uint32_t aStartIntlOffset) const;
|
||||
|
||||
void MoveInternal(ETextUnit aUnit, int32_t aCount,
|
||||
HyperTextAccessible& aContainer, int32_t aOffset,
|
||||
HyperTextAccessible* aStopContainer = nullptr,
|
||||
int32_t aStopOffset = 0);
|
||||
|
||||
nsRefPtr<HyperTextAccessible> mRoot;
|
||||
nsRefPtr<Accessible> mStartContainer;
|
||||
nsRefPtr<Accessible> mEndContainer;
|
||||
nsRefPtr<HyperTextAccessible> mStartContainer;
|
||||
nsRefPtr<HyperTextAccessible> mEndContainer;
|
||||
int32_t mStartOffset;
|
||||
int32_t mEndOffset;
|
||||
};
|
||||
|
|
|
@ -120,7 +120,7 @@ Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
|
|||
#ifdef NS_DEBUG_X
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aShell));
|
||||
printf(">>> %p Created Acc - DOM: %p PS: %p",
|
||||
printf(">>> %p Created Acc - DOM: %p PS: %p",
|
||||
(void*)static_cast<nsIAccessible*>(this), (void*)aNode,
|
||||
(void*)shell.get());
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||
|
@ -267,7 +267,7 @@ Accessible::Description(nsString& aDescription)
|
|||
// 1. it's a text node; or
|
||||
// 2. It has no DHTML describedby property
|
||||
// 3. it doesn't have an accName; or
|
||||
// 4. its title attribute already equals to its accName nsAutoString name;
|
||||
// 4. its title attribute already equals to its accName nsAutoString name;
|
||||
|
||||
if (!HasOwnContent() || mContent->IsNodeOfType(nsINode::eTEXT))
|
||||
return;
|
||||
|
@ -550,7 +550,7 @@ Accessible::GetIndexInParent(int32_t* aIndexInParent)
|
|||
return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
|
@ -560,7 +560,7 @@ Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
|||
|
||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||
stringBundleService->CreateBundle(
|
||||
"chrome://global-platform/locale/accessible.properties",
|
||||
"chrome://global-platform/locale/accessible.properties",
|
||||
getter_AddRefs(stringBundle));
|
||||
if (!stringBundle)
|
||||
return;
|
||||
|
@ -1104,7 +1104,7 @@ Accessible::XULElmName(DocAccessible* aDocument,
|
|||
itemEl->GetLabel(aName);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMXULSelectControlElement> select = do_QueryInterface(aElm);
|
||||
// Use label if this is not a select control element which
|
||||
// Use label if this is not a select control element which
|
||||
// uses label attribute to indicate which option is selected
|
||||
if (!select) {
|
||||
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aElm));
|
||||
|
@ -1578,7 +1578,7 @@ Accessible::ApplyARIAState(uint64_t* aState) const
|
|||
*aState |= states::UNAVAILABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// special case: A native button element whose role got transformed by ARIA to a toggle button
|
||||
|
@ -2451,7 +2451,7 @@ Accessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
|
|||
void
|
||||
Accessible::Shutdown()
|
||||
{
|
||||
// Mark the accessible as defunct, invalidate the child count and pointers to
|
||||
// Mark the accessible as defunct, invalidate the child count and pointers to
|
||||
// other accessibles, also make sure none of its children point to this parent
|
||||
mStateFlags |= eIsDefunct;
|
||||
|
||||
|
@ -3058,7 +3058,7 @@ Accessible::TestChildCache(Accessible* aCachedChild) const
|
|||
}
|
||||
|
||||
NS_ASSERTION(child == aCachedChild,
|
||||
"[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");
|
||||
"[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3135,7 +3135,7 @@ Accessible::GetActionRule()
|
|||
|
||||
if (isOnclick)
|
||||
return eClickAction;
|
||||
|
||||
|
||||
// Get an action based on ARIA role.
|
||||
if (mRoleMapEntry &&
|
||||
mRoleMapEntry->actionRule != eNoAction)
|
||||
|
|
|
@ -1551,9 +1551,9 @@ HyperTextAccessible::EnclosingRange(a11y::TextRange& aRange) const
|
|||
{
|
||||
if (IsTextField()) {
|
||||
aRange.Set(mDoc, const_cast<HyperTextAccessible*>(this), 0,
|
||||
const_cast<HyperTextAccessible*>(this), ChildCount());
|
||||
const_cast<HyperTextAccessible*>(this), CharacterCount());
|
||||
} else {
|
||||
aRange.Set(mDoc, mDoc, 0, mDoc, mDoc->ChildCount());
|
||||
aRange.Set(mDoc, mDoc, 0, mDoc, mDoc->CharacterCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1599,7 +1599,26 @@ void
|
|||
HyperTextAccessible::RangeByChild(Accessible* aChild,
|
||||
a11y::TextRange& aRange) const
|
||||
{
|
||||
aRange.Set(mDoc, aChild, 0, aChild, aChild->ChildCount());
|
||||
HyperTextAccessible* ht = aChild->AsHyperText();
|
||||
if (ht) {
|
||||
aRange.Set(mDoc, ht, 0, ht, ht->CharacterCount());
|
||||
return;
|
||||
}
|
||||
|
||||
Accessible* child = aChild;
|
||||
Accessible* parent = nullptr;
|
||||
while ((parent = child->Parent()) && !(ht = parent->AsHyperText()))
|
||||
child = parent;
|
||||
|
||||
// If no text then return collapsed text range, otherwise return a range
|
||||
// containing the text enclosed by the given child.
|
||||
if (ht) {
|
||||
int32_t childIdx = child->IndexInParent();
|
||||
int32_t startOffset = ht->GetChildOffset(childIdx);
|
||||
int32_t endOffset = child->IsTextLeaf() ?
|
||||
ht->GetChildOffset(childIdx + 1) : startOffset;
|
||||
aRange.Set(mDoc, ht, startOffset, ht, endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1607,8 +1626,19 @@ 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());
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
Accessible* parent = nullptr;
|
||||
while ((parent = child->Parent()) && !parent->IsHyperText())
|
||||
child = parent;
|
||||
|
||||
// Return collapsed text range for the point.
|
||||
if (parent) {
|
||||
HyperTextAccessible* ht = parent->AsHyperText();
|
||||
int32_t offset = ht->GetChildOffset(child);
|
||||
aRange.Set(mDoc, ht, offset, ht, offset);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "HyperTextAccessible.h"
|
||||
#include "TextRange.h"
|
||||
|
||||
#include "nsIMutableArray.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
|
@ -21,6 +23,7 @@ NS_IMPL_CYCLE_COLLECTION(xpcAccessibleTextRange,
|
|||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleTextRange)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleTextRange)
|
||||
NS_INTERFACE_MAP_ENTRY(xpcAccessibleTextRange)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleTextRange)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -30,10 +33,10 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleTextRange)
|
|||
// nsIAccessibleTextRange
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetStartContainer(nsIAccessible** aAnchor)
|
||||
xpcAccessibleTextRange::GetStartContainer(nsIAccessibleText** aAnchor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAnchor);
|
||||
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessible*>(mRange.StartContainer()));
|
||||
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessibleText*>(mRange.StartContainer()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -46,10 +49,10 @@ xpcAccessibleTextRange::GetStartOffset(int32_t* aOffset)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetEndContainer(nsIAccessible** aAnchor)
|
||||
xpcAccessibleTextRange::GetEndContainer(nsIAccessibleText** aAnchor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAnchor);
|
||||
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessible*>(mRange.EndContainer()));
|
||||
NS_IF_ADDREF(*aAnchor = static_cast<nsIAccessibleText*>(mRange.EndContainer()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -61,6 +64,70 @@ xpcAccessibleTextRange::GetEndOffset(int32_t* aOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetContainer(nsIAccessible** aContainer)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContainer);
|
||||
NS_IF_ADDREF(*aContainer = static_cast<nsIAccessible*>(mRange.Container()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetEmbeddedChildren(nsIArray** aList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMutableArray> xpcList =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsTArray<Accessible*> objects;
|
||||
mRange.EmbeddedChildren(&objects);
|
||||
|
||||
uint32_t len = objects.Length();
|
||||
for (uint32_t idx = 0; idx < len; idx++)
|
||||
xpcList->AppendElement(static_cast<nsIAccessible*>(objects[idx]), false);
|
||||
|
||||
xpcList.forget(aList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::Compare(nsIAccessibleTextRange* aOtherRange,
|
||||
bool* aResult)
|
||||
{
|
||||
|
||||
nsRefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
|
||||
if (!xpcRange || !aResult)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*aResult = (mRange == xpcRange->mRange);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::CompareEndPoints(uint32_t aEndPoint,
|
||||
nsIAccessibleTextRange* aOtherRange,
|
||||
uint32_t aOtherRangeEndPoint,
|
||||
int32_t* aResult)
|
||||
{
|
||||
nsRefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
|
||||
if (!xpcRange || !aResult)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
TextPoint p = (aEndPoint == EndPoint_Start) ?
|
||||
mRange.StartPoint() : mRange.EndPoint();
|
||||
TextPoint otherPoint = (aOtherRangeEndPoint == EndPoint_Start) ?
|
||||
xpcRange->mRange.StartPoint() : xpcRange->mRange.EndPoint();
|
||||
|
||||
if (p == otherPoint)
|
||||
*aResult = 0;
|
||||
else
|
||||
*aResult = p < otherPoint ? -1 : 1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetText(nsAString& aText)
|
||||
{
|
||||
|
@ -70,3 +137,73 @@ xpcAccessibleTextRange::GetText(nsAString& aText)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::GetBounds(nsIArray** aRectList)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::Move(uint32_t aUnit, int32_t aCount)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::MoveStart(uint32_t aUnit, int32_t aCount)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::MoveEnd(uint32_t aUnit, int32_t aCount)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::Normalize(uint32_t aUnit)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::FindText(const nsAString& aText, bool aIsBackward,
|
||||
bool aIsIgnoreCase,
|
||||
nsIAccessibleTextRange** aRange)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::FindAttr(uint32_t aAttr, nsIVariant* aVal,
|
||||
bool aIsBackward,
|
||||
nsIAccessibleTextRange** aRange)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::AddToSelection()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::RemoveFromSelection()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::Select()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibleTextRange::ScrollIntoView(uint32_t aHow)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -18,17 +18,47 @@ namespace a11y {
|
|||
|
||||
class TextRange;
|
||||
|
||||
#define NS_ACCESSIBLETEXTRANGE_IMPL_IID \
|
||||
{ /* 133c8bf4-4913-4355-bd50-426bd1d6e1ad */ \
|
||||
0xb17652d9, \
|
||||
0x4f54, \
|
||||
0x4c56, \
|
||||
{ 0xbb, 0x62, 0x6d, 0x5b, 0xf1, 0xef, 0x91, 0x0c } \
|
||||
}
|
||||
|
||||
class xpcAccessibleTextRange MOZ_FINAL : public nsIAccessibleTextRange
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(xpcAccessibleTextRange)
|
||||
|
||||
NS_IMETHOD GetStartContainer(nsIAccessible** aAnchor) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetStartContainer(nsIAccessibleText** aAnchor) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetStartOffset(int32_t* aOffset) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetEndContainer(nsIAccessible** aAnchor) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetEndContainer(nsIAccessibleText** aAnchor) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetEndOffset(int32_t* aOffset) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetContainer(nsIAccessible** aContainer) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetEmbeddedChildren(nsIArray** aList) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD Compare(nsIAccessibleTextRange* aOtherRange, bool* aResult) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD CompareEndPoints(uint32_t aEndPoint,
|
||||
nsIAccessibleTextRange* aOtherRange,
|
||||
uint32_t aOtherRangeEndPoint,
|
||||
int32_t* aResult) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetText(nsAString& aText) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetBounds(nsIArray** aRectList) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD Move(uint32_t aUnit, int32_t aCount) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD MoveStart(uint32_t aUnit, int32_t aCount) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD MoveEnd(uint32_t aUnit, int32_t aCount) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD Normalize(uint32_t aUnit) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD FindText(const nsAString& aText, bool aIsBackward, bool aIsIgnoreCase,
|
||||
nsIAccessibleTextRange** aRange) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD FindAttr(uint32_t aAttr, nsIVariant* aVal, bool aIsBackward,
|
||||
nsIAccessibleTextRange** aRange) MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD AddToSelection() MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD RemoveFromSelection() MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD Select() MOZ_FINAL MOZ_OVERRIDE;
|
||||
NS_IMETHOD ScrollIntoView(uint32_t aHow) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLETEXTRANGE_IMPL_IID)
|
||||
|
||||
private:
|
||||
xpcAccessibleTextRange(TextRange&& aRange) :
|
||||
|
@ -42,6 +72,9 @@ private:
|
|||
TextRange mRange;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(xpcAccessibleTextRange,
|
||||
NS_ACCESSIBLETEXTRANGE_IMPL_IID)
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ const nsIAccessibleScrollType = Components.interfaces.nsIAccessibleScrollType;
|
|||
const nsIAccessibleCoordinateType = Components.interfaces.nsIAccessibleCoordinateType;
|
||||
|
||||
const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
|
||||
const nsIAccessibleTextRange = Components.interfaces.nsIAccessibleTextRange;
|
||||
|
||||
const nsIAccessible = Components.interfaces.nsIAccessible;
|
||||
|
||||
|
@ -434,7 +435,7 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if (prop.indexOf("todo_") == 0)
|
||||
|
|
|
@ -10,6 +10,9 @@ const BOUNDARY_LINE_END = nsIAccessibleText.BOUNDARY_LINE_END;
|
|||
const kTextEndOffset = nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT;
|
||||
const kCaretOffset = nsIAccessibleText.TEXT_OFFSET_CARET;
|
||||
|
||||
const EndPoint_Start = nsIAccessibleTextRange.EndPoint_Start;
|
||||
const EndPoint_End = nsIAccessibleTextRange.EndPoint_End;
|
||||
|
||||
const kTodo = 1; // a test is expected to fail
|
||||
const kOk = 2; // a test doesn't fail
|
||||
|
||||
|
@ -393,8 +396,8 @@ function testTextRemoveSelection(aID, aSelectionIndex, aSelectionsCount)
|
|||
|
||||
acc.removeSelection(aSelectionIndex);
|
||||
|
||||
ok(acc.selectionCount, aSelectionsCount,
|
||||
text + ": failed to remove selection at index '" +
|
||||
ok(acc.selectionCount, aSelectionsCount,
|
||||
text + ": failed to remove selection at index '" +
|
||||
aSelectionIndex + "': selectionCount after");
|
||||
}
|
||||
|
||||
|
@ -416,8 +419,8 @@ function testTextSetSelection(aID, aStartOffset, aEndOffset,
|
|||
|
||||
acc.setSelectionBounds(aSelectionIndex, aStartOffset, aEndOffset);
|
||||
|
||||
is(acc.selectionCount, aSelectionsCount,
|
||||
text + ": failed to set selection at index '" +
|
||||
is(acc.selectionCount, aSelectionsCount,
|
||||
text + ": failed to set selection at index '" +
|
||||
aSelectionIndex + "': selectionCount after");
|
||||
}
|
||||
|
||||
|
@ -457,17 +460,36 @@ function testTextGetSelection(aID, aStartOffset, aEndOffset, aSelectionIndex)
|
|||
aSelectionIndex + "'");
|
||||
}
|
||||
|
||||
function testTextRange(aRange, aStartContainer, aStartOffset,
|
||||
aEndContainer, aEndOffset)
|
||||
function testTextRange(aRange, aRangeDescr, aStartContainer, aStartOffset,
|
||||
aEndContainer, aEndOffset, aText,
|
||||
aCommonContainer, aChildren)
|
||||
{
|
||||
is(aRange.startContainer, getAccessible(aStartContainer),
|
||||
"Wrong start container");
|
||||
isObject(aRange.startContainer, getAccessible(aStartContainer),
|
||||
"Wrong start container of " + aRangeDescr);
|
||||
is(aRange.startOffset, aStartOffset,
|
||||
"Wrong start offset");
|
||||
is(aRange.endContainer, getAccessible(aEndContainer),
|
||||
"Wrong end container");
|
||||
"Wrong start offset of " + aRangeDescr);
|
||||
isObject(aRange.endContainer, getAccessible(aEndContainer),
|
||||
"Wrong end container of " + aRangeDescr);
|
||||
is(aRange.endOffset, aEndOffset,
|
||||
"Wrong end offset");
|
||||
"Wrong end offset of " + aRangeDescr);
|
||||
|
||||
is(aRange.text, aText, "Wrong text of " + aRangeDescr);
|
||||
|
||||
var children = aRange.embeddedChildren;
|
||||
is(children ? children.length : 0, aChildren ? aChildren.length : 0,
|
||||
"Wrong embedded children count of " + aRangeDescr);
|
||||
|
||||
isObject(aRange.container, getAccessible(aCommonContainer),
|
||||
"Wrong container of " + aRangeDescr);
|
||||
|
||||
if (aChildren) {
|
||||
for (var i = 0; i < aChildren.length; i++) {
|
||||
var expectedChild = getAccessible(aChildren[i]);
|
||||
var actualChild = children.queryElementAt(i, nsIAccessible);
|
||||
isObject(actualChild, expectedChild,
|
||||
"Wrong child at index '" + i + "' of " + aRangeDescr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -11,19 +11,75 @@
|
|||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../layout.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// enclosingRange
|
||||
var input = getAccessible("input", [ nsIAccessibleText ]);
|
||||
testTextRange(input.enclosingRange, input, 0, input, 1);
|
||||
testTextRange(input.enclosingRange, "enclosing range for 'input'",
|
||||
input, 0, input, 5, "hello", input);
|
||||
|
||||
var ta = getAccessible("textarea", [ nsIAccessibleText ]);
|
||||
testTextRange(ta.enclosingRange, ta, 0, ta, 1);
|
||||
testTextRange(ta.enclosingRange, "enclosing range for 'textarea'",
|
||||
ta, 0, ta, 5, "hello", textarea);
|
||||
|
||||
var iframeDoc = getAccessible(getNode("iframe").contentDocument,
|
||||
[ nsIAccessibleText ]);
|
||||
testTextRange(iframeDoc.enclosingRange, iframeDoc, 0, iframeDoc, 1);
|
||||
var iframeDocNode = getNode("iframe").contentDocument;
|
||||
var iframeDoc = getAccessible(iframeDocNode, [ nsIAccessibleText ]);
|
||||
testTextRange(iframeDoc.enclosingRange, "enclosing range for iframe doc",
|
||||
iframeDoc, 0, iframeDoc, 1, "hello",
|
||||
iframeDoc, [ getNode("p", iframeDocNode) ]);
|
||||
|
||||
// getRangeByChild
|
||||
var docacc = getAccessible(document, [ nsIAccessibleText ]);
|
||||
var p1 = getAccessible("p1");
|
||||
var p1Range = docacc.getRangeByChild(p1);
|
||||
testTextRange(p1Range, "range by 'p1' child",
|
||||
p1, 0, "p1", 11, "text text",
|
||||
p1, ["p1_img"]);
|
||||
|
||||
testTextRange(docacc.getRangeByChild(getAccessible("p1_img")),
|
||||
"range by 'p1_img' child",
|
||||
"p1", 5, "p1", 5, "",
|
||||
"p1", ["p1_img"]);
|
||||
|
||||
var p2 = getAccessible("p2");
|
||||
var p2Range = docacc.getRangeByChild(p2);
|
||||
testTextRange(p2Range, "range by 'p2' child",
|
||||
p2, 0, "p2", 11, "text link text",
|
||||
p2, ["p2_a"]);
|
||||
|
||||
testTextRange(docacc.getRangeByChild(getAccessible("p2_a")),
|
||||
"range by 'p2_a' child",
|
||||
"p2_a", 0, "p2_a", 5, "link",
|
||||
"p2_a", ["p2_img"]);
|
||||
|
||||
// getRangeAtPoint
|
||||
getNode("p2_a").scrollIntoView(true);
|
||||
var [x, y] = getPos("p2_a");
|
||||
testTextRange(docacc.getRangeAtPoint(x + 1, y + 1),
|
||||
"range at 'p2_a' top-left edge",
|
||||
"p2_a", 0, "p2_a", 0, "",
|
||||
"p2_a");
|
||||
|
||||
// TextRange::compare
|
||||
ok(input.enclosingRange.compare(input.enclosingRange),
|
||||
"input enclosing ranges should be equal");
|
||||
|
||||
ok(!input.enclosingRange.compare(ta.enclosingRange),
|
||||
"input and textarea enclosing ranges can't be equal");
|
||||
|
||||
// TextRange::compareEndPoints
|
||||
var res = p1Range.compareEndPoints(EndPoint_End, p2Range, EndPoint_Start);
|
||||
is(res, -1, "p1 range must be lesser with p2 range");
|
||||
|
||||
res = p2Range.compareEndPoints(EndPoint_Start, p1Range, EndPoint_End);
|
||||
is(res, 1, "p2 range must be greater with p1 range");
|
||||
|
||||
res = p1Range.compareEndPoints(EndPoint_Start, p1Range, EndPoint_Start);
|
||||
is(res, 0, "p1 range must be equal with p1 range");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -44,7 +100,9 @@
|
|||
|
||||
<input id="input" value="hello">
|
||||
<textarea id="textarea">hello</textarea>
|
||||
<iframe id="iframe" src="data:text/html,<p>hello</p>"></iframe>
|
||||
<iframe id="iframe" src="data:text/html,<html><body><p id='p'>hello</p></body></html>"></iframe>
|
||||
<p id="p1">text <img id="p1_img", src="../moz.png"> text</p>
|
||||
<p id="p2">text <a id="p2_a" href="www">link<img id="p2_img", src="../moz.png"></a> text</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
Загрузка…
Ссылка в новой задаче