mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1011496 - complete the TextRange interface design, r=davidb
This commit is contained in:
parent
c360e10994
commit
8ed8f08ecd
@ -6,20 +6,149 @@
|
|||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
interface nsIAccessible;
|
interface nsIAccessible;
|
||||||
|
interface nsIAccessibleText;
|
||||||
|
interface nsIArray;
|
||||||
|
interface nsIVariant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A range representing a piece of text in the document.
|
* 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
|
interface nsIAccessibleTextRange : nsISupports
|
||||||
{
|
{
|
||||||
readonly attribute nsIAccessible startContainer;
|
readonly attribute nsIAccessibleText startContainer;
|
||||||
readonly attribute long startOffset;
|
readonly attribute long startOffset;
|
||||||
readonly attribute nsIAccessible endContainer;
|
readonly attribute nsIAccessibleText endContainer;
|
||||||
readonly attribute long endOffset;
|
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.
|
* Return text within the range.
|
||||||
*/
|
*/
|
||||||
readonly attribute AString text;
|
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);
|
||||||
};
|
};
|
||||||
|
@ -6,28 +6,239 @@
|
|||||||
|
|
||||||
#include "TextRange.h"
|
#include "TextRange.h"
|
||||||
|
|
||||||
|
#include "Accessible-inl.h"
|
||||||
#include "HyperTextAccessible.h"
|
#include "HyperTextAccessible.h"
|
||||||
|
#include "nsAccUtils.h"
|
||||||
|
|
||||||
using namespace mozilla::a11y;
|
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,
|
TextRange::TextRange(HyperTextAccessible* aRoot,
|
||||||
Accessible* aStartContainer, int32_t aStartOffset,
|
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||||
Accessible* aEndContainer, int32_t aEndOffset) :
|
HyperTextAccessible* aEndContainer, int32_t aEndOffset) :
|
||||||
mRoot(aRoot), mStartContainer(aStartContainer), mEndContainer(aEndContainer),
|
mRoot(aRoot), mStartContainer(aStartContainer), mEndContainer(aEndContainer),
|
||||||
mStartOffset(aStartOffset), mEndOffset(aEndOffset)
|
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
|
void
|
||||||
TextRange::Text(nsAString& aText) const
|
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
|
void
|
||||||
TextRange::Set(HyperTextAccessible* aRoot,
|
TextRange::Set(HyperTextAccessible* aRoot,
|
||||||
Accessible* aStartContainer, int32_t aStartOffset,
|
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||||
Accessible* aEndContainer, int32_t aEndOffset)
|
HyperTextAccessible* aEndContainer, int32_t aEndOffset)
|
||||||
{
|
{
|
||||||
mRoot = aRoot;
|
mRoot = aRoot;
|
||||||
mStartContainer = aStartContainer;
|
mStartContainer = aStartContainer;
|
||||||
@ -35,3 +246,51 @@ TextRange::Set(HyperTextAccessible* aRoot,
|
|||||||
mStartOffset = aStartOffset;
|
mStartOffset = aStartOffset;
|
||||||
mEndOffset = aEndOffset;
|
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 "mozilla/Move.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCaseTreatment.h"
|
||||||
|
#include "nsRect.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
class nsIVariant;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
@ -16,6 +21,24 @@ namespace a11y {
|
|||||||
class Accessible;
|
class Accessible;
|
||||||
class HyperTextAccessible;
|
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.
|
* Represents a text range within the text control or document.
|
||||||
*/
|
*/
|
||||||
@ -23,39 +46,177 @@ class TextRange MOZ_FINAL
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextRange(HyperTextAccessible* aRoot,
|
TextRange(HyperTextAccessible* aRoot,
|
||||||
Accessible* aStartContainer, int32_t aStartOffset,
|
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||||
Accessible* aEndContainer, int32_t aEndOffset);
|
HyperTextAccessible* aEndContainer, int32_t aEndOffset);
|
||||||
TextRange() {}
|
TextRange() {}
|
||||||
TextRange(TextRange&& aRange) :
|
TextRange(TextRange&& aRange) :
|
||||||
mRoot(Move(aRange.mRoot)), mStartContainer(Move(aRange.mStartContainer)),
|
mRoot(mozilla::Move(aRange.mRoot)),
|
||||||
mEndContainer(Move(aRange.mEndContainer)),
|
mStartContainer(mozilla::Move(aRange.mStartContainer)),
|
||||||
|
mEndContainer(mozilla::Move(aRange.mEndContainer)),
|
||||||
mStartOffset(aRange.mStartOffset), mEndOffset(aRange.mEndOffset) {}
|
mStartOffset(aRange.mStartOffset), mEndOffset(aRange.mEndOffset) {}
|
||||||
|
|
||||||
TextRange& operator= (TextRange&& aRange)
|
TextRange& operator= (TextRange&& aRange)
|
||||||
{
|
{
|
||||||
mRoot = Move(aRange.mRoot);
|
mRoot = mozilla::Move(aRange.mRoot);
|
||||||
mStartContainer = Move(aRange.mStartContainer);
|
mStartContainer = mozilla::Move(aRange.mStartContainer);
|
||||||
mEndContainer = Move(aRange.mEndContainer);
|
mEndContainer = mozilla::Move(aRange.mEndContainer);
|
||||||
mStartOffset = aRange.mStartOffset;
|
mStartOffset = aRange.mStartOffset;
|
||||||
mEndOffset = aRange.mEndOffset;
|
mEndOffset = aRange.mEndOffset;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessible* StartContainer() const { return mStartContainer; }
|
HyperTextAccessible* StartContainer() const { return mStartContainer; }
|
||||||
int32_t StartOffset() const { return mStartOffset; }
|
int32_t StartOffset() const { return mStartOffset; }
|
||||||
Accessible* EndContainer() const { return mEndContainer; }
|
HyperTextAccessible* EndContainer() const { return mEndContainer; }
|
||||||
int32_t EndOffset() const { return mEndOffset; }
|
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.
|
* Return text enclosed by the range.
|
||||||
*/
|
*/
|
||||||
void Text(nsAString& aText) const;
|
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.
|
* Return true if this TextRange object represents an actual range of text.
|
||||||
*/
|
*/
|
||||||
bool IsValid() const { return mRoot; }
|
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:
|
private:
|
||||||
TextRange(const TextRange& aRange) MOZ_DELETE;
|
TextRange(const TextRange& aRange) MOZ_DELETE;
|
||||||
TextRange& operator=(const TextRange& aRange) MOZ_DELETE;
|
TextRange& operator=(const TextRange& aRange) MOZ_DELETE;
|
||||||
@ -64,12 +225,27 @@ private:
|
|||||||
friend class xpcAccessibleTextRange;
|
friend class xpcAccessibleTextRange;
|
||||||
|
|
||||||
void Set(HyperTextAccessible* aRoot,
|
void Set(HyperTextAccessible* aRoot,
|
||||||
Accessible* aStartContainer, int32_t aStartOffset,
|
HyperTextAccessible* aStartContainer, int32_t aStartOffset,
|
||||||
Accessible* aEndContainer, int32_t aEndOffset);
|
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<HyperTextAccessible> mRoot;
|
||||||
nsRefPtr<Accessible> mStartContainer;
|
nsRefPtr<HyperTextAccessible> mStartContainer;
|
||||||
nsRefPtr<Accessible> mEndContainer;
|
nsRefPtr<HyperTextAccessible> mEndContainer;
|
||||||
int32_t mStartOffset;
|
int32_t mStartOffset;
|
||||||
int32_t mEndOffset;
|
int32_t mEndOffset;
|
||||||
};
|
};
|
||||||
|
@ -120,7 +120,7 @@ Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
|
|||||||
#ifdef NS_DEBUG_X
|
#ifdef NS_DEBUG_X
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aShell));
|
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*)static_cast<nsIAccessible*>(this), (void*)aNode,
|
||||||
(void*)shell.get());
|
(void*)shell.get());
|
||||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||||
@ -267,7 +267,7 @@ Accessible::Description(nsString& aDescription)
|
|||||||
// 1. it's a text node; or
|
// 1. it's a text node; or
|
||||||
// 2. It has no DHTML describedby property
|
// 2. It has no DHTML describedby property
|
||||||
// 3. it doesn't have an accName; or
|
// 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))
|
if (!HasOwnContent() || mContent->IsNodeOfType(nsINode::eTEXT))
|
||||||
return;
|
return;
|
||||||
@ -550,7 +550,7 @@ Accessible::GetIndexInParent(int32_t* aIndexInParent)
|
|||||||
return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE;
|
return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||||
@ -560,7 +560,7 @@ Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
|
|||||||
|
|
||||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||||
stringBundleService->CreateBundle(
|
stringBundleService->CreateBundle(
|
||||||
"chrome://global-platform/locale/accessible.properties",
|
"chrome://global-platform/locale/accessible.properties",
|
||||||
getter_AddRefs(stringBundle));
|
getter_AddRefs(stringBundle));
|
||||||
if (!stringBundle)
|
if (!stringBundle)
|
||||||
return;
|
return;
|
||||||
@ -1104,7 +1104,7 @@ Accessible::XULElmName(DocAccessible* aDocument,
|
|||||||
itemEl->GetLabel(aName);
|
itemEl->GetLabel(aName);
|
||||||
} else {
|
} else {
|
||||||
nsCOMPtr<nsIDOMXULSelectControlElement> select = do_QueryInterface(aElm);
|
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
|
// uses label attribute to indicate which option is selected
|
||||||
if (!select) {
|
if (!select) {
|
||||||
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aElm));
|
nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(aElm));
|
||||||
@ -1578,7 +1578,7 @@ Accessible::ApplyARIAState(uint64_t* aState) const
|
|||||||
*aState |= states::UNAVAILABLE;
|
*aState |= states::UNAVAILABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case: A native button element whose role got transformed by ARIA to a toggle button
|
// 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
|
void
|
||||||
Accessible::Shutdown()
|
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
|
// other accessibles, also make sure none of its children point to this parent
|
||||||
mStateFlags |= eIsDefunct;
|
mStateFlags |= eIsDefunct;
|
||||||
|
|
||||||
@ -3058,7 +3058,7 @@ Accessible::TestChildCache(Accessible* aCachedChild) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(child == aCachedChild,
|
NS_ASSERTION(child == aCachedChild,
|
||||||
"[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");
|
"[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3135,7 +3135,7 @@ Accessible::GetActionRule()
|
|||||||
|
|
||||||
if (isOnclick)
|
if (isOnclick)
|
||||||
return eClickAction;
|
return eClickAction;
|
||||||
|
|
||||||
// Get an action based on ARIA role.
|
// Get an action based on ARIA role.
|
||||||
if (mRoleMapEntry &&
|
if (mRoleMapEntry &&
|
||||||
mRoleMapEntry->actionRule != eNoAction)
|
mRoleMapEntry->actionRule != eNoAction)
|
||||||
|
@ -1551,9 +1551,9 @@ HyperTextAccessible::EnclosingRange(a11y::TextRange& aRange) const
|
|||||||
{
|
{
|
||||||
if (IsTextField()) {
|
if (IsTextField()) {
|
||||||
aRange.Set(mDoc, const_cast<HyperTextAccessible*>(this), 0,
|
aRange.Set(mDoc, const_cast<HyperTextAccessible*>(this), 0,
|
||||||
const_cast<HyperTextAccessible*>(this), ChildCount());
|
const_cast<HyperTextAccessible*>(this), CharacterCount());
|
||||||
} else {
|
} 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,
|
HyperTextAccessible::RangeByChild(Accessible* aChild,
|
||||||
a11y::TextRange& aRange) const
|
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
|
void
|
||||||
@ -1607,8 +1626,19 @@ HyperTextAccessible::RangeAtPoint(int32_t aX, int32_t aY,
|
|||||||
a11y::TextRange& aRange) const
|
a11y::TextRange& aRange) const
|
||||||
{
|
{
|
||||||
Accessible* child = mDoc->ChildAtPoint(aX, aY, eDeepestChild);
|
Accessible* child = mDoc->ChildAtPoint(aX, aY, eDeepestChild);
|
||||||
if (child)
|
if (!child)
|
||||||
aRange.Set(mDoc, child, 0, child, child->ChildCount());
|
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 "HyperTextAccessible.h"
|
||||||
#include "TextRange.h"
|
#include "TextRange.h"
|
||||||
|
|
||||||
|
#include "nsIMutableArray.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::a11y;
|
using namespace mozilla::a11y;
|
||||||
|
|
||||||
@ -21,6 +23,7 @@ NS_IMPL_CYCLE_COLLECTION(xpcAccessibleTextRange,
|
|||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleTextRange)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleTextRange)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleTextRange)
|
NS_INTERFACE_MAP_ENTRY(nsIAccessibleTextRange)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(xpcAccessibleTextRange)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleTextRange)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleTextRange)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
@ -30,10 +33,10 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleTextRange)
|
|||||||
// nsIAccessibleTextRange
|
// nsIAccessibleTextRange
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
xpcAccessibleTextRange::GetStartContainer(nsIAccessible** aAnchor)
|
xpcAccessibleTextRange::GetStartContainer(nsIAccessibleText** aAnchor)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +49,10 @@ xpcAccessibleTextRange::GetStartOffset(int32_t* aOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
xpcAccessibleTextRange::GetEndContainer(nsIAccessible** aAnchor)
|
xpcAccessibleTextRange::GetEndContainer(nsIAccessibleText** aAnchor)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +64,70 @@ xpcAccessibleTextRange::GetEndOffset(int32_t* aOffset)
|
|||||||
return NS_OK;
|
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
|
NS_IMETHODIMP
|
||||||
xpcAccessibleTextRange::GetText(nsAString& aText)
|
xpcAccessibleTextRange::GetText(nsAString& aText)
|
||||||
{
|
{
|
||||||
@ -70,3 +137,73 @@ xpcAccessibleTextRange::GetText(nsAString& aText)
|
|||||||
|
|
||||||
return NS_OK;
|
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;
|
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
|
class xpcAccessibleTextRange MOZ_FINAL : public nsIAccessibleTextRange
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS(xpcAccessibleTextRange)
|
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 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 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 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:
|
private:
|
||||||
xpcAccessibleTextRange(TextRange&& aRange) :
|
xpcAccessibleTextRange(TextRange&& aRange) :
|
||||||
@ -42,6 +72,9 @@ private:
|
|||||||
TextRange mRange;
|
TextRange mRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(xpcAccessibleTextRange,
|
||||||
|
NS_ACCESSIBLETEXTRANGE_IMPL_IID)
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const nsIAccessibleScrollType = Components.interfaces.nsIAccessibleScrollType;
|
|||||||
const nsIAccessibleCoordinateType = Components.interfaces.nsIAccessibleCoordinateType;
|
const nsIAccessibleCoordinateType = Components.interfaces.nsIAccessibleCoordinateType;
|
||||||
|
|
||||||
const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
|
const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
|
||||||
|
const nsIAccessibleTextRange = Components.interfaces.nsIAccessibleTextRange;
|
||||||
|
|
||||||
const nsIAccessible = Components.interfaces.nsIAccessible;
|
const nsIAccessible = Components.interfaces.nsIAccessible;
|
||||||
|
|
||||||
@ -434,7 +435,7 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree, aFlags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (prop.indexOf("todo_") == 0)
|
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 kTextEndOffset = nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT;
|
||||||
const kCaretOffset = nsIAccessibleText.TEXT_OFFSET_CARET;
|
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 kTodo = 1; // a test is expected to fail
|
||||||
const kOk = 2; // a test doesn't fail
|
const kOk = 2; // a test doesn't fail
|
||||||
|
|
||||||
@ -393,8 +396,8 @@ function testTextRemoveSelection(aID, aSelectionIndex, aSelectionsCount)
|
|||||||
|
|
||||||
acc.removeSelection(aSelectionIndex);
|
acc.removeSelection(aSelectionIndex);
|
||||||
|
|
||||||
ok(acc.selectionCount, aSelectionsCount,
|
ok(acc.selectionCount, aSelectionsCount,
|
||||||
text + ": failed to remove selection at index '" +
|
text + ": failed to remove selection at index '" +
|
||||||
aSelectionIndex + "': selectionCount after");
|
aSelectionIndex + "': selectionCount after");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,8 +419,8 @@ function testTextSetSelection(aID, aStartOffset, aEndOffset,
|
|||||||
|
|
||||||
acc.setSelectionBounds(aSelectionIndex, aStartOffset, aEndOffset);
|
acc.setSelectionBounds(aSelectionIndex, aStartOffset, aEndOffset);
|
||||||
|
|
||||||
is(acc.selectionCount, aSelectionsCount,
|
is(acc.selectionCount, aSelectionsCount,
|
||||||
text + ": failed to set selection at index '" +
|
text + ": failed to set selection at index '" +
|
||||||
aSelectionIndex + "': selectionCount after");
|
aSelectionIndex + "': selectionCount after");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,17 +460,36 @@ function testTextGetSelection(aID, aStartOffset, aEndOffset, aSelectionIndex)
|
|||||||
aSelectionIndex + "'");
|
aSelectionIndex + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function testTextRange(aRange, aStartContainer, aStartOffset,
|
function testTextRange(aRange, aRangeDescr, aStartContainer, aStartOffset,
|
||||||
aEndContainer, aEndOffset)
|
aEndContainer, aEndOffset, aText,
|
||||||
|
aCommonContainer, aChildren)
|
||||||
{
|
{
|
||||||
is(aRange.startContainer, getAccessible(aStartContainer),
|
isObject(aRange.startContainer, getAccessible(aStartContainer),
|
||||||
"Wrong start container");
|
"Wrong start container of " + aRangeDescr);
|
||||||
is(aRange.startOffset, aStartOffset,
|
is(aRange.startOffset, aStartOffset,
|
||||||
"Wrong start offset");
|
"Wrong start offset of " + aRangeDescr);
|
||||||
is(aRange.endContainer, getAccessible(aEndContainer),
|
isObject(aRange.endContainer, getAccessible(aEndContainer),
|
||||||
"Wrong end container");
|
"Wrong end container of " + aRangeDescr);
|
||||||
is(aRange.endOffset, aEndOffset,
|
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>
|
src="../common.js"></script>
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="../text.js"></script>
|
src="../text.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../layout.js"></script>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
|
||||||
function doTest()
|
function doTest()
|
||||||
{
|
{
|
||||||
|
// enclosingRange
|
||||||
var input = getAccessible("input", [ nsIAccessibleText ]);
|
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 ]);
|
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,
|
var iframeDocNode = getNode("iframe").contentDocument;
|
||||||
[ nsIAccessibleText ]);
|
var iframeDoc = getAccessible(iframeDocNode, [ nsIAccessibleText ]);
|
||||||
testTextRange(iframeDoc.enclosingRange, iframeDoc, 0, iframeDoc, 1);
|
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();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
@ -44,7 +100,9 @@
|
|||||||
|
|
||||||
<input id="input" value="hello">
|
<input id="input" value="hello">
|
||||||
<textarea id="textarea">hello</textarea>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user