summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/accessibility')
-rw-r--r--Source/WebCore/accessibility/AXObjectCache.cpp16
-rw-r--r--Source/WebCore/accessibility/AXObjectCache.h3
-rw-r--r--Source/WebCore/accessibility/AccessibilityARIAGrid.cpp42
-rw-r--r--Source/WebCore/accessibility/AccessibilityObject.cpp14
-rw-r--r--Source/WebCore/accessibility/AccessibilityRenderObject.cpp31
-rw-r--r--Source/WebCore/accessibility/AccessibilityScrollView.cpp14
-rw-r--r--Source/WebCore/accessibility/AccessibilityScrollView.h5
-rw-r--r--Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp72
-rw-r--r--Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp73
-rw-r--r--Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm18
10 files changed, 212 insertions, 76 deletions
diff --git a/Source/WebCore/accessibility/AXObjectCache.cpp b/Source/WebCore/accessibility/AXObjectCache.cpp
index d0d19f7..a01cb59 100644
--- a/Source/WebCore/accessibility/AXObjectCache.cpp
+++ b/Source/WebCore/accessibility/AXObjectCache.cpp
@@ -290,6 +290,13 @@ AccessibilityObject* AXObjectCache::rootObject()
return getOrCreate(m_document->view());
}
+AccessibilityObject* AXObjectCache::rootObjectForFrame(Frame* frame)
+{
+ if (!frame)
+ return 0;
+ return getOrCreate(frame->view());
+}
+
AccessibilityObject* AXObjectCache::getOrCreate(AccessibilityRole role)
{
RefPtr<AccessibilityObject> obj = 0;
@@ -573,12 +580,13 @@ VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData&
if (!isNodeInUse(textMarkerData.node))
return VisiblePosition();
- VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity);
+ // FIXME: Accessability should make it clear these are DOM-compliant offsets or store Position objects.
+ VisiblePosition visiblePos = VisiblePosition(Position(textMarkerData.node, textMarkerData.offset), textMarkerData.affinity);
Position deepPos = visiblePos.deepEquivalent();
if (deepPos.isNull())
return VisiblePosition();
- RenderObject* renderer = deepPos.node()->renderer();
+ RenderObject* renderer = deepPos.deprecatedNode()->renderer();
if (!renderer)
return VisiblePosition();
@@ -586,7 +594,7 @@ VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData&
if (!cache->isIDinUse(textMarkerData.axID))
return VisiblePosition();
- if (deepPos.node() != textMarkerData.node || deepPos.deprecatedEditingOffset() != textMarkerData.offset)
+ if (deepPos.deprecatedNode() != textMarkerData.node || deepPos.deprecatedEditingOffset() != textMarkerData.offset)
return VisiblePosition();
return visiblePos;
@@ -602,7 +610,7 @@ void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerD
return;
Position deepPos = visiblePos.deepEquivalent();
- Node* domNode = deepPos.node();
+ Node* domNode = deepPos.deprecatedNode();
ASSERT(domNode);
if (!domNode)
return;
diff --git a/Source/WebCore/accessibility/AXObjectCache.h b/Source/WebCore/accessibility/AXObjectCache.h
index d2d40c1..4c231b5 100644
--- a/Source/WebCore/accessibility/AXObjectCache.h
+++ b/Source/WebCore/accessibility/AXObjectCache.h
@@ -62,7 +62,10 @@ public:
static AccessibilityObject* focusedUIElementForPage(const Page*);
+ // Returns the root object for the entire document.
AccessibilityObject* rootObject();
+ // Returns the root object for a specific frame.
+ AccessibilityObject* rootObjectForFrame(Frame*);
// For AX objects with elements that back them.
AccessibilityObject* getOrCreate(RenderObject*);
diff --git a/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp b/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp
index 8651a80..d51750a 100644
--- a/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp
+++ b/Source/WebCore/accessibility/AccessibilityARIAGrid.cpp
@@ -137,18 +137,40 @@ AccessibilityTableCell* AccessibilityARIAGrid::cellForColumnAndRow(unsigned colu
if (column >= columnCount() || row >= rowCount())
return 0;
- AccessibilityObject* tableRow = m_rows[row].get();
- if (!tableRow)
- return 0;
+ int intRow = (int)row;
+ int intColumn = (int)column;
+
+ pair<int, int> columnRange;
+ pair<int, int> rowRange;
- AccessibilityChildrenVector children = tableRow->children();
- // in case this row had fewer columns than other rows
- AccessibilityObject* tableCell = 0;
- if (column >= children.size())
- return 0;
+ // Iterate backwards through the rows in case the desired cell has a rowspan and exists
+ // in a previous row.
+ for (; intRow >= 0; --intRow) {
+ AccessibilityObject* tableRow = m_rows[intRow].get();
+ if (!tableRow)
+ continue;
+
+ AccessibilityChildrenVector children = tableRow->children();
+ unsigned childrenLength = children.size();
+
+ // Since some cells may have colspans, we have to check the actual range of each
+ // cell to determine which is the right one.
+ for (unsigned k = 0; k < childrenLength; ++k) {
+ AccessibilityObject* child = children[k].get();
+ if (!child->isTableCell())
+ continue;
+
+ AccessibilityTableCell* tableCellChild = static_cast<AccessibilityTableCell*>(child);
+ tableCellChild->columnIndexRange(columnRange);
+ tableCellChild->rowIndexRange(rowRange);
+
+ if ((intColumn >= columnRange.first && intColumn < (columnRange.first + columnRange.second))
+ && (intRow >= rowRange.first && intRow < (rowRange.first + rowRange.second)))
+ return tableCellChild;
+ }
+ }
- tableCell = children[column].get();
- return static_cast<AccessibilityTableCell*>(tableCell);
+ return 0;
}
} // namespace WebCore
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
index ba03ef4..10b5094 100644
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
@@ -222,9 +222,9 @@ static VisiblePosition updateAXLineStartForVisiblePosition(const VisiblePosition
if (tempPosition.isNull())
break;
p = tempPosition.deepEquivalent();
- if (!p.node())
+ if (!p.deprecatedNode())
break;
- renderer = p.node()->renderer();
+ renderer = p.deprecatedNode()->renderer();
if (!renderer || (renderer->isRenderBlock() && !p.deprecatedEditingOffset()))
break;
InlineBox* box;
@@ -318,7 +318,7 @@ VisiblePositionRange AccessibilityObject::paragraphForPosition(const VisiblePosi
static VisiblePosition startOfStyleRange(const VisiblePosition visiblePos)
{
- RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer();
+ RenderObject* renderer = visiblePos.deepEquivalent().deprecatedNode()->renderer();
RenderObject* startRenderer = renderer;
RenderStyle* style = renderer->style();
@@ -336,12 +336,12 @@ static VisiblePosition startOfStyleRange(const VisiblePosition visiblePos)
startRenderer = r;
}
- return VisiblePosition(startRenderer->node(), 0, VP_DEFAULT_AFFINITY);
+ return firstPositionInOrBeforeNode(startRenderer->node());
}
static VisiblePosition endOfStyleRange(const VisiblePosition& visiblePos)
{
- RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer();
+ RenderObject* renderer = visiblePos.deepEquivalent().deprecatedNode()->renderer();
RenderObject* endRenderer = renderer;
RenderStyle* style = renderer->style();
@@ -359,7 +359,7 @@ static VisiblePosition endOfStyleRange(const VisiblePosition& visiblePos)
endRenderer = r;
}
- return lastDeepEditingPositionForNode(endRenderer->node());
+ return lastPositionInOrAfterNode(endRenderer->node());
}
VisiblePositionRange AccessibilityObject::styleRangeForPosition(const VisiblePosition& visiblePos) const
@@ -649,7 +649,7 @@ AccessibilityObject* AccessibilityObject::accessibilityObjectForPosition(const V
if (visiblePos.isNull())
return 0;
- RenderObject* obj = visiblePos.deepEquivalent().node()->renderer();
+ RenderObject* obj = visiblePos.deepEquivalent().deprecatedNode()->renderer();
if (!obj)
return 0;
diff --git a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
index 70ed839..a626950 100644
--- a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -51,6 +51,7 @@
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "LocalizedStrings.h"
+#include "MathMLNames.h"
#include "NodeList.h"
#include "ProgressTracker.h"
#include "RenderButton.h"
@@ -662,12 +663,8 @@ bool AccessibilityRenderObject::isReadOnly() const
HTMLElement* body = document->body();
if (body && body->isContentEditable())
return false;
-
- Frame* frame = document->frame();
- if (!frame)
- return true;
-
- return !frame->isContentEditable();
+
+ return !document->inDesignMode();
}
if (m_renderer->isBoxModelObject()) {
@@ -1354,8 +1351,8 @@ String AccessibilityRenderObject::accessibilityDescription() const
if (!ariaDescription.isEmpty())
return ariaDescription;
+ Node* node = m_renderer->node();
if (isImage() || isInputImage() || isNativeImage()) {
- Node* node = m_renderer->node();
if (node && node->isHTMLElement()) {
const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
if (alt.isEmpty())
@@ -1364,6 +1361,11 @@ String AccessibilityRenderObject::accessibilityDescription() const
}
}
+#if ENABLE(MATHML)
+ if (node && node->isElementNode() && static_cast<Element*>(node)->isMathMLElement())
+ return getAttribute(MathMLNames::alttextAttr);
+#endif
+
if (isWebArea()) {
Document* document = m_renderer->document();
@@ -2459,14 +2461,14 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) co
return VisiblePosition();
if (index <= 0)
- return VisiblePosition(node, 0, DOWNSTREAM);
+ return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(m_renderer->document());
range->selectNodeContents(node, ec);
CharacterIterator it(range.get());
it.advance(index - 1);
- return VisiblePosition(it.range()->endContainer(ec), it.range()->endOffset(ec), UPSTREAM);
+ return VisiblePosition(Position(it.range()->endContainer(ec), it.range()->endOffset(ec), Position::PositionIsOffsetInAnchor), UPSTREAM);
}
int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
@@ -2482,13 +2484,13 @@ int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& po
return 0;
Position indexPosition = pos.deepEquivalent();
- if (!indexPosition.node() || indexPosition.node()->rootEditableElement() != node)
+ if (!indexPosition.anchorNode() || indexPosition.anchorNode()->rootEditableElement() != node)
return 0;
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(m_renderer->document());
range->setStart(node, 0, ec);
- range->setEnd(indexPosition.node(), indexPosition.deprecatedEditingOffset(), ec);
+ range->setEnd(indexPosition.anchorNode(), indexPosition.deprecatedEditingOffset(), ec);
return TextIterator::rangeLength(range.get());
}
@@ -2621,7 +2623,7 @@ int AccessibilityRenderObject::index(const VisiblePosition& position) const
if (!isTextControl())
return -1;
- Node* node = position.deepEquivalent().node();
+ Node* node = position.deepEquivalent().deprecatedNode();
if (!node)
return -1;
@@ -3048,6 +3050,11 @@ AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
if (headingLevel())
return HeadingRole;
+#if ENABLE(MATHML)
+ if (node && node->hasTagName(MathMLNames::mathTag))
+ return DocumentMathRole;
+#endif
+
if (node && node->hasTagName(ddTag))
return DefinitionListDefinitionRole;
diff --git a/Source/WebCore/accessibility/AccessibilityScrollView.cpp b/Source/WebCore/accessibility/AccessibilityScrollView.cpp
index 5b94fe3..5e34f81 100644
--- a/Source/WebCore/accessibility/AccessibilityScrollView.cpp
+++ b/Source/WebCore/accessibility/AccessibilityScrollView.cpp
@@ -32,6 +32,7 @@
#include "HTMLFrameOwnerElement.h"
#include "RenderPart.h"
#include "ScrollView.h"
+#include "Widget.h"
namespace WebCore {
@@ -63,6 +64,19 @@ const AccessibilityObject::AccessibilityChildrenVector& AccessibilityScrollView:
addChildren();
return m_children;
}
+
+// If this is WebKit1 then the native scroll view needs to return the
+// AX information (because there are no scroll bar children in the ScrollView object in WK1).
+// In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
+bool AccessibilityScrollView::isAttachment() const
+{
+ return m_scrollView->platformWidget();
+}
+
+Widget* AccessibilityScrollView::widgetForAttachmentView() const
+{
+ return m_scrollView.get();
+}
void AccessibilityScrollView::updateChildrenIfNecessary()
{
diff --git a/Source/WebCore/accessibility/AccessibilityScrollView.h b/Source/WebCore/accessibility/AccessibilityScrollView.h
index f19bde8..3d72ab5 100644
--- a/Source/WebCore/accessibility/AccessibilityScrollView.h
+++ b/Source/WebCore/accessibility/AccessibilityScrollView.h
@@ -45,6 +45,10 @@ private:
virtual bool accessibilityIsIgnored() const { return false; }
virtual bool isAccessibilityScrollView() const { return true; }
+
+ virtual bool isAttachment() const;
+ virtual Widget* widgetForAttachmentView() const;
+
virtual AccessibilityObject* scrollBar(AccessibilityOrientation) const;
virtual void addChildren();
virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const;
@@ -56,6 +60,7 @@ private:
virtual AccessibilityObject* parentObject() const;
AccessibilityObject* webAreaObject() const;
+ virtual AccessibilityObject* firstChild() const { return webAreaObject(); }
AccessibilityScrollbar* addChildScrollbar(Scrollbar*);
void removeChildScrollbar(AccessibilityObject*);
diff --git a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
index c341a2d..0701ece 100644
--- a/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
+++ b/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
@@ -42,34 +42,67 @@ void AXObjectCache::attachWrapper(AccessibilityObject* obj)
g_object_unref(atkObj);
}
-static void notifyChildrenSelectionChange(AccessibilityObject* object)
+static AccessibilityObject* getListObject(AccessibilityObject* object)
{
- // This static variable is needed to keep track of the old focused
- // object as per previous calls to this function, in order to
- // properly decide whether to emit some signals or not.
- static RefPtr<AccessibilityObject> oldFocusedObject = 0;
+ // Only list boxes and menu lists supported so far.
+ if (!object->isListBox() && !object->isMenuList())
+ return 0;
+
+ // For list boxes the list object is just itself.
+ if (object->isListBox())
+ return object;
+
+ // For menu lists we need to return the first accessible child,
+ // with role MenuListPopupRole, since that's the one holding the list
+ // of items with role MenuListOptionRole.
+ AccessibilityObject::AccessibilityChildrenVector children = object->children();
+ if (!children.size())
+ return 0;
+
+ AccessibilityObject* listObject = children.at(0).get();
+ if (!listObject->isMenuListPopup())
+ return 0;
+
+ return listObject;
+}
- // Only list boxes supported so far.
- if (!object || !object->isListBox())
+static void notifyChildrenSelectionChange(AccessibilityObject* object)
+{
+ // This static variables are needed to keep track of the old
+ // focused object and its associated list object, as per previous
+ // calls to this function, in order to properly decide whether to
+ // emit some signals or not.
+ DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldListObject, ());
+ DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldFocusedObject, ());
+
+ // Only list boxes and menu lists supported so far.
+ if (!object || !(object->isListBox() || object->isMenuList()))
return;
// Emit signal from the listbox's point of view first.
g_signal_emit_by_name(object->wrapper(), "selection-changed");
// Find the item where the selection change was triggered from.
- AccessibilityObject::AccessibilityChildrenVector items = object->children();
SelectElement* select = toSelectElement(static_cast<Element*>(object->node()));
if (!select)
return;
int changedItemIndex = select->activeSelectionStartListIndex();
+
+ AccessibilityObject* listObject = getListObject(object);
+ if (!listObject) {
+ oldListObject = 0;
+ return;
+ }
+
+ AccessibilityObject::AccessibilityChildrenVector items = listObject->children();
if (changedItemIndex < 0 || changedItemIndex >= static_cast<int>(items.size()))
return;
AccessibilityObject* item = items.at(changedItemIndex).get();
- // Ensure the oldFocusedObject belongs to the same document that
- // the current item so further comparisons make sense. Otherwise,
- // just reset oldFocusedObject so it won't be taken into account.
- if (item && oldFocusedObject && item->document() != oldFocusedObject->document())
+ // Ensure the current list object is the same than the old one so
+ // further comparisons make sense. Otherwise, just reset
+ // oldFocusedObject so it won't be taken into account.
+ if (oldListObject != listObject)
oldFocusedObject = 0;
AtkObject* axItem = item ? item->wrapper() : 0;
@@ -89,7 +122,8 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object)
g_signal_emit_by_name(axItem, "state-change", "focused", isSelected);
}
- // Update pointer to the previously focused object.
+ // Update pointers to the previously involved objects.
+ oldListObject = listObject;
oldFocusedObject = item;
}
@@ -103,13 +137,13 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX
if (!coreObject->isCheckboxOrRadio())
return;
g_signal_emit_by_name(axObject, "state-change", "checked", coreObject->isChecked());
- } else if (notification == AXMenuListValueChanged) {
- if (!coreObject->isMenuList())
- return;
- g_signal_emit_by_name(axObject, "focus-event", true);
- g_signal_emit_by_name(axObject, "state-change", "focused", true);
- } else if (notification == AXSelectedChildrenChanged)
+ } else if (notification == AXSelectedChildrenChanged || notification == AXMenuListValueChanged) {
+ if (notification == AXMenuListValueChanged && coreObject->isMenuList()) {
+ g_signal_emit_by_name(axObject, "focus-event", true);
+ g_signal_emit_by_name(axObject, "state-change", "focused", true);
+ }
notifyChildrenSelectionChange(coreObject);
+ }
}
static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count)
diff --git a/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index 8f39113..1d23612 100644
--- a/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -175,7 +175,7 @@ static const gchar* webkit_accessible_get_name(AtkObject* object)
return webkit_accessible_text_get_text(ATK_TEXT(atkObject), 0, -1);
}
- // Try text under the node
+ // Try text under the node.
String textUnder = renderObject->textUnderElement();
if (textUnder.length())
return returnString(textUnder);
@@ -191,6 +191,13 @@ static const gchar* webkit_accessible_get_name(AtkObject* object)
}
}
+ // Fallback for the webArea object: just return the document's title.
+ if (renderObject->isWebArea()) {
+ Document* document = coreObject->document();
+ if (document)
+ return returnString(document->title());
+ }
+
return returnString(coreObject->stringValue());
}
@@ -1113,29 +1120,28 @@ gchar* textForObject(AccessibilityRenderObject* accObject)
static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, gint endOffset)
{
AccessibilityObject* coreObject = core(text);
- String ret;
- unsigned start = startOffset;
+
+ int end = endOffset;
if (endOffset == -1) {
- endOffset = coreObject->stringValue().length();
- if (!endOffset)
- endOffset = coreObject->textUnderElement().length();
+ end = coreObject->stringValue().length();
+ if (!end)
+ end = coreObject->textUnderElement().length();
}
- int length = endOffset - startOffset;
+ String ret;
if (coreObject->isTextControl())
- ret = coreObject->doAXStringForRange(PlainTextRange(start, length));
+ ret = coreObject->doAXStringForRange(PlainTextRange(0, endOffset));
else {
- ret = coreObject->stringValue().substring(start, length);
+ ret = coreObject->stringValue();
if (!ret)
- ret = coreObject->textUnderElement().substring(start, length);
+ ret = coreObject->textUnderElement();
}
if (!ret.length()) {
// This can happen at least with anonymous RenderBlocks (e.g. body text amongst paragraphs)
- ret = String(textForObject(static_cast<AccessibilityRenderObject*>(coreObject)));
- if (!endOffset)
- endOffset = ret.length();
- ret = ret.substring(start, endOffset - startOffset);
+ ret = String(textForObject(toAccessibilityRenderObject(coreObject)));
+ if (!end)
+ end = ret.length();
}
// Prefix a item number/bullet if needed
@@ -1144,9 +1150,12 @@ static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, g
if (objRenderer && objRenderer->isListItem()) {
String markerText = toRenderListItem(objRenderer)->markerTextWithSuffix();
ret = objRenderer->style()->direction() == LTR ? markerText + ret : ret + markerText;
+ if (endOffset == -1)
+ end += markerText.length();
}
}
+ ret = ret.substring(startOffset, end - startOffset);
return g_strdup(ret.utf8().data());
}
@@ -1212,7 +1221,7 @@ static gint webkit_accessible_text_get_caret_offset(AtkText* text)
if (!coreObject->isAccessibilityRenderObject())
return 0;
- Node* focusedNode = coreObject->selection().end().node();
+ Node* focusedNode = coreObject->selection().end().deprecatedNode();
if (!focusedNode)
return 0;
@@ -1619,6 +1628,14 @@ static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, Visibl
// Set values for start and end offsets.
startOffset = TextIterator::rangeLength(rangeInParent.get());
+
+ // We need to adjust the offsets for the list item marker.
+ RenderObject* renderer = toAccessibilityRenderObject(coreObject)->renderer();
+ if (renderer && renderer->isListItem()) {
+ String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
+ startOffset += markerText.length();
+ }
+
RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
endOffset = startOffset + TextIterator::rangeLength(nodeRange.get());
}
@@ -1675,6 +1692,10 @@ static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selecti
if (selectionNum)
return FALSE;
+ AccessibilityObject* coreObject = core(text);
+ if (!coreObject->isAccessibilityRenderObject())
+ return FALSE;
+
// Consider -1 and out-of-bound values and correct them to length
gint textCount = webkit_accessible_text_get_character_count(text);
if (startOffset < 0 || startOffset > textCount)
@@ -1682,11 +1703,24 @@ static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selecti
if (endOffset < 0 || endOffset > textCount)
endOffset = textCount;
- AccessibilityObject* coreObject = core(text);
+ // We need to adjust the offsets for the list item marker.
+ RenderObject* renderer = toAccessibilityRenderObject(coreObject)->renderer();
+ if (renderer && renderer->isListItem()) {
+ String markerText = toRenderListItem(renderer)->markerTextWithSuffix();
+ int markerLength = markerText.length();
+ if (startOffset < markerLength || endOffset < markerLength)
+ return FALSE;
+
+ startOffset -= markerLength;
+ endOffset -= markerLength;
+ }
+
PlainTextRange textRange(startOffset, endOffset - startOffset);
VisiblePositionRange range = coreObject->visiblePositionRangeForRange(textRange);
- coreObject->setSelectedVisiblePositionRange(range);
+ if (range.isNull())
+ return FALSE;
+ coreObject->setSelectedVisiblePositionRange(range);
return TRUE;
}
@@ -2464,6 +2498,9 @@ void webkit_accessible_detach(WebKitAccessible* accessible)
{
ASSERT(accessible->m_object);
+ if (core(accessible)->roleValue() == WebAreaRole)
+ g_signal_emit_by_name(accessible, "state-change", "defunct", true);
+
// We replace the WebCore AccessibilityObject with a fallback object that
// provides default implementations to avoid repetitive null-checking after
// detachment.
@@ -2500,7 +2537,7 @@ AccessibilityObject* objectAndOffsetUnignored(AccessibilityObject* coreObject, i
Node* node = realObject->node();
if (node) {
- VisiblePosition startPosition = VisiblePosition(node, 0, DOWNSTREAM);
+ VisiblePosition startPosition = VisiblePosition(positionBeforeNode(node), DOWNSTREAM);
VisiblePosition endPosition = realObject->selection().visibleEnd();
if (startPosition == endPosition)
diff --git a/Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index 8fe3a49..a71ccd4 100644
--- a/Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -42,7 +42,6 @@
#import "AccessibilityTableRow.h"
#import "AccessibilityTableColumn.h"
#import "ColorMac.h"
-#import "EditorClient.h"
#import "Frame.h"
#import "FrameLoaderClient.h"
#import "HTMLAnchorElement.h"
@@ -58,6 +57,7 @@
#import "ScrollView.h"
#import "SelectionController.h"
#import "SimpleFontData.h"
+#import "TextCheckerClient.h"
#import "TextIterator.h"
#import "WebCoreFrameView.h"
#import "WebCoreObjCExtras.h"
@@ -480,14 +480,14 @@ static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrS
static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, const UChar* chars, int charLength, NSRange range)
{
// Check the spelling directly since document->markersForNode() does not store the misspelled marking when the cursor is in a word.
- EditorClient* client = node->document()->page()->editorClient();
int currentPosition = 0;
while (charLength > 0) {
const UChar* charData = chars + currentPosition;
+ TextCheckerClient* checker = node->document()->frame()->editor()->textChecker();
int misspellingLocation = -1;
int misspellingLength = 0;
- client->checkSpellingOfString(charData, charLength, &misspellingLocation, &misspellingLength);
+ checker->checkSpellingOfString(charData, charLength, &misspellingLocation, &misspellingLength);
if (misspellingLocation == -1 || !misspellingLength)
break;
@@ -1543,9 +1543,15 @@ static NSString* roleValueToNSString(AccessibilityRole value)
}
AccessibilityObject* parent = m_object->parentObjectUnignored();
- if (parent)
- return parent->wrapper();
- return nil;
+ if (!parent)
+ return nil;
+
+ // In WebKit1, the scroll view is provided by the system (the attachment view), so the parent
+ // should be reported directly as such.
+ if (m_object->isWebArea() && parent->isAttachment())
+ return [parent->wrapper() attachmentView];
+
+ return parent->wrapper();
}
if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) {