1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "WebAXObject.h" 33 34 #include "HTMLNames.h" 35 #include "WebDocument.h" 36 #include "WebNode.h" 37 #include "core/accessibility/AXObject.h" 38 #include "core/accessibility/AXObjectCache.h" 39 #include "core/accessibility/AXTable.h" 40 #include "core/accessibility/AXTableCell.h" 41 #include "core/accessibility/AXTableColumn.h" 42 #include "core/accessibility/AXTableRow.h" 43 #include "core/css/CSSPrimitiveValueMappings.h" 44 #include "core/dom/Document.h" 45 #include "core/dom/Node.h" 46 #include "core/page/EventHandler.h" 47 #include "core/frame/FrameView.h" 48 #include "core/rendering/style/RenderStyle.h" 49 #include "platform/PlatformKeyboardEvent.h" 50 #include "public/platform/WebPoint.h" 51 #include "public/platform/WebRect.h" 52 #include "public/platform/WebString.h" 53 #include "public/platform/WebURL.h" 54 #include "wtf/text/StringBuilder.h" 55 56 using namespace WebCore; 57 58 namespace blink { 59 60 void WebAXObject::reset() 61 { 62 m_private.reset(); 63 } 64 65 void WebAXObject::assign(const blink::WebAXObject& other) 66 { 67 m_private = other.m_private; 68 } 69 70 bool WebAXObject::equals(const WebAXObject& n) const 71 { 72 return m_private.get() == n.m_private.get(); 73 } 74 75 // static 76 void WebAXObject::enableAccessibility() 77 { 78 AXObjectCache::enableAccessibility(); 79 } 80 81 // static 82 bool WebAXObject::accessibilityEnabled() 83 { 84 return AXObjectCache::accessibilityEnabled(); 85 } 86 87 // static 88 void WebAXObject::enableInlineTextBoxAccessibility() 89 { 90 AXObjectCache::setInlineTextBoxAccessibility(true); 91 } 92 93 void WebAXObject::startCachingComputedObjectAttributesUntilTreeMutates() 94 { 95 m_private->axObjectCache()->startCachingComputedObjectAttributesUntilTreeMutates(); 96 } 97 98 void WebAXObject::stopCachingComputedObjectAttributes() 99 { 100 m_private->axObjectCache()->stopCachingComputedObjectAttributes(); 101 } 102 103 bool WebAXObject::isDetached() const 104 { 105 if (m_private.isNull()) 106 return true; 107 108 return m_private->isDetached(); 109 } 110 111 int WebAXObject::axID() const 112 { 113 if (isDetached()) 114 return -1; 115 116 return m_private->axObjectID(); 117 } 118 119 bool WebAXObject::updateBackingStoreAndCheckValidity() 120 { 121 if (!isDetached()) 122 m_private->updateBackingStore(); 123 return !isDetached(); 124 } 125 126 WebString WebAXObject::accessibilityDescription() const 127 { 128 if (isDetached()) 129 return WebString(); 130 131 return m_private->accessibilityDescription(); 132 } 133 134 WebString WebAXObject::actionVerb() const 135 { 136 if (isDetached()) 137 return WebString(); 138 139 return m_private->actionVerb(); 140 } 141 142 bool WebAXObject::canDecrement() const 143 { 144 if (isDetached()) 145 return false; 146 147 return m_private->isSlider(); 148 } 149 150 bool WebAXObject::canIncrement() const 151 { 152 if (isDetached()) 153 return false; 154 155 return m_private->isSlider(); 156 } 157 158 bool WebAXObject::canPress() const 159 { 160 if (isDetached()) 161 return false; 162 163 return m_private->actionElement() || m_private->isButton() || m_private->isMenuRelated(); 164 } 165 166 bool WebAXObject::canSetFocusAttribute() const 167 { 168 if (isDetached()) 169 return false; 170 171 return m_private->canSetFocusAttribute(); 172 } 173 174 bool WebAXObject::canSetValueAttribute() const 175 { 176 if (isDetached()) 177 return false; 178 179 return m_private->canSetValueAttribute(); 180 } 181 182 unsigned WebAXObject::childCount() const 183 { 184 if (isDetached()) 185 return 0; 186 187 return m_private->children().size(); 188 } 189 190 WebAXObject WebAXObject::childAt(unsigned index) const 191 { 192 if (isDetached()) 193 return WebAXObject(); 194 195 if (m_private->children().size() <= index) 196 return WebAXObject(); 197 198 return WebAXObject(m_private->children()[index]); 199 } 200 201 WebAXObject WebAXObject::parentObject() const 202 { 203 if (isDetached()) 204 return WebAXObject(); 205 206 return WebAXObject(m_private->parentObject()); 207 } 208 209 bool WebAXObject::canSetSelectedAttribute() const 210 { 211 if (isDetached()) 212 return 0; 213 214 return m_private->canSetSelectedAttribute(); 215 } 216 217 bool WebAXObject::isAnchor() const 218 { 219 if (isDetached()) 220 return 0; 221 222 return m_private->isAnchor(); 223 } 224 225 bool WebAXObject::isAriaReadOnly() const 226 { 227 if (isDetached()) 228 return 0; 229 230 return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true"); 231 } 232 233 bool WebAXObject::isButtonStateMixed() const 234 { 235 if (isDetached()) 236 return 0; 237 238 return m_private->checkboxOrRadioValue() == ButtonStateMixed; 239 } 240 241 bool WebAXObject::isChecked() const 242 { 243 if (isDetached()) 244 return 0; 245 246 return m_private->isChecked(); 247 } 248 249 bool WebAXObject::isClickable() const 250 { 251 if (isDetached()) 252 return 0; 253 254 return m_private->isClickable(); 255 } 256 257 bool WebAXObject::isCollapsed() const 258 { 259 if (isDetached()) 260 return 0; 261 262 return m_private->isCollapsed(); 263 } 264 265 bool WebAXObject::isControl() const 266 { 267 if (isDetached()) 268 return 0; 269 270 return m_private->isControl(); 271 } 272 273 bool WebAXObject::isEnabled() const 274 { 275 if (isDetached()) 276 return 0; 277 278 return m_private->isEnabled(); 279 } 280 281 bool WebAXObject::isFocused() const 282 { 283 if (isDetached()) 284 return 0; 285 286 return m_private->isFocused(); 287 } 288 289 bool WebAXObject::isHovered() const 290 { 291 if (isDetached()) 292 return 0; 293 294 return m_private->isHovered(); 295 } 296 297 bool WebAXObject::isIndeterminate() const 298 { 299 if (isDetached()) 300 return 0; 301 302 return m_private->isIndeterminate(); 303 } 304 305 bool WebAXObject::isLinked() const 306 { 307 if (isDetached()) 308 return 0; 309 310 return m_private->isLinked(); 311 } 312 313 bool WebAXObject::isLoaded() const 314 { 315 if (isDetached()) 316 return 0; 317 318 return m_private->isLoaded(); 319 } 320 321 bool WebAXObject::isMultiSelectable() const 322 { 323 if (isDetached()) 324 return 0; 325 326 return m_private->isMultiSelectable(); 327 } 328 329 bool WebAXObject::isOffScreen() const 330 { 331 if (isDetached()) 332 return 0; 333 334 return m_private->isOffScreen(); 335 } 336 337 bool WebAXObject::isPasswordField() const 338 { 339 if (isDetached()) 340 return 0; 341 342 return m_private->isPasswordField(); 343 } 344 345 bool WebAXObject::isPressed() const 346 { 347 if (isDetached()) 348 return 0; 349 350 return m_private->isPressed(); 351 } 352 353 bool WebAXObject::isReadOnly() const 354 { 355 if (isDetached()) 356 return 0; 357 358 return m_private->isReadOnly(); 359 } 360 361 bool WebAXObject::isRequired() const 362 { 363 if (isDetached()) 364 return 0; 365 366 return m_private->isRequired(); 367 } 368 369 bool WebAXObject::isSelected() const 370 { 371 if (isDetached()) 372 return 0; 373 374 return m_private->isSelected(); 375 } 376 377 bool WebAXObject::isSelectedOptionActive() const 378 { 379 if (isDetached()) 380 return false; 381 382 return m_private->isSelectedOptionActive(); 383 } 384 385 bool WebAXObject::isVertical() const 386 { 387 if (isDetached()) 388 return 0; 389 390 return m_private->orientation() == AccessibilityOrientationVertical; 391 } 392 393 bool WebAXObject::isVisible() const 394 { 395 if (isDetached()) 396 return 0; 397 398 return m_private->isVisible(); 399 } 400 401 bool WebAXObject::isVisited() const 402 { 403 if (isDetached()) 404 return 0; 405 406 return m_private->isVisited(); 407 } 408 409 WebString WebAXObject::accessKey() const 410 { 411 if (isDetached()) 412 return WebString(); 413 414 return WebString(m_private->accessKey()); 415 } 416 417 bool WebAXObject::ariaHasPopup() const 418 { 419 if (isDetached()) 420 return 0; 421 422 return m_private->ariaHasPopup(); 423 } 424 425 bool WebAXObject::ariaLiveRegionAtomic() const 426 { 427 if (isDetached()) 428 return 0; 429 430 return m_private->ariaLiveRegionAtomic(); 431 } 432 433 bool WebAXObject::ariaLiveRegionBusy() const 434 { 435 if (isDetached()) 436 return 0; 437 438 return m_private->ariaLiveRegionBusy(); 439 } 440 441 WebString WebAXObject::ariaLiveRegionRelevant() const 442 { 443 if (isDetached()) 444 return WebString(); 445 446 return m_private->ariaLiveRegionRelevant(); 447 } 448 449 WebString WebAXObject::ariaLiveRegionStatus() const 450 { 451 if (isDetached()) 452 return WebString(); 453 454 return m_private->ariaLiveRegionStatus(); 455 } 456 457 WebRect WebAXObject::boundingBoxRect() const 458 { 459 if (isDetached()) 460 return WebRect(); 461 462 return pixelSnappedIntRect(m_private->elementRect()); 463 } 464 465 bool WebAXObject::canvasHasFallbackContent() const 466 { 467 if (isDetached()) 468 return false; 469 470 return m_private->canvasHasFallbackContent(); 471 } 472 473 WebPoint WebAXObject::clickPoint() const 474 { 475 if (isDetached()) 476 return WebPoint(); 477 478 return WebPoint(m_private->clickPoint()); 479 } 480 481 void WebAXObject::colorValue(int& r, int& g, int& b) const 482 { 483 if (isDetached()) 484 return; 485 486 m_private->colorValue(r, g, b); 487 } 488 489 double WebAXObject::estimatedLoadingProgress() const 490 { 491 if (isDetached()) 492 return 0.0; 493 494 return m_private->estimatedLoadingProgress(); 495 } 496 497 WebString WebAXObject::helpText() const 498 { 499 if (isDetached()) 500 return WebString(); 501 502 return m_private->helpText(); 503 } 504 505 int WebAXObject::headingLevel() const 506 { 507 if (isDetached()) 508 return 0; 509 510 return m_private->headingLevel(); 511 } 512 513 int WebAXObject::hierarchicalLevel() const 514 { 515 if (isDetached()) 516 return 0; 517 518 return m_private->hierarchicalLevel(); 519 } 520 521 WebAXObject WebAXObject::hitTest(const WebPoint& point) const 522 { 523 if (isDetached()) 524 return WebAXObject(); 525 526 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point); 527 RefPtr<AXObject> hit = m_private->accessibilityHitTest(contentsPoint); 528 529 if (hit) 530 return WebAXObject(hit); 531 532 if (m_private->elementRect().contains(contentsPoint)) 533 return *this; 534 535 return WebAXObject(); 536 } 537 538 WebString WebAXObject::keyboardShortcut() const 539 { 540 if (isDetached()) 541 return WebString(); 542 543 String accessKey = m_private->accessKey(); 544 if (accessKey.isNull()) 545 return WebString(); 546 547 DEFINE_STATIC_LOCAL(String, modifierString, ()); 548 if (modifierString.isNull()) { 549 unsigned modifiers = EventHandler::accessKeyModifiers(); 550 // Follow the same order as Mozilla MSAA implementation: 551 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings 552 // should not be localized and defines the separator as "+". 553 StringBuilder modifierStringBuilder; 554 if (modifiers & PlatformEvent::CtrlKey) 555 modifierStringBuilder.appendLiteral("Ctrl+"); 556 if (modifiers & PlatformEvent::AltKey) 557 modifierStringBuilder.appendLiteral("Alt+"); 558 if (modifiers & PlatformEvent::ShiftKey) 559 modifierStringBuilder.appendLiteral("Shift+"); 560 if (modifiers & PlatformEvent::MetaKey) 561 modifierStringBuilder.appendLiteral("Win+"); 562 modifierString = modifierStringBuilder.toString(); 563 } 564 565 return String(modifierString + accessKey); 566 } 567 568 bool WebAXObject::performDefaultAction() const 569 { 570 if (isDetached()) 571 return false; 572 573 return m_private->performDefaultAction(); 574 } 575 576 bool WebAXObject::increment() const 577 { 578 if (isDetached()) 579 return false; 580 581 if (canIncrement()) { 582 m_private->increment(); 583 return true; 584 } 585 return false; 586 } 587 588 bool WebAXObject::decrement() const 589 { 590 if (isDetached()) 591 return false; 592 593 if (canDecrement()) { 594 m_private->decrement(); 595 return true; 596 } 597 return false; 598 } 599 600 bool WebAXObject::press() const 601 { 602 if (isDetached()) 603 return false; 604 605 return m_private->press(); 606 } 607 608 WebAXRole WebAXObject::role() const 609 { 610 if (isDetached()) 611 return blink::WebAXRoleUnknown; 612 613 return static_cast<WebAXRole>(m_private->roleValue()); 614 } 615 616 unsigned WebAXObject::selectionEnd() const 617 { 618 if (isDetached()) 619 return 0; 620 621 return m_private->selectedTextRange().start + m_private->selectedTextRange().length; 622 } 623 624 unsigned WebAXObject::selectionStart() const 625 { 626 if (isDetached()) 627 return 0; 628 629 return m_private->selectedTextRange().start; 630 } 631 632 unsigned WebAXObject::selectionEndLineNumber() const 633 { 634 if (isDetached()) 635 return 0; 636 637 VisiblePosition position = m_private->visiblePositionForIndex(selectionEnd()); 638 int lineNumber = m_private->lineForPosition(position); 639 if (lineNumber < 0) 640 return 0; 641 return lineNumber; 642 } 643 644 unsigned WebAXObject::selectionStartLineNumber() const 645 { 646 if (isDetached()) 647 return 0; 648 649 VisiblePosition position = m_private->visiblePositionForIndex(selectionStart()); 650 int lineNumber = m_private->lineForPosition(position); 651 if (lineNumber < 0) 652 return 0; 653 return lineNumber; 654 } 655 656 void WebAXObject::setFocused(bool on) const 657 { 658 if (!isDetached()) 659 m_private->setFocused(on); 660 } 661 662 void WebAXObject::setSelectedTextRange(int selectionStart, int selectionEnd) const 663 { 664 if (isDetached()) 665 return; 666 667 m_private->setSelectedTextRange(AXObject::PlainTextRange(selectionStart, selectionEnd - selectionStart)); 668 } 669 670 WebString WebAXObject::stringValue() const 671 { 672 if (isDetached()) 673 return WebString(); 674 675 return m_private->stringValue(); 676 } 677 678 WebString WebAXObject::title() const 679 { 680 if (isDetached()) 681 return WebString(); 682 683 return m_private->title(); 684 } 685 686 WebAXObject WebAXObject::titleUIElement() const 687 { 688 if (isDetached()) 689 return WebAXObject(); 690 691 if (!m_private->exposesTitleUIElement()) 692 return WebAXObject(); 693 694 return WebAXObject(m_private->titleUIElement()); 695 } 696 697 WebURL WebAXObject::url() const 698 { 699 if (isDetached()) 700 return WebURL(); 701 702 return m_private->url(); 703 } 704 705 bool WebAXObject::supportsRangeValue() const 706 { 707 if (isDetached()) 708 return false; 709 710 return m_private->supportsRangeValue(); 711 } 712 713 WebString WebAXObject::valueDescription() const 714 { 715 if (isDetached()) 716 return WebString(); 717 718 return m_private->valueDescription(); 719 } 720 721 float WebAXObject::valueForRange() const 722 { 723 if (isDetached()) 724 return 0.0; 725 726 return m_private->valueForRange(); 727 } 728 729 float WebAXObject::maxValueForRange() const 730 { 731 if (isDetached()) 732 return 0.0; 733 734 return m_private->maxValueForRange(); 735 } 736 737 float WebAXObject::minValueForRange() const 738 { 739 if (isDetached()) 740 return 0.0; 741 742 return m_private->minValueForRange(); 743 } 744 745 WebNode WebAXObject::node() const 746 { 747 if (isDetached()) 748 return WebNode(); 749 750 Node* node = m_private->node(); 751 if (!node) 752 return WebNode(); 753 754 return WebNode(node); 755 } 756 757 WebDocument WebAXObject::document() const 758 { 759 if (isDetached()) 760 return WebDocument(); 761 762 Document* document = m_private->document(); 763 if (!document) 764 return WebDocument(); 765 766 return WebDocument(document); 767 } 768 769 bool WebAXObject::hasComputedStyle() const 770 { 771 if (isDetached()) 772 return false; 773 774 Document* document = m_private->document(); 775 if (document) 776 document->updateStyleIfNeeded(); 777 778 Node* node = m_private->node(); 779 if (!node) 780 return false; 781 782 return node->computedStyle(); 783 } 784 785 WebString WebAXObject::computedStyleDisplay() const 786 { 787 if (isDetached()) 788 return WebString(); 789 790 Document* document = m_private->document(); 791 if (document) 792 document->updateStyleIfNeeded(); 793 794 Node* node = m_private->node(); 795 if (!node) 796 return WebString(); 797 798 RenderStyle* renderStyle = node->computedStyle(); 799 if (!renderStyle) 800 return WebString(); 801 802 return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue()); 803 } 804 805 bool WebAXObject::accessibilityIsIgnored() const 806 { 807 if (isDetached()) 808 return false; 809 810 return m_private->accessibilityIsIgnored(); 811 } 812 813 bool WebAXObject::lineBreaks(WebVector<int>& result) const 814 { 815 if (isDetached()) 816 return false; 817 818 Vector<int> lineBreaksVector; 819 m_private->lineBreaks(lineBreaksVector); 820 821 size_t vectorSize = lineBreaksVector.size(); 822 WebVector<int> lineBreaksWebVector(vectorSize); 823 for (size_t i = 0; i< vectorSize; i++) 824 lineBreaksWebVector[i] = lineBreaksVector[i]; 825 result.swap(lineBreaksWebVector); 826 827 return true; 828 } 829 830 unsigned WebAXObject::columnCount() const 831 { 832 if (isDetached()) 833 return false; 834 835 if (!m_private->isAXTable()) 836 return 0; 837 838 return toAXTable(m_private.get())->columnCount(); 839 } 840 841 unsigned WebAXObject::rowCount() const 842 { 843 if (isDetached()) 844 return false; 845 846 if (!m_private->isAXTable()) 847 return 0; 848 849 return toAXTable(m_private.get())->rowCount(); 850 } 851 852 WebAXObject WebAXObject::cellForColumnAndRow(unsigned column, unsigned row) const 853 { 854 if (isDetached()) 855 return WebAXObject(); 856 857 if (!m_private->isAXTable()) 858 return WebAXObject(); 859 860 WebCore::AXTableCell* cell = toAXTable(m_private.get())->cellForColumnAndRow(column, row); 861 return WebAXObject(static_cast<WebCore::AXObject*>(cell)); 862 } 863 864 WebAXObject WebAXObject::headerContainerObject() const 865 { 866 if (isDetached()) 867 return WebAXObject(); 868 869 if (!m_private->isAXTable()) 870 return WebAXObject(); 871 872 return WebAXObject(toAXTable(m_private.get())->headerContainer()); 873 } 874 875 WebAXObject WebAXObject::rowAtIndex(unsigned rowIndex) const 876 { 877 if (isDetached()) 878 return WebAXObject(); 879 880 if (!m_private->isAXTable()) 881 return WebAXObject(); 882 883 const AXObject::AccessibilityChildrenVector& rows = toAXTable(m_private.get())->rows(); 884 if (rowIndex < rows.size()) 885 return WebAXObject(rows[rowIndex]); 886 887 return WebAXObject(); 888 } 889 890 WebAXObject WebAXObject::columnAtIndex(unsigned columnIndex) const 891 { 892 if (isDetached()) 893 return WebAXObject(); 894 895 if (!m_private->isAXTable()) 896 return WebAXObject(); 897 898 const AXObject::AccessibilityChildrenVector& columns = toAXTable(m_private.get())->columns(); 899 if (columnIndex < columns.size()) 900 return WebAXObject(columns[columnIndex]); 901 902 return WebAXObject(); 903 } 904 905 unsigned WebAXObject::rowIndex() const 906 { 907 if (isDetached()) 908 return 0; 909 910 if (!m_private->isTableRow()) 911 return 0; 912 913 return WebCore::toAXTableRow(m_private.get())->rowIndex(); 914 } 915 916 WebAXObject WebAXObject::rowHeader() const 917 { 918 if (isDetached()) 919 return WebAXObject(); 920 921 if (!m_private->isTableRow()) 922 return WebAXObject(); 923 924 return WebAXObject(WebCore::toAXTableRow(m_private.get())->headerObject()); 925 } 926 927 unsigned WebAXObject::columnIndex() const 928 { 929 if (isDetached()) 930 return 0; 931 932 if (m_private->roleValue() != ColumnRole) 933 return 0; 934 935 return WebCore::toAXTableColumn(m_private.get())->columnIndex(); 936 } 937 938 WebAXObject WebAXObject::columnHeader() const 939 { 940 if (isDetached()) 941 return WebAXObject(); 942 943 if (m_private->roleValue() != ColumnRole) 944 return WebAXObject(); 945 946 return WebAXObject(WebCore::toAXTableColumn(m_private.get())->headerObject()); 947 } 948 949 unsigned WebAXObject::cellColumnIndex() const 950 { 951 if (isDetached()) 952 return 0; 953 954 if (!m_private->isTableCell()) 955 return 0; 956 957 pair<unsigned, unsigned> columnRange; 958 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange); 959 return columnRange.first; 960 } 961 962 unsigned WebAXObject::cellColumnSpan() const 963 { 964 if (isDetached()) 965 return 0; 966 967 if (!m_private->isTableCell()) 968 return 0; 969 970 pair<unsigned, unsigned> columnRange; 971 WebCore::toAXTableCell(m_private.get())->columnIndexRange(columnRange); 972 return columnRange.second; 973 } 974 975 unsigned WebAXObject::cellRowIndex() const 976 { 977 if (isDetached()) 978 return 0; 979 980 if (!m_private->isTableCell()) 981 return 0; 982 983 pair<unsigned, unsigned> rowRange; 984 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange); 985 return rowRange.first; 986 } 987 988 unsigned WebAXObject::cellRowSpan() const 989 { 990 if (isDetached()) 991 return 0; 992 993 if (!m_private->isTableCell()) 994 return 0; 995 996 pair<unsigned, unsigned> rowRange; 997 WebCore::toAXTableCell(m_private.get())->rowIndexRange(rowRange); 998 return rowRange.second; 999 } 1000 1001 WebAXTextDirection WebAXObject::textDirection() const 1002 { 1003 if (isDetached()) 1004 return WebAXTextDirectionLR; 1005 1006 return static_cast<WebAXTextDirection>(m_private->textDirection()); 1007 } 1008 1009 void WebAXObject::characterOffsets(WebVector<int>& offsets) const 1010 { 1011 if (isDetached()) 1012 return; 1013 1014 Vector<int> offsetsVector; 1015 m_private->textCharacterOffsets(offsetsVector); 1016 1017 size_t vectorSize = offsetsVector.size(); 1018 WebVector<int> offsetsWebVector(vectorSize); 1019 for (size_t i = 0; i < vectorSize; i++) 1020 offsetsWebVector[i] = offsetsVector[i]; 1021 offsets.swap(offsetsWebVector); 1022 } 1023 1024 void WebAXObject::wordBoundaries(WebVector<int>& starts, WebVector<int>& ends) const 1025 { 1026 if (isDetached()) 1027 return; 1028 1029 Vector<AXObject::PlainTextRange> words; 1030 m_private->wordBoundaries(words); 1031 1032 WebVector<int> startsWebVector(words.size()); 1033 WebVector<int> endsWebVector(words.size()); 1034 for (size_t i = 0; i < words.size(); i++) { 1035 startsWebVector[i] = words[i].start; 1036 endsWebVector[i] = words[i].start + words[i].length; 1037 } 1038 starts.swap(startsWebVector); 1039 ends.swap(endsWebVector); 1040 } 1041 1042 void WebAXObject::scrollToMakeVisible() const 1043 { 1044 if (!isDetached()) 1045 m_private->scrollToMakeVisible(); 1046 } 1047 1048 void WebAXObject::scrollToMakeVisibleWithSubFocus(const WebRect& subfocus) const 1049 { 1050 if (!isDetached()) 1051 m_private->scrollToMakeVisibleWithSubFocus(subfocus); 1052 } 1053 1054 void WebAXObject::scrollToGlobalPoint(const WebPoint& point) const 1055 { 1056 if (!isDetached()) 1057 m_private->scrollToGlobalPoint(point); 1058 } 1059 1060 WebAXObject::WebAXObject(const WTF::PassRefPtr<WebCore::AXObject>& object) 1061 : m_private(object) 1062 { 1063 } 1064 1065 WebAXObject& WebAXObject::operator=(const WTF::PassRefPtr<WebCore::AXObject>& object) 1066 { 1067 m_private = object; 1068 return *this; 1069 } 1070 1071 WebAXObject::operator WTF::PassRefPtr<WebCore::AXObject>() const 1072 { 1073 return m_private.get(); 1074 } 1075 1076 } // namespace blink 1077