123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "TextRange-inl.h"
- #include "Accessible-inl.h"
- #include "nsAccUtils.h"
- namespace mozilla {
- namespace 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;
- AutoTArray<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,
- HyperTextAccessible* aStartContainer, int32_t aStartOffset,
- HyperTextAccessible* aEndContainer, int32_t aEndOffset) :
- mRoot(aRoot), mStartContainer(aStartContainer), mEndContainer(aEndContainer),
- mStartOffset(aStartOffset), mEndOffset(aEndOffset)
- {
- }
- 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 (!child->IsText()) {
- aChildren->AppendElement(child);
- }
- }
- return;
- }
- Accessible* p1 = mStartContainer->GetChildAtOffset(mStartOffset);
- Accessible* p2 = mEndContainer->GetChildAtOffset(mEndOffset);
- uint32_t pos1 = 0, pos2 = 0;
- AutoTArray<Accessible*, 30> parents1, parents2;
- Accessible* container =
- CommonParent(p1, p2, &parents1, &pos1, &parents2, &pos2);
- // 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 (!next->IsText()) {
- 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 (!next->IsText()) {
- 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 (!next->IsText()) {
- 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)
- {
- }
- bool
- TextRange::Crop(Accessible* aContainer)
- {
- uint32_t boundaryPos = 0, containerPos = 0;
- AutoTArray<Accessible*, 30> boundaryParents, containerParents;
- // Crop the start boundary.
- Accessible* container = nullptr;
- Accessible* boundary = mStartContainer->GetChildAtOffset(mStartOffset);
- if (boundary != aContainer) {
- CommonParent(boundary, aContainer, &boundaryParents, &boundaryPos,
- &containerParents, &containerPos);
- if (boundaryPos == 0) {
- if (containerPos != 0) {
- // The container is contained by the start boundary, reduce the range to
- // the point starting at the container.
- aContainer->ToTextPoint(mStartContainer.StartAssignment(), &mStartOffset);
- static_cast<Accessible*>(mStartContainer)->AddRef();
- }
- else {
- // The start boundary and the container are siblings.
- container = aContainer;
- }
- }
- else if (containerPos != 0) {
- // The container does not contain the start boundary.
- boundary = boundaryParents[boundaryPos];
- container = containerParents[containerPos];
- }
- if (container) {
- // If the range start is after the container, then make the range invalid.
- if (boundary->IndexInParent() > container->IndexInParent()) {
- return !!(mRoot = nullptr);
- }
- // If the range starts before the container, then reduce the range to
- // the point starting at the container.
- if (boundary->IndexInParent() < container->IndexInParent()) {
- container->ToTextPoint(mStartContainer.StartAssignment(), &mStartOffset);
- mStartContainer.get()->AddRef();
- }
- }
- boundaryParents.SetLengthAndRetainStorage(0);
- containerParents.SetLengthAndRetainStorage(0);
- }
- boundary = mEndContainer->GetChildAtOffset(mEndOffset);
- if (boundary == aContainer) {
- return true;
- }
- // Crop the end boundary.
- container = nullptr;
- CommonParent(boundary, aContainer, &boundaryParents, &boundaryPos,
- &containerParents, &containerPos);
- if (boundaryPos == 0) {
- if (containerPos != 0) {
- aContainer->ToTextPoint(mEndContainer.StartAssignment(), &mEndOffset, false);
- static_cast<Accessible*>(mEndContainer)->AddRef();
- }
- else {
- container = aContainer;
- }
- }
- else if (containerPos != 0) {
- boundary = boundaryParents[boundaryPos];
- container = containerParents[containerPos];
- }
- if (!container) {
- return true;
- }
- if (boundary->IndexInParent() < container->IndexInParent()) {
- return !!(mRoot = nullptr);
- }
- if (boundary->IndexInParent() > container->IndexInParent()) {
- container->ToTextPoint(mEndContainer.StartAssignment(), &mEndOffset, false);
- static_cast<Accessible*>(mEndContainer)->AddRef();
- }
- return true;
- }
- 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,
- HyperTextAccessible* aStartContainer, int32_t aStartOffset,
- HyperTextAccessible* aEndContainer, int32_t aEndOffset)
- {
- mRoot = aRoot;
- mStartContainer = aStartContainer;
- mEndContainer = aEndContainer;
- 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)
- {
- }
- Accessible*
- TextRange::CommonParent(Accessible* aAcc1, Accessible* aAcc2,
- nsTArray<Accessible*>* aParents1, uint32_t* aPos1,
- nsTArray<Accessible*>* aParents2, uint32_t* aPos2) const
- {
- if (aAcc1 == aAcc2) {
- return aAcc1;
- }
- MOZ_ASSERT(aParents1->Length() == 0 || aParents2->Length() == 0,
- "Wrong arguments");
- // Build the chain of parents.
- Accessible* p1 = aAcc1;
- Accessible* p2 = aAcc2;
- do {
- aParents1->AppendElement(p1);
- p1 = p1->Parent();
- } while (p1);
- do {
- aParents2->AppendElement(p2);
- p2 = p2->Parent();
- } while (p2);
- // Find where the parent chain differs
- *aPos1 = aParents1->Length();
- *aPos2 = aParents2->Length();
- Accessible* parent = nullptr;
- uint32_t len = 0;
- for (len = std::min(*aPos1, *aPos2); len > 0; --len) {
- Accessible* child1 = aParents1->ElementAt(--(*aPos1));
- Accessible* child2 = aParents2->ElementAt(--(*aPos2));
- if (child1 != child2)
- break;
- parent = child1;
- }
- return parent;
- }
- } // namespace a11y
- } // namespace mozilla
|