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(Accessible * aAcc)27 explicit Relation(Accessible* 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(Move(aOther.mFirstIter)), mLastIter(aOther.mLastIter) { 39 aOther.mLastIter = nullptr; 40 } 41 42 Relation& operator=(Relation&& aRH) { 43 mFirstIter = 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 mLastIter = aIter; 56 } 57 58 /** 59 * Append the given accessible to the set of related accessibles. 60 */ AppendTarget(Accessible * aAcc)61 inline void AppendTarget(Accessible* aAcc) { 62 if (aAcc) AppendIter(new SingleAccIterator(aAcc)); 63 } 64 65 /** 66 * Append the one accessible for this content node to the set of related 67 * accessibles. 68 */ AppendTarget(DocAccessible * aDocument,nsIContent * aContent)69 void AppendTarget(DocAccessible* aDocument, nsIContent* aContent) { 70 if (aContent) AppendTarget(aDocument->GetAccessible(aContent)); 71 } 72 73 /** 74 * compute and return the next related accessible. 75 */ Next()76 inline Accessible* Next() { 77 Accessible* target = nullptr; 78 79 while (mFirstIter && !(target = mFirstIter->Next())) 80 mFirstIter = std::move(mFirstIter->mNextIter); 81 82 if (!mFirstIter) mLastIter = nullptr; 83 84 return target; 85 } 86 87 private: 88 Relation& operator=(const Relation&) = delete; 89 Relation(const Relation&) = delete; 90 91 std::unique_ptr<AccIterable> mFirstIter; 92 AccIterable* mLastIter; 93 }; 94 95 } // namespace a11y 96 } // namespace mozilla 97 98 #endif 99