Bug 534527 - Accessibility needs new DOM API, r=olli.pettay, sr=roc

This commit is contained in:
Alexander Surkov 2010-02-12 01:34:01 +08:00
parent d6e29f98be
commit 73e251f02b
26 changed files with 245 additions and 30 deletions

View File

@ -152,6 +152,30 @@ public:
return GetCurrentDoc();
}
enum {
/**
* All children will be returned.
*
* @note the result children order is
* 1. :before generated contnent
* 2. explicit children and XBL anonymous children
* 3. native anonymous content
* 4. :after generated content
*/
eAllChildren = 0,
/**
* All children but XBL anonymous children will be returned.
*/
eAllButXBL = 1
};
/**
* Return children of the node, including explict, native anonymous, XBL
* anonymous and genererated nodes until the child type is given (see above).
*/
virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType) = 0;
/**
* Get whether this content is C++-generated anonymous content
* @see nsIAnonymousContentCreator

View File

@ -97,6 +97,11 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsBaseContentList, nsINodeList)
void AppendElement(nsIContent *aContent);
void MaybeAppendElement(nsIContent* aContent)
{
if (aContent)
AppendElement(aContent);
}
/**
* Insert the element at a given index, shifting the objects at

View File

@ -619,6 +619,12 @@ nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
nsNodeUtils::ParentChainChanged(this);
}
already_AddRefed<nsINodeList>
nsGenericDOMDataNode::GetChildren(PRInt32 aChildType)
{
return nsnull;
}
nsIAtom *
nsGenericDOMDataNode::GetIDAttributeName() const
{

View File

@ -200,6 +200,8 @@ public:
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
virtual nsIAtom *GetIDAttributeName() const;
virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,

View File

@ -60,6 +60,7 @@
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsStyleConsts.h"
@ -2696,6 +2697,80 @@ nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
nsNodeUtils::ParentChainChanged(this);
}
already_AddRefed<nsINodeList>
nsGenericElement::GetChildren(PRInt32 aChildType)
{
nsRefPtr<nsBaseContentList> list = new nsBaseContentList();
if (!list) {
return nsnull;
}
nsIFrame *frame = GetPrimaryFrame();
// Append :before generated content.
if (frame) {
nsIFrame *beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
if (beforeFrame) {
nsIContent* beforeContent = beforeFrame->GetContent();
if (beforeFrame) {
list->AppendElement(beforeContent);
}
}
}
// If XBL is bound to this node then append XBL anonymous content including
// explict content altered by insertion point if we were requested for XBL
// anonymous content, otherwise append explicit content with respect to
// insertion point if any.
nsINodeList *childList = nsnull;
nsIDocument* document = GetOwnerDoc();
if (document) {
if (aChildType != eAllButXBL) {
childList = document->BindingManager()->GetXBLChildNodesFor(this);
if (!childList) {
childList = GetChildNodesList();
}
} else {
childList = document->BindingManager()->GetContentListFor(this);
}
} else {
childList = GetChildNodesList();
}
if (childList) {
PRUint32 length = 0;
childList->GetLength(&length);
for (PRUint32 idx = 0; idx < length; idx++) {
nsIContent* child = childList->GetNodeAt(idx);
list->AppendElement(child);
}
}
if (frame) {
// Append native anonymous content to the end.
nsIAnonymousContentCreator* creator = do_QueryFrame(frame);
if (creator) {
creator->GetAnonymousContent(*list);
}
// Append :after generated content.
nsIFrame *afterFrame = nsLayoutUtils::GetAfterFrame(frame);
if (afterFrame) {
nsIContent* afterContent = afterFrame->GetContent();
if (afterFrame) {
list->AppendElement(afterContent);
}
}
}
nsINodeList* returnList = nsnull;
list.forget(&returnList);
return returnList;
}
nsresult
nsGenericElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{

View File

@ -378,6 +378,7 @@ public:
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
virtual nsIAtom *GetIDAttributeName() const;
virtual nsIAtom *GetClassAttributeName() const;
virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;

View File

@ -96,6 +96,7 @@ public:
// for nsSVGUseFrame's nsIAnonymousContentCreator implementation.
nsIContent* CreateAnonymousContent();
nsIContent* GetAnonymousContent() const { return mClone; }
void DestroyAnonymousContent();
// nsSVGElement specializations:

View File

@ -683,21 +683,26 @@ nsBindingManager::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID)
nsresult
nsBindingManager::GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult)
{
NS_IF_ADDREF(*aResult = GetContentListFor(aContent));
return NS_OK;
}
nsINodeList*
nsBindingManager::GetContentListFor(nsIContent* aContent)
{
*aResult = nsnull;
nsINodeList* result = nsnull;
if (mContentListTable.ops) {
*aResult = static_cast<nsAnonymousContentList*>
(LookupObject(mContentListTable, aContent));
NS_IF_ADDREF(*aResult);
}
if (!*aResult) {
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
node->GetChildNodes(aResult);
result = static_cast<nsAnonymousContentList*>
(LookupObject(mContentListTable, aContent));
}
return NS_OK;
if (!result) {
result = aContent->GetChildNodesList();
}
return result;
}
nsresult

View File

@ -108,6 +108,11 @@ public:
*/
nsresult GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult);
/**
* Non-COMy version of GetContentListFor.
*/
nsINodeList* GetContentListFor(nsIContent* aContent);
/**
* Set the insertion point children for the specified element.
* The binding manager assumes ownership of aList.

View File

@ -1042,6 +1042,13 @@ nsComboboxControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsComboboxControlFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mDisplayContent);
aElements.MaybeAppendElement(mButtonContent);
}
// XXXbz this is a for-now hack. Now that display:inline-block works,
// need to revisit this.
class nsComboboxDisplayFrame : public nsBlockFrame {

View File

@ -99,6 +99,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
virtual nsIFrame* CreateFrameFor(nsIContent* aContent);
#ifdef ACCESSIBILITY

View File

@ -99,10 +99,10 @@
class UploadLastDir : public nsIObserver, public nsSupportsWeakReference {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
UploadLastDir();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
UploadLastDir();
/**
* Fetch the last used directory for this location from the content
@ -127,7 +127,7 @@ private:
PRBool mInPrivateBrowsing;
};
NS_IMPL_ISUPPORTS2(UploadLastDir, nsIObserver, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS2(UploadLastDir, nsIObserver, nsISupportsWeakReference)
UploadLastDir* gUploadLastDir = nsnull;
nsIFrame*
@ -286,6 +286,13 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsFileControlFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mTextContent);
aElements.MaybeAppendElement(mBrowse);
}
NS_QUERYFRAME_HEAD(nsFileControlFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
@ -497,11 +504,11 @@ void nsFileControlFrame::DestroyUploadLastDir() {
UploadLastDir::UploadLastDir():
mInPrivateBrowsing(PR_FALSE)
{
nsCOMPtr<nsIPrivateBrowsingService> pbService =
do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbService) {
pbService->GetPrivateBrowsingEnabled(&mInPrivateBrowsing);
}
nsCOMPtr<nsIPrivateBrowsingService> pbService =
do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbService) {
pbService->GetPrivateBrowsingEnabled(&mInPrivateBrowsing);
}
mUploadLastDirStore.Init();
}
@ -544,13 +551,13 @@ UploadLastDir::FetchLastUsedDirectory(nsIURI* aURI, nsILocalFile** aFile)
nsString prefStr;
pref->GetAsAString(prefStr);
nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (!localFile)
return NS_ERROR_OUT_OF_MEMORY;
localFile->InitWithPath(prefStr);
nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (!localFile)
return NS_ERROR_OUT_OF_MEMORY;
localFile->InitWithPath(prefStr);
*aFile = localFile;
NS_ADDREF(*aFile);
NS_ADDREF(*aFile);
}
return NS_OK;
}
@ -598,9 +605,9 @@ UploadLastDir::StoreLastUsedDirectory(nsIURI* aURI, nsILocalFile* aFile)
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue);
}
NS_IMETHODIMP
UploadLastDir::Observe(nsISupports *aSubject, char const *aTopic, PRUnichar const *aData)
{
NS_IMETHODIMP
UploadLastDir::Observe(nsISupports *aSubject, char const *aTopic, PRUnichar const *aData)
{
if (strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC) == 0) {
if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).Equals(aData)) {
mInPrivateBrowsing = PR_TRUE;

View File

@ -93,6 +93,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
#ifdef ACCESSIBILITY
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);

View File

@ -131,6 +131,12 @@ nsGfxButtonControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements
return NS_OK;
}
void
nsGfxButtonControlFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mTextContent);
}
// Create the text content used as label for the button.
// The frame will be generated by the frame constructor.
nsIFrame*

View File

@ -81,6 +81,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
virtual nsIFrame* CreateFrameFor(nsIContent* aContent);
// nsIFormControlFrame

View File

@ -238,6 +238,13 @@ nsIsIndexFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsIsIndexFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mTextContent);
aElements.MaybeAppendElement(mInputContent);
}
NS_QUERYFRAME_HEAD(nsIsIndexFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)

View File

@ -98,6 +98,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
NS_IMETHOD OnSubmit(nsPresContext* aPresContext);

View File

@ -1670,6 +1670,12 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsTextControlFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mAnonymousDiv);
}
nscoord
nsTextControlFrame::GetMinWidth(nsIRenderingContext* aRenderingContext)
{

View File

@ -139,6 +139,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
// Utility methods to set current widget state

View File

@ -105,6 +105,12 @@ nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return mInner.CreateAnonymousContent(aElements);
}
void
nsHTMLScrollFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
mInner.GetAnonymousContent(aElements);
}
void
nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
@ -953,6 +959,12 @@ nsXULScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return mInner.CreateAnonymousContent(aElements);
}
void
nsXULScrollFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
mInner.GetAnonymousContent(aElements);
}
void
nsXULScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
@ -2238,6 +2250,14 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsGfxScrollFrameInner::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mHScrollbarContent);
aElements.MaybeAppendElement(mVScrollbarContent);
aElements.MaybeAppendElement(mScrollCornerContent);
}
void
nsGfxScrollFrameInner::Destroy()
{

View File

@ -81,6 +81,7 @@ public:
void ReloadChildFrames();
nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
void GetAnonymousContent(nsBaseContentList& aElements);
nsresult FireScrollPortEvent();
void PostOverflowEvent();
void Destroy();
@ -372,6 +373,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
// nsIScrollableFrame
virtual nsIFrame* GetScrolledFrame() const {
@ -566,6 +568,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);

View File

@ -71,6 +71,11 @@ public:
*/
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements)=0;
/**
* Returns "native" anonymous content created by CreateAnonymousContent().
*/
virtual void GetAnonymousContent(nsBaseContentList& aElements) = 0;
/**
* Implementations can override this method to create special frames for the
* anonymous content returned from CreateAnonymousContent.

View File

@ -135,6 +135,13 @@ nsVideoFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsVideoFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mPosterImage);
aElements.MaybeAppendElement(mVideoControls);
}
void
nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
{

View File

@ -100,6 +100,7 @@ public:
}
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
nsIContent* GetPosterImage() { return mPosterImage; }

View File

@ -89,6 +89,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
};
//----------------------------------------------------------------------
@ -180,3 +181,11 @@ nsSVGUseFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
void
nsSVGUseFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
nsSVGUseElement *use = static_cast<nsSVGUseElement*>(mContent);
nsIContent* clone = use->GetAnonymousContent();
aElements.MaybeAppendElement(clone);
}

View File

@ -76,6 +76,7 @@ public:
// nsIAnonymousContentCreator
virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
virtual void GetAnonymousContent(nsBaseContentList& aElements);
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
{
@ -150,6 +151,13 @@ nsDocElementBoxFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
void
nsDocElementBoxFrame::GetAnonymousContent(nsBaseContentList& aElements)
{
aElements.MaybeAppendElement(mPopupgroupContent);
aElements.MaybeAppendElement(mTooltipContent);
}
NS_QUERYFRAME_HEAD(nsDocElementBoxFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)