Bug 346730. List bullets not exposed. Also, expose content generated frames within nsIAccessibleText. r=ginn.chen

This commit is contained in:
aaronleventhal%moonset.net 2006-08-17 13:21:41 +00:00
Родитель d02c93cc4d
Коммит ebe9a9e97b
6 изменённых файлов: 62 добавлений и 74 удалений

Просмотреть файл

@ -45,7 +45,7 @@ interface nsIFrame;
interface nsObjectFrame;
interface nsIContent;
[scriptable, uuid(e9f2dd1f-5660-4084-bc5d-9e86e0647232)]
[scriptable, uuid(7b2dc92f-bd14-4f0c-bdff-1caa0621fea5)]
interface nsIAccessibilityService : nsIAccessibleRetrieval
{
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
@ -56,7 +56,7 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
nsIAccessible createHyperTextAccessible(in nsISupports aFrame);
nsIAccessible createHTMLBRAccessible(in nsISupports aFrame);
nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame);
nsIAccessible createHTMLAccessibleByMarkup(in nsISupports aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode, in AString aRole);
[noscript] nsIAccessible createHTMLAccessibleByMarkup(in nsIFrame aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode, in AString aRole);
nsIAccessible createHTMLLIAccessible(in nsISupports aFrame, in nsISupports aBulletFrame, in AString aBulletText);
nsIAccessible createHTMLCheckboxAccessible(in nsISupports aFrame);
nsIAccessible createHTMLComboboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);

Просмотреть файл

@ -422,14 +422,12 @@ nsAccessibilityService::CreateHTMLButtonAccessible(nsISupports *aFrame, nsIAcces
}
nsresult
nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame,
nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
nsIWeakReference *aWeakShell,
nsIDOMNode *aNode,
const nsAString& aRole,
nsIAccessible **aAccessible)
{
// aFrame type was generic, we'll use the DOM to decide
// if and what kind of accessible object is needed.
// This method assumes we're in an HTML namespace.
*aAccessible = nsnull;
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
@ -444,9 +442,9 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame,
*aAccessible = new nsHTMLListAccessible(aNode, aWeakShell);
}
else if (tag == nsAccessibilityAtoms::a) {
*aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell, NS_STATIC_CAST(nsIFrame*, aFrame));
*aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell, aFrame);
}
else if (tag == nsAccessibilityAtoms::li) {
else if (tag == nsAccessibilityAtoms::li && aFrame->GetType() != nsAccessibilityAtoms::blockFrame) {
// Normally this is created by the list item frame which knows about the bullet frame
// However, in this case the list item must have been styled using display: foo
*aAccessible = new nsHTMLLIAccessible(aNode, aWeakShell, nsnull, EmptyString());
@ -1030,7 +1028,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
// Please leave this in for now, it's a convenient debugging method
nsAutoString name;
aNode->GetLocalName(name);
if (name.LowerCaseEqualsLiteral("table"))
if (name.LowerCaseEqualsLiteral("h1"))
printf("## aaronl debugging tag name\n");
nsAutoString attrib;
@ -1247,15 +1245,16 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
// If no accessible, see if we need to create a generic accessible because
// of some property that makes this object interesting
if (!newAcc &&
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
// correspond to the doc accessible and will be created in any case
if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() &&
(content->IsFocusable() ||
content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::onclick) ||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::describedby) ||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::labelledby) ||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::required) ||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::invalid) ||
// The role from a <body> or doc element is already exposed in nsDocAccessible
(content->Tag() != nsAccessibilityAtoms::body && content->GetParent() && !role.IsEmpty()))) {
!role.IsEmpty())) {
// This content is focusable or has an interesting dynamic content accessibility property.
// If it's interesting we need it in the accessibility hierarchy so that events or
// other accessibles can point to it, or so that it can hold a state, etc.

Просмотреть файл

@ -2710,12 +2710,8 @@ nsresult nsAccessible::GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset)
PRInt32 characterCount = 0;
while (NextChild(accessible)) {
if (Role(accessible) == ROLE_TEXT_LEAF) {
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (frame) {
characterCount += frame->GetContent()->TextLength();
}
if (IsText(accessible)) {
characterCount += TextLength(accessible);
}
else if (accessible == this) {
*aStartOffset = characterCount;
@ -2730,3 +2726,25 @@ nsresult nsAccessible::GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset)
return NS_ERROR_FAILURE;
}
PRInt32 nsAccessible::TextLength(nsIAccessible *aAccessible)
{
if (!IsText(aAccessible)) {
return 1;
}
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(aAccessible));
nsIFrame *frame = accessNode->GetFrame();
if (!frame) {
return 0;
}
PRInt32 textLength = frame->GetContent()->TextLength();
if (!textLength) {
// This is exception to the frame owns the text.
// The only known case where this occurs is for list bullets
// We could do this for all accessibles but it's not as performant
// as dealing with nsIContent directly
nsAutoString childText;
aAccessible->GetName(childText);
textLength = childText.Length();
}
return textLength;
}

Просмотреть файл

@ -145,7 +145,9 @@ public:
static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state); return state; }
static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role; aAcc->GetFinalRole(&role); return role; }
static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != ROLE_TEXT_LEAF && role != ROLE_WHITESPACE; }
static PRBool IsText(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role == ROLE_TEXT_LEAF || role == ROLE_STATICTEXT; }
static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != ROLE_TEXT_LEAF && role != ROLE_WHITESPACE && role != ROLE_STATICTEXT; }
static PRInt32 TextLength(nsIAccessible *aAccessible);
protected:
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);

Просмотреть файл

@ -286,6 +286,7 @@ nsHTMLListBulletAccessible::nsHTMLListBulletAccessible(nsIDOMNode* aDomNode,
nsIWeakReference* aShell, nsIFrame *aFrame, const nsAString& aBulletText):
nsHTMLTextAccessible(aDomNode, aShell, aFrame), mWeakParent(nsnull), mBulletText(aBulletText)
{
mBulletText += ' '; // Otherwise bullets are jammed up against list text
}
NS_IMETHODIMP nsHTMLListBulletAccessible::GetUniqueID(void **aUniqueID)

Просмотреть файл

@ -297,16 +297,26 @@ nsIFrame* nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& a
if (!frame) {
continue;
}
if (Role(accessible) == ROLE_TEXT_LEAF) {
if (IsText(accessible)) {
// Avoid string copies
PRInt32 substringEndOffset = frame->GetContent()->TextLength();
nsAutoString newText;
if (!substringEndOffset) {
// This is exception to the frame owns the text.
// The only known case where this occurs is for list bullets
// We could do this for all accessibles but it's not as performant
// as dealing with nsIContent directly
accessible->GetName(newText);
substringEndOffset = newText.Length();
}
if (startOffset < substringEndOffset) {
// Our start is within this substring
// XXX Can we somehow optimize further by getting the nsTextFragment
// and use CopyTo to a PRUnichar buffer to copy it directly to
// the string?
nsAutoString newText;
if (newText.IsEmpty()) { // Don't have text yet
frame->GetContent()->AppendTextTo(newText);
}
if (startOffset > 0 || endOffset < substringEndOffset) {
// XXX the Substring operation is efficient, but does the
// reassignment to the original nsAutoString cause a copy?
@ -402,16 +412,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetCharacterCount(PRInt32 *aCharacterCount)
nsCOMPtr<nsIAccessible> accessible;
while (NextChild(accessible)) {
if (Role(accessible) == ROLE_TEXT_LEAF) {
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (frame) {
*aCharacterCount += frame->GetContent()->TextLength();
}
}
else {
++*aCharacterCount;
}
*aCharacterCount += TextLength(accessible);
}
return NS_OK;
}
@ -464,16 +465,7 @@ nsresult nsHyperTextAccessible::DOMPointToOffset(nsIDOMNode* aNode, PRInt32 aNod
// came after the last accessible child's node
nsCOMPtr<nsIAccessible> accessible;
while (NextChild(accessible) && accessible != childAccessible) {
if (Role(accessible) == ROLE_TEXT_LEAF) {
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (frame) {
*aResult += frame->GetContent()->TextLength();
}
}
else {
++ *aResult; // Embedded object or <br>
}
*aResult += TextLength(accessible);
}
return NS_OK;
}
@ -489,20 +481,11 @@ nsresult nsHyperTextAccessible::DOMPointToOffset(nsIDOMNode* aNode, PRInt32 aNod
return NS_ERROR_FAILURE;
}
nsIContent *content = frame->GetContent();
if (frame && SameCOMIdentity(content, aNode)) {
if (frame && SameCOMIdentity(frame->GetContent(), aNode)) {
return NS_OK;
}
if (Role(accessible) == ROLE_TEXT_LEAF) {
if (frame) {
*aResult += content->TextLength();
}
}
else {
++ *aResult; // Increment by 1 embedded object char
}
*aResult += TextLength(accessible);
}
return NS_ERROR_FAILURE;
@ -626,6 +609,8 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
case BOUNDARY_ATTRIBUTE_RANGE:
{
// XXX We should merge identically formatted frames
// XXX deal with static text case
// XXX deal with boundary type
nsIContent *textContent = startFrame->GetContent();
// If not text, then it's represented by an embedded object char
// (length of 1)
@ -730,20 +715,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetAttributeRange(PRInt32 aOffset, PRInt32
nsCOMPtr<nsIAccessible> accessible;
while (NextChild(accessible)) {
PRInt32 length = 1;
if (Role(accessible) == ROLE_TEXT_LEAF) {
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (frame) {
length = frame->GetContent()->TextLength();
}
else {
break;
}
}
else {
length = 1;
}
PRInt32 length = TextLength(accessible);
if (*aRangeStartOffset + length > aOffset) {
*aRangeEndOffset = *aRangeStartOffset + length;
NS_ADDREF(*aAccessibleWithAttrs = accessible);
@ -866,7 +838,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY, ns
PRBool finished = frame->GetRect().Contains(pointInFrame);
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (Role(accessible) == ROLE_TEXT_LEAF) {
if (IsText(accessible)) {
if (frame) {
if (finished) {
nsCOMPtr<nsIRenderingContext> rc;
@ -890,7 +862,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY, ns
}
return NS_ERROR_FAILURE;
}
*aOffset += frame->GetContent()->TextLength();
*aOffset += TextLength(accessible);
}
}
else if (finished) {
@ -954,12 +926,8 @@ NS_IMETHODIMP nsHyperTextAccessible::GetLinkIndex(PRInt32 aCharIndex, PRInt32 *a
while (NextChild(accessible) && characterCount <= aCharIndex) {
PRUint32 role = Role(accessible);
if (role == ROLE_TEXT_LEAF) {
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(accessible));
nsIFrame *frame = accessNode->GetFrame();
if (frame) {
characterCount += frame->GetContent()->TextLength();
}
if (role == ROLE_TEXT_LEAF || role == ROLE_STATICTEXT) {
characterCount += TextLength(accessible);
}
else {
if (characterCount ++ == aCharIndex) {