Bug 1187995 - Add proxy handling to mozTextAccessible r=tbsaunde

This commit is contained in:
Lorien Hu 2015-08-05 21:55:13 -04:00
parent 1a99cebbe6
commit 49bce20292
6 changed files with 206 additions and 48 deletions

View File

@ -10,6 +10,7 @@
#include "ProxyAccessible.h"
#include "Relation.h"
#include "HyperTextAccessible-inl.h"
#include "TextLeafAccessible.h"
#include "ImageAccessible.h"
#include "TableAccessible.h"
#include "TableCellAccessible.h"
@ -97,6 +98,13 @@ DocAccessibleChild::IdToHyperTextAccessible(const uint64_t& aID) const
return acc && acc->IsHyperText() ? acc->AsHyperText() : nullptr;
}
TextLeafAccessible*
DocAccessibleChild::IdToTextLeafAccessible(const uint64_t& aID) const
{
Accessible* acc = IdToAccessible(aID);
return acc && acc->IsTextLeaf() ? acc->AsTextLeaf() : nullptr;
}
ImageAccessible*
DocAccessibleChild::IdToImageAccessible(const uint64_t& aID) const
{
@ -342,6 +350,14 @@ DocAccessibleChild::RecvARIARoleAtom(const uint64_t& aID, nsString* aRole)
return true;
}
bool
DocAccessibleChild::RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
*aLineNumber = acc && acc->IsTextRole() ? acc->CaretLineNumber() : 0;
return true;
}
bool
DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
{
@ -636,6 +652,17 @@ DocAccessibleChild::RecvScrollSubstringToPoint(const uint64_t& aID,
return true;
}
bool
DocAccessibleChild::RecvText(const uint64_t& aID,
nsString* aText)
{
TextLeafAccessible* acc = IdToTextLeafAccessible(aID);
if (acc) {
*aText = acc->Text();
}
return true;
}
bool
DocAccessibleChild::RecvReplaceText(const uint64_t& aID,

View File

@ -15,6 +15,7 @@ namespace mozilla {
namespace a11y {
class Accessible;
class HyperTextAccessible;
class TextLeafAccessible;
class ImageAccessible;
class TableAccessible;
class TableCellAccessible;
@ -96,6 +97,8 @@ public:
virtual bool RecvAttributes(const uint64_t& aID,
nsTArray<Attribute> *aAttributes) override;
virtual bool RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
override;
virtual bool RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
override;
virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset,
@ -194,6 +197,9 @@ public:
const int32_t& aX,
const int32_t& aY) override;
virtual bool RecvText(const uint64_t& aID,
nsString* aText) override;
virtual bool RecvReplaceText(const uint64_t& aID,
const nsString& aText) override;
@ -460,6 +466,7 @@ private:
Accessible* IdToAccessibleLink(const uint64_t& aID) const;
Accessible* IdToAccessibleSelect(const uint64_t& aID) const;
HyperTextAccessible* IdToHyperTextAccessible(const uint64_t& aID) const;
TextLeafAccessible* IdToTextLeafAccessible(const uint64_t& aID) const;
ImageAccessible* IdToImageAccessible(const uint64_t& aID) const;
TableCellAccessible* IdToTableCellAccessible(const uint64_t& aID) const;
TableAccessible* IdToTableAccessible(const uint64_t& aID) const;

View File

@ -89,6 +89,7 @@ child:
// AccessibleText
// TextSubstring is getText in IDL.
prio(high) sync CaretLineNumber(uint64_t aID) returns(int32_t aLineNumber);
prio(high) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
prio(high) sync SetCaretOffset(uint64_t aID, int32_t aOffset) returns (bool aValid);
prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
@ -135,6 +136,7 @@ child:
uint32_t aCoordinateType,
int32_t aX, int32_t aY);
prio(high) sync Text(uint64_t aID) returns(nsString aText);
prio(high) sync ReplaceText(uint64_t aID, nsString aText);
prio(high) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition)
returns(bool aValid);

View File

@ -191,6 +191,14 @@ ProxyAccessible::ARIARoleAtom() const
return NS_GetStaticAtom(role);
}
int32_t
ProxyAccessible::CaretLineNumber()
{
int32_t line = -1;
unused << mDoc->SendCaretOffset(mID, &line);
return line;
}
int32_t
ProxyAccessible::CaretOffset()
{
@ -371,6 +379,12 @@ ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
aCoordinateType, aX, aY);
}
void
ProxyAccessible::Text(nsString* aText)
{
unused << mDoc->SendText(mID, aText);
}
void
ProxyAccessible::ReplaceText(const nsString& aText)
{

View File

@ -9,6 +9,7 @@
#include "mozilla/a11y/Role.h"
#include "nsIAccessibleText.h"
#include "nsIAccessibleTypes.h"
#include "Accessible.h"
#include "nsString.h"
#include "nsTArray.h"
@ -126,6 +127,7 @@ public:
nsIAtom* ARIARoleAtom() const;
int32_t CaretLineNumber();
int32_t CaretOffset();
bool SetCaretOffset(int32_t aOffset);
@ -160,7 +162,7 @@ public:
void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType);
uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType);
@ -188,6 +190,8 @@ public:
uint32_t aCoordinateType,
int32_t aX, int32_t aY);
void Text(nsString* aText);
void ReplaceText(const nsString& aText);
bool InsertText(const nsString& aText, int32_t aPosition);

View File

@ -114,13 +114,23 @@ ToNSString(id aValue)
return [self text];
}
AccessibleWrap* accWrap = [self getGeckoAccessible];
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if ([attribute isEqualToString:@"AXRequired"]) {
return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
}
if ([attribute isEqualToString:@"AXRequired"])
return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
if ([attribute isEqualToString:@"AXInvalid"]) {
return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
}
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
if ([attribute isEqualToString:@"AXRequired"]) {
return [NSNumber numberWithBool:!!(proxy->State() & states::REQUIRED)];
}
if ([attribute isEqualToString:@"AXInvalid"])
return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
if ([attribute isEqualToString:@"AXInvalid"]) {
return [NSNumber numberWithBool:!!(proxy->State() & states::INVALID)];
}
}
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
return [self visibleCharacterRange];
@ -157,8 +167,10 @@ ToNSString(id aValue)
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc)
if (!textAcc && !proxy)
return nil;
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
@ -206,7 +218,12 @@ ToNSString(id aValue)
int32_t start = range.location;
int32_t end = start + range.length;
nsIntRect bounds = textAcc->TextBounds(start, end);
nsIntRect bounds;
if (textAcc) {
bounds = textAcc->TextBounds(start, end);
} else if (proxy) {
bounds = proxy->TextBounds(start, end);
}
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
}
@ -240,8 +257,10 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc)
if (!textAcc && !proxy)
return;
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
@ -256,12 +275,19 @@ ToNSString(id aValue)
return;
int32_t start = 0, end = 0;
textAcc->SelectionBoundsAt(0, &start, &end);
textAcc->DeleteText(start, end - start);
nsString text;
nsCocoaUtils::GetStringForNSString(stringValue, text);
textAcc->InsertText(text, start);
if (textAcc) {
textAcc->SelectionBoundsAt(0, &start, &end);
textAcc->DeleteText(start, end - start);
nsCocoaUtils::GetStringForNSString(stringValue, text);
textAcc->InsertText(text, start);
} else if (proxy) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
proxy->DeleteText(start, end - start);
nsCocoaUtils::GetStringForNSString(stringValue, text);
proxy->InsertText(text, start);
}
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
@ -269,8 +295,13 @@ ToNSString(id aValue)
if (!ToNSRange(value, &range))
return;
textAcc->SetSelectionBoundsAt(0, range.location,
if (textAcc) {
textAcc->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
} else if (proxy) {
proxy->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
}
return;
}
@ -279,8 +310,13 @@ ToNSString(id aValue)
if (!ToNSRange(value, &range))
return;
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
if (textAcc) {
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
} else if (proxy) {
proxy->ScrollSubstringTo(range.location, range.location + range.length,
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
}
return;
}
@ -311,6 +347,9 @@ ToNSString(id aValue)
if (textAcc)
return (accWrap->State() & states::READONLY) == 0;
if (ProxyAccessible* proxy = [self getProxyAccessible])
return (proxy->State() & states::READONLY) == 0;
return NO;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
@ -320,8 +359,13 @@ ToNSString(id aValue)
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
int32_t lineNumber = textAcc ?
textAcc->CaretLineNumber() - 1 : -1;
int32_t lineNumber = -1;
if (textAcc) {
lineNumber = textAcc->CaretLineNumber() - 1;
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
lineNumber = proxy->CaretLineNumber() - 1;
}
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
}
@ -332,10 +376,13 @@ ToNSString(id aValue)
AccessibleWrap* accWrap = [self getGeckoAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
nsString text;
nsCocoaUtils::GetStringForNSString(aNewString, text);
if (textAcc) {
nsString text;
nsCocoaUtils::GetStringForNSString(aNewString, text);
textAcc->ReplaceText(text);
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
proxy->ReplaceText(text);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -344,8 +391,9 @@ ToNSString(id aValue)
- (NSString*)text
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!accWrap || !textAcc)
if (!textAcc && !proxy)
return nil;
// A password text field returns an empty value
@ -353,7 +401,12 @@ ToNSString(id aValue)
return @"";
nsAutoString text;
textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
if (textAcc) {
textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
} else if (proxy) {
proxy->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
}
return nsCocoaUtils::ToNSString(text);
}
@ -362,11 +415,12 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!accWrap || !textAcc)
if (!textAcc && !proxy)
return 0;
return textAcc ? textAcc->CharacterCount() : 0;
return textAcc ? textAcc->CharacterCount() : proxy->CharacterCount();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
@ -376,13 +430,19 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
int32_t start = 0, end = 0;
if (textAcc) {
int32_t start = 0, end = 0;
textAcc->SelectionBoundsAt(0, &start, &end);
return (end - start);
} else if (proxy) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
}
return 0;
return (end - start);
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
@ -392,17 +452,23 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return nil;
int32_t start = 0, end = 0;
nsAutoString selText;
if (textAcc) {
int32_t start = 0, end = 0;
textAcc->SelectionBoundsAt(0, &start, &end);
if (start != end) {
nsAutoString selText;
textAcc->TextSubstring(start, end, selText);
return nsCocoaUtils::ToNSString(selText);
}
} else if (proxy) {
proxy->SelectionBoundsAt(0, selText, &start, &end);
}
return nil;
return nsCocoaUtils::ToNSString(selText);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@ -412,20 +478,35 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (textAcc) {
int32_t start = 0;
int32_t end = 0;
int32_t count = textAcc->SelectionCount();
int32_t start = 0;
int32_t end = 0;
int32_t count = 0;
if (textAcc) {
count = textAcc->SelectionCount();
if (count) {
textAcc->SelectionBoundsAt(0, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
start = textAcc->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
if (proxy) {
count = proxy->SelectionCount();
if (count) {
nsString data;
proxy->SelectionBoundsAt(0, data, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
start = proxy->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
return [NSValue valueWithRange:NSMakeRange(0, 0)];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
@ -436,10 +517,14 @@ ToNSString(id aValue)
// XXX this won't work with Textarea and such as we actually don't give
// the visible character range.
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc && !proxy)
return 0;
return [NSValue valueWithRange:
NSMakeRange(0, textAcc ?
textAcc->CharacterCount() : 0)];
textAcc->CharacterCount() : proxy->CharacterCount())];
}
- (void)valueDidChange
@ -463,13 +548,20 @@ ToNSString(id aValue)
NS_PRECONDITION(range, "no range");
AccessibleWrap* accWrap = [self getGeckoAccessible];
ProxyAccessible* proxy = [self getProxyAccessible];
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
if (!textAcc)
if (!textAcc && !proxy)
return nil;
nsAutoString text;
textAcc->TextSubstring(range->location,
range->location + range->length, text);
if (textAcc) {
textAcc->TextSubstring(range->location,
range->location + range->length, text);
} else if (proxy) {
proxy->TextSubstring(range->location,
range->location + range->length, text);
}
return nsCocoaUtils::ToNSString(text);
}
@ -501,20 +593,32 @@ ToNSString(id aValue)
- (NSString*)text
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
if (!accWrap)
return nil;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
}
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
nsString text;
proxy->Text(&text);
return nsCocoaUtils::ToNSString(text);
}
return nil;
}
- (long)textLength
{
AccessibleWrap* accWrap = [self getGeckoAccessible];
if (!accWrap)
return 0;
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
return accWrap->AsTextLeaf()->Text().Length();
}
return accWrap->AsTextLeaf()->Text().Length();
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
nsString text;
proxy->Text(&text);
return text.Length();
}
return 0;
}
@end