1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_a11y_relation_h_ 8 #define mozilla_a11y_relation_h_ 9 10 #include "AccIterator.h" 11 12 #include <memory> 13 14 namespace mozilla { 15 namespace a11y { 16 17 /** 18 * A collection of relation targets of a certain type. Targets are computed 19 * lazily while enumerating. 20 */ 21 class Relation { 22 public: Relation()23 Relation() : mFirstIter(nullptr), mLastIter(nullptr) {} 24 Relation(AccIterable * aIter)25 explicit Relation(AccIterable* aIter) : mFirstIter(aIter), mLastIter(aIter) {} 26 Relation(LocalAccessible * aAcc)27 explicit Relation(LocalAccessible* aAcc) 28 : mFirstIter(nullptr), mLastIter(nullptr) { 29 AppendTarget(aAcc); 30 } 31 Relation(DocAccessible * aDocument,nsIContent * aContent)32 Relation(DocAccessible* aDocument, nsIContent* aContent) 33 : mFirstIter(nullptr), mLastIter(nullptr) { 34 AppendTarget(aDocument, aContent); 35 } 36 Relation(Relation && aOther)37 Relation(Relation&& aOther) 38 : mFirstIter(std::move(aOther.mFirstIter)), mLastIter(aOther.mLastIter) { 39 aOther.mLastIter = nullptr; 40 } 41 42 Relation& operator=(Relation&& aRH) { 43 mFirstIter = std::move(aRH.mFirstIter); 44 mLastIter = aRH.mLastIter; 45 aRH.mLastIter = nullptr; 46 return *this; 47 } 48 AppendIter(AccIterable * aIter)49 inline void AppendIter(AccIterable* aIter) { 50 if (mLastIter) { 51 mLastIter->mNextIter.reset(aIter); 52 } else { 53 mFirstIter.reset(aIter); 54 } 55 56 mLastIter = aIter; 57 } 58 59 /** 60 * Append the given accessible to the set of related accessibles. 61 */ AppendTarget(LocalAccessible * aAcc)62 inline void AppendTarget(LocalAccessible* aAcc) { 63 if (aAcc) AppendIter(new SingleAccIterator(aAcc)); 64 } 65 66 /** 67 * Append the one accessible for this content node to the set of related 68 * accessibles. 69 */ AppendTarget(DocAccessible * aDocument,nsIContent * aContent)70 void AppendTarget(DocAccessible* aDocument, nsIContent* aContent) { 71 if (aContent) AppendTarget(aDocument->GetAccessible(aContent)); 72 } 73 74 /** 75 * compute and return the next related accessible. 76 */ Next()77 inline LocalAccessible* Next() { 78 LocalAccessible* target = nullptr; 79 80 while (mFirstIter && !(target = mFirstIter->Next())) { 81 mFirstIter = std::move(mFirstIter->mNextIter); 82 } 83 84 if (!mFirstIter) mLastIter = nullptr; 85 86 return target; 87 } 88 89 private: 90 Relation& operator=(const Relation&) = delete; 91 Relation(const Relation&) = delete; 92 93 std::unique_ptr<AccIterable> mFirstIter; 94 AccIterable* mLastIter; 95 }; 96 97 } // namespace a11y 98 } // namespace mozilla 99 100 #endif 101