michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_a11y_relation_h_ michael@0: #define mozilla_a11y_relation_h_ michael@0: michael@0: #include "AccIterator.h" michael@0: michael@0: #include "mozilla/Move.h" michael@0: michael@0: namespace mozilla { michael@0: namespace a11y { michael@0: michael@0: /** michael@0: * A collection of relation targets of a certain type. Targets are computed michael@0: * lazily while enumerating. michael@0: */ michael@0: class Relation michael@0: { michael@0: public: michael@0: Relation() : mFirstIter(nullptr), mLastIter(nullptr) { } michael@0: michael@0: Relation(AccIterable* aIter) : michael@0: mFirstIter(aIter), mLastIter(aIter) { } michael@0: michael@0: Relation(Accessible* aAcc) : michael@0: mFirstIter(nullptr), mLastIter(nullptr) michael@0: { AppendTarget(aAcc); } michael@0: michael@0: Relation(DocAccessible* aDocument, nsIContent* aContent) : michael@0: mFirstIter(nullptr), mLastIter(nullptr) michael@0: { AppendTarget(aDocument, aContent); } michael@0: michael@0: Relation(Relation&& aOther) : michael@0: mFirstIter(Move(aOther.mFirstIter)), mLastIter(aOther.mLastIter) michael@0: { michael@0: aOther.mLastIter = nullptr; michael@0: } michael@0: michael@0: Relation& operator = (Relation&& aRH) michael@0: { michael@0: mFirstIter = Move(aRH.mFirstIter); michael@0: mLastIter = aRH.mLastIter; michael@0: aRH.mLastIter = nullptr; michael@0: return *this; michael@0: } michael@0: michael@0: inline void AppendIter(AccIterable* aIter) michael@0: { michael@0: if (mLastIter) michael@0: mLastIter->mNextIter = aIter; michael@0: else michael@0: mFirstIter = aIter; michael@0: michael@0: mLastIter = aIter; michael@0: } michael@0: michael@0: /** michael@0: * Append the given accessible to the set of related accessibles. michael@0: */ michael@0: inline void AppendTarget(Accessible* aAcc) michael@0: { michael@0: if (aAcc) michael@0: AppendIter(new SingleAccIterator(aAcc)); michael@0: } michael@0: michael@0: /** michael@0: * Append the one accessible for this content node to the set of related michael@0: * accessibles. michael@0: */ michael@0: void AppendTarget(DocAccessible* aDocument, nsIContent* aContent) michael@0: { michael@0: if (aContent) michael@0: AppendTarget(aDocument->GetAccessible(aContent)); michael@0: } michael@0: michael@0: /** michael@0: * compute and return the next related accessible. michael@0: */ michael@0: inline Accessible* Next() michael@0: { michael@0: Accessible* target = nullptr; michael@0: michael@0: // a trick nsAutoPtr deletes what it used to point to when assigned to michael@0: while (mFirstIter && !(target = mFirstIter->Next())) michael@0: mFirstIter = mFirstIter->mNextIter; michael@0: michael@0: if (!mFirstIter) michael@0: mLastIter = nullptr; michael@0: michael@0: return target; michael@0: } michael@0: michael@0: private: michael@0: Relation& operator = (const Relation&) MOZ_DELETE; michael@0: Relation(const Relation&) MOZ_DELETE; michael@0: michael@0: nsAutoPtr mFirstIter; michael@0: AccIterable* mLastIter; michael@0: }; michael@0: michael@0: } // namespace a11y michael@0: } // namespace mozilla michael@0: michael@0: #endif michael@0: