Backed out changeset e29fc477ab4d, bug 576777, because of perma-orange in test_text.html.

This commit is contained in:
Markus Stange 2010-08-05 14:55:15 +02:00
parent 1afc4fee04
commit 59e3f99f2f
9 changed files with 121 additions and 264 deletions

View File

@ -92,7 +92,7 @@ AccCollector::EnsureNGetObject(PRUint32 aIndex)
if (!mFilterFunc(child))
continue;
AppendObject(child);
mObjects.AppendElement(child);
if (mObjects.Length() - 1 == aIndex)
return mObjects[aIndex];
}
@ -109,39 +109,10 @@ AccCollector::EnsureNGetIndex(nsAccessible* aAccessible)
if (!mFilterFunc(child))
continue;
AppendObject(child);
mObjects.AppendElement(child);
if (child == aAccessible)
return mObjects.Length() - 1;
}
return -1;
}
void
AccCollector::AppendObject(nsAccessible* aAccessible)
{
mObjects.AppendElement(aAccessible);
}
////////////////////////////////////////////////////////////////////////////////
// EmbeddedObjCollector
////////////////////////////////////////////////////////////////////////////////
PRInt32
EmbeddedObjCollector::GetIndexAt(nsAccessible *aAccessible)
{
if (aAccessible->mParent != mRoot)
return -1;
if (aAccessible->mIndexOfEmbeddedChild != -1)
return aAccessible->mIndexOfEmbeddedChild;
return mFilterFunc(aAccessible) ? EnsureNGetIndex(aAccessible) : -1;
}
void
EmbeddedObjCollector::AppendObject(nsAccessible* aAccessible)
{
aAccessible->mIndexOfEmbeddedChild = mObjects.Length();
mObjects.AppendElement(aAccessible);
}

View File

@ -66,7 +66,7 @@ public:
/**
* Return index of the given accessible within the collection.
*/
virtual PRInt32 GetIndexAt(nsAccessible* aAccessible);
PRInt32 GetIndexAt(nsAccessible* aAccessible);
protected:
/**
@ -79,11 +79,6 @@ protected:
*/
PRInt32 EnsureNGetIndex(nsAccessible* aAccessible);
/**
* Append the object to collection.
*/
virtual void AppendObject(nsAccessible* aAccessible);
filters::FilterFuncPtr mFilterFunc;
nsAccessible* mRoot;
PRInt32 mRootChildIdx;
@ -96,26 +91,4 @@ private:
AccCollector& operator =(const AccCollector&);
};
/**
* Collect embedded objects. Provide quick access to accessible by index and
* vice versa.
*/
class EmbeddedObjCollector : public AccCollector
{
public:
virtual ~EmbeddedObjCollector() { };
public:
virtual PRInt32 GetIndexAt(nsAccessible* aAccessible);
protected:
// Make sure it's used by nsAccessible class only.
EmbeddedObjCollector(nsAccessible* aRoot) :
AccCollector(aRoot, filters::GetEmbeddedObject) { }
virtual void AppendObject(nsAccessible* aAccessible);
friend class nsAccessible;
};
#endif

View File

@ -193,8 +193,8 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
nsAccessible::nsAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
nsAccessNodeWrap(aContent, aShell),
mParent(nsnull), mIndexInParent(-1), mChildrenFlags(eChildrenUninitialized),
mIndexOfEmbeddedChild(-1), mRoleMapEntry(nsnull)
mParent(nsnull), mAreChildrenInitialized(PR_FALSE), mIndexInParent(-1),
mRoleMapEntry(nsnull)
{
#ifdef NS_DEBUG_X
{
@ -2751,7 +2751,6 @@ nsAccessible::UnbindFromParent()
{
mParent = nsnull;
mIndexInParent = -1;
mIndexOfEmbeddedChild = -1;
mGroupInfo = nsnull;
}
@ -2764,9 +2763,8 @@ nsAccessible::InvalidateChildren()
child->UnbindFromParent();
}
mEmbeddedObjCollector = nsnull;
mChildren.Clear();
mChildrenFlags = eChildrenUninitialized;
mAreChildrenInitialized = PR_FALSE;
}
PRBool
@ -2775,9 +2773,6 @@ nsAccessible::AppendChild(nsAccessible* aChild)
if (!mChildren.AppendElement(aChild))
return PR_FALSE;
if (nsAccUtils::IsText(aChild))
mChildrenFlags = eMixedChildren;
aChild->BindToParent(this, mChildren.Length() - 1);
return PR_TRUE;
}
@ -2791,11 +2786,6 @@ nsAccessible::InsertChildAt(PRUint32 aIndex, nsAccessible* aChild)
for (PRUint32 idx = aIndex + 1; idx < mChildren.Length(); idx++)
mChildren[idx]->mIndexInParent++;
if (nsAccUtils::IsText(aChild))
mChildrenFlags = eMixedChildren;
mEmbeddedObjCollector = nsnull;
aChild->BindToParent(this, aIndex);
return PR_TRUE;
}
@ -2810,8 +2800,6 @@ nsAccessible::RemoveChild(nsAccessible* aChild)
mChildren[idx]->mIndexInParent--;
mChildren.RemoveElementAt(aChild->mIndexInParent);
mEmbeddedObjCollector = nsnull;
aChild->UnbindFromParent();
return PR_TRUE;
}
@ -2889,53 +2877,6 @@ nsAccessible::GetIndexInParent()
return mIndexInParent;
}
PRInt32
nsAccessible::GetEmbeddedChildCount()
{
if (EnsureChildren())
return -1;
if (mChildrenFlags == eMixedChildren) {
if (!mEmbeddedObjCollector)
mEmbeddedObjCollector = new EmbeddedObjCollector(this);
return mEmbeddedObjCollector ? mEmbeddedObjCollector->Count() : -1;
}
return GetChildCount();
}
nsAccessible*
nsAccessible::GetEmbeddedChildAt(PRUint32 aIndex)
{
if (EnsureChildren())
return nsnull;
if (mChildrenFlags == eMixedChildren) {
if (!mEmbeddedObjCollector)
mEmbeddedObjCollector = new EmbeddedObjCollector(this);
return mEmbeddedObjCollector ?
mEmbeddedObjCollector->GetAccessibleAt(aIndex) : nsnull;
}
return GetChildAt(aIndex);
}
PRInt32
nsAccessible::GetIndexOfEmbeddedChild(nsAccessible* aChild)
{
if (EnsureChildren())
return -1;
if (mChildrenFlags == eMixedChildren) {
if (!mEmbeddedObjCollector)
mEmbeddedObjCollector = new EmbeddedObjCollector(this);
return mEmbeddedObjCollector ?
mEmbeddedObjCollector->GetIndexAt(aChild) : -1;
}
return GetIndexOf(aChild);
}
#ifdef DEBUG
PRBool
nsAccessible::IsInCache()
@ -2971,8 +2912,7 @@ nsAccessible::TestChildCache(nsAccessible *aCachedChild)
#ifdef DEBUG
PRInt32 childCount = mChildren.Length();
if (childCount == 0) {
NS_ASSERTION(mChildrenFlags == eChildrenUninitialized,
"No children but initialized!");
NS_ASSERTION(!mAreChildrenInitialized, "No children but initialized!");
return;
}
@ -2993,15 +2933,14 @@ PRBool
nsAccessible::EnsureChildren()
{
if (IsDefunct()) {
mChildrenFlags = eChildrenUninitialized;
mAreChildrenInitialized = PR_FALSE;
return PR_TRUE;
}
if (mChildrenFlags != eChildrenUninitialized)
if (mAreChildrenInitialized)
return PR_FALSE;
// State is embedded children until text leaf accessible is appended.
mChildrenFlags = eEmbeddedChildren; // Prevent reentry
mAreChildrenInitialized = PR_TRUE; // Prevent reentry
CacheChildren();
return PR_FALSE;

View File

@ -53,7 +53,6 @@
#include "nsRefPtrHashtable.h"
class AccGroupInfo;
class EmbeddedObjCollector;
class nsAccessible;
class nsAccEvent;
struct nsRoleMapEntry;
@ -257,21 +256,6 @@ public:
*/
PRBool HasChildren() { return !!GetChildAt(0); }
/**
* Return embedded accessible children count.
*/
PRInt32 GetEmbeddedChildCount();
/**
* Return embedded accessible child at the given index.
*/
nsAccessible* GetEmbeddedChildAt(PRUint32 aIndex);
/**
* Return index of the given embedded accessible child.
*/
PRInt32 GetIndexOfEmbeddedChild(nsAccessible* aChild);
/**
* Return cached accessible of parent-child relatives.
*/
@ -287,7 +271,7 @@ public:
mParent->mChildren.SafeElementAt(mIndexInParent - 1, nsnull).get() : nsnull;
}
PRUint32 GetCachedChildCount() const { return mChildren.Length(); }
PRBool AreChildrenCached() const { return mChildrenFlags != eChildrenUninitialized; }
PRBool AreChildrenCached() const { return mAreChildrenInitialized; }
#ifdef DEBUG
/**
@ -459,19 +443,9 @@ protected:
// Data Members
nsRefPtr<nsAccessible> mParent;
nsTArray<nsRefPtr<nsAccessible> > mChildren;
PRBool mAreChildrenInitialized;
PRInt32 mIndexInParent;
enum ChildrenFlags {
eChildrenUninitialized = 0x00,
eMixedChildren = 0x01,
eEmbeddedChildren = 0x02
};
ChildrenFlags mChildrenFlags;
nsAutoPtr<EmbeddedObjCollector> mEmbeddedObjCollector;
PRInt32 mIndexOfEmbeddedChild;
friend class EmbeddedObjCollector;
nsAutoPtr<AccGroupInfo> mGroupInfo;
friend class AccGroupInfo;

View File

@ -191,7 +191,7 @@ nsOuterDocAccessible::InvalidateChildren()
// then allow nsAccDocManager to handle this case since the document
// accessible is created and appended as a child when it's requested.
mChildrenFlags = eChildrenUninitialized;
mAreChildrenInitialized = PR_FALSE;
}
PRBool

View File

@ -1091,8 +1091,11 @@ nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
NS_ADDREF(*aAttributes = attributes);
}
nsAccessible* accAtOffset = GetChildAtOffset(aOffset);
if (!accAtOffset) {
PRInt32 offsetAccIdx = -1;
PRInt32 startOffset = 0, endOffset = 0;
nsAccessible *offsetAcc = GetAccessibleAtOffset(aOffset, &offsetAccIdx,
&startOffset, &endOffset);
if (!offsetAcc) {
// Offset 0 is correct offset when accessible has empty text. Include
// default attributes if they were requested, otherwise return empty set.
if (aOffset == 0) {
@ -1105,21 +1108,17 @@ nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
return NS_ERROR_INVALID_ARG;
}
PRInt32 accAtOffsetIdx = accAtOffset->GetIndexInParent();
PRInt32 startOffset = GetChildOffset(accAtOffsetIdx);
PRInt32 endOffset = GetChildOffset(accAtOffsetIdx + 1);
PRInt32 offsetInAcc = aOffset - startOffset;
nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
accAtOffsetIdx);
nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, offsetAcc, offsetAccIdx);
nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Compute spelling attributes on text accessible only.
nsIFrame *offsetFrame = accAtOffset->GetFrame();
nsIFrame *offsetFrame = offsetAcc->GetFrame();
if (offsetFrame && offsetFrame->GetType() == nsAccessibilityAtoms::textFrame) {
nsCOMPtr<nsIDOMNode> node = accAtOffset->GetDOMNode();
nsCOMPtr<nsIDOMNode> node = offsetAcc->GetDOMNode();
PRInt32 nodeOffset = 0;
nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
@ -1370,7 +1369,7 @@ nsHyperTextAccessible::GetLinkIndex(nsIAccessibleHyperLink* aLink,
}
NS_IMETHODIMP
nsHyperTextAccessible::GetLinkIndexAtOffset(PRInt32 aOffset,
nsHyperTextAccessible::GetLinkIndexAtOffset(PRInt32 aCharIndex,
PRInt32* aLinkIndex)
{
NS_ENSURE_ARG_POINTER(aLinkIndex);
@ -1379,7 +1378,29 @@ nsHyperTextAccessible::GetLinkIndexAtOffset(PRInt32 aOffset,
if (IsDefunct())
return NS_ERROR_FAILURE;
*aLinkIndex = GetLinkIndexAtOffset(aOffset);
PRInt32 characterCount = 0;
PRInt32 linkIndex = 0;
PRInt32 childCount = GetChildCount();
for (PRInt32 childIdx = 0;
childIdx < childCount && characterCount <= aCharIndex; childIdx++) {
nsAccessible *childAcc = mChildren[childIdx];
PRUint32 role = nsAccUtils::Role(childAcc);
if (role == nsIAccessibleRole::ROLE_TEXT_LEAF ||
role == nsIAccessibleRole::ROLE_STATICTEXT) {
characterCount += nsAccUtils::TextLength(childAcc);
}
else {
if (characterCount ++ == aCharIndex) {
*aLinkIndex = linkIndex;
break;
}
if (role != nsIAccessibleRole::ROLE_WHITESPACE) {
++ linkIndex;
}
}
}
return NS_OK;
}
@ -2022,6 +2043,7 @@ nsHyperTextAccessible::ScrollSubstringToPoint(PRInt32 aStartIndex,
void
nsHyperTextAccessible::InvalidateChildren()
{
mLinks = nsnull;
mOffsets.Clear();
nsAccessibleWrap::InvalidateChildren();
@ -2088,77 +2110,70 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
// nsHyperTextAccessible public
PRInt32
nsHyperTextAccessible::GetChildOffset(PRUint32 aChildIndex,
nsHyperTextAccessible::GetChildOffset(nsAccessible* aChild,
PRBool aInvalidateAfter)
{
if (aChildIndex == 0)
return aChildIndex;
PRInt32 index = GetIndexOf(aChild);
if (index == -1 || index == 0)
return index;
PRInt32 count = mOffsets.Length() - aChildIndex;
PRInt32 count = mOffsets.Length() - index;
if (count > 0) {
if (aInvalidateAfter)
mOffsets.RemoveElementsAt(aChildIndex, count);
mOffsets.RemoveElementsAt(index, count);
return mOffsets[aChildIndex - 1];
return mOffsets[index - 1];
}
PRUint32 lastOffset = mOffsets.IsEmpty() ?
0 : mOffsets[mOffsets.Length() - 1];
EnsureChildren();
while (mOffsets.Length() < aChildIndex) {
while (mOffsets.Length() < index) {
nsAccessible* child = mChildren[mOffsets.Length()];
lastOffset += nsAccUtils::TextLength(child);
mOffsets.AppendElement(lastOffset);
}
return mOffsets[aChildIndex - 1];
return mOffsets[index - 1];
}
PRInt32
nsHyperTextAccessible::GetChildIndexAtOffset(PRUint32 aOffset)
{
PRUint32 lastOffset = 0;
PRUint32 offsetCount = mOffsets.Length();
if (offsetCount > 0) {
lastOffset = mOffsets[offsetCount - 1];
if (aOffset < lastOffset) {
PRUint32 low = 0, high = offsetCount;
while (high > low) {
PRUint32 mid = (high + low) >> 1;
if (mOffsets[mid] == aOffset)
return mid < offsetCount - 1 ? mid + 1 : mid;
if (mOffsets[mid] < aOffset)
low = mid + 1;
else
high = mid;
}
if (high == offsetCount)
return -1;
return low < offsetCount - 1 ? low + 1 : low;
}
}
PRUint32 childCount = GetChildCount();
while (mOffsets.Length() < childCount) {
nsAccessible* child = GetChildAt(mOffsets.Length());
lastOffset += nsAccUtils::TextLength(child);
mOffsets.AppendElement(lastOffset);
if (aOffset < lastOffset)
return mOffsets.Length() - 1;
}
if (aOffset == lastOffset)
return mOffsets.Length() - 1;
return -1;
}
////////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible protected
AccCollector*
nsHyperTextAccessible::GetLinkCollector()
{
if (IsDefunct())
return nsnull;
if (!mLinks)
mLinks = new AccCollector(this, filters::GetEmbeddedObject);
return mLinks;
}
nsAccessible *
nsHyperTextAccessible::GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
PRInt32 *aStartOffset,
PRInt32 *aEndOffset)
{
PRInt32 startOffset = 0, endOffset = 0;
PRInt32 childCount = GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *child = mChildren[childIdx];
endOffset += nsAccUtils::TextLength(child);
if (endOffset > aOffset) {
*aStartOffset = startOffset;
*aEndOffset = endOffset;
*aAccIdx = childIdx;
return child;
}
startOffset = endOffset;
}
return nsnull;
}
nsresult
nsHyperTextAccessible::GetDOMPointByFrameOffset(nsIFrame *aFrame,
PRInt32 aOffset,

View File

@ -106,7 +106,8 @@ public:
*/
inline PRUint32 GetLinkCount()
{
return GetEmbeddedChildCount();
AccCollector* links = GetLinkCollector();
return links ? links->Count() : 0;
}
/**
@ -114,7 +115,8 @@ public:
*/
inline nsAccessible* GetLinkAt(PRUint32 aIndex)
{
return GetEmbeddedChildAt(aIndex);
AccCollector* links = GetLinkCollector();
return links ? links->GetAccessibleAt(aIndex) : nsnull;
}
/**
@ -122,16 +124,8 @@ public:
*/
inline PRInt32 GetLinkIndex(nsAccessible* aLink)
{
return GetIndexOfEmbeddedChild(aLink);
}
/**
* Return link accessible at the given text offset.
*/
inline PRInt32 GetLinkIndexAtOffset(PRUint32 aOffset)
{
nsAccessible* child = GetChildAtOffset(aOffset);
return GetLinkIndex(child);
AccCollector* links = GetLinkCollector();
return links ? links->GetIndexAt(aLink) : -1;
}
/**
@ -193,46 +187,23 @@ public:
PRInt32 *aEndOffset);
/**
* Return text offset of the given child accessible within hypertext
* accessible.
* Return text offset the given child accessible of hypertext accessible.
*
* @param aChild [in] accessible child to get text offset for
* @param aInvalidateAfter [in, optional] indicates whether invalidate
* cached offsets for next siblings of the child
*/
PRInt32 GetChildOffset(nsAccessible* aChild,
PRBool aInvalidateAfter = PR_FALSE)
{
PRInt32 index = GetIndexOf(aChild);
return index == -1 ? -1 : GetChildOffset(index, aInvalidateAfter);
}
/**
* Return text offset for the child accessible index.
*/
PRInt32 GetChildOffset(PRUint32 aChildIndex,
PRBool aInvalidateAfter = PR_FALSE);
/**
* Return child accessible at the given text offset.
*
* @param aOffset [in] the given text offset
*/
PRInt32 GetChildIndexAtOffset(PRUint32 aOffset);
/**
* Return child accessible at the given text offset.
*
* @param aOffset [in] the given text offset
*/
nsAccessible* GetChildAtOffset(PRUint32 aOffset)
{
return GetChildAt(GetChildIndexAtOffset(aOffset));
}
protected:
// nsHyperTextAccessible
/**
* Return link collection, create it if necessary.
*/
AccCollector* GetLinkCollector();
/*
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
* @param aType, eGetBefore, eGetAt, eGetAfter
@ -328,6 +299,18 @@ protected:
*/
PRInt32 GetCaretLineNumber();
/**
* Return an accessible at the given hypertext offset.
*
* @param aOffset [out] the given hypertext offset
* @param aAccIdx [out] child index of returned accessible
* @param aStartOffset [out] start hypertext offset of returned accessible
* @param aEndOffset [out] end hypertext offset of returned accessible
*/
nsAccessible *GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
PRInt32 *aStartOffset,
PRInt32 *aEndOffset);
// Helpers
nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
nsIAccessible *aAccessible,

View File

@ -117,11 +117,16 @@ CAccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long *aHyperlinkIndex)
__try {
*aHyperlinkIndex = 0;
nsRefPtr<nsHyperTextAccessible> hyperAcc(do_QueryObject(this));
nsCOMPtr<nsIAccessibleHyperText> hyperAcc(do_QueryObject(this));
if (!hyperAcc)
return E_FAIL;
*aHyperlinkIndex = hyperAcc->GetLinkIndexAtOffset(aCharIndex);
PRInt32 index = 0;
nsresult rv = hyperAcc->GetLinkIndexAtOffset(aCharIndex, &index);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aHyperlinkIndex = index;
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -428,10 +428,7 @@
ID = "area14";
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
// XXX: While we expose text leaf accessibles for placeholder we grab its
// style, bug 545817.
attrs = { color: "rgb(109, 109, 109)" };
attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
//////////////////////////////////////////////////////////////////////////