зеркало из https://github.com/mozilla/gecko-dev.git
Bug 573469 - part1, add iterator for IDRefs elements, r=fherrera, sr=neil, a=blockingFinal+
This commit is contained in:
Родитель
b17c3a82d2
Коммит
99e3c36599
|
@ -47,7 +47,6 @@
|
|||
#include "nsIDOM3Node.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
|
@ -805,67 +804,6 @@ nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
|
|||
walkUp = walkUp->GetParent();
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::GetElementsByIDRefsAttr(nsIContent *aContent, nsIAtom *aAttr,
|
||||
nsIArray **aRefElements)
|
||||
{
|
||||
*aRefElements = nsnull;
|
||||
|
||||
nsAutoString ids;
|
||||
if (!aContent->GetAttr(kNameSpaceID_None, aAttr, ids))
|
||||
return;
|
||||
|
||||
ids.CompressWhitespace(PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(aContent->GetOwnerDoc());
|
||||
NS_ASSERTION(document, "The given node is not in document!");
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentXBL> xblDocument;
|
||||
if (aContent->IsInAnonymousSubtree())
|
||||
xblDocument = do_QueryInterface(document);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> refElms = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
|
||||
while (!ids.IsEmpty()) {
|
||||
nsAutoString id;
|
||||
PRInt32 idLength = ids.FindChar(' ');
|
||||
NS_ASSERTION(idLength != 0,
|
||||
"Should not be 0 because of CompressWhitespace() call above");
|
||||
|
||||
if (idLength == kNotFound) {
|
||||
id = ids;
|
||||
ids.Truncate();
|
||||
} else {
|
||||
id = Substring(ids, 0, idLength);
|
||||
ids.Cut(0, idLength + 1);
|
||||
}
|
||||
|
||||
// If content is anonymous subtree then use "anonid" attribute to get
|
||||
// elements, otherwise search elements in DOM by ID attribute.
|
||||
nsCOMPtr<nsIDOMElement> refElement;
|
||||
if (xblDocument) {
|
||||
nsCOMPtr<nsIDOMElement> elm =
|
||||
do_QueryInterface(aContent->GetBindingParent());
|
||||
xblDocument->GetAnonymousElementByAttribute(elm,
|
||||
NS_LITERAL_STRING("anonid"),
|
||||
id,
|
||||
getter_AddRefs(refElement));
|
||||
} else {
|
||||
document->GetElementById(id, getter_AddRefs(refElement));
|
||||
}
|
||||
|
||||
if (!refElement)
|
||||
continue;
|
||||
|
||||
refElms->AppendElement(refElement, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aRefElements = refElms);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
|
||||
nsIContent *aContent,
|
||||
|
@ -1165,3 +1103,74 @@ nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// IDRefsIterator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IDRefsIterator::IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr) :
|
||||
mCurrIdx(0)
|
||||
{
|
||||
if (!aContent->IsInDoc() ||
|
||||
!aContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs))
|
||||
return;
|
||||
|
||||
if (aContent->IsInAnonymousSubtree()) {
|
||||
mXBLDocument = do_QueryInterface(aContent->GetOwnerDoc());
|
||||
mBindingParent = do_QueryInterface(aContent->GetBindingParent());
|
||||
} else {
|
||||
mDocument = aContent->GetOwnerDoc();
|
||||
}
|
||||
}
|
||||
|
||||
const nsDependentSubstring
|
||||
IDRefsIterator::NextID()
|
||||
{
|
||||
for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
|
||||
if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (mCurrIdx >= mIDs.Length())
|
||||
return nsDependentSubstring();
|
||||
|
||||
nsAString::index_type idStartIdx = mCurrIdx;
|
||||
while (++mCurrIdx < mIDs.Length()) {
|
||||
if (NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
|
||||
break;
|
||||
}
|
||||
|
||||
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
IDRefsIterator::NextElem()
|
||||
{
|
||||
while (true) {
|
||||
const nsDependentSubstring id = NextID();
|
||||
if (id.IsEmpty())
|
||||
break;
|
||||
|
||||
if (mXBLDocument) {
|
||||
// If content is anonymous subtree then use "anonid" attribute to get
|
||||
// elements, otherwise search elements in DOM by ID attribute.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> refElm;
|
||||
mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
|
||||
NS_LITERAL_STRING("anonid"),
|
||||
id,
|
||||
getter_AddRefs(refElm));
|
||||
nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
|
||||
if (refContent)
|
||||
return refContent;
|
||||
|
||||
} else {
|
||||
nsIContent* refContent = mDocument->GetElementById(id);
|
||||
if (refContent)
|
||||
return refContent;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
|
||||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIBoxObject.h"
|
||||
|
@ -304,17 +305,6 @@ public:
|
|||
static void GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
|
||||
nsAString& aLanguage);
|
||||
|
||||
/**
|
||||
* Return the array of elements the given node is referred to by its
|
||||
* IDRefs attribute.
|
||||
*
|
||||
* @param aContent [in] the given node
|
||||
* @param aAttr [in] IDRefs attribute on the given node
|
||||
* @param aRefElements [out] result array of elements
|
||||
*/
|
||||
static void GetElementsByIDRefsAttr(nsIContent *aContent, nsIAtom *aAttr,
|
||||
nsIArray **aRefElements);
|
||||
|
||||
/**
|
||||
* Return the array of elements having IDRefs that points to the given node.
|
||||
*
|
||||
|
@ -515,5 +505,34 @@ private:
|
|||
nsTArray<nsString> mNames;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to iterate through IDs or elements pointed by IDRefs attribute. Note,
|
||||
* any method used to iterate through IDs or elements moves iterator to next
|
||||
* position.
|
||||
*/
|
||||
class IDRefsIterator
|
||||
{
|
||||
public:
|
||||
IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr);
|
||||
|
||||
/**
|
||||
* Return next ID.
|
||||
*/
|
||||
const nsDependentSubstring NextID();
|
||||
|
||||
/**
|
||||
* Return next element.
|
||||
*/
|
||||
nsIContent* NextElem();
|
||||
|
||||
private:
|
||||
nsString mIDs;
|
||||
nsAString::index_type mCurrIdx;
|
||||
|
||||
nsIDocument* mDocument;
|
||||
nsCOMPtr<nsIDOMDocumentXBL> mXBLDocument;
|
||||
nsCOMPtr<nsIDOMElement> mBindingParent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -134,27 +134,16 @@ nsRelUtils::AddTargetFromIDRefsAttr(PRUint32 aRelationType,
|
|||
nsIAccessibleRelation **aRelation,
|
||||
nsIContent *aContent, nsIAtom *aAttr)
|
||||
{
|
||||
nsCOMPtr<nsIArray> refElms;
|
||||
nsCoreUtils::GetElementsByIDRefsAttr(aContent, aAttr, getter_AddRefs(refElms));
|
||||
nsresult rv = NS_OK_NO_RELATION_TARGET;
|
||||
|
||||
if (!refElms)
|
||||
return NS_OK_NO_RELATION_TARGET;
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = refElms->GetLength(&count);
|
||||
if (NS_FAILED(rv) || count == 0)
|
||||
return NS_OK_NO_RELATION_TARGET;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
||||
content = do_QueryElementAt(refElms, idx, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AddTargetFromContent(aRelationType, aRelation, content);
|
||||
nsIContent* refElm = nsnull;
|
||||
IDRefsIterator iter(aContent, aAttr);
|
||||
while ((refElm = iter.NextElem())) {
|
||||
rv = AddTargetFromContent(aRelationType, aRelation, refElm);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -92,26 +92,14 @@ nsTextEquivUtils::GetTextEquivFromIDRefs(nsAccessible *aAccessible,
|
|||
if (!content)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIArray> refElms;
|
||||
nsCoreUtils::GetElementsByIDRefsAttr(content, aIDRefsAttr,
|
||||
getter_AddRefs(refElms));
|
||||
|
||||
if (!refElms)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = refElms->GetLength(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> refContent;
|
||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
||||
refContent = do_QueryElementAt(refElms, idx, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIContent* refContent = nsnull;
|
||||
IDRefsIterator iter(content, aIDRefsAttr);
|
||||
while ((refContent = iter.NextElem())) {
|
||||
if (!aTextEquiv.IsEmpty())
|
||||
aTextEquiv += ' ';
|
||||
|
||||
rv = AppendTextEquivFromContent(aAccessible, refContent, &aTextEquiv);
|
||||
nsresult rv = AppendTextEquivFromContent(aAccessible, refContent,
|
||||
&aTextEquiv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -308,34 +308,27 @@ nsHTMLTableCellAccessible::GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
|
|||
nsIArray **aHeaderCells)
|
||||
{
|
||||
// Get header cells from @header attribute.
|
||||
nsCOMPtr<nsIArray> headerCellElms;
|
||||
nsCoreUtils::GetElementsByIDRefsAttr(mContent, nsAccessibilityAtoms::headers,
|
||||
getter_AddRefs(headerCellElms));
|
||||
|
||||
if (headerCellElms) {
|
||||
IDRefsIterator iter(mContent, nsAccessibilityAtoms::headers);
|
||||
nsIContent* headerCellElm = iter.NextElem();
|
||||
if (headerCellElm) {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMutableArray> headerCells =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 count = 0;
|
||||
rv = headerCellElms->GetLength(&count);
|
||||
if (NS_SUCCEEDED(rv) && count > 0) {
|
||||
nsCOMPtr<nsIContent> headerCellContent;
|
||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
||||
headerCellContent = do_QueryElementAt(headerCellElms, idx, &rv);
|
||||
nsAccessible *headerCell =
|
||||
GetAccService()->GetAccessibleInWeakShell(headerCellContent, mWeakShell);
|
||||
do {
|
||||
nsAccessible* headerCell =
|
||||
GetAccService()->GetAccessibleInWeakShell(headerCellElm, mWeakShell);
|
||||
|
||||
if (headerCell &&
|
||||
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
|
||||
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
|
||||
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER))
|
||||
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
|
||||
PR_FALSE);
|
||||
if (headerCell &&
|
||||
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
|
||||
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
|
||||
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER)) {
|
||||
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
} while ((headerCellElm = iter.NextElem()));
|
||||
|
||||
NS_ADDREF(*aHeaderCells = headerCells);
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче