xpcAccessibleHyperText.cpp (13699B)
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 "xpcAccessibleHyperText.h" 8 9 #include "TextRange.h" 10 #include "AccAttributes.h" 11 #include "nsComponentManagerUtils.h" 12 #include "nsPersistentProperties.h" 13 #include "xpcAccessibleDocument.h" 14 #include "xpcAccessibleTextRange.h" 15 16 #include "nsIMutableArray.h" 17 18 using namespace mozilla::a11y; 19 20 //////////////////////////////////////////////////////////////////////////////// 21 // nsISupports 22 23 NS_INTERFACE_MAP_BEGIN(xpcAccessibleHyperText) 24 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleText, 25 mSupportedIfaces & eText) 26 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleEditableText, 27 mSupportedIfaces & eText) 28 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleHyperText, 29 mSupportedIfaces & eText) 30 NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleGeneric) 31 32 NS_IMPL_ADDREF_INHERITED(xpcAccessibleHyperText, xpcAccessibleGeneric) 33 NS_IMPL_RELEASE_INHERITED(xpcAccessibleHyperText, xpcAccessibleGeneric) 34 35 //////////////////////////////////////////////////////////////////////////////// 36 // nsIAccessibleText 37 38 NS_IMETHODIMP 39 xpcAccessibleHyperText::GetCharacterCount(int32_t* aCharacterCount) { 40 NS_ENSURE_ARG_POINTER(aCharacterCount); 41 *aCharacterCount = 0; 42 43 if (!mIntl) return NS_ERROR_FAILURE; 44 45 *aCharacterCount = static_cast<int32_t>(Intl()->CharacterCount()); 46 return NS_OK; 47 } 48 49 NS_IMETHODIMP 50 xpcAccessibleHyperText::GetText(int32_t aStartOffset, int32_t aEndOffset, 51 nsAString& aText) { 52 aText.Truncate(); 53 54 if (!mIntl) return NS_ERROR_FAILURE; 55 56 Intl()->TextSubstring(aStartOffset, aEndOffset, aText); 57 return NS_OK; 58 } 59 60 NS_IMETHODIMP 61 xpcAccessibleHyperText::GetTextBeforeOffset( 62 int32_t aOffset, AccessibleTextBoundary aBoundaryType, 63 int32_t* aStartOffset, int32_t* aEndOffset, nsAString& aText) { 64 NS_ENSURE_ARG_POINTER(aStartOffset); 65 NS_ENSURE_ARG_POINTER(aEndOffset); 66 *aStartOffset = *aEndOffset = 0; 67 aText.Truncate(); 68 69 if (!mIntl) return NS_ERROR_FAILURE; 70 71 Intl()->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 72 aText); 73 return NS_OK; 74 } 75 76 NS_IMETHODIMP 77 xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset, 78 AccessibleTextBoundary aBoundaryType, 79 int32_t* aStartOffset, 80 int32_t* aEndOffset, nsAString& aText) { 81 NS_ENSURE_ARG_POINTER(aStartOffset); 82 NS_ENSURE_ARG_POINTER(aEndOffset); 83 *aStartOffset = *aEndOffset = 0; 84 aText.Truncate(); 85 86 if (!mIntl) return NS_ERROR_FAILURE; 87 88 Intl()->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText); 89 return NS_OK; 90 } 91 92 NS_IMETHODIMP 93 xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset, 94 AccessibleTextBoundary aBoundaryType, 95 int32_t* aStartOffset, 96 int32_t* aEndOffset, 97 nsAString& aText) { 98 NS_ENSURE_ARG_POINTER(aStartOffset); 99 NS_ENSURE_ARG_POINTER(aEndOffset); 100 *aStartOffset = *aEndOffset = 0; 101 aText.Truncate(); 102 103 Intl()->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 104 aText); 105 return NS_OK; 106 } 107 108 NS_IMETHODIMP 109 xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset, 110 char16_t* aCharacter) { 111 NS_ENSURE_ARG_POINTER(aCharacter); 112 *aCharacter = L'\0'; 113 114 if (!mIntl) return NS_ERROR_FAILURE; 115 116 *aCharacter = Intl()->CharAt(aOffset); 117 return NS_OK; 118 } 119 120 NS_IMETHODIMP 121 xpcAccessibleHyperText::GetTextAttributes( 122 bool aIncludeDefAttrs, int32_t aOffset, int32_t* aStartOffset, 123 int32_t* aEndOffset, nsIPersistentProperties** aAttributes) { 124 NS_ENSURE_ARG_POINTER(aStartOffset); 125 NS_ENSURE_ARG_POINTER(aEndOffset); 126 NS_ENSURE_ARG_POINTER(aAttributes); 127 *aStartOffset = *aEndOffset = 0; 128 *aAttributes = nullptr; 129 130 if (!mIntl) return NS_ERROR_FAILURE; 131 132 RefPtr<AccAttributes> attributes = Intl()->TextAttributes( 133 aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset); 134 RefPtr<nsPersistentProperties> props = new nsPersistentProperties(); 135 nsAutoString unused; 136 for (auto iter : *attributes) { 137 nsAutoString name; 138 iter.NameAsString(name); 139 140 nsAutoString value; 141 iter.ValueAsString(value); 142 143 props->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused); 144 } 145 146 props.forget(aAttributes); 147 return NS_OK; 148 } 149 150 NS_IMETHODIMP 151 xpcAccessibleHyperText::GetDefaultTextAttributes( 152 nsIPersistentProperties** aAttributes) { 153 NS_ENSURE_ARG_POINTER(aAttributes); 154 *aAttributes = nullptr; 155 156 if (!mIntl) return NS_ERROR_FAILURE; 157 158 RefPtr<AccAttributes> attributes = Intl()->DefaultTextAttributes(); 159 RefPtr<nsPersistentProperties> props = new nsPersistentProperties(); 160 nsAutoString unused; 161 for (auto iter : *attributes) { 162 nsAutoString name; 163 iter.NameAsString(name); 164 165 nsAutoString value; 166 iter.ValueAsString(value); 167 168 props->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused); 169 } 170 171 props.forget(aAttributes); 172 173 return NS_OK; 174 } 175 176 NS_IMETHODIMP 177 xpcAccessibleHyperText::GetCharacterExtents(int32_t aOffset, int32_t* aX, 178 int32_t* aY, int32_t* aWidth, 179 int32_t* aHeight, 180 uint32_t aCoordType) { 181 NS_ENSURE_ARG_POINTER(aX); 182 NS_ENSURE_ARG_POINTER(aY); 183 NS_ENSURE_ARG_POINTER(aWidth); 184 NS_ENSURE_ARG_POINTER(aHeight); 185 *aX = *aY = *aWidth = *aHeight; 186 187 if (!mIntl) return NS_ERROR_FAILURE; 188 189 LayoutDeviceIntRect rect = Intl()->CharBounds(aOffset, aCoordType); 190 rect.GetRect(aX, aY, aWidth, aHeight); 191 return NS_OK; 192 } 193 194 NS_IMETHODIMP 195 xpcAccessibleHyperText::GetRangeExtents(int32_t aStartOffset, 196 int32_t aEndOffset, int32_t* aX, 197 int32_t* aY, int32_t* aWidth, 198 int32_t* aHeight, uint32_t aCoordType) { 199 NS_ENSURE_ARG_POINTER(aX); 200 NS_ENSURE_ARG_POINTER(aY); 201 NS_ENSURE_ARG_POINTER(aWidth); 202 NS_ENSURE_ARG_POINTER(aHeight); 203 *aX = *aY = *aWidth = *aHeight = 0; 204 205 if (!mIntl) return NS_ERROR_FAILURE; 206 207 LayoutDeviceIntRect rect = 208 Intl()->TextBounds(aStartOffset, aEndOffset, aCoordType); 209 rect.GetRect(aX, aY, aWidth, aHeight); 210 return NS_OK; 211 } 212 213 NS_IMETHODIMP 214 xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY, 215 uint32_t aCoordType, 216 int32_t* aOffset) { 217 NS_ENSURE_ARG_POINTER(aOffset); 218 *aOffset = -1; 219 220 if (!mIntl) return NS_ERROR_FAILURE; 221 222 *aOffset = Intl()->OffsetAtPoint(aX, aY, aCoordType); 223 return NS_OK; 224 } 225 226 NS_IMETHODIMP 227 xpcAccessibleHyperText::GetCaretOffset(int32_t* aCaretOffset) { 228 NS_ENSURE_ARG_POINTER(aCaretOffset); 229 *aCaretOffset = -1; 230 231 if (!mIntl) return NS_ERROR_FAILURE; 232 233 *aCaretOffset = Intl()->CaretOffset(); 234 return NS_OK; 235 } 236 237 NS_IMETHODIMP 238 xpcAccessibleHyperText::SetCaretOffset(int32_t aCaretOffset) { 239 if (!mIntl) return NS_ERROR_FAILURE; 240 241 Intl()->SetCaretOffset(aCaretOffset); 242 return NS_OK; 243 } 244 245 NS_IMETHODIMP 246 xpcAccessibleHyperText::GetCaretRect(int32_t* aX, int32_t* aY, int32_t* aWidth, 247 int32_t* aHeight) { 248 NS_ENSURE_ARG_POINTER(aX); 249 NS_ENSURE_ARG_POINTER(aY); 250 NS_ENSURE_ARG_POINTER(aWidth); 251 NS_ENSURE_ARG_POINTER(aHeight); 252 *aX = *aY = *aWidth = *aHeight; 253 254 if (!mIntl) { 255 return NS_ERROR_FAILURE; 256 } 257 258 auto [rect, _] = Intl()->GetCaretRect(); 259 rect.GetRect(aX, aY, aWidth, aHeight); 260 return NS_OK; 261 } 262 263 NS_IMETHODIMP 264 xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount) { 265 NS_ENSURE_ARG_POINTER(aSelectionCount); 266 *aSelectionCount = 0; 267 268 if (!mIntl) return NS_ERROR_FAILURE; 269 270 *aSelectionCount = Intl()->SelectionCount(); 271 return NS_OK; 272 } 273 274 NS_IMETHODIMP 275 xpcAccessibleHyperText::GetSelectionBounds(int32_t aSelectionNum, 276 int32_t* aStartOffset, 277 int32_t* aEndOffset) { 278 NS_ENSURE_ARG_POINTER(aStartOffset); 279 NS_ENSURE_ARG_POINTER(aEndOffset); 280 *aStartOffset = *aEndOffset = 0; 281 282 if (!mIntl) return NS_ERROR_FAILURE; 283 284 if (aSelectionNum < 0) return NS_ERROR_INVALID_ARG; 285 286 if (aSelectionNum >= Intl()->SelectionCount()) { 287 return NS_ERROR_INVALID_ARG; 288 } 289 290 Intl()->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); 291 return NS_OK; 292 } 293 294 NS_IMETHODIMP 295 xpcAccessibleHyperText::SetSelectionBounds(int32_t aSelectionNum, 296 int32_t aStartOffset, 297 int32_t aEndOffset) { 298 if (!mIntl) return NS_ERROR_FAILURE; 299 300 if (aSelectionNum < 0) return NS_ERROR_INVALID_ARG; 301 302 Intl()->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); 303 return NS_OK; 304 } 305 306 NS_IMETHODIMP 307 xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset) { 308 if (!mIntl) return NS_ERROR_FAILURE; 309 310 Intl()->AddToSelection(aStartOffset, aEndOffset); 311 return NS_OK; 312 } 313 314 NS_IMETHODIMP 315 xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum) { 316 if (!mIntl) return NS_ERROR_FAILURE; 317 318 Intl()->RemoveFromSelection(aSelectionNum); 319 return NS_OK; 320 } 321 322 NS_IMETHODIMP 323 xpcAccessibleHyperText::ScrollSubstringTo(int32_t aStartOffset, 324 int32_t aEndOffset, 325 uint32_t aScrollType) { 326 if (!mIntl) return NS_ERROR_FAILURE; 327 328 Intl()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType); 329 return NS_OK; 330 } 331 332 NS_IMETHODIMP 333 xpcAccessibleHyperText::ScrollSubstringToPoint(int32_t aStartOffset, 334 int32_t aEndOffset, 335 uint32_t aCoordinateType, 336 int32_t aX, int32_t aY) { 337 if (!mIntl) return NS_ERROR_FAILURE; 338 339 Intl()->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType, aX, 340 aY); 341 return NS_OK; 342 } 343 344 NS_IMETHODIMP 345 xpcAccessibleHyperText::GetSelectionRanges(nsIArray** aRanges) { 346 NS_ENSURE_ARG_POINTER(aRanges); 347 *aRanges = nullptr; 348 349 nsresult rv = NS_OK; 350 nsCOMPtr<nsIMutableArray> xpcRanges = 351 do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); 352 NS_ENSURE_SUCCESS(rv, rv); 353 354 AutoTArray<TextRange, 1> ranges; 355 Intl()->SelectionRanges(&ranges); 356 uint32_t len = ranges.Length(); 357 for (uint32_t idx = 0; idx < len; idx++) { 358 xpcRanges->AppendElement(new xpcAccessibleTextRange(ranges[idx])); 359 } 360 361 xpcRanges.forget(aRanges); 362 return NS_OK; 363 } 364 365 //////////////////////////////////////////////////////////////////////////////// 366 // nsIAccessibleEditableText 367 368 NS_IMETHODIMP 369 xpcAccessibleHyperText::SetTextContents(const nsAString& aText) { 370 if (!mIntl) return NS_ERROR_FAILURE; 371 372 Intl()->ReplaceText(aText); 373 374 return NS_OK; 375 } 376 377 NS_IMETHODIMP 378 xpcAccessibleHyperText::InsertText(const nsAString& aText, int32_t aOffset) { 379 if (!mIntl) return NS_ERROR_FAILURE; 380 381 Intl()->InsertText(aText, aOffset); 382 383 return NS_OK; 384 } 385 386 NS_IMETHODIMP 387 xpcAccessibleHyperText::CopyText(int32_t aStartOffset, int32_t aEndOffset) { 388 if (!mIntl) return NS_ERROR_FAILURE; 389 390 Intl()->CopyText(aStartOffset, aEndOffset); 391 392 return NS_OK; 393 } 394 395 NS_IMETHODIMP 396 xpcAccessibleHyperText::CutText(int32_t aStartOffset, int32_t aEndOffset) { 397 if (!mIntl) return NS_ERROR_FAILURE; 398 399 Intl()->CutText(aStartOffset, aEndOffset); 400 401 return NS_OK; 402 } 403 404 NS_IMETHODIMP 405 xpcAccessibleHyperText::DeleteText(int32_t aStartOffset, int32_t aEndOffset) { 406 if (!mIntl) return NS_ERROR_FAILURE; 407 408 Intl()->DeleteText(aStartOffset, aEndOffset); 409 410 return NS_OK; 411 } 412 413 NS_IMETHODIMP 414 xpcAccessibleHyperText::PasteText(int32_t aOffset) { 415 if (!mIntl) return NS_ERROR_FAILURE; 416 417 Intl()->PasteText(aOffset); 418 419 return NS_OK; 420 } 421 422 //////////////////////////////////////////////////////////////////////////////// 423 // nsIAccessibleHyperText 424 425 NS_IMETHODIMP 426 xpcAccessibleHyperText::GetLinkCount(int32_t* aLinkCount) { 427 NS_ENSURE_ARG_POINTER(aLinkCount); 428 *aLinkCount = 0; 429 430 if (!mIntl) return NS_ERROR_FAILURE; 431 432 *aLinkCount = static_cast<int32_t>(Intl()->LinkCount()); 433 return NS_OK; 434 } 435 436 NS_IMETHODIMP 437 xpcAccessibleHyperText::GetLinkAt(int32_t aIndex, 438 nsIAccessibleHyperLink** aLink) { 439 NS_ENSURE_ARG_POINTER(aLink); 440 *aLink = nullptr; 441 442 if (!mIntl) return NS_ERROR_FAILURE; 443 444 NS_IF_ADDREF(*aLink = ToXPC(Intl()->LinkAt(aIndex))); 445 return NS_OK; 446 } 447 448 NS_IMETHODIMP 449 xpcAccessibleHyperText::GetLinkIndex(nsIAccessibleHyperLink* aLink, 450 int32_t* aIndex) { 451 NS_ENSURE_ARG_POINTER(aLink); 452 NS_ENSURE_ARG_POINTER(aIndex); 453 *aIndex = -1; 454 455 if (!mIntl) return NS_ERROR_FAILURE; 456 457 nsCOMPtr<nsIAccessible> xpcLink(do_QueryInterface(aLink)); 458 Accessible* accLink = xpcLink->ToInternalGeneric(); 459 *aIndex = Intl()->LinkIndexOf(accLink); 460 return NS_OK; 461 } 462 463 NS_IMETHODIMP 464 xpcAccessibleHyperText::GetLinkIndexAtOffset(int32_t aOffset, 465 int32_t* aLinkIndex) { 466 NS_ENSURE_ARG_POINTER(aLinkIndex); 467 *aLinkIndex = -1; // API says this magic value means 'not found' 468 469 if (!mIntl) return NS_ERROR_FAILURE; 470 471 *aLinkIndex = Intl()->LinkIndexAtOffset(aOffset); 472 return NS_OK; 473 }