зеркало из https://github.com/mozilla/pjs.git
Bug 346730. List bullets not exposed. Also, expose content generated frames within nsIAccessibleText. r=ginn.chen
This commit is contained in:
Родитель
d02c93cc4d
Коммит
ebe9a9e97b
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче