accessible/src/xul/XULFormControlAccessible.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "XULFormControlAccessible.h"
michael@0 7
michael@0 8 #include "Accessible-inl.h"
michael@0 9 #include "HTMLFormControlAccessible.h"
michael@0 10 #include "nsAccUtils.h"
michael@0 11 #include "nsCoreUtils.h"
michael@0 12 #include "DocAccessible.h"
michael@0 13 #include "nsIAccessibleRelation.h"
michael@0 14 #include "Relation.h"
michael@0 15 #include "Role.h"
michael@0 16 #include "States.h"
michael@0 17 #include "TreeWalker.h"
michael@0 18 #include "XULMenuAccessible.h"
michael@0 19
michael@0 20 #include "nsIDOMNSEditableElement.h"
michael@0 21 #include "nsIDOMXULButtonElement.h"
michael@0 22 #include "nsIDOMXULCheckboxElement.h"
michael@0 23 #include "nsIDOMXULMenuListElement.h"
michael@0 24 #include "nsIDOMXULSelectCntrlItemEl.h"
michael@0 25 #include "nsIDOMXULTextboxElement.h"
michael@0 26 #include "nsIEditor.h"
michael@0 27 #include "nsIFrame.h"
michael@0 28 #include "nsITextControlFrame.h"
michael@0 29 #include "nsMenuPopupFrame.h"
michael@0 30 #include "nsNameSpaceManager.h"
michael@0 31 #include "mozilla/dom/Element.h"
michael@0 32
michael@0 33 using namespace mozilla::a11y;
michael@0 34
michael@0 35 ////////////////////////////////////////////////////////////////////////////////
michael@0 36 // XULButtonAccessible
michael@0 37 ////////////////////////////////////////////////////////////////////////////////
michael@0 38
michael@0 39 XULButtonAccessible::
michael@0 40 XULButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 41 AccessibleWrap(aContent, aDoc)
michael@0 42 {
michael@0 43 if (ContainsMenu()) {
michael@0 44 mGenericTypes |= eMenuButton;
michael@0 45 } else {
michael@0 46 mGenericTypes |= eButton;
michael@0 47 }
michael@0 48 }
michael@0 49
michael@0 50 ////////////////////////////////////////////////////////////////////////////////
michael@0 51 // XULButtonAccessible: nsISupports
michael@0 52
michael@0 53 NS_IMPL_ISUPPORTS_INHERITED0(XULButtonAccessible, Accessible)
michael@0 54
michael@0 55 ////////////////////////////////////////////////////////////////////////////////
michael@0 56 // XULButtonAccessible: nsIAccessible
michael@0 57
michael@0 58 uint8_t
michael@0 59 XULButtonAccessible::ActionCount()
michael@0 60 {
michael@0 61 return 1;
michael@0 62 }
michael@0 63
michael@0 64 NS_IMETHODIMP
michael@0 65 XULButtonAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
michael@0 66 {
michael@0 67 if (aIndex == eAction_Click) {
michael@0 68 aName.AssignLiteral("press");
michael@0 69 return NS_OK;
michael@0 70 }
michael@0 71 return NS_ERROR_INVALID_ARG;
michael@0 72 }
michael@0 73
michael@0 74 NS_IMETHODIMP
michael@0 75 XULButtonAccessible::DoAction(uint8_t aIndex)
michael@0 76 {
michael@0 77 if (aIndex != 0)
michael@0 78 return NS_ERROR_INVALID_ARG;
michael@0 79
michael@0 80 DoCommand();
michael@0 81 return NS_OK;
michael@0 82 }
michael@0 83
michael@0 84 ////////////////////////////////////////////////////////////////////////////////
michael@0 85 // XULButtonAccessible: Accessible
michael@0 86
michael@0 87 role
michael@0 88 XULButtonAccessible::NativeRole()
michael@0 89 {
michael@0 90 return roles::PUSHBUTTON;
michael@0 91 }
michael@0 92
michael@0 93 uint64_t
michael@0 94 XULButtonAccessible::NativeState()
michael@0 95 {
michael@0 96 // Possible states: focused, focusable, unavailable(disabled).
michael@0 97
michael@0 98 // get focus and disable status from base class
michael@0 99 uint64_t state = Accessible::NativeState();
michael@0 100
michael@0 101 // Buttons can be checked -- they simply appear pressed in rather than checked
michael@0 102 nsCOMPtr<nsIDOMXULButtonElement> xulButtonElement(do_QueryInterface(mContent));
michael@0 103 if (xulButtonElement) {
michael@0 104 nsAutoString type;
michael@0 105 xulButtonElement->GetType(type);
michael@0 106 if (type.EqualsLiteral("checkbox") || type.EqualsLiteral("radio")) {
michael@0 107 state |= states::CHECKABLE;
michael@0 108 bool checked = false;
michael@0 109 int32_t checkState = 0;
michael@0 110 xulButtonElement->GetChecked(&checked);
michael@0 111 if (checked) {
michael@0 112 state |= states::PRESSED;
michael@0 113 xulButtonElement->GetCheckState(&checkState);
michael@0 114 if (checkState == nsIDOMXULButtonElement::CHECKSTATE_MIXED) {
michael@0 115 state |= states::MIXED;
michael@0 116 }
michael@0 117 }
michael@0 118 }
michael@0 119 }
michael@0 120
michael@0 121 if (ContainsMenu())
michael@0 122 state |= states::HASPOPUP;
michael@0 123
michael@0 124 if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::_default))
michael@0 125 state |= states::DEFAULT;
michael@0 126
michael@0 127 return state;
michael@0 128 }
michael@0 129
michael@0 130 ////////////////////////////////////////////////////////////////////////////////
michael@0 131 // XULButtonAccessible: Widgets
michael@0 132
michael@0 133 bool
michael@0 134 XULButtonAccessible::IsWidget() const
michael@0 135 {
michael@0 136 return true;
michael@0 137 }
michael@0 138
michael@0 139 bool
michael@0 140 XULButtonAccessible::IsActiveWidget() const
michael@0 141 {
michael@0 142 return FocusMgr()->HasDOMFocus(mContent);
michael@0 143 }
michael@0 144
michael@0 145 bool
michael@0 146 XULButtonAccessible::AreItemsOperable() const
michael@0 147 {
michael@0 148 if (IsMenuButton()) {
michael@0 149 Accessible* menuPopup = mChildren.SafeElementAt(0, nullptr);
michael@0 150 if (menuPopup) {
michael@0 151 nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(menuPopup->GetFrame());
michael@0 152 return menuPopupFrame->IsOpen();
michael@0 153 }
michael@0 154 }
michael@0 155 return false; // no items
michael@0 156 }
michael@0 157
michael@0 158 Accessible*
michael@0 159 XULButtonAccessible::ContainerWidget() const
michael@0 160 {
michael@0 161 if (IsMenuButton() && mParent && mParent->IsAutoComplete())
michael@0 162 return mParent;
michael@0 163 return nullptr;
michael@0 164 }
michael@0 165
michael@0 166 bool
michael@0 167 XULButtonAccessible::IsAcceptableChild(Accessible* aPossibleChild) const
michael@0 168 {
michael@0 169 // In general XUL button has not accessible children. Nevertheless menu
michael@0 170 // buttons can have button (@type="menu-button") and popup accessibles
michael@0 171 // (@type="menu-button", @type="menu" or columnpicker.
michael@0 172
michael@0 173 // XXX: no children until the button is menu button. Probably it's not
michael@0 174 // totally correct but in general AT wants to have leaf buttons.
michael@0 175 roles::Role role = aPossibleChild->Role();
michael@0 176
michael@0 177 // Get an accessible for menupopup or panel elements.
michael@0 178 if (role == roles::MENUPOPUP)
michael@0 179 return true;
michael@0 180
michael@0 181 // Button type="menu-button" contains a real button. Get an accessible
michael@0 182 // for it. Ignore dropmarker button which is placed as a last child.
michael@0 183 if (role != roles::PUSHBUTTON ||
michael@0 184 aPossibleChild->GetContent()->Tag() == nsGkAtoms::dropMarker)
michael@0 185 return false;
michael@0 186
michael@0 187 return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
michael@0 188 nsGkAtoms::menuButton, eCaseMatters);
michael@0 189 }
michael@0 190
michael@0 191 ////////////////////////////////////////////////////////////////////////////////
michael@0 192 // XULButtonAccessible protected
michael@0 193
michael@0 194 bool
michael@0 195 XULButtonAccessible::ContainsMenu()
michael@0 196 {
michael@0 197 static nsIContent::AttrValuesArray strings[] =
michael@0 198 {&nsGkAtoms::menu, &nsGkAtoms::menuButton, nullptr};
michael@0 199
michael@0 200 return mContent->FindAttrValueIn(kNameSpaceID_None,
michael@0 201 nsGkAtoms::type,
michael@0 202 strings, eCaseMatters) >= 0;
michael@0 203 }
michael@0 204
michael@0 205 ////////////////////////////////////////////////////////////////////////////////
michael@0 206 // XULDropmarkerAccessible
michael@0 207 ////////////////////////////////////////////////////////////////////////////////
michael@0 208
michael@0 209 XULDropmarkerAccessible::
michael@0 210 XULDropmarkerAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 211 LeafAccessible(aContent, aDoc)
michael@0 212 {
michael@0 213 }
michael@0 214
michael@0 215 uint8_t
michael@0 216 XULDropmarkerAccessible::ActionCount()
michael@0 217 {
michael@0 218 return 1;
michael@0 219 }
michael@0 220
michael@0 221 bool
michael@0 222 XULDropmarkerAccessible::DropmarkerOpen(bool aToggleOpen)
michael@0 223 {
michael@0 224 bool isOpen = false;
michael@0 225
michael@0 226 nsCOMPtr<nsIDOMXULButtonElement> parentButtonElement =
michael@0 227 do_QueryInterface(mContent->GetFlattenedTreeParent());
michael@0 228
michael@0 229 if (parentButtonElement) {
michael@0 230 parentButtonElement->GetOpen(&isOpen);
michael@0 231 if (aToggleOpen)
michael@0 232 parentButtonElement->SetOpen(!isOpen);
michael@0 233 }
michael@0 234 else {
michael@0 235 nsCOMPtr<nsIDOMXULMenuListElement> parentMenuListElement =
michael@0 236 do_QueryInterface(parentButtonElement);
michael@0 237 if (parentMenuListElement) {
michael@0 238 parentMenuListElement->GetOpen(&isOpen);
michael@0 239 if (aToggleOpen)
michael@0 240 parentMenuListElement->SetOpen(!isOpen);
michael@0 241 }
michael@0 242 }
michael@0 243
michael@0 244 return isOpen;
michael@0 245 }
michael@0 246
michael@0 247 /**
michael@0 248 * Return the name of our only action
michael@0 249 */
michael@0 250 NS_IMETHODIMP
michael@0 251 XULDropmarkerAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
michael@0 252 {
michael@0 253 if (aIndex == eAction_Click) {
michael@0 254 if (DropmarkerOpen(false))
michael@0 255 aName.AssignLiteral("close");
michael@0 256 else
michael@0 257 aName.AssignLiteral("open");
michael@0 258 return NS_OK;
michael@0 259 }
michael@0 260
michael@0 261 return NS_ERROR_INVALID_ARG;
michael@0 262 }
michael@0 263
michael@0 264 /**
michael@0 265 * Tell the Dropmarker to do its action
michael@0 266 */
michael@0 267 NS_IMETHODIMP
michael@0 268 XULDropmarkerAccessible::DoAction(uint8_t index)
michael@0 269 {
michael@0 270 if (index == eAction_Click) {
michael@0 271 DropmarkerOpen(true); // Reverse the open attribute
michael@0 272 return NS_OK;
michael@0 273 }
michael@0 274 return NS_ERROR_INVALID_ARG;
michael@0 275 }
michael@0 276
michael@0 277 role
michael@0 278 XULDropmarkerAccessible::NativeRole()
michael@0 279 {
michael@0 280 return roles::PUSHBUTTON;
michael@0 281 }
michael@0 282
michael@0 283 uint64_t
michael@0 284 XULDropmarkerAccessible::NativeState()
michael@0 285 {
michael@0 286 return DropmarkerOpen(false) ? states::PRESSED : 0;
michael@0 287 }
michael@0 288
michael@0 289 ////////////////////////////////////////////////////////////////////////////////
michael@0 290 // XULCheckboxAccessible
michael@0 291 ////////////////////////////////////////////////////////////////////////////////
michael@0 292
michael@0 293 XULCheckboxAccessible::
michael@0 294 XULCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 295 LeafAccessible(aContent, aDoc)
michael@0 296 {
michael@0 297 }
michael@0 298
michael@0 299 role
michael@0 300 XULCheckboxAccessible::NativeRole()
michael@0 301 {
michael@0 302 return roles::CHECKBUTTON;
michael@0 303 }
michael@0 304
michael@0 305 uint8_t
michael@0 306 XULCheckboxAccessible::ActionCount()
michael@0 307 {
michael@0 308 return 1;
michael@0 309 }
michael@0 310
michael@0 311 /**
michael@0 312 * Return the name of our only action
michael@0 313 */
michael@0 314 NS_IMETHODIMP
michael@0 315 XULCheckboxAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
michael@0 316 {
michael@0 317 if (aIndex == eAction_Click) {
michael@0 318 // check or uncheck
michael@0 319
michael@0 320 if (NativeState() & states::CHECKED)
michael@0 321 aName.AssignLiteral("uncheck");
michael@0 322 else
michael@0 323 aName.AssignLiteral("check");
michael@0 324
michael@0 325 return NS_OK;
michael@0 326 }
michael@0 327 return NS_ERROR_INVALID_ARG;
michael@0 328 }
michael@0 329
michael@0 330 /**
michael@0 331 * Tell the checkbox to do its only action -- check( or uncheck) itself
michael@0 332 */
michael@0 333 NS_IMETHODIMP
michael@0 334 XULCheckboxAccessible::DoAction(uint8_t aIndex)
michael@0 335 {
michael@0 336 if (aIndex != eAction_Click)
michael@0 337 return NS_ERROR_INVALID_ARG;
michael@0 338
michael@0 339 DoCommand();
michael@0 340 return NS_OK;
michael@0 341 }
michael@0 342
michael@0 343 uint64_t
michael@0 344 XULCheckboxAccessible::NativeState()
michael@0 345 {
michael@0 346 // Possible states: focused, focusable, unavailable(disabled), checked
michael@0 347 // Get focus and disable status from base class
michael@0 348 uint64_t state = LeafAccessible::NativeState();
michael@0 349
michael@0 350 state |= states::CHECKABLE;
michael@0 351
michael@0 352 // Determine Checked state
michael@0 353 nsCOMPtr<nsIDOMXULCheckboxElement> xulCheckboxElement =
michael@0 354 do_QueryInterface(mContent);
michael@0 355 if (xulCheckboxElement) {
michael@0 356 bool checked = false;
michael@0 357 xulCheckboxElement->GetChecked(&checked);
michael@0 358 if (checked) {
michael@0 359 state |= states::CHECKED;
michael@0 360 int32_t checkState = 0;
michael@0 361 xulCheckboxElement->GetCheckState(&checkState);
michael@0 362 if (checkState == nsIDOMXULCheckboxElement::CHECKSTATE_MIXED)
michael@0 363 state |= states::MIXED;
michael@0 364 }
michael@0 365 }
michael@0 366
michael@0 367 return state;
michael@0 368 }
michael@0 369
michael@0 370 ////////////////////////////////////////////////////////////////////////////////
michael@0 371 // XULGroupboxAccessible
michael@0 372 ////////////////////////////////////////////////////////////////////////////////
michael@0 373
michael@0 374 XULGroupboxAccessible::
michael@0 375 XULGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 376 AccessibleWrap(aContent, aDoc)
michael@0 377 {
michael@0 378 }
michael@0 379
michael@0 380 role
michael@0 381 XULGroupboxAccessible::NativeRole()
michael@0 382 {
michael@0 383 return roles::GROUPING;
michael@0 384 }
michael@0 385
michael@0 386 ENameValueFlag
michael@0 387 XULGroupboxAccessible::NativeName(nsString& aName)
michael@0 388 {
michael@0 389 // XXX: we use the first related accessible only.
michael@0 390 Accessible* label =
michael@0 391 RelationByType(RelationType::LABELLED_BY).Next();
michael@0 392 if (label)
michael@0 393 return label->Name(aName);
michael@0 394
michael@0 395 return eNameOK;
michael@0 396 }
michael@0 397
michael@0 398 Relation
michael@0 399 XULGroupboxAccessible::RelationByType(RelationType aType)
michael@0 400 {
michael@0 401 Relation rel = AccessibleWrap::RelationByType(aType);
michael@0 402 if (aType != RelationType::LABELLED_BY)
michael@0 403 return rel;
michael@0 404
michael@0 405 // The label for xul:groupbox is generated from xul:label that is
michael@0 406 // inside the anonymous content of the xul:caption.
michael@0 407 // The xul:label has an accessible object but the xul:caption does not
michael@0 408 uint32_t childCount = ChildCount();
michael@0 409 for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
michael@0 410 Accessible* childAcc = GetChildAt(childIdx);
michael@0 411 if (childAcc->Role() == roles::LABEL) {
michael@0 412 // Ensure that it's our label
michael@0 413 Relation reverseRel = childAcc->RelationByType(RelationType::LABEL_FOR);
michael@0 414 Accessible* testGroupbox = nullptr;
michael@0 415 while ((testGroupbox = reverseRel.Next()))
michael@0 416 if (testGroupbox == this) {
michael@0 417 // The <label> points back to this groupbox
michael@0 418 rel.AppendTarget(childAcc);
michael@0 419 }
michael@0 420 }
michael@0 421 }
michael@0 422
michael@0 423 return rel;
michael@0 424 }
michael@0 425
michael@0 426 ////////////////////////////////////////////////////////////////////////////////
michael@0 427 // XULRadioButtonAccessible
michael@0 428 ////////////////////////////////////////////////////////////////////////////////
michael@0 429
michael@0 430 XULRadioButtonAccessible::
michael@0 431 XULRadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 432 RadioButtonAccessible(aContent, aDoc)
michael@0 433 {
michael@0 434 }
michael@0 435
michael@0 436 uint64_t
michael@0 437 XULRadioButtonAccessible::NativeState()
michael@0 438 {
michael@0 439 uint64_t state = LeafAccessible::NativeState();
michael@0 440 state |= states::CHECKABLE;
michael@0 441
michael@0 442 nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton =
michael@0 443 do_QueryInterface(mContent);
michael@0 444 if (radioButton) {
michael@0 445 bool selected = false; // Radio buttons can be selected
michael@0 446 radioButton->GetSelected(&selected);
michael@0 447 if (selected) {
michael@0 448 state |= states::CHECKED;
michael@0 449 }
michael@0 450 }
michael@0 451
michael@0 452 return state;
michael@0 453 }
michael@0 454
michael@0 455 uint64_t
michael@0 456 XULRadioButtonAccessible::NativeInteractiveState() const
michael@0 457 {
michael@0 458 return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE;
michael@0 459 }
michael@0 460
michael@0 461 ////////////////////////////////////////////////////////////////////////////////
michael@0 462 // XULRadioButtonAccessible: Widgets
michael@0 463
michael@0 464 Accessible*
michael@0 465 XULRadioButtonAccessible::ContainerWidget() const
michael@0 466 {
michael@0 467 return mParent;
michael@0 468 }
michael@0 469
michael@0 470
michael@0 471 ////////////////////////////////////////////////////////////////////////////////
michael@0 472 // XULRadioGroupAccessible
michael@0 473 ////////////////////////////////////////////////////////////////////////////////
michael@0 474
michael@0 475 /**
michael@0 476 * XUL Radio Group
michael@0 477 * The Radio Group proxies for the Radio Buttons themselves. The Group gets
michael@0 478 * focus whereas the Buttons do not. So we only have an accessible object for
michael@0 479 * this for the purpose of getting the proper RadioButton. Need this here to
michael@0 480 * avoid circular reference problems when navigating the accessible tree and
michael@0 481 * for getting to the radiobuttons.
michael@0 482 */
michael@0 483
michael@0 484 XULRadioGroupAccessible::
michael@0 485 XULRadioGroupAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 486 XULSelectControlAccessible(aContent, aDoc)
michael@0 487 {
michael@0 488 }
michael@0 489
michael@0 490 role
michael@0 491 XULRadioGroupAccessible::NativeRole()
michael@0 492 {
michael@0 493 return roles::GROUPING;
michael@0 494 }
michael@0 495
michael@0 496 uint64_t
michael@0 497 XULRadioGroupAccessible::NativeInteractiveState() const
michael@0 498 {
michael@0 499 // The radio group is not focusable. Sometimes the focus controller will
michael@0 500 // report that it is focused. That means that the actual selected radio button
michael@0 501 // should be considered focused.
michael@0 502 return NativelyUnavailable() ? states::UNAVAILABLE : 0;
michael@0 503 }
michael@0 504
michael@0 505 ////////////////////////////////////////////////////////////////////////////////
michael@0 506 // XULRadioGroupAccessible: Widgets
michael@0 507
michael@0 508 bool
michael@0 509 XULRadioGroupAccessible::IsWidget() const
michael@0 510 {
michael@0 511 return true;
michael@0 512 }
michael@0 513
michael@0 514 bool
michael@0 515 XULRadioGroupAccessible::IsActiveWidget() const
michael@0 516 {
michael@0 517 return FocusMgr()->HasDOMFocus(mContent);
michael@0 518 }
michael@0 519
michael@0 520 bool
michael@0 521 XULRadioGroupAccessible::AreItemsOperable() const
michael@0 522 {
michael@0 523 return true;
michael@0 524 }
michael@0 525
michael@0 526
michael@0 527 ////////////////////////////////////////////////////////////////////////////////
michael@0 528 // XULStatusBarAccessible
michael@0 529 ////////////////////////////////////////////////////////////////////////////////
michael@0 530
michael@0 531 XULStatusBarAccessible::
michael@0 532 XULStatusBarAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 533 AccessibleWrap(aContent, aDoc)
michael@0 534 {
michael@0 535 }
michael@0 536
michael@0 537 role
michael@0 538 XULStatusBarAccessible::NativeRole()
michael@0 539 {
michael@0 540 return roles::STATUSBAR;
michael@0 541 }
michael@0 542
michael@0 543
michael@0 544 ////////////////////////////////////////////////////////////////////////////////
michael@0 545 // XULToolbarButtonAccessible
michael@0 546 ////////////////////////////////////////////////////////////////////////////////
michael@0 547
michael@0 548 XULToolbarButtonAccessible::
michael@0 549 XULToolbarButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 550 XULButtonAccessible(aContent, aDoc)
michael@0 551 {
michael@0 552 }
michael@0 553
michael@0 554 void
michael@0 555 XULToolbarButtonAccessible::GetPositionAndSizeInternal(int32_t* aPosInSet,
michael@0 556 int32_t* aSetSize)
michael@0 557 {
michael@0 558 int32_t setSize = 0;
michael@0 559 int32_t posInSet = 0;
michael@0 560
michael@0 561 Accessible* parent = Parent();
michael@0 562 if (!parent)
michael@0 563 return;
michael@0 564
michael@0 565 uint32_t childCount = parent->ChildCount();
michael@0 566 for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
michael@0 567 Accessible* child = parent->GetChildAt(childIdx);
michael@0 568 if (IsSeparator(child)) { // end of a group of buttons
michael@0 569 if (posInSet)
michael@0 570 break; // we've found our group, so we're done
michael@0 571
michael@0 572 setSize = 0; // not our group, so start a new group
michael@0 573
michael@0 574 } else {
michael@0 575 setSize++; // another button in the group
michael@0 576
michael@0 577 if (child == this)
michael@0 578 posInSet = setSize; // we've found our button
michael@0 579 }
michael@0 580 }
michael@0 581
michael@0 582 *aPosInSet = posInSet;
michael@0 583 *aSetSize = setSize;
michael@0 584 }
michael@0 585
michael@0 586 bool
michael@0 587 XULToolbarButtonAccessible::IsSeparator(Accessible* aAccessible)
michael@0 588 {
michael@0 589 nsIContent* content = aAccessible->GetContent();
michael@0 590 return content && ((content->Tag() == nsGkAtoms::toolbarseparator) ||
michael@0 591 (content->Tag() == nsGkAtoms::toolbarspacer) ||
michael@0 592 (content->Tag() == nsGkAtoms::toolbarspring)); }
michael@0 593
michael@0 594
michael@0 595 ////////////////////////////////////////////////////////////////////////////////
michael@0 596 // XULToolbarAccessible
michael@0 597 ////////////////////////////////////////////////////////////////////////////////
michael@0 598
michael@0 599 XULToolbarAccessible::
michael@0 600 XULToolbarAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 601 AccessibleWrap(aContent, aDoc)
michael@0 602 {
michael@0 603 }
michael@0 604
michael@0 605 role
michael@0 606 XULToolbarAccessible::NativeRole()
michael@0 607 {
michael@0 608 return roles::TOOLBAR;
michael@0 609 }
michael@0 610
michael@0 611 ENameValueFlag
michael@0 612 XULToolbarAccessible::NativeName(nsString& aName)
michael@0 613 {
michael@0 614 if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::toolbarname, aName))
michael@0 615 aName.CompressWhitespace();
michael@0 616
michael@0 617 return eNameOK;
michael@0 618 }
michael@0 619
michael@0 620
michael@0 621 ////////////////////////////////////////////////////////////////////////////////
michael@0 622 // XULToolbarAccessible
michael@0 623 ////////////////////////////////////////////////////////////////////////////////
michael@0 624
michael@0 625 XULToolbarSeparatorAccessible::
michael@0 626 XULToolbarSeparatorAccessible(nsIContent* aContent, DocAccessible* aDoc) :
michael@0 627 LeafAccessible(aContent, aDoc)
michael@0 628 {
michael@0 629 }
michael@0 630
michael@0 631 role
michael@0 632 XULToolbarSeparatorAccessible::NativeRole()
michael@0 633 {
michael@0 634 return roles::SEPARATOR;
michael@0 635 }
michael@0 636
michael@0 637 uint64_t
michael@0 638 XULToolbarSeparatorAccessible::NativeState()
michael@0 639 {
michael@0 640 return 0;
michael@0 641 }

mercurial