diff options
Diffstat (limited to 'WebCore/accessibility')
-rw-r--r-- | WebCore/accessibility/AXObjectCache.cpp | 19 | ||||
-rw-r--r-- | WebCore/accessibility/AXObjectCache.h | 22 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityRenderObject.h | 17 | ||||
-rw-r--r-- | WebCore/accessibility/chromium/AXObjectCacheChromium.cpp | 52 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AXObjectCacheAtk.cpp | 37 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp | 6 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp | 75 | ||||
-rw-r--r-- | WebCore/accessibility/mac/AXObjectCacheMac.mm | 8 | ||||
-rw-r--r-- | WebCore/accessibility/mac/AccessibilityObjectWrapper.mm | 259 | ||||
-rw-r--r-- | WebCore/accessibility/win/AXObjectCacheWin.cpp | 4 |
10 files changed, 313 insertions, 186 deletions
diff --git a/WebCore/accessibility/AXObjectCache.cpp b/WebCore/accessibility/AXObjectCache.cpp index 907bb15..30cce3a 100644 --- a/WebCore/accessibility/AXObjectCache.cpp +++ b/WebCore/accessibility/AXObjectCache.cpp @@ -465,6 +465,16 @@ void AXObjectCache::selectedChildrenChanged(RenderObject* renderer) // to find the container which should send out the notification. postNotification(renderer, AXSelectedChildrenChanged, false); } + +void AXObjectCache::nodeTextChangeNotification(RenderObject* renderer, AXTextChange textChange, unsigned offset, unsigned count) +{ + if (!renderer) + return; + + // Delegate on the right platform + AccessibilityObject* obj = getOrCreate(renderer); + nodeTextChangePlatformNotification(obj, textChange, offset, count); +} #endif #if HAVE(ACCESSIBILITY) @@ -495,9 +505,12 @@ void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer) static_cast<AccessibilityRenderObject*>(obj)->updateAccessibilityRole(); } #endif - + VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData) { + if (!isNodeInUse(textMarkerData.node)) + return VisiblePosition(); + VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity); Position deepPos = visiblePos.deepEquivalent(); if (deepPos.isNull()) @@ -549,7 +562,9 @@ void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerD textMarkerData.axID = obj.get()->axObjectID(); textMarkerData.node = domNode; textMarkerData.offset = deepPos.deprecatedEditingOffset(); - textMarkerData.affinity = visiblePos.affinity(); + textMarkerData.affinity = visiblePos.affinity(); + + cache->setNodeInUse(domNode); } } // namespace WebCore diff --git a/WebCore/accessibility/AXObjectCache.h b/WebCore/accessibility/AXObjectCache.h index 28a5917..2ee56ee 100644 --- a/WebCore/accessibility/AXObjectCache.h +++ b/WebCore/accessibility/AXObjectCache.h @@ -100,9 +100,14 @@ public: AXID platformGenerateAXID() const; AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); } + // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid. + void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); } + void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); } + bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); } + // Text marker utilities. - static void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&); - static VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&); + void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&); + VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&); enum AXNotification { AXActiveDescendantChanged, @@ -125,12 +130,23 @@ public: void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously); void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously); + enum AXTextChange { + AXTextInserted, + AXTextDeleted, + }; + + void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count); + + bool nodeHasRole(Node*, const AtomicString& role); + protected: void postPlatformNotification(AccessibilityObject*, AXNotification); + void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count); private: HashMap<AXID, RefPtr<AccessibilityObject> > m_objects; HashMap<RenderObject*, AXID> m_renderObjectMapping; + HashSet<Node*> m_textMarkerNodes; static bool gAccessibilityEnabled; static bool gAccessibilityEnhancedUserInterfaceEnabled; @@ -156,6 +172,8 @@ inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { } inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { } inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { } inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { } +inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { } +inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { } inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { } inline void AXObjectCache::handleScrolledToAnchor(const Node*) { } inline void AXObjectCache::contentChanged(RenderObject*) { } diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h index cefaa94..b7b85fe 100644 --- a/WebCore/accessibility/AccessibilityRenderObject.h +++ b/WebCore/accessibility/AccessibilityRenderObject.h @@ -311,7 +311,22 @@ private: mutable AccessibilityRole m_roleForMSAA; }; - + +inline AccessibilityRenderObject* toAccessibilityRenderObject(AccessibilityObject* object) +{ + ASSERT(!object || object->isAccessibilityRenderObject()); + return static_cast<AccessibilityRenderObject*>(object); +} + +inline const AccessibilityRenderObject* toAccessibilityRenderObject(const AccessibilityObject* object) +{ + ASSERT(!object || object->isAccessibilityRenderObject()); + return static_cast<const AccessibilityRenderObject*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toAccessibilityRenderObject(const AccessibilityRenderObject*); + } // namespace WebCore #endif // AccessibilityRenderObject_h diff --git a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp index 3ff0837..b02fe00 100644 --- a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp +++ b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp @@ -28,20 +28,11 @@ #include "AXObjectCache.h" #include "AccessibilityObject.h" #include "Chrome.h" -#include "ChromeClientChromium.h" +#include "ChromeClient.h" #include "FrameView.h" namespace WebCore { -static ChromeClientChromium* toChromeClientChromium(FrameView* view) -{ - Page* page = view->frame() ? view->frame()->page() : 0; - if (!page) - return 0; - - return static_cast<ChromeClientChromium*>(page->chrome()->client()); -} - void AXObjectCache::detachWrapper(AccessibilityObject* obj) { // In Chromium, AccessibilityObjects are wrapped lazily. @@ -56,22 +47,24 @@ void AXObjectCache::attachWrapper(AccessibilityObject*) void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotification notification) { - if (!obj || !obj->document() || !obj->documentFrameView()) + if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentFrameView()->frame() || !obj->documentFrameView()->frame()->page()) return; - ChromeClientChromium* client = toChromeClientChromium(obj->documentFrameView()); + ChromeClient* client = obj->documentFrameView()->frame()->page()->chrome()->client(); if (!client) return; - // TODO: Remove after the new postAccessibilityNotification is used downstream. switch (notification) { - case AXCheckedStateChanged: - client->didChangeAccessibilityObjectState(obj); + case AXActiveDescendantChanged: + if (!obj->document()->focusedNode() || (obj->node() != obj->document()->focusedNode())) + break; + + // Calling handleFocusedUIElementChanged will focus the new active + // descendant and send the AXFocusedUIElementChanged notification. + handleFocusedUIElementChanged(0, obj->document()->focusedNode()->renderer()); break; + case AXCheckedStateChanged: case AXChildrenChanged: - client->didChangeAccessibilityObjectChildren(obj); - break; - case AXActiveDescendantChanged: case AXFocusedUIElementChanged: case AXLayoutComplete: case AXLiveRegionChanged: @@ -90,12 +83,31 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific client->postAccessibilityNotification(obj, notification); } -void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { } -void AXObjectCache::handleScrolledToAnchor(const Node*) +void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject* newFocusedRenderer) +{ + if (!newFocusedRenderer) + return; + + Page* page = newFocusedRenderer->document()->page(); + if (!page) + return; + + AccessibilityObject* focusedObject = focusedUIElementForPage(page); + if (!focusedObject) + return; + + postPlatformNotification(focusedObject, AXFocusedUIElementChanged); +} + +void AXObjectCache::handleScrolledToAnchor(const Node* anchorNode) { + // The anchor node may not be accessible. Post the notification for the + // first accessible object. + postPlatformNotification(AccessibilityObject::firstAccessibleObjectFromNode(anchorNode), AXScrolledToAnchor); } } // namespace WebCore diff --git a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp index c30b006..a4ea87c 100644 --- a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp +++ b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp @@ -22,6 +22,10 @@ #include "AccessibilityObject.h" #include "AccessibilityObjectWrapperAtk.h" +#include "AccessibilityRenderObject.h" +#include "GOwnPtr.h" +#include "Range.h" +#include "TextIterator.h" namespace WebCore { @@ -50,6 +54,39 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX } } +static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count) +{ + // Get the axObject for the parent object + AtkObject* wrapper = object->parentObjectUnignored()->wrapper(); + if (!wrapper || !ATK_IS_TEXT(wrapper)) + return; + + // Select the right signal to be emitted + CString detail; + switch (textChange) { + case AXObjectCache::AXTextInserted: + detail = "text-changed::insert"; + break; + case AXObjectCache::AXTextDeleted: + detail = "text-changed::delete"; + break; + } + + if (!detail.isNull()) + g_signal_emit_by_name(wrapper, detail.data(), offset, count); +} + +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, unsigned count) +{ + // Sanity check + if (count < 1 || !object || !object->isAccessibilityRenderObject()) + return; + + Node* node = object->node(); + RefPtr<Range> range = Range::create(node->document(), Position(node->parentNode(), 0), Position(node, 0)); + emitTextChanged(toAccessibilityRenderObject(object), textChange, offset + TextIterator::rangeLength(range.get()), count); +} + void AXObjectCache::handleFocusedUIElementChanged(RenderObject* oldFocusedRender, RenderObject* newFocusedRender) { RefPtr<AccessibilityObject> oldObject = getOrCreate(oldFocusedRender); diff --git a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp index 7f9fd1a..9772b43 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp @@ -73,8 +73,12 @@ AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesO if (role == StaticTextRole) return IgnoreObject; + // Include all list items, regardless they have or not inline children + if (role == ListItemRole) + return IncludeObject; + // Bullets/numbers for list items shouldn't be exposed as AtkObjects. - if (roleValue() == ListMarkerRole) + if (role == ListMarkerRole) return IgnoreObject; return DefaultBehavior; diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp index 01dddd1..3575afe 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp @@ -55,6 +55,7 @@ #include "InlineTextBox.h" #include "IntRect.h" #include "NotImplemented.h" +#include "RenderListItem.h" #include "RenderListMarker.h" #include "RenderText.h" #include "TextEncoding.h" @@ -878,9 +879,13 @@ gchar* textForObject(AccessibilityRenderObject* accObject) g_string_append(str, "\n"); range = accObject->doAXRangeForLine(++lineNumber); } - } else if (accObject->renderer()) { + } else { + RenderObject* renderer = accObject->renderer(); + if (!renderer) + return g_string_free(str, FALSE); + // For RenderBlocks, piece together the text from the RenderText objects they contain. - for (RenderObject* obj = accObject->renderer()->firstChild(); obj; obj = obj->nextSibling()) { + for (RenderObject* obj = renderer->firstChild(); obj; obj = obj->nextSibling()) { if (obj->isBR()) { g_string_append(str, "\n"); continue; @@ -907,7 +912,17 @@ gchar* textForObject(AccessibilityRenderObject* accObject) box = box->nextTextBox(); } } + + // Insert the text of the marker for list item in the right place, if present + if (renderer->isListItem()) { + String markerText = toRenderListItem(renderer)->markerTextWithSuffix(); + if (renderer->style()->direction() == LTR) + g_string_prepend(str, markerText.utf8().data()); + else + g_string_append(str, markerText.utf8().data()); + } } + return g_string_free(str, FALSE); } @@ -939,10 +954,9 @@ static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, g // Prefix a item number/bullet if needed if (coreObject->roleValue() == ListItemRole) { RenderObject* objRenderer = static_cast<AccessibilityRenderObject*>(coreObject)->renderer(); - RenderObject* markerRenderer = objRenderer ? objRenderer->firstChild() : 0; - if (markerRenderer && markerRenderer->isListMarker()) { - String markerTxt = toRenderListMarker(markerRenderer)->text(); - ret = markerTxt.length() > 0 ? markerTxt + " " + ret : ret; + if (objRenderer && objRenderer->isListItem()) { + String markerText = toRenderListItem(objRenderer)->markerTextWithSuffix(); + ret = objRenderer->style()->direction() == LTR ? markerText + ret : ret + markerText; } } @@ -1185,8 +1199,29 @@ static AtkAttributeSet* attributeSetDifference(AtkAttributeSet* a1, AtkAttribute static guint accessibilityObjectLength(const AccessibilityObject* object) { - GOwnPtr<gchar> text(webkit_accessible_text_get_text(ATK_TEXT(object->wrapper()), 0, -1)); - return g_utf8_strlen(text.get(), -1); + // Non render objects are not taken into account + if (!object->isAccessibilityRenderObject()) + return 0; + + // For those objects implementing the AtkText interface we use the + // well known API to always get the text in a consistent way + AtkObject* atkObj = ATK_OBJECT(object->wrapper()); + if (ATK_IS_TEXT(atkObj)) { + GOwnPtr<gchar> text(webkit_accessible_text_get_text(ATK_TEXT(atkObj), 0, -1)); + return g_utf8_strlen(text.get(), -1); + } + + // Even if we don't expose list markers to Assistive + // Technologies, we need to have a way to measure their length + // for those cases when it's needed to take it into account + // separately (as in getAccessibilityObjectForOffset) + RenderObject* renderer = static_cast<const AccessibilityRenderObject*>(object)->renderer(); + if (renderer && renderer->isListMarker()) { + RenderListMarker* marker = toRenderListMarker(renderer); + return marker->text().length() + marker->suffix().length(); + } + + return 0; } static const AccessibilityObject* getAccessibilityObjectForOffset(const AccessibilityObject* object, guint offset, gint* startOffset, gint* endOffset) @@ -1321,12 +1356,7 @@ static void webkit_accessible_text_get_range_extents(AtkText* text, gint startOf static gint webkit_accessible_text_get_character_count(AtkText* text) { - AccessibilityObject* coreObject = core(text); - - if (coreObject->isTextControl()) - return coreObject->textLength(); - else - return coreObject->textUnderElement().length(); + return accessibilityObjectLength(core(text)); } static gint webkit_accessible_text_get_offset_at_point(AtkText* text, gint x, gint y, AtkCoordType coords) @@ -2026,8 +2056,21 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) interfaceMask |= 1 << WAI_TEXT; if (!coreObject->isReadOnly()) interfaceMask |= 1 << WAI_EDITABLE_TEXT; - } else if (role != TableRole && static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->childrenInline()) - interfaceMask |= 1 << WAI_TEXT; + } else { + AccessibilityRenderObject* axRenderObject = static_cast<AccessibilityRenderObject*>(coreObject); + RenderObject* renderer = axRenderObject->renderer(); + if (role != TableRole && renderer && renderer->childrenInline()) + interfaceMask |= 1 << WAI_TEXT; + else if (role == ListItemRole) { + // Add the TEXT interface for list items whose + // first accessible child has a text renderer + AccessibilityObject::AccessibilityChildrenVector children = axRenderObject->children(); + if (children.size()) { + AccessibilityObject* axRenderChild = children.at(0).get(); + interfaceMask |= getInterfaceMaskFromObject(axRenderChild); + } + } + } // Image if (coreObject->isImage()) diff --git a/WebCore/accessibility/mac/AXObjectCacheMac.mm b/WebCore/accessibility/mac/AXObjectCacheMac.mm index a02bc75..fbb485d 100644 --- a/WebCore/accessibility/mac/AXObjectCacheMac.mm +++ b/WebCore/accessibility/mac/AXObjectCacheMac.mm @@ -108,12 +108,20 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific return; } + // NSAccessibilityPostNotification will call this method, (but not when running DRT), so ASSERT here to make sure it does not crash. + // https://bugs.webkit.org/show_bug.cgi?id=46662 + ASSERT([obj->wrapper() accessibilityIsIgnored] || true); + NSAccessibilityPostNotification(obj->wrapper(), macNotification); // Used by DRT to know when notifications are posted. [obj->wrapper() accessibilityPostedNotification:macNotification]; } +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) +{ +} + void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { [[WebCoreViewFactory sharedFactory] accessibilityHandleFocusChanged]; diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm index e3e28d7..cb983eb 100644 --- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm +++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm @@ -200,6 +200,22 @@ typedef unsigned NSUInteger; m_object = 0; } +- (BOOL)updateObjectBackingStore +{ + // Calling updateBackingStore() can invalidate this element so self must be retained. + // If it does become invalidated, m_object will be nil. + [[self retain] autorelease]; + + if (!m_object) + return NO; + + m_object->updateBackingStore(); + if (!m_object) + return NO; + + return YES; +} + - (AccessibilityObject*)accessibilityObject { return m_object; @@ -214,35 +230,49 @@ typedef unsigned NSUInteger; return NSAccessibilityUnignoredDescendant(widget->platformWidget()); } -static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& visiblePos) +static WebCoreTextMarker* textMarkerForVisiblePosition(AXObjectCache* cache, const VisiblePosition& visiblePos) { + ASSERT(cache); + TextMarkerData textMarkerData; - AXObjectCache::textMarkerDataForVisiblePosition(textMarkerData, visiblePos); + cache->textMarkerDataForVisiblePosition(textMarkerData, visiblePos); if (!textMarkerData.axID) return nil; return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)]; } -static VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker* textMarker) +- (WebCoreTextMarker *)textMarkerForVisiblePosition:(const VisiblePosition &)visiblePos +{ + return textMarkerForVisiblePosition(m_object->axObjectCache(), visiblePos); +} + +static VisiblePosition visiblePositionForTextMarker(AXObjectCache* cache, WebCoreTextMarker* textMarker) { + ASSERT(cache); + if (!textMarker) return VisiblePosition(); TextMarkerData textMarkerData; if (![[WebCoreViewFactory sharedFactory] getBytes:&textMarkerData fromTextMarker:textMarker length:sizeof(textMarkerData)]) return VisiblePosition(); - return AXObjectCache::visiblePositionForTextMarkerData(textMarkerData); + return cache->visiblePositionForTextMarkerData(textMarkerData); +} + +- (VisiblePosition)visiblePositionForTextMarker:(WebCoreTextMarker *)textMarker +{ + return visiblePositionForTextMarker(m_object->axObjectCache(), textMarker); } -static VisiblePosition visiblePositionForStartOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange) +static VisiblePosition visiblePositionForStartOfTextMarkerRange(AXObjectCache *cache, WebCoreTextMarkerRange* textMarkerRange) { - return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]); + return visiblePositionForTextMarker(cache, [[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]); } -static VisiblePosition visiblePositionForEndOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange) +static VisiblePosition visiblePositionForEndOfTextMarkerRange(AXObjectCache *cache, WebCoreTextMarkerRange* textMarkerRange) { - return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]); + return visiblePositionForTextMarker(cache, [[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]); } static WebCoreTextMarkerRange* textMarkerRangeFromMarkers(WebCoreTextMarker* textMarker1, WebCoreTextMarker* textMarker2) @@ -512,11 +542,11 @@ static NSString* nsStringForReplacedNode(Node* replacedNode) return nil; // extract the start and end VisiblePosition - VisiblePosition startVisiblePosition = visiblePositionForStartOfTextMarkerRange(textMarkerRange); + VisiblePosition startVisiblePosition = visiblePositionForStartOfTextMarkerRange(m_object->axObjectCache(), textMarkerRange); if (startVisiblePosition.isNull()) return nil; - VisiblePosition endVisiblePosition = visiblePositionForEndOfTextMarkerRange(textMarkerRange); + VisiblePosition endVisiblePosition = visiblePositionForEndOfTextMarkerRange(m_object->axObjectCache(), textMarkerRange); if (endVisiblePosition.isNull()) return nil; @@ -562,20 +592,21 @@ static NSString* nsStringForReplacedNode(Node* replacedNode) return [attrString autorelease]; } -static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePosition startPosition, VisiblePosition endPosition) +static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(AXObjectCache *cache, VisiblePosition startPosition, VisiblePosition endPosition) { - WebCoreTextMarker* startTextMarker = textMarkerForVisiblePosition(startPosition); - WebCoreTextMarker* endTextMarker = textMarkerForVisiblePosition(endPosition); + WebCoreTextMarker* startTextMarker = textMarkerForVisiblePosition(cache, startPosition); + WebCoreTextMarker* endTextMarker = textMarkerForVisiblePosition(cache, endPosition); return textMarkerRangeFromMarkers(startTextMarker, endTextMarker); } -- (NSArray*)accessibilityActionNames +- (WebCoreTextMarkerRange *)textMarkerRangeFromVisiblePositions:(VisiblePosition)startPosition endPosition:(VisiblePosition)endPosition { - if (!m_object) - return nil; + return textMarkerRangeFromVisiblePositions(m_object->axObjectCache(), startPosition, endPosition); +} - m_object->updateBackingStore(); - if (!m_object) +- (NSArray*)accessibilityActionNames +{ + if (![self updateObjectBackingStore]) return nil; static NSArray* actionElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil]; @@ -638,11 +669,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi - (NSArray*)accessibilityAttributeNames { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; if (m_object->isAttachment()) @@ -982,7 +1009,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi { if (!textMarkerRange) return VisiblePositionRange(); - return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(textMarkerRange), visiblePositionForEndOfTextMarkerRange(textMarkerRange)); + AXObjectCache* cache = m_object->axObjectCache(); + return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(cache, textMarkerRange), visiblePositionForEndOfTextMarkerRange(cache, textMarkerRange)); } - (NSArray*)renderWidgetChildren @@ -1028,7 +1056,7 @@ static NSMutableArray* convertToNSArray(const AccessibilityObject::Accessibility VisibleSelection selection = m_object->selection(); if (selection.isNone()) return nil; - return textMarkerRangeFromVisiblePositions(selection.visibleStart(), selection.visibleEnd()); + return [self textMarkerRangeFromVisiblePositions:selection.visibleStart() endPosition:selection.visibleEnd()]; } - (NSValue*)position @@ -1354,11 +1382,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) // or maybe pointers to member functions - (id)accessibilityAttributeValue:(NSString*)attributeName { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; if ([attributeName isEqualToString: NSAccessibilityRoleAttribute]) @@ -1784,9 +1808,9 @@ static NSString* roleValueToNSString(AccessibilityRole value) return nil; if ([attributeName isEqualToString: @"AXStartTextMarker"]) - return textMarkerForVisiblePosition(startOfDocument(renderer->document())); + return [self textMarkerForVisiblePosition:startOfDocument(renderer->document())]; if ([attributeName isEqualToString: @"AXEndTextMarker"]) - return textMarkerForVisiblePosition(endOfDocument(renderer->document())); + return [self textMarkerForVisiblePosition:endOfDocument(renderer->document())]; if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute]) return [NSNumber numberWithInt:blockquoteLevel(renderer)]; @@ -1889,11 +1913,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (id)accessibilityFocusedUIElement { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; RefPtr<AccessibilityObject> focusedObj = m_object->focusedUIElement(); @@ -1906,11 +1926,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (id)accessibilityHitTest:(NSPoint)point { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; RefPtr<AccessibilityObject> axObject = m_object->doAccessibilityHitTest(IntPoint(point)); @@ -1921,11 +1937,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) @@ -1971,11 +1983,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) // Registering an object is also required for observing notifications. Only registered objects can be observed. - (BOOL)accessibilityIsIgnored { - if (!m_object) - return YES; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return YES; if (m_object->isAttachment()) @@ -1985,11 +1993,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (NSArray* )accessibilityParameterizedAttributeNames { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; if (m_object->isAttachment()) @@ -2073,11 +2077,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (void)accessibilityPerformPressAction { - if (!m_object) - return; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return; if (m_object->isAttachment()) @@ -2088,11 +2088,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (void)accessibilityPerformIncrementAction { - if (!m_object) - return; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return; if (m_object->isAttachment()) @@ -2103,11 +2099,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (void)accessibilityPerformDecrementAction { - if (!m_object) - return; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return; if (m_object->isAttachment()) @@ -2158,11 +2150,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (void)accessibilityPerformAction:(NSString*)action { - if (!m_object) - return; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return; if ([action isEqualToString:NSAccessibilityPressAction]) @@ -2180,11 +2168,7 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName { - if (!m_object) - return; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return; WebCoreTextMarkerRange* textMarkerRange = nil; @@ -2290,7 +2274,7 @@ static RenderObject* rendererForView(NSView* view) { PlainTextRange textRange = PlainTextRange(range.location, range.length); VisiblePositionRange visiblePosRange = m_object->visiblePositionRangeForRange(textRange); - return [self doAXAttributedStringForTextMarkerRange:textMarkerRangeFromVisiblePositions(visiblePosRange.start, visiblePosRange.end)]; + return [self doAXAttributedStringForTextMarkerRange:[self textMarkerRangeFromVisiblePositions:visiblePosRange.start endPosition:visiblePosRange.end]]; } // The RTF representation of the text associated with this accessibility object that is @@ -2317,8 +2301,7 @@ static RenderObject* rendererForView(NSView* view) if (!m_object || !attribute || !parameter) return nil; - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; // common parameter type check/casting. Nil checks in handlers catch wrong type case. @@ -2353,7 +2336,7 @@ static RenderObject* rendererForView(NSView* view) // dispatch if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; AccessibilityObject* axObject = m_object->accessibilityObjectForPosition(visiblePos); if (!axObject) return nil; @@ -2362,17 +2345,17 @@ static RenderObject* rendererForView(NSView* view) if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) { VisiblePositionRange vpRange = uiElement.get()->visiblePositionRange(); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXLineForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; return [NSNumber numberWithUnsignedInt:m_object->lineForPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) { VisiblePositionRange vpRange = m_object->visiblePositionRangeForLine([number intValue]); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) { @@ -2382,7 +2365,7 @@ static RenderObject* rendererForView(NSView* view) if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) { IntPoint webCorePoint = IntPoint(point); - return pointSet ? textMarkerForVisiblePosition(m_object->visiblePositionForPoint(webCorePoint)) : nil; + return pointSet ? [self textMarkerForVisiblePosition:m_object->visiblePositionForPoint(webCorePoint)] : nil; } if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) { @@ -2421,102 +2404,102 @@ static RenderObject* rendererForView(NSView* view) || ![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker2]) return nil; - VisiblePosition visiblePos1 = visiblePositionForTextMarker(textMarker1); - VisiblePosition visiblePos2 = visiblePositionForTextMarker(textMarker2); + VisiblePosition visiblePos1 = [self visiblePositionForTextMarker:(textMarker1)]; + VisiblePosition visiblePos2 = [self visiblePositionForTextMarker:(textMarker2)]; VisiblePositionRange vpRange = m_object->visiblePositionRangeForUnorderedPositions(visiblePos1, visiblePos2); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->nextVisiblePosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->nextVisiblePosition(visiblePos)]; } if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->previousVisiblePosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->previousVisiblePosition(visiblePos)]; } if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->positionOfLeftWord(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->positionOfRightWord(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->leftLineVisiblePositionRange(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->rightLineVisiblePositionRange(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->sentenceForPosition(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->paragraphForPosition(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->nextWordEnd(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->nextWordEnd(visiblePos)]; } if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->previousWordStart(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->previousWordStart(visiblePos)]; } if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->nextLineEndPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->nextLineEndPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->previousLineStartPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->previousLineStartPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->nextSentenceEndPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->nextSentenceEndPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->previousSentenceStartPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->previousSentenceStartPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->nextParagraphEndPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->nextParagraphEndPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return textMarkerForVisiblePosition(m_object->previousParagraphStartPosition(visiblePos)); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; + return [self textMarkerForVisiblePosition:m_object->previousParagraphStartPosition(visiblePos)]; } if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) { - VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); + VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)]; VisiblePositionRange vpRange = m_object->styleRangeForPosition(visiblePos); - return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end); + return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end]; } if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) { @@ -2530,12 +2513,12 @@ static RenderObject* rendererForView(NSView* view) // Used only by DumpRenderTree (so far). if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) { VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange]; - return textMarkerForVisiblePosition(visiblePosRange.start); + return [self textMarkerForVisiblePosition:visiblePosRange.start]; } if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) { VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange]; - return textMarkerForVisiblePosition(visiblePosRange.end); + return [self textMarkerForVisiblePosition:visiblePosRange.end]; } if (m_object->isDataTable()) { @@ -2614,11 +2597,7 @@ static RenderObject* rendererForView(NSView* view) // API that AppKit uses for faster access - (NSUInteger)accessibilityIndexOfChild:(id)child { - if (!m_object) - return NSNotFound; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return NSNotFound; // Tree objects return their rows as their children. We can use the original method @@ -2643,11 +2622,7 @@ static RenderObject* rendererForView(NSView* view) - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute { - if (!m_object) - return 0; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return 0; if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { @@ -2668,11 +2643,7 @@ static RenderObject* rendererForView(NSView* view) - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount { - if (!m_object) - return nil; - - m_object->updateBackingStore(); - if (!m_object) + if (![self updateObjectBackingStore]) return nil; if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { diff --git a/WebCore/accessibility/win/AXObjectCacheWin.cpp b/WebCore/accessibility/win/AXObjectCacheWin.cpp index 21e61d9..b20b51a 100644 --- a/WebCore/accessibility/win/AXObjectCacheWin.cpp +++ b/WebCore/accessibility/win/AXObjectCacheWin.cpp @@ -103,6 +103,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific NotifyWinEvent(msaaEvent, page->chrome()->platformPageClient(), OBJID_CLIENT, -static_cast<LONG>(obj->axObjectID())); } +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) +{ +} + AXID AXObjectCache::platformGenerateAXID() const { static AXID lastUsedID = 0; |