xpcAccessibleDocument.cpp (5700B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "xpcAccessibleDocument.h" 8 #include "xpcAccessibleImage.h" 9 #include "xpcAccessibleTable.h" 10 #include "xpcAccessibleTableCell.h" 11 12 #include "nsAccUtils.h" 13 #include "DocAccessible-inl.h" 14 #include "mozilla/a11y/DocAccessibleParent.h" 15 #include "mozilla/dom/CanonicalBrowsingContext.h" 16 17 using namespace mozilla; 18 using namespace mozilla::a11y; 19 20 //////////////////////////////////////////////////////////////////////////////// 21 // nsISupports 22 23 NS_IMPL_QUERY_INTERFACE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText, 24 nsIAccessibleDocument) 25 NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText) 26 NS_IMETHODIMP_(MozExternalRefCountType) xpcAccessibleDocument::Release(void) { 27 nsrefcnt r = xpcAccessibleHyperText::Release(); 28 NS_LOG_RELEASE(this, r, "xpcAccessibleDocument"); 29 30 // The only reference to the xpcAccessibleDocument is in DocManager's cache. 31 if (r == 1 && !!mIntl && mCache.Count() == 0) { 32 if (mIntl->IsLocal()) { 33 GetAccService()->RemoveFromXPCDocumentCache(mIntl->AsLocal()->AsDoc()); 34 } else { 35 GetAccService()->RemoveFromRemoteXPCDocumentCache( 36 mIntl->AsRemote()->AsDoc()); 37 } 38 } 39 return r; 40 } 41 42 //////////////////////////////////////////////////////////////////////////////// 43 // nsIAccessibleDocument 44 45 NS_IMETHODIMP 46 xpcAccessibleDocument::GetURL(nsAString& aURL) { 47 if (!mIntl) return NS_ERROR_FAILURE; 48 49 nsAccUtils::DocumentURL(mIntl, aURL); 50 return NS_OK; 51 } 52 53 NS_IMETHODIMP 54 xpcAccessibleDocument::GetTitle(nsAString& aTitle) { 55 if (!Intl()) return NS_ERROR_FAILURE; 56 57 nsAutoString title; 58 Intl()->Title(title); 59 aTitle = title; 60 return NS_OK; 61 } 62 63 NS_IMETHODIMP 64 xpcAccessibleDocument::GetMimeType(nsAString& aType) { 65 if (!mIntl) return NS_ERROR_FAILURE; 66 67 nsAccUtils::DocumentMimeType(mIntl, aType); 68 return NS_OK; 69 } 70 71 NS_IMETHODIMP 72 xpcAccessibleDocument::GetDocType(nsAString& aType) { 73 if (!Intl()) return NS_ERROR_FAILURE; 74 75 Intl()->DocType(aType); 76 return NS_OK; 77 } 78 79 NS_IMETHODIMP 80 xpcAccessibleDocument::GetDOMDocument(dom::Document** aDOMDocument) { 81 NS_ENSURE_ARG_POINTER(aDOMDocument); 82 *aDOMDocument = nullptr; 83 84 if (!Intl()) return NS_ERROR_FAILURE; 85 86 if (Intl()->DocumentNode()) NS_ADDREF(*aDOMDocument = Intl()->DocumentNode()); 87 88 return NS_OK; 89 } 90 91 NS_IMETHODIMP 92 xpcAccessibleDocument::GetWindow(mozIDOMWindowProxy** aDOMWindow) { 93 NS_ENSURE_ARG_POINTER(aDOMWindow); 94 *aDOMWindow = nullptr; 95 96 if (!Intl()) return NS_ERROR_FAILURE; 97 98 NS_IF_ADDREF(*aDOMWindow = Intl()->DocumentNode()->GetWindow()); 99 return NS_OK; 100 } 101 102 NS_IMETHODIMP 103 xpcAccessibleDocument::GetParentDocument(nsIAccessibleDocument** aDocument) { 104 NS_ENSURE_ARG_POINTER(aDocument); 105 *aDocument = nullptr; 106 107 if (!Intl()) return NS_ERROR_FAILURE; 108 109 NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->ParentDocument())); 110 return NS_OK; 111 } 112 113 NS_IMETHODIMP 114 xpcAccessibleDocument::GetChildDocumentCount(uint32_t* aCount) { 115 NS_ENSURE_ARG_POINTER(aCount); 116 *aCount = 0; 117 118 if (!Intl()) return NS_ERROR_FAILURE; 119 120 *aCount = Intl()->ChildDocumentCount(); 121 return NS_OK; 122 } 123 124 NS_IMETHODIMP 125 xpcAccessibleDocument::GetChildDocumentAt(uint32_t aIndex, 126 nsIAccessibleDocument** aDocument) { 127 NS_ENSURE_ARG_POINTER(aDocument); 128 *aDocument = nullptr; 129 130 if (!Intl()) return NS_ERROR_FAILURE; 131 132 NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->GetChildDocumentAt(aIndex))); 133 return *aDocument ? NS_OK : NS_ERROR_INVALID_ARG; 134 } 135 136 NS_IMETHODIMP 137 xpcAccessibleDocument::GetBrowsingContext( 138 dom::BrowsingContext** aBrowsingContext) { 139 NS_ENSURE_ARG_POINTER(aBrowsingContext); 140 *aBrowsingContext = nullptr; 141 if (!mIntl) { 142 return NS_ERROR_FAILURE; 143 } 144 if (LocalAccessible* local = mIntl->AsLocal()) { 145 NS_IF_ADDREF(*aBrowsingContext = 146 local->AsDoc()->DocumentNode()->GetBrowsingContext()); 147 } else { 148 NS_IF_ADDREF(*aBrowsingContext = 149 mIntl->AsRemote()->AsDoc()->GetBrowsingContext()); 150 } 151 return NS_OK; 152 } 153 154 //////////////////////////////////////////////////////////////////////////////// 155 // xpcAccessibleDocument 156 157 xpcAccessibleGeneric* xpcAccessibleDocument::GetAccessible( 158 Accessible* aAccessible) { 159 if (aAccessible->IsLocal() && 160 ToXPCDocument(aAccessible->AsLocal()->Document()) != this) { 161 NS_ERROR( 162 "This XPCOM document is not related with given internal accessible!"); 163 return nullptr; 164 } 165 166 if (aAccessible->IsRemote() && 167 ToXPCDocument(aAccessible->AsRemote()->Document()) != this) { 168 NS_ERROR( 169 "This XPCOM document is not related with given internal accessible!"); 170 return nullptr; 171 } 172 173 if (aAccessible->IsDoc()) return this; 174 175 return mCache.LookupOrInsertWith(aAccessible, [&]() -> xpcAccessibleGeneric* { 176 if (aAccessible->IsImage()) { 177 return new xpcAccessibleImage(aAccessible); 178 } 179 if (aAccessible->IsTable()) { 180 return new xpcAccessibleTable(aAccessible); 181 } 182 if (aAccessible->IsTableCell()) { 183 return new xpcAccessibleTableCell(aAccessible); 184 } 185 if (aAccessible->IsHyperText()) { 186 return new xpcAccessibleHyperText(aAccessible); 187 } 188 189 return new xpcAccessibleGeneric(aAccessible); 190 }); 191 } 192 193 void xpcAccessibleDocument::Shutdown() { 194 for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) { 195 iter.Data()->Shutdown(); 196 iter.Remove(); 197 } 198 xpcAccessibleGeneric::Shutdown(); 199 }