diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/accessibility | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/accessibility')
35 files changed, 289 insertions, 85 deletions
diff --git a/Source/WebCore/accessibility/AXObjectCache.cpp b/Source/WebCore/accessibility/AXObjectCache.cpp index 02d5bfb23..c0fb7d30c 100644 --- a/Source/WebCore/accessibility/AXObjectCache.cpp +++ b/Source/WebCore/accessibility/AXObjectCache.cpp @@ -129,6 +129,9 @@ AccessibilityObject* AXObjectCache::focusedImageMapUIElement(HTMLAreaElement* ar AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page* page) { + if (!gAccessibilityEnabled) + return 0; + // get the focused node in the page Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document(); Node* focusedNode = focusedDocument->focusedNode(); @@ -288,11 +291,17 @@ AccessibilityObject* AXObjectCache::getOrCreate(RenderObject* renderer) AccessibilityObject* AXObjectCache::rootObject() { + if (!gAccessibilityEnabled) + return 0; + return getOrCreate(m_document->view()); } AccessibilityObject* AXObjectCache::rootObjectForFrame(Frame* frame) { + if (!gAccessibilityEnabled) + return 0; + if (!frame) return 0; return getOrCreate(frame->view()); diff --git a/Source/WebCore/accessibility/AccessibilityARIAGrid.h b/Source/WebCore/accessibility/AccessibilityARIAGrid.h index edc26d9c4..89b917240 100644 --- a/Source/WebCore/accessibility/AccessibilityARIAGrid.h +++ b/Source/WebCore/accessibility/AccessibilityARIAGrid.h @@ -54,7 +54,8 @@ public: private: // ARIA treegrids and grids support selected rows. virtual bool supportsSelectedRows() { return true; } - + virtual bool isMultiSelectable() const { return true; } + bool addChild(AccessibilityObject*, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount); }; diff --git a/Source/WebCore/accessibility/AccessibilityListBox.cpp b/Source/WebCore/accessibility/AccessibilityListBox.cpp index db11ac061..22e5b8185 100644 --- a/Source/WebCore/accessibility/AccessibilityListBox.cpp +++ b/Source/WebCore/accessibility/AccessibilityListBox.cpp @@ -163,7 +163,7 @@ bool AccessibilityListBox::accessibilityIsIgnored() const return false; } -AccessibilityObject* AccessibilityListBox::elementAccessibilityHitTest(const LayoutPoint& point) const +AccessibilityObject* AccessibilityListBox::elementAccessibilityHitTest(const IntPoint& point) const { // the internal HTMLSelectElement methods for returning a listbox option at a point // ignore optgroup elements. diff --git a/Source/WebCore/accessibility/AccessibilityListBox.h b/Source/WebCore/accessibility/AccessibilityListBox.h index 62cda6c97..cfccb5248 100644 --- a/Source/WebCore/accessibility/AccessibilityListBox.h +++ b/Source/WebCore/accessibility/AccessibilityListBox.h @@ -56,7 +56,7 @@ public: private: AccessibilityObject* listBoxOptionAccessibilityObject(HTMLElement*) const; virtual bool accessibilityIsIgnored() const; - virtual AccessibilityObject* elementAccessibilityHitTest(const LayoutPoint&) const; + virtual AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const; }; } // namespace WebCore diff --git a/Source/WebCore/accessibility/AccessibilityMediaControls.cpp b/Source/WebCore/accessibility/AccessibilityMediaControls.cpp index ce20f2547..563669132 100644 --- a/Source/WebCore/accessibility/AccessibilityMediaControls.cpp +++ b/Source/WebCore/accessibility/AccessibilityMediaControls.cpp @@ -82,7 +82,8 @@ MediaControlElementType AccessibilityMediaControl::controlType() const String AccessibilityMediaControl::controlTypeName() const { - DEFINE_STATIC_LOCAL(const String, mediaFullscreenButtonName, ("FullscreenButton")); + DEFINE_STATIC_LOCAL(const String, mediaEnterFullscreenButtonName, ("EnterFullscreenButton")); + DEFINE_STATIC_LOCAL(const String, mediaExitFullscreenButtonName, ("ExitFullscreenButton")); DEFINE_STATIC_LOCAL(const String, mediaMuteButtonName, ("MuteButton")); DEFINE_STATIC_LOCAL(const String, mediaPlayButtonName, ("PlayButton")); DEFINE_STATIC_LOCAL(const String, mediaSeekBackButtonName, ("SeekBackButton")); @@ -98,8 +99,10 @@ String AccessibilityMediaControl::controlTypeName() const DEFINE_STATIC_LOCAL(const String, mediaHideClosedCaptionsButtonName, ("HideClosedCaptionsButton")); switch (controlType()) { - case MediaFullscreenButton: - return mediaFullscreenButtonName; + case MediaEnterFullscreenButton: + return mediaEnterFullscreenButtonName; + case MediaExitFullscreenButton: + return mediaExitFullscreenButtonName; case MediaMuteButton: return mediaMuteButtonName; case MediaPlayButton: @@ -165,7 +168,8 @@ bool AccessibilityMediaControl::accessibilityIsIgnored() const AccessibilityRole AccessibilityMediaControl::roleValue() const { switch (controlType()) { - case MediaFullscreenButton: + case MediaEnterFullscreenButton: + case MediaExitFullscreenButton: case MediaMuteButton: case MediaPlayButton: case MediaSeekBackButton: diff --git a/Source/WebCore/accessibility/AccessibilityMenuListOption.cpp b/Source/WebCore/accessibility/AccessibilityMenuListOption.cpp index f0bde317b..e6d237a62 100644 --- a/Source/WebCore/accessibility/AccessibilityMenuListOption.cpp +++ b/Source/WebCore/accessibility/AccessibilityMenuListOption.cpp @@ -96,6 +96,11 @@ bool AccessibilityMenuListOption::canSetSelectedAttribute() const return isEnabled(); } +bool AccessibilityMenuListOption::accessibilityIsIgnored() const +{ + return accessibilityPlatformIncludesObject() != IgnoreObject; +} + LayoutRect AccessibilityMenuListOption::elementRect() const { AccessibilityObject* parent = parentObject(); diff --git a/Source/WebCore/accessibility/AccessibilityMenuListOption.h b/Source/WebCore/accessibility/AccessibilityMenuListOption.h index d2c461335..191bf42c0 100644 --- a/Source/WebCore/accessibility/AccessibilityMenuListOption.h +++ b/Source/WebCore/accessibility/AccessibilityMenuListOption.h @@ -37,6 +37,8 @@ class AccessibilityMenuListOption : public AccessibilityMockObject { public: static PassRefPtr<AccessibilityMenuListOption> create() { return adoptRef(new AccessibilityMenuListOption); } + virtual bool accessibilityIsIgnored() const; + void setElement(HTMLElement*); private: @@ -46,7 +48,6 @@ private: virtual AccessibilityRole roleValue() const { return MenuListOptionRole; } virtual bool canHaveChildren() const { return false; } - virtual LayoutSize size() const { return elementRect().size(); } virtual Element* actionElement() const; virtual bool isEnabled() const; diff --git a/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp b/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp index d379dfa46..fe5716309 100644 --- a/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp +++ b/Source/WebCore/accessibility/AccessibilityMenuListPopup.cpp @@ -62,6 +62,11 @@ bool AccessibilityMenuListPopup::isEnabled() const return m_parent->isEnabled(); } +bool AccessibilityMenuListPopup::accessibilityIsIgnored() const +{ + return accessibilityPlatformIncludesObject() != IgnoreObject; +} + AccessibilityMenuListOption* AccessibilityMenuListPopup::menuListOptionAccessibilityObject(HTMLElement* element) const { if (!element || !element->hasTagName(optionTag)) diff --git a/Source/WebCore/accessibility/AccessibilityMenuListPopup.h b/Source/WebCore/accessibility/AccessibilityMenuListPopup.h index 2a03211cc..09435d02b 100644 --- a/Source/WebCore/accessibility/AccessibilityMenuListPopup.h +++ b/Source/WebCore/accessibility/AccessibilityMenuListPopup.h @@ -41,16 +41,17 @@ public: virtual bool isEnabled() const; virtual bool isOffScreen() const; + virtual bool accessibilityIsIgnored() const; void didUpdateActiveOption(int optionIndex); + private: AccessibilityMenuListPopup(); virtual bool isMenuListPopup() const { return true; } virtual LayoutRect elementRect() const { return LayoutRect(); } - virtual LayoutSize size() const { return LayoutSize(); } virtual AccessibilityRole roleValue() const { return MenuListPopupRole; } virtual bool isVisible() const; diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp index c0af86102..9441d538b 100644 --- a/Source/WebCore/accessibility/AccessibilityObject.cpp +++ b/Source/WebCore/accessibility/AccessibilityObject.cpp @@ -489,25 +489,25 @@ bool AccessibilityObject::isARIAControl(AccessibilityRole ariaRole) || ariaRole == ComboBoxRole || ariaRole == SliderRole; } -LayoutPoint AccessibilityObject::clickPoint() +IntPoint AccessibilityObject::clickPoint() { LayoutRect rect = elementRect(); - return LayoutPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); + return roundedIntPoint(LayoutPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2)); } -LayoutRect AccessibilityObject::boundingBoxForQuads(RenderObject* obj, const Vector<FloatQuad>& quads) +IntRect AccessibilityObject::boundingBoxForQuads(RenderObject* obj, const Vector<FloatQuad>& quads) { ASSERT(obj); if (!obj) - return LayoutRect(); + return IntRect(); size_t count = quads.size(); if (!count) - return LayoutRect(); + return IntRect(); - LayoutRect result; + IntRect result; for (size_t i = 0; i < count; ++i) { - LayoutRect r = quads[i].enclosingBoundingBox(); + IntRect r = quads[i].enclosingBoundingBox(); if (!r.isEmpty()) { if (obj->style()->hasAppearance()) obj->theme()->adjustRepaintRect(obj, r); @@ -1140,7 +1140,7 @@ void AccessibilityObject::updateChildrenIfNecessary() if (!hasChildren()) addChildren(); } - + void AccessibilityObject::clearChildren() { // Some objects have weak pointers to their parents and those associations need to be detached. @@ -1460,7 +1460,7 @@ bool AccessibilityObject::supportsARIALiveRegion() const return equalIgnoringCase(liveRegion, "polite") || equalIgnoringCase(liveRegion, "assertive"); } -AccessibilityObject* AccessibilityObject::elementAccessibilityHitTest(const LayoutPoint& point) const +AccessibilityObject* AccessibilityObject::elementAccessibilityHitTest(const IntPoint& point) const { // Send the hit test back into the sub-frame if necessary. if (isAttachment()) { @@ -1613,8 +1613,8 @@ static int computeBestScrollOffset(int currentScrollOffset, void AccessibilityObject::scrollToMakeVisible() const { - IntRect objectRect = boundingBoxRect(); - objectRect.move(-objectRect.x(), -objectRect.y()); + IntRect objectRect = pixelSnappedIntRect(boundingBoxRect()); + objectRect.setLocation(IntPoint()); scrollToMakeVisibleWithSubFocus(objectRect); } diff --git a/Source/WebCore/accessibility/AccessibilityObject.h b/Source/WebCore/accessibility/AccessibilityObject.h index e9a6aff57..2e30f06f9 100644 --- a/Source/WebCore/accessibility/AccessibilityObject.h +++ b/Source/WebCore/accessibility/AccessibilityObject.h @@ -121,6 +121,7 @@ enum AccessibilityRole { DocumentRegionRole, DrawerRole, EditableTextRole, + FooterRole, FormRole, GridRole, GroupRole, @@ -330,6 +331,7 @@ public: virtual bool isImageButton() const { return false; } virtual bool isPasswordField() const { return false; } virtual bool isNativeTextControl() const { return false; } + virtual bool isSearchField() const { return false; } virtual bool isWebArea() const { return false; } virtual bool isCheckbox() const { return roleValue() == CheckBoxRole; } virtual bool isRadioButton() const { return roleValue() == RadioButtonRole; } @@ -460,9 +462,9 @@ public: virtual void determineARIADropEffects(Vector<String>&) { } // Called on the root AX object to return the deepest available element. - virtual AccessibilityObject* accessibilityHitTest(const LayoutPoint&) const { return 0; } + virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const { return 0; } // Called on the AX object after the render tree determines which is the right AccessibilityRenderObject. - virtual AccessibilityObject* elementAccessibilityHitTest(const LayoutPoint&) const; + virtual AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const; virtual AccessibilityObject* focusedUIElement() const; @@ -502,10 +504,13 @@ public: virtual Element* anchorElement() const { return 0; } virtual Element* actionElement() const { return 0; } virtual LayoutRect boundingBoxRect() const { return LayoutRect(); } + IntRect pixelSnappedBoundingBoxRect() const { return pixelSnappedIntRect(boundingBoxRect()); } virtual LayoutRect elementRect() const = 0; - virtual LayoutSize size() const { return elementRect().size(); } - virtual LayoutPoint clickPoint(); - static LayoutRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&); + IntRect pixelSnappedElementRect() const { return pixelSnappedIntRect(elementRect()); } + LayoutSize size() const { return elementRect().size(); } + IntSize pixelSnappedSize() const { return elementRect().pixelSnappedSize(); } + virtual IntPoint clickPoint(); + static IntRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&); virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); } unsigned selectionStart() const { return selectedTextRange().start; } @@ -557,7 +562,11 @@ public: virtual void updateChildrenIfNecessary(); virtual void setNeedsToUpdateChildren() { } virtual void clearChildren(); +#if PLATFORM(MAC) + virtual void detachFromParent(); +#else virtual void detachFromParent() { } +#endif virtual void selectedChildren(AccessibilityChildrenVector&) { } virtual void visibleChildren(AccessibilityChildrenVector&) { } @@ -667,7 +676,13 @@ public: } #endif #endif - + +#if PLATFORM(MAC) + void overrideAttachmentParent(AccessibilityObject* parent); +#else + void overrideAttachmentParent(AccessibilityObject*) { } +#endif + #if HAVE(ACCESSIBILITY) // a platform-specific method for determining if an attachment is ignored bool accessibilityIgnoreAttachment() const; diff --git a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp index 8799346c9..92b5a175e 100644 --- a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -33,6 +33,7 @@ #include "AccessibilityImageMapLink.h" #include "AccessibilityListBox.h" #include "AccessibilitySpinButton.h" +#include "AccessibilityTable.h" #include "EventNames.h" #include "FloatRect.h" #include "Frame.h" @@ -490,6 +491,35 @@ bool AccessibilityRenderObject::isNativeTextControl() const return m_renderer->isTextControl(); } +bool AccessibilityRenderObject::isSearchField() const +{ + if (!node()) + return false; + + HTMLInputElement* inputElement = node()->toInputElement(); + if (!inputElement) + return false; + + if (inputElement->isSearchField()) + return true; + + // Some websites don't label their search fields as such. However, they will + // use the word "search" in either the form or input type. This won't catch every case, + // but it will catch google.com for example. + + // Check the node name of the input type, sometimes it's "search". + const AtomicString& nameAttribute = getAttribute(nameAttr); + if (nameAttribute.contains("search", false)) + return true; + + // Check the form action and the name, which will sometimes be "search". + HTMLFormElement* form = inputElement->form(); + if (form && (form->name().contains("search", false) || form->action().contains("search", false))) + return true; + + return false; +} + bool AccessibilityRenderObject::isNativeImage() const { return m_renderer->isBoxModelObject() && toRenderBoxModelObject(m_renderer)->isImage(); @@ -1074,7 +1104,7 @@ String AccessibilityRenderObject::textUnderElement() const if (!m_renderer) return String(); - if (isFileUploadButton()) + if (m_renderer->isFileUploadControl()) return toRenderFileUploadControl(m_renderer)->buttonValue(); Node* node = m_renderer->node(); @@ -1197,7 +1227,7 @@ String AccessibilityRenderObject::stringValue() const if (isTextControl()) return text(); - if (isFileUploadButton()) + if (m_renderer->isFileUploadControl()) return toRenderFileUploadControl(m_renderer)->fileTextValue(); // FIXME: We might need to implement a value here for more types @@ -1493,12 +1523,6 @@ LayoutRect AccessibilityRenderObject::elementRect() const return boundingBoxRect(); } -LayoutSize AccessibilityRenderObject::size() const -{ - LayoutRect rect = elementRect(); - return rect.size(); -} - IntPoint AccessibilityRenderObject::clickPoint() { // Headings are usually much wider than their textual content. If the mid point is used, often it can be wrong. @@ -2650,7 +2674,7 @@ void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePos } } -VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const LayoutPoint& point) const +VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const { if (!m_renderer) return VisiblePosition(); @@ -2675,14 +2699,14 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const LayoutP while (1) { LayoutPoint ourpoint; #if PLATFORM(MAC) - ourpoint = frameView->screenToContents(roundedIntPoint(point)); + ourpoint = frameView->screenToContents(point); #else ourpoint = point; #endif HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); HitTestResult result(ourpoint); - renderView->layer()->hitTest(request, result); + renderView->hitTest(request, result); innerNode = result.innerNode(); if (!innerNode) return VisiblePosition(); @@ -2730,7 +2754,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned inde // NOTE: Consider providing this utility method as AX API int AccessibilityRenderObject::index(const VisiblePosition& position) const { - if (!isTextControl()) + if (position.isNull() || !isTextControl()) return -1; if (renderObjectContainsPosition(m_renderer, position.deepEquivalent())) @@ -2818,7 +2842,7 @@ IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& rang return IntRect(); } -AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const LayoutPoint& point) const +AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const { if (!area) return 0; @@ -2854,7 +2878,7 @@ AccessibilityObject* AccessibilityRenderObject::accessibilityHitTest(const IntPo Node* node = hitTestResult.innerNode()->shadowAncestorNode(); if (node->hasTagName(areaTag)) - return accessibilityImageMapHitTest(static_cast<HTMLAreaElement*>(node), roundedIntPoint(point)); + return accessibilityImageMapHitTest(static_cast<HTMLAreaElement*>(node), point); if (node->hasTagName(optionTag)) node = static_cast<HTMLOptionElement*>(node)->ownerSelectElement(); @@ -3250,7 +3274,7 @@ AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole() if (node && node->hasTagName(headerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag)) return LandmarkBannerRole; if (node && node->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag)) - return LandmarkContentInfoRole; + return FooterRole; if (m_renderer->isBlockFlow()) return GroupRole; @@ -3528,7 +3552,23 @@ void AccessibilityRenderObject::addAttachmentChildren() if (!axWidget->accessibilityIsIgnored()) m_children.append(axWidget); } + +#if PLATFORM(MAC) +void AccessibilityRenderObject::updateAttachmentViewParents() +{ + // Only the unignored parent should set the attachment parent, because that's what is reflected in the AX + // hierarchy to the client. + if (accessibilityIsIgnored()) + return; + size_t length = m_children.size(); + for (size_t k = 0; k < length; k++) { + if (m_children[k]->isAttachment()) + m_children[k]->overrideAttachmentParent(this); + } +} +#endif + void AccessibilityRenderObject::addChildren() { // If the need to add more children in addition to existing children arises, @@ -3566,6 +3606,10 @@ void AccessibilityRenderObject::addChildren() addAttachmentChildren(); addImageMapChildren(); addTextFieldChildren(); + +#if PLATFORM(MAC) + updateAttachmentViewParents(); +#endif } const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const @@ -3621,7 +3665,10 @@ void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& re { // Get all the rows. AccessibilityChildrenVector allRows; - ariaTreeRows(allRows); + if (isTree()) + ariaTreeRows(allRows); + else if (isAccessibilityTable() && toAccessibilityTable(this)->supportsSelectedRows()) + allRows = toAccessibilityTable(this)->rows(); // Determine which rows are selected. bool isMulti = isMultiSelectable(); diff --git a/Source/WebCore/accessibility/AccessibilityRenderObject.h b/Source/WebCore/accessibility/AccessibilityRenderObject.h index 9056dc842..4d66e5596 100644 --- a/Source/WebCore/accessibility/AccessibilityRenderObject.h +++ b/Source/WebCore/accessibility/AccessibilityRenderObject.h @@ -73,6 +73,7 @@ public: virtual bool isNativeImage() const; virtual bool isPasswordField() const; virtual bool isNativeTextControl() const; + virtual bool isSearchField() const; virtual bool isWebArea() const; virtual bool isFileUploadButton() const; virtual bool isInputImage() const; @@ -154,7 +155,7 @@ public: void updateAccessibilityRole(); // Should be called on the root accessibility object to kick off a hit test. - virtual AccessibilityObject* accessibilityHitTest(const LayoutPoint&) const; + virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const; virtual Element* actionElement() const; Element* mouseButtonListener() const; @@ -165,7 +166,6 @@ public: virtual LayoutRect boundingBoxRect() const; virtual LayoutRect elementRect() const; - virtual LayoutSize size() const; virtual IntPoint clickPoint(); void setRenderer(RenderObject* renderer) { m_renderer = renderer; } @@ -239,7 +239,7 @@ public: virtual bool isARIAGrabbed(); virtual void determineARIADropEffects(Vector<String>&); - virtual VisiblePosition visiblePositionForPoint(const LayoutPoint&) const; + virtual VisiblePosition visiblePositionForPoint(const IntPoint&) const; virtual VisiblePosition visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const; virtual int index(const VisiblePosition&) const; @@ -306,7 +306,10 @@ private: void addTextFieldChildren(); void addImageMapChildren(); void addAttachmentChildren(); - +#if PLATFORM(MAC) + void updateAttachmentViewParents(); +#endif + void ariaSelectedRows(AccessibilityChildrenVector&); bool elementAttributeValue(const QualifiedName&) const; diff --git a/Source/WebCore/accessibility/AccessibilityScrollView.cpp b/Source/WebCore/accessibility/AccessibilityScrollView.cpp index 537b09445..dc3abb8dc 100644 --- a/Source/WebCore/accessibility/AccessibilityScrollView.cpp +++ b/Source/WebCore/accessibility/AccessibilityScrollView.cpp @@ -163,7 +163,7 @@ AccessibilityObject* AccessibilityScrollView::webAreaObject() const return axObjectCache()->getOrCreate(doc->renderer()); } -AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const LayoutPoint& point) const +AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const { AccessibilityObject* webArea = webAreaObject(); if (!webArea) diff --git a/Source/WebCore/accessibility/AccessibilityScrollView.h b/Source/WebCore/accessibility/AccessibilityScrollView.h index c65b2626c..912f53d2c 100644 --- a/Source/WebCore/accessibility/AccessibilityScrollView.h +++ b/Source/WebCore/accessibility/AccessibilityScrollView.h @@ -57,7 +57,7 @@ private: virtual AccessibilityObject* scrollBar(AccessibilityOrientation); virtual void addChildren(); virtual void clearChildren(); - virtual AccessibilityObject* accessibilityHitTest(const LayoutPoint&) const; + virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const; virtual void updateChildrenIfNecessary(); virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; } void updateScrollbars(); diff --git a/Source/WebCore/accessibility/AccessibilitySlider.cpp b/Source/WebCore/accessibility/AccessibilitySlider.cpp index 9751e7826..56cef7ff9 100644 --- a/Source/WebCore/accessibility/AccessibilitySlider.cpp +++ b/Source/WebCore/accessibility/AccessibilitySlider.cpp @@ -102,7 +102,7 @@ const AtomicString& AccessibilitySlider::getAttribute(const QualifiedName& attri return element()->getAttribute(attribute); } -AccessibilityObject* AccessibilitySlider::elementAccessibilityHitTest(const LayoutPoint& point) const +AccessibilityObject* AccessibilitySlider::elementAccessibilityHitTest(const IntPoint& point) const { if (m_children.size()) { ASSERT(m_children.size() == 1); @@ -178,11 +178,6 @@ LayoutRect AccessibilitySliderThumb::elementRect() const return sliderThumbElementOf(sliderRenderer->node())->getRect(); } -LayoutSize AccessibilitySliderThumb::size() const -{ - return elementRect().size(); -} - bool AccessibilitySliderThumb::accessibilityIsIgnored() const { AccessibilityObjectInclusion decision = accessibilityPlatformIncludesObject(); diff --git a/Source/WebCore/accessibility/AccessibilitySlider.h b/Source/WebCore/accessibility/AccessibilitySlider.h index 2b831032d..81fe918d7 100644 --- a/Source/WebCore/accessibility/AccessibilitySlider.h +++ b/Source/WebCore/accessibility/AccessibilitySlider.h @@ -48,7 +48,7 @@ protected: private: HTMLInputElement* element() const; virtual bool accessibilityIsIgnored() const; - virtual AccessibilityObject* elementAccessibilityHitTest(const LayoutPoint&) const; + virtual AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const; virtual AccessibilityRole roleValue() const { return SliderRole; } virtual bool isSlider() const { return true; } @@ -75,7 +75,6 @@ public: virtual AccessibilityRole roleValue() const { return SliderThumbRole; } - virtual LayoutSize size() const; virtual LayoutRect elementRect() const; virtual bool accessibilityIsIgnored() const; diff --git a/Source/WebCore/accessibility/AccessibilitySpinButton.cpp b/Source/WebCore/accessibility/AccessibilitySpinButton.cpp index ff843e994..46a182805 100644 --- a/Source/WebCore/accessibility/AccessibilitySpinButton.cpp +++ b/Source/WebCore/accessibility/AccessibilitySpinButton.cpp @@ -105,6 +105,7 @@ void AccessibilitySpinButton::step(int amount) // AccessibilitySpinButtonPart AccessibilitySpinButtonPart::AccessibilitySpinButtonPart() + : m_isIncrementor(false) { } diff --git a/Source/WebCore/accessibility/AccessibilityTable.cpp b/Source/WebCore/accessibility/AccessibilityTable.cpp index 56ef47bcd..87382ebee 100644 --- a/Source/WebCore/accessibility/AccessibilityTable.cpp +++ b/Source/WebCore/accessibility/AccessibilityTable.cpp @@ -501,7 +501,7 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, cell = tableSection->primaryCellAt(testRow, column); // cell overlapped. use this one ASSERT(cell->rowSpan() >= 1); - if (cell && ((cell->row() + (cell->rowSpan() - 1)) >= sectionSpecificRow)) + if (cell && ((cell->rowIndex() + (cell->rowSpan() - 1)) >= sectionSpecificRow)) break; cell = 0; } diff --git a/Source/WebCore/accessibility/AccessibilityTableCell.cpp b/Source/WebCore/accessibility/AccessibilityTableCell.cpp index b5f7445a2..7ec87b2d8 100644 --- a/Source/WebCore/accessibility/AccessibilityTableCell.cpp +++ b/Source/WebCore/accessibility/AccessibilityTableCell.cpp @@ -104,7 +104,7 @@ void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange) return; RenderTableCell* renderCell = toRenderTableCell(m_renderer); - rowRange.first = renderCell->row(); + rowRange.first = renderCell->rowIndex(); rowRange.second = renderCell->rowSpan(); // since our table might have multiple sections, we have to offset our row appropriately @@ -160,7 +160,7 @@ AccessibilityObject* AccessibilityTableCell::titleUIElement() const if (!col) return 0; - int row = renderCell->row(); + int row = renderCell->rowIndex(); RenderTableSection* section = renderCell->section(); if (!section) diff --git a/Source/WebCore/accessibility/AccessibilityTableColumn.cpp b/Source/WebCore/accessibility/AccessibilityTableColumn.cpp index c94521b1e..d8af046d0 100644 --- a/Source/WebCore/accessibility/AccessibilityTableColumn.cpp +++ b/Source/WebCore/accessibility/AccessibilityTableColumn.cpp @@ -68,11 +68,6 @@ LayoutRect AccessibilityTableColumn::elementRect() const return m_columnRect; } -LayoutSize AccessibilityTableColumn::size() const -{ - return elementRect().size(); -} - AccessibilityObject* AccessibilityTableColumn::headerObject() { if (!m_parent) diff --git a/Source/WebCore/accessibility/AccessibilityTableColumn.h b/Source/WebCore/accessibility/AccessibilityTableColumn.h index 014f32d84..632097ec4 100644 --- a/Source/WebCore/accessibility/AccessibilityTableColumn.h +++ b/Source/WebCore/accessibility/AccessibilityTableColumn.h @@ -57,7 +57,6 @@ public: virtual void addChildren(); virtual void setParent(AccessibilityObject*); - virtual LayoutSize size() const; virtual LayoutRect elementRect() const; private: diff --git a/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp b/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp index ff959cd5b..a85e53a1b 100644 --- a/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp +++ b/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp @@ -55,11 +55,6 @@ LayoutRect AccessibilityTableHeaderContainer::elementRect() const return m_headerRect; } -LayoutSize AccessibilityTableHeaderContainer::size() const -{ - return elementRect().size(); -} - bool AccessibilityTableHeaderContainer::accessibilityIsIgnored() const { if (!m_parent) diff --git a/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.h b/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.h index 3cffd28fb..625e1dd35 100644 --- a/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.h +++ b/Source/WebCore/accessibility/AccessibilityTableHeaderContainer.h @@ -47,7 +47,6 @@ public: virtual void addChildren(); - virtual LayoutSize size() const; virtual LayoutRect elementRect() const; private: diff --git a/Source/WebCore/accessibility/AccessibilityTableRow.cpp b/Source/WebCore/accessibility/AccessibilityTableRow.cpp index 09db13248..cfbdfb5c5 100644 --- a/Source/WebCore/accessibility/AccessibilityTableRow.cpp +++ b/Source/WebCore/accessibility/AccessibilityTableRow.cpp @@ -74,6 +74,12 @@ bool AccessibilityTableRow::isTableRow() const return true; } +AccessibilityObject* AccessibilityTableRow::observableObject() const +{ + // This allows the table to be the one who sends notifications about tables. + return parentTable(); +} + bool AccessibilityTableRow::accessibilityIsIgnored() const { AccessibilityObjectInclusion decision = accessibilityIsIgnoredBase(); diff --git a/Source/WebCore/accessibility/AccessibilityTableRow.h b/Source/WebCore/accessibility/AccessibilityTableRow.h index 29ac935c9..80bfbf67b 100644 --- a/Source/WebCore/accessibility/AccessibilityTableRow.h +++ b/Source/WebCore/accessibility/AccessibilityTableRow.h @@ -58,6 +58,8 @@ public: private: int m_rowIndex; + + virtual AccessibilityObject* observableObject() const; }; } // namespace WebCore diff --git a/Source/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp b/Source/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp index 5b4cfd5a5..b65e9cf5e 100644 --- a/Source/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp +++ b/Source/WebCore/accessibility/chromium/AccessibilityObjectChromium.cpp @@ -37,7 +37,7 @@ bool AccessibilityObject::accessibilityIgnoreAttachment() const AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const { if (isMenuListPopup() || isMenuListOption()) - return IgnoreObject; + return IncludeObject; return DefaultBehavior; } diff --git a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp index c24224b95..9b46b38b6 100644 --- a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp +++ b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp @@ -23,7 +23,7 @@ #include "AccessibilityObject.h" #include "Document.h" #include "Element.h" -#include "GOwnPtr.h" +#include <wtf/gobject/GOwnPtr.h> #include "HTMLSelectElement.h" #include "Range.h" #include "TextIterator.h" diff --git a/Source/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/Source/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp index e2ba6b455..101834986 100644 --- a/Source/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp +++ b/Source/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp @@ -20,9 +20,9 @@ #include "config.h" #include "AccessibilityObject.h" + #include "RenderObject.h" #include "RenderText.h" - #include <glib-object.h> #if HAVE(ACCESSIBILITY) diff --git a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceComponent.cpp b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceComponent.cpp index a494feea0..3969f149d 100644 --- a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceComponent.cpp +++ b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceComponent.cpp @@ -77,7 +77,7 @@ static AtkObject* webkitAccessibleComponentRefAccessibleAtPoint(AtkComponent* co static void webkitAccessibleComponentGetExtents(AtkComponent* component, gint* x, gint* y, gint* width, gint* height, AtkCoordType coordType) { - IntRect rect = core(component)->elementRect(); + IntRect rect = pixelSnappedIntRect(core(component)->elementRect()); contentsRelativeToAtkCoordinateType(core(component), coordType, rect, x, y, width, height); } diff --git a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceImage.cpp b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceImage.cpp index 4deb137fe..f9e42b84a 100644 --- a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceImage.cpp +++ b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceImage.cpp @@ -48,7 +48,7 @@ static AccessibilityObject* core(AtkImage* image) static void webkitAccessibleImageGetImagePosition(AtkImage* image, gint* x, gint* y, AtkCoordType coordType) { - IntRect rect = core(image)->elementRect(); + IntRect rect = pixelSnappedIntRect(core(image)->elementRect()); contentsRelativeToAtkCoordinateType(core(image), coordType, rect, x, y); } @@ -59,7 +59,7 @@ static const gchar* webkitAccessibleImageGetImageDescription(AtkImage* image) static void webkitAccessibleImageGetImageSize(AtkImage* image, gint* width, gint* height) { - IntSize size = core(image)->size(); + IntSize size = core(image)->pixelSnappedSize(); if (width) *width = size.width(); diff --git a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceText.cpp b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceText.cpp index f7bbc30ef..2b20f9fac 100644 --- a/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceText.cpp +++ b/Source/WebCore/accessibility/gtk/WebKitAccessibleInterfaceText.cpp @@ -34,7 +34,7 @@ #include "AccessibilityObject.h" #include "Document.h" #include "FrameView.h" -#include "GOwnPtr.h" +#include <wtf/gobject/GOwnPtr.h> #include "HostWindow.h" #include "InlineTextBox.h" #include "NotImplemented.h" @@ -240,7 +240,7 @@ static AtkAttributeSet* getAttributeSetForAccessibilityObject(const Accessibilit } if (!style->textIndent().isUndefined()) { - int indentation = style->textIndent().calcValue(object->size().width()); + int indentation = valueForLength(style->textIndent(), object->size().width(), renderer->view()); buffer.set(g_strdup_printf("%i", indentation)); result = addToAtkAttributeSet(result, atk_text_attribute_get_name(ATK_TEXT_ATTR_INDENT), buffer.get()); } diff --git a/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm b/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm index 50e2bbe17..acbc25f70 100644 --- a/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm +++ b/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm @@ -90,7 +90,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific macNotification = "AXInvalidStatusChanged"; break; case AXSelectedChildrenChanged: - macNotification = NSAccessibilitySelectedChildrenChangedNotification; + if (obj->isAccessibilityTable()) + macNotification = NSAccessibilitySelectedRowsChangedNotification; + else + macNotification = NSAccessibilitySelectedChildrenChangedNotification; break; case AXSelectedTextChanged: macNotification = NSAccessibilitySelectedTextChangedNotification; diff --git a/Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm b/Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm index 169a2ee3c..fd4987fa1 100644 --- a/Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm +++ b/Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm @@ -33,6 +33,27 @@ namespace WebCore { +void AccessibilityObject::detachFromParent() +{ + if (isAttachment()) + overrideAttachmentParent(0); +} + +void AccessibilityObject::overrideAttachmentParent(AccessibilityObject* parent) +{ + if (!isAttachment()) + return; + + id parentWrapper = nil; + if (parent) { + if (parent->accessibilityIsIgnored()) + parent = parent->parentObjectUnignored(); + parentWrapper = parent->wrapper(); + } + + [[wrapper() attachmentView] accessibilitySetOverrideValue:parentWrapper forAttribute:NSAccessibilityParentAttribute]; +} + bool AccessibilityObject::accessibilityIgnoreAttachment() const { // FrameView attachments are now handled by AccessibilityScrollView, diff --git a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm index edd72236c..7a9d4bb7c 100644 --- a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm +++ b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapper.mm @@ -332,6 +332,9 @@ using namespace std; #define NSAccessibilityVisitedLinkSearchKey @"AXVisitedLinkSearchKey" #endif +#define NSAccessibilityTextMarkerIsValidParameterizedAttribute @"AXTextMarkerIsValid" +#define NSAccessibilityIndexForTextMarkerParameterizedAttribute @"AXIndexForTextMarker" +#define NSAccessibilityTextMarkerForIndexParameterizedAttribute @"AXTextMarkerForIndex" @interface NSObject (WebKitAccessibilityArrayCategory) @@ -566,12 +569,20 @@ static id textMarkerRangeFromMarkers(id textMarker1, id textMarker2) return AXTextMarkerRange(textMarker1, textMarker2); } +// When modifying attributed strings, the range can come from a source which may provide faulty information (e.g. the spell checker). +// To protect against such cases the range should be validated before adding or removing attributes. +static BOOL AXAttributedStringRangeIsValid(NSAttributedString* attrString, NSRange range) +{ + return (range.location < [attrString length] && NSMaxRange(range) <= [attrString length]); +} + static void AXAttributeStringSetFont(NSMutableAttributedString* attrString, NSString* attribute, NSFont* font, NSRange range) { - NSDictionary* dict; + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; if (font) { - dict = [NSDictionary dictionaryWithObjectsAndKeys: + NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: [font fontName] , NSAccessibilityFontNameKey, [font familyName] , NSAccessibilityFontFamilyKey, [font displayName] , NSAccessibilityVisibleNameKey, @@ -609,6 +620,9 @@ static CGColorRef CreateCGColorIfDifferent(NSColor* nsColor, CGColorRef existing static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range) { + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; + if (color) { CGColorRef existingColor = (CGColorRef) [attrString attribute:attribute atIndex:range.location effectiveRange:nil]; CGColorRef cgColor = CreateCGColorIfDifferent(color, existingColor); @@ -622,6 +636,9 @@ static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSS static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range) { + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; + if (number) [attrString addAttribute:attribute value:number range:range]; else @@ -692,6 +709,9 @@ static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, Ren static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range) { + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; + AccessibilityObject* obj = renderer->document()->axObjectCache()->getOrCreate(renderer); int quoteLevel = obj->blockquoteLevel(); @@ -743,6 +763,9 @@ static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrStri if (!renderer) return; + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; + // Sometimes there are objects between the text and the heading. // In those cases the parent hierarchy should be queried to see if there is a heading level. int parentHeadingLevel = 0; @@ -761,6 +784,9 @@ static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrStri static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, AccessibilityObject* object, NSRange range) { + if (!AXAttributedStringRangeIsValid(attrString, range)) + return; + if (object && object->isAccessibilityRenderObject()) { // make a serializable AX object @@ -1406,7 +1432,7 @@ static NSMutableArray* convertToNSArray(const AccessibilityObject::Accessibility - (NSValue *)position { - LayoutRect rect = m_object->elementRect(); + IntRect rect = pixelSnappedIntRect(m_object->elementRect()); NSPoint point; FrameView* frameView = m_object->documentFrameView(); @@ -1549,7 +1575,8 @@ static const AccessibilityRoleMap& createAccessibilityRoleMap() { LabelRole, NSAccessibilityGroupRole }, { DivRole, NSAccessibilityGroupRole }, { FormRole, NSAccessibilityGroupRole }, - { SpinButtonRole, NSAccessibilityIncrementorRole } + { SpinButtonRole, NSAccessibilityIncrementorRole }, + { FooterRole, NSAccessibilityGroupRole } }; AccessibilityRoleMap& roleMap = *new AccessibilityRoleMap; @@ -1580,6 +1607,8 @@ static NSString* roleValueToNSString(AccessibilityRole value) { if (m_object->isPasswordField()) return NSAccessibilitySecureTextFieldSubrole; + if (m_object->isSearchField()) + return NSAccessibilitySearchFieldSubrole; if (m_object->isAttachment()) { NSView* attachView = [self attachmentView]; @@ -1614,6 +1643,8 @@ static NSString* roleValueToNSString(AccessibilityRole value) return @"AXLandmarkBanner"; case LandmarkComplementaryRole: return @"AXLandmarkComplementary"; + // Footer roles should appear as content info types. + case FooterRole: case LandmarkContentInfoRole: return @"AXLandmarkContentInfo"; case LandmarkMainRole: @@ -1726,6 +1757,8 @@ static NSString* roleValueToNSString(AccessibilityRole value) return AXDefinitionListTermText(); case DefinitionListDefinitionRole: return AXDefinitionListDefinitionText(); + case FooterRole: + return AXFooterRoleDescriptionText(); } } @@ -2015,7 +2048,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) return [NSNumber numberWithBool: m_object->isEnabled()]; if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) { - LayoutSize s = m_object->size(); + IntSize s = m_object->pixelSnappedSize(); return [NSValue valueWithSize: NSMakeSize(s.width(), s.height())]; } @@ -2486,6 +2519,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) static NSArray* paramAttrs = nil; static NSArray* textParamAttrs = nil; static NSArray* tableParamAttrs = nil; + static NSArray* webAreaParamAttrs = nil; if (paramAttrs == nil) { paramAttrs = [[NSArray alloc] initWithObjects: @"AXUIElementForTextMarker", @@ -2541,6 +2575,14 @@ static NSString* roleValueToNSString(AccessibilityRole value) tableParamAttrs = [[NSArray alloc] initWithArray:tempArray]; [tempArray release]; } + if (!webAreaParamAttrs) { + NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs]; + [tempArray addObject:NSAccessibilityTextMarkerForIndexParameterizedAttribute]; + [tempArray addObject:NSAccessibilityTextMarkerIsValidParameterizedAttribute]; + [tempArray addObject:NSAccessibilityIndexForTextMarkerParameterizedAttribute]; + webAreaParamAttrs = [[NSArray alloc] initWithArray:tempArray]; + [tempArray release]; + } if (m_object->isPasswordField()) return [NSArray array]; @@ -2557,6 +2599,9 @@ static NSString* roleValueToNSString(AccessibilityRole value) if (m_object->isMenuRelated()) return nil; + if (m_object->isWebArea()) + return webAreaParamAttrs; + return paramAttrs; } @@ -2748,6 +2793,48 @@ static RenderObject* rendererForView(NSView* view) return [self doAXAttributedStringForTextMarkerRange:[self textMarkerRangeFromVisiblePositions:visiblePosRange.start endPosition:visiblePosRange.end]]; } +- (NSRange)_convertToNSRange:(Range*)range +{ + NSRange result = NSMakeRange(NSNotFound, 0); + if (!range || !range->startContainer()) + return result; + + Document* document = m_object->document(); + if (!document) + return result; + + size_t location; + size_t length; + TextIterator::getLocationAndLengthFromRange(document->documentElement(), range, location, length); + result.location = location; + result.length = length; + + return result; +} + +- (NSInteger)_indexForTextMarker:(id)marker +{ + if (!marker) + return NSNotFound; + + VisibleSelection selection([self visiblePositionForTextMarker:marker]); + return [self _convertToNSRange:selection.toNormalizedRange().get()].location; +} + +- (id)_textMarkerForIndex:(NSInteger)textIndex +{ + Document* document = m_object->document(); + if (!document) + return nil; + + PassRefPtr<Range> textRange = TextIterator::rangeFromLocationAndLength(document->documentElement(), textIndex, 0); + if (!textRange || !textRange->boundaryPointsValid()) + return nil; + + VisiblePosition position(textRange->startPosition()); + return [self textMarkerForVisiblePosition:position]; +} + // The RTF representation of the text associated with this accessibility object that is // specified by the given range. - (NSData*)doAXRTFForRange:(NSRange)range @@ -2839,6 +2926,17 @@ static RenderObject* rendererForView(NSView* view) return convertToNSArray(results); } + if ([attribute isEqualToString:NSAccessibilityTextMarkerIsValidParameterizedAttribute]) { + VisiblePosition pos = [self visiblePositionForTextMarker:textMarker]; + return [NSNumber numberWithBool:!pos.isNull()]; + } + if ([attribute isEqualToString:NSAccessibilityIndexForTextMarkerParameterizedAttribute]) { + return [NSNumber numberWithInteger:[self _indexForTextMarker:textMarker]]; + } + if ([attribute isEqualToString:NSAccessibilityTextMarkerForIndexParameterizedAttribute]) { + return [self _textMarkerForIndex:[number integerValue]]; + } + if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; AccessibilityObject* axObject = m_object->accessibilityObjectForPosition(visiblePos); |