|
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 "mozilla/Move.h" |
|
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 { |
|
23 public: |
|
24 Relation() : mFirstIter(nullptr), mLastIter(nullptr) { } |
|
25 |
|
26 Relation(AccIterable* aIter) : |
|
27 mFirstIter(aIter), mLastIter(aIter) { } |
|
28 |
|
29 Relation(Accessible* aAcc) : |
|
30 mFirstIter(nullptr), mLastIter(nullptr) |
|
31 { AppendTarget(aAcc); } |
|
32 |
|
33 Relation(DocAccessible* aDocument, nsIContent* aContent) : |
|
34 mFirstIter(nullptr), mLastIter(nullptr) |
|
35 { AppendTarget(aDocument, aContent); } |
|
36 |
|
37 Relation(Relation&& aOther) : |
|
38 mFirstIter(Move(aOther.mFirstIter)), mLastIter(aOther.mLastIter) |
|
39 { |
|
40 aOther.mLastIter = nullptr; |
|
41 } |
|
42 |
|
43 Relation& operator = (Relation&& aRH) |
|
44 { |
|
45 mFirstIter = Move(aRH.mFirstIter); |
|
46 mLastIter = aRH.mLastIter; |
|
47 aRH.mLastIter = nullptr; |
|
48 return *this; |
|
49 } |
|
50 |
|
51 inline void AppendIter(AccIterable* aIter) |
|
52 { |
|
53 if (mLastIter) |
|
54 mLastIter->mNextIter = aIter; |
|
55 else |
|
56 mFirstIter = aIter; |
|
57 |
|
58 mLastIter = aIter; |
|
59 } |
|
60 |
|
61 /** |
|
62 * Append the given accessible to the set of related accessibles. |
|
63 */ |
|
64 inline void AppendTarget(Accessible* aAcc) |
|
65 { |
|
66 if (aAcc) |
|
67 AppendIter(new SingleAccIterator(aAcc)); |
|
68 } |
|
69 |
|
70 /** |
|
71 * Append the one accessible for this content node to the set of related |
|
72 * accessibles. |
|
73 */ |
|
74 void AppendTarget(DocAccessible* aDocument, nsIContent* aContent) |
|
75 { |
|
76 if (aContent) |
|
77 AppendTarget(aDocument->GetAccessible(aContent)); |
|
78 } |
|
79 |
|
80 /** |
|
81 * compute and return the next related accessible. |
|
82 */ |
|
83 inline Accessible* Next() |
|
84 { |
|
85 Accessible* target = nullptr; |
|
86 |
|
87 // a trick nsAutoPtr deletes what it used to point to when assigned to |
|
88 while (mFirstIter && !(target = mFirstIter->Next())) |
|
89 mFirstIter = mFirstIter->mNextIter; |
|
90 |
|
91 if (!mFirstIter) |
|
92 mLastIter = nullptr; |
|
93 |
|
94 return target; |
|
95 } |
|
96 |
|
97 private: |
|
98 Relation& operator = (const Relation&) MOZ_DELETE; |
|
99 Relation(const Relation&) MOZ_DELETE; |
|
100 |
|
101 nsAutoPtr<AccIterable> mFirstIter; |
|
102 AccIterable* mLastIter; |
|
103 }; |
|
104 |
|
105 } // namespace a11y |
|
106 } // namespace mozilla |
|
107 |
|
108 #endif |
|
109 |