diff options
author | Steve Block <steveblock@google.com> | 2010-09-29 17:32:26 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-29 17:35:08 +0100 |
commit | 68513a70bcd92384395513322f1b801e7bf9c729 (patch) | |
tree | 161b50f75a5921d61731bb25e730005994fcec85 /WebCore/accessibility | |
parent | fd5c6425ce58eb75211be7718d5dee960842a37e (diff) | |
download | external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.zip external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.gz external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.bz2 |
Merge WebKit at r67908: Initial merge by Git
Change-Id: I43a553e7b3299b28cb6ee8aa035ed70fe342b972
Diffstat (limited to 'WebCore/accessibility')
-rw-r--r--[-rwxr-xr-x] | WebCore/accessibility/AccessibilityAllInOne.cpp | 0 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityObject.cpp | 17 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityObject.h | 2 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityRenderObject.cpp | 33 | ||||
-rw-r--r-- | WebCore/accessibility/AccessibilityTableRow.cpp | 3 | ||||
-rw-r--r-- | WebCore/accessibility/chromium/AXObjectCacheChromium.cpp | 50 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp | 25 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp | 141 | ||||
-rw-r--r-- | WebCore/accessibility/mac/AccessibilityObjectWrapper.mm | 9 |
9 files changed, 194 insertions, 86 deletions
diff --git a/WebCore/accessibility/AccessibilityAllInOne.cpp b/WebCore/accessibility/AccessibilityAllInOne.cpp index 28b1c9b..28b1c9b 100755..100644 --- a/WebCore/accessibility/AccessibilityAllInOne.cpp +++ b/WebCore/accessibility/AccessibilityAllInOne.cpp diff --git a/WebCore/accessibility/AccessibilityObject.cpp b/WebCore/accessibility/AccessibilityObject.cpp index a6bb033..3ddcdc5 100644 --- a/WebCore/accessibility/AccessibilityObject.cpp +++ b/WebCore/accessibility/AccessibilityObject.cpp @@ -373,22 +373,7 @@ VisiblePositionRange AccessibilityObject::styleRangeForPosition(const VisiblePos // NOTE: Consider providing this utility method as AX API VisiblePositionRange AccessibilityObject::visiblePositionRangeForRange(const PlainTextRange& range) const { - unsigned textLength = text().length(); -#if PLATFORM(GTK) - // Gtk ATs need this for all text objects; not just text controls. - if (!textLength) { - Node* node = this->node(); - RenderObject* renderer = node ? node->renderer() : 0; - if (renderer && renderer->isText()) { - RenderText* renderText = toRenderText(renderer); - textLength = renderText ? renderText->textLength() : 0; - } - // Get the text length from the elements under the - // accessibility object if the value is still zero. - if (!textLength && allowsTextRanges()) - textLength = textUnderElement().length(); - } -#endif + unsigned textLength = getLengthForTextRange(); if (range.start + range.length > textLength) return VisiblePositionRange(); diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h index 0e44d1b..e8f6d1b 100644 --- a/WebCore/accessibility/AccessibilityObject.h +++ b/WebCore/accessibility/AccessibilityObject.h @@ -574,8 +574,10 @@ protected: #if PLATFORM(GTK) bool allowsTextRanges() const; + unsigned getLengthForTextRange() const; #else bool allowsTextRanges() const { return isTextControl(); } + unsigned getLengthForTextRange() const { return text().length(); } #endif #if PLATFORM(MAC) diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp index e292971..5ca78ca 100644 --- a/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -503,7 +503,7 @@ bool AccessibilityRenderObject::isFileUploadButton() const { if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->node()); - return input->inputType() == HTMLInputElement::FILE; + return input->isFileUpload(); } return false; @@ -514,7 +514,7 @@ bool AccessibilityRenderObject::isInputImage() const Node* elementNode = node(); if (roleValue() == ButtonRole && elementNode && elementNode->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(elementNode); - return input->inputType() == HTMLInputElement::IMAGE; + return input->isImageButton(); } return false; @@ -1025,7 +1025,7 @@ String AccessibilityRenderObject::textUnderElement() const // catch stale WebCoreAXObject (see <rdar://problem/3960196>) if (frame->document() != node->document()) return String(); - return plainText(rangeOfContents(node).get()); + return plainText(rangeOfContents(node).get(), TextIteratorIgnoresStyleVisibility); } } @@ -1140,7 +1140,7 @@ String AccessibilityRenderObject::stringValue() const if (startVisiblePosition.isNull() || endVisiblePosition.isNull()) return String(); - return plainText(makeRange(startVisiblePosition, endVisiblePosition).get()); + return plainText(makeRange(startVisiblePosition, endVisiblePosition).get(), TextIteratorIgnoresStyleVisibility); } if (isTextControl()) @@ -1310,10 +1310,9 @@ String AccessibilityRenderObject::title() const || ariaRole == RadioButtonRole || ariaRole == CheckBoxRole || ariaRole == TabRole - || isHeading()) - return textUnderElement(); - - if (isLink()) + || ariaRole == PopUpButtonRole + || isHeading() + || isLink()) return textUnderElement(); return String(); @@ -1393,7 +1392,9 @@ IntRect AccessibilityRenderObject::boundingBoxRect() const // absoluteFocusRingQuads will query the hierarchy below this element, which for large webpages can be very slow. // For a web area, which will have the most elements of any element, absoluteQuads should be used. Vector<FloatQuad> quads; - if (obj->isText() || isWebArea()) + if (obj->isText()) + toRenderText(obj)->absoluteQuads(quads, RenderText::ClipToEllipsis); + else if (isWebArea()) obj->absoluteQuads(quads); else obj->absoluteFocusRingQuads(quads); @@ -2538,6 +2539,9 @@ void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePos VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const { + if (!m_renderer) + return VisiblePosition(); + // convert absolute point to view coordinates FrameView* frameView = m_renderer->document()->topDocument()->renderer()->view()->frameView(); RenderView* renderView = topRenderer(); @@ -2557,13 +2561,16 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin HitTestResult result(ourpoint); renderView->layer()->hitTest(request, result); innerNode = result.innerNode(); - if (!innerNode || !innerNode->renderer()) + if (!innerNode) + return VisiblePosition(); + + RenderObject* renderer = innerNode->renderer(); + if (!renderer) return VisiblePosition(); pointResult = result.localPoint(); // done if hit something other than a widget - RenderBoxModelObject* renderer = innerNode->renderBoxModelObject(); if (!renderer->isWidget()) break; @@ -3029,9 +3036,9 @@ AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole() if (node && node->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(node); - if (input->inputType() == HTMLInputElement::CHECKBOX) + if (input->isCheckbox()) return CheckBoxRole; - if (input->inputType() == HTMLInputElement::RADIO) + if (input->isRadioButton()) return RadioButtonRole; if (input->isTextButton()) return ButtonRole; diff --git a/WebCore/accessibility/AccessibilityTableRow.cpp b/WebCore/accessibility/AccessibilityTableRow.cpp index e2a1157..5e9f05c 100644 --- a/WebCore/accessibility/AccessibilityTableRow.cpp +++ b/WebCore/accessibility/AccessibilityTableRow.cpp @@ -93,7 +93,8 @@ AccessibilityObject* AccessibilityTableRow::parentTable() const if (!m_renderer || !m_renderer->isTableRow()) return 0; - return axObjectCache()->getOrCreate(toRenderTableRow(m_renderer)->table()); + // Do not use getOrCreate. parentTable() can be called while the render tree is being modified. + return axObjectCache()->get(toRenderTableRow(m_renderer)->table()); } AccessibilityObject* AccessibilityTableRow::headerObject() diff --git a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp index d906a91..3ff0837 100644 --- a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp +++ b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp @@ -60,30 +60,34 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific return; ChromeClientChromium* client = toChromeClientChromium(obj->documentFrameView()); - if (client) { - switch (notification) { - case AXCheckedStateChanged: - client->didChangeAccessibilityObjectState(obj); - break; - case AXChildrenChanged: - client->didChangeAccessibilityObjectChildren(obj); - break; - case AXActiveDescendantChanged: - case AXFocusedUIElementChanged: - case AXLayoutComplete: - case AXLiveRegionChanged: - case AXLoadComplete: - case AXMenuListValueChanged: - case AXRowCollapsed: - case AXRowCountChanged: - case AXRowExpanded: - case AXScrolledToAnchor: - case AXSelectedChildrenChanged: - case AXSelectedTextChanged: - case AXValueChanged: - break; - } + if (!client) + return; + + // TODO: Remove after the new postAccessibilityNotification is used downstream. + switch (notification) { + case AXCheckedStateChanged: + client->didChangeAccessibilityObjectState(obj); + break; + case AXChildrenChanged: + client->didChangeAccessibilityObjectChildren(obj); + break; + case AXActiveDescendantChanged: + case AXFocusedUIElementChanged: + case AXLayoutComplete: + case AXLiveRegionChanged: + case AXLoadComplete: + case AXMenuListValueChanged: + case AXRowCollapsed: + case AXRowCountChanged: + case AXRowExpanded: + case AXScrolledToAnchor: + case AXSelectedChildrenChanged: + case AXSelectedTextChanged: + case AXValueChanged: + break; } + + client->postAccessibilityNotification(obj, notification); } void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) diff --git a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp index b22a51e..7f9fd1a 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "AccessibilityObject.h" +#include "RenderObject.h" +#include "RenderText.h" #include <glib-object.h> @@ -102,6 +104,29 @@ bool AccessibilityObject::allowsTextRanges() const return isTextControl() || isWebArea() || isGroup() || isLink() || isHeading(); } +unsigned AccessibilityObject::getLengthForTextRange() const +{ + unsigned textLength = text().length(); + + if (textLength) + return textLength; + + // Gtk ATs need this for all text objects; not just text controls. + Node* node = this->node(); + RenderObject* renderer = node ? node->renderer() : 0; + if (renderer && renderer->isText()) { + RenderText* renderText = toRenderText(renderer); + textLength = renderText ? renderText->textLength() : 0; + } + + // Get the text length from the elements under the + // accessibility object if the value is still zero. + if (!textLength && allowsTextRanges()) + textLength = textUnderElement().length(); + + return textLength; +} + } // namespace WebCore #endif // HAVE(ACCESSIBILITY) diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp index 90f363f..01dddd1 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp @@ -58,6 +58,7 @@ #include "RenderListMarker.h" #include "RenderText.h" #include "TextEncoding.h" +#include "TextIterator.h" #include <wtf/text/CString.h> #include <wtf/text/AtomicString.h> @@ -1342,8 +1343,64 @@ static bool selectionBelongsToObject(AccessibilityObject* coreObject, VisibleSel if (!coreObject->isAccessibilityRenderObject()) return false; - Node* node = static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->node(); - return node == selection.base().containerNode(); + RefPtr<Range> range = selection.toNormalizedRange(); + if (!range) + return false; + + // We want to check that both the selection intersects the node + // AND that the selection is not just "touching" one of the + // boundaries for the selected node. We want to check whether the + // node is actually inside the region, at least partially + Node* node = coreObject->node(); + Node* lastDescendant = node->lastDescendant(); + ExceptionCode ec = 0; + return (range->intersectsNode(node, ec) + && (range->endContainer() != node || range->endOffset()) + && (range->startContainer() != lastDescendant || range->startOffset() != lastOffsetInNode(lastDescendant))); +} + +static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, VisibleSelection& selection, gint& startOffset, gint& endOffset) +{ + if (!coreObject->isAccessibilityRenderObject()) + return; + + // Early return if the selection doesn't affect the selected node + if (!selectionBelongsToObject(coreObject, selection)) + return; + + // We need to find the exact start and end positions in the + // selected node that intersects the selection, to later on get + // the right values for the effective start and end offsets + ExceptionCode ec = 0; + Position nodeRangeStart; + Position nodeRangeEnd; + Node* node = coreObject->node(); + RefPtr<Range> selRange = selection.toNormalizedRange(); + + // If the selection affects the selected node and its first + // possible position is also in the selection, we must set + // nodeRangeStart to that position, otherwise to the selection's + // start position (it would belong to the node anyway) + Node* firstLeafNode = node->firstDescendant(); + if (selRange->isPointInRange(firstLeafNode, 0, ec)) + nodeRangeStart = firstPositionInNode(firstLeafNode); + else + nodeRangeStart = selRange->startPosition(); + + // If the selection affects the selected node and its last + // possible position is also in the selection, we must set + // nodeRangeEnd to that position, otherwise to the selection's + // end position (it would belong to the node anyway) + Node* lastLeafNode = node->lastDescendant(); + if (selRange->isPointInRange(lastLeafNode, lastOffsetInNode(lastLeafNode), ec)) + nodeRangeEnd = lastPositionInNode(lastLeafNode); + else + nodeRangeEnd = selRange->endPosition(); + + // Set values for start and end offsets + RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd); + startOffset = nodeRangeStart.offsetInContainerNode(); + endOffset = startOffset + TextIterator::rangeLength(nodeRange.get()); } static gint webkit_accessible_text_get_n_selections(AtkText* text) @@ -1351,6 +1408,10 @@ static gint webkit_accessible_text_get_n_selections(AtkText* text) AccessibilityObject* coreObject = core(text); VisibleSelection selection = coreObject->selection(); + // Only range selections are needed for the purpose of this method + if (!selection.isRange()) + return 0; + // We don't support multiple selections for now, so there's only // two possibilities // Also, we don't want to do anything if the selection does not @@ -1360,25 +1421,26 @@ static gint webkit_accessible_text_get_n_selections(AtkText* text) return !selectionBelongsToObject(coreObject, selection) || selection.isNone() ? 0 : 1; } -static gchar* webkit_accessible_text_get_selection(AtkText* text, gint selection_num, gint* start_offset, gint* end_offset) +static gchar* webkit_accessible_text_get_selection(AtkText* text, gint selectionNum, gint* startOffset, gint* endOffset) { - AccessibilityObject* coreObject = core(text); - VisibleSelection selection = coreObject->selection(); + // Default values, unless the contrary is proved + *startOffset = *endOffset = 0; // WebCore does not support multiple selection, so anything but 0 does not make sense for now. - // Also, we don't want to do anything if the selection does not - // belong to the currently selected object. We have to check since - // there's no way to get the selection for a given object, only - // the global one (the API is a bit confusing) - if (selection_num != 0 || !selectionBelongsToObject(coreObject, selection)) { - *start_offset = *end_offset = 0; + if (selectionNum) return 0; - } - *start_offset = selection.start().offsetInContainerNode(); - *end_offset = selection.end().offsetInContainerNode(); + // Get the offsets of the selection for the selected object + AccessibilityObject* coreObject = core(text); + VisibleSelection selection = coreObject->selection(); + getSelectionOffsetsForObject(coreObject, selection, *startOffset, *endOffset); + + // Return 0 instead of "", as that's the expected result for + // this AtkText method when there's no selection + if (*startOffset == *endOffset) + return 0; - return webkit_accessible_text_get_text(text, *start_offset, *end_offset); + return webkit_accessible_text_get_text(text, *startOffset, *endOffset); } static gboolean webkit_accessible_text_add_selection(AtkText* text, gint start_offset, gint end_offset) @@ -1387,32 +1449,51 @@ static gboolean webkit_accessible_text_add_selection(AtkText* text, gint start_o return FALSE; } -static gboolean webkit_accessible_text_remove_selection(AtkText* text, gint selection_num) +static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selectionNum, gint startOffset, gint endOffset) { - notImplemented(); - return FALSE; + // WebCore does not support multiple selection, so anything but 0 does not make sense for now. + if (selectionNum) + 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) + startOffset = textCount; + if (endOffset < 0 || endOffset > textCount) + endOffset = textCount; + + AccessibilityObject* coreObject = core(text); + PlainTextRange textRange(startOffset, endOffset - startOffset); + VisiblePositionRange range = coreObject->visiblePositionRangeForRange(textRange); + coreObject->setSelectedVisiblePositionRange(range); + + return TRUE; } -static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selection_num, gint start_offset, gint end_offset) +static gboolean webkit_accessible_text_remove_selection(AtkText* text, gint selectionNum) { - notImplemented(); - return FALSE; + // WebCore does not support multiple selection, so anything but 0 does not make sense for now. + if (selectionNum) + return FALSE; + + // Do nothing if current selection doesn't belong to the object + if (!webkit_accessible_text_get_n_selections(text)) + return FALSE; + + // Set a new 0-sized selection to the caret position, in order + // to simulate selection removal (GAIL style) + gint caretOffset = webkit_accessible_text_get_caret_offset(text); + return webkit_accessible_text_set_selection(text, selectionNum, caretOffset, caretOffset); } static gboolean webkit_accessible_text_set_caret_offset(AtkText* text, gint offset) { AccessibilityObject* coreObject = core(text); - // FIXME: We need to reimplement visiblePositionRangeForRange here - // because the actual function checks the offset is within the - // boundaries of text().length(), but text() only works for text - // controls... - VisiblePosition startPosition = coreObject->visiblePositionForIndex(offset); - startPosition.setAffinity(DOWNSTREAM); - VisiblePosition endPosition = coreObject->visiblePositionForIndex(offset); - VisiblePositionRange range = VisiblePositionRange(startPosition, endPosition); - + PlainTextRange textRange(offset, 0); + VisiblePositionRange range = coreObject->visiblePositionRangeForRange(textRange); coreObject->setSelectedVisiblePositionRange(range); + return TRUE; } diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm index 859a799..e3e28d7 100644 --- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm +++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm @@ -1972,11 +1972,11 @@ static NSString* roleValueToNSString(AccessibilityRole value) - (BOOL)accessibilityIsIgnored { if (!m_object) - return nil; + return YES; m_object->updateBackingStore(); if (!m_object) - return nil; + return YES; if (m_object->isAttachment()) return [[self attachmentView] accessibilityIsIgnored]; @@ -2354,7 +2354,10 @@ static RenderObject* rendererForView(NSView* view) // dispatch if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker); - return m_object->accessibilityObjectForPosition(visiblePos)->wrapper(); + AccessibilityObject* axObject = m_object->accessibilityObjectForPosition(visiblePos); + if (!axObject) + return nil; + return axObject->wrapper(); } if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) { |