diff --git a/mozilla/docshell/base/nsDocShellEnumerator.cpp b/mozilla/docshell/base/nsDocShellEnumerator.cpp new file mode 100644 index 00000000000..740de2e85f6 --- /dev/null +++ b/mozilla/docshell/base/nsDocShellEnumerator.cpp @@ -0,0 +1,212 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Author: + * Simon Fraser + */ + + +#include "nsDocShellEnumerator.h" + +#include "nsIDocShellTreeNode.h" + +nsDocShellEnumerator::nsDocShellEnumerator(PRInt32 inEnumerationDirection) +: mRootItem(nsnull) +, mItemArray(nsnull) +, mCurIndex(0) +, mDocShellType(nsIDocShellTreeItem::typeAll) +, mEnumerationDirection(inEnumerationDirection) +{ + NS_INIT_REFCNT(); +} + +nsDocShellEnumerator::~nsDocShellEnumerator() +{ + delete mItemArray; +} + +NS_IMPL_ISUPPORTS1(nsDocShellEnumerator, nsISimpleEnumerator); + + +/* nsISupports getNext (); */ +NS_IMETHODIMP nsDocShellEnumerator::GetNext(nsISupports **outCurItem) +{ + NS_ENSURE_ARG_POINTER(outCurItem); + *outCurItem = nsnull; + + nsresult rv = EnsureDocShellArray(); + if (NS_FAILED(rv)) return rv; + + if (mCurIndex >= 0 && mCurIndex < mItemArray->Count()) + { + nsIDocShellTreeItem* thisItem = NS_REINTERPRET_CAST(nsIDocShellTreeItem*, mItemArray->ElementAt(mCurIndex)); + rv = thisItem->QueryInterface(NS_GET_IID(nsISupports), (void **)outCurItem); + if (NS_FAILED(rv)) return rv; + } + else + return NS_ERROR_FAILURE; + + mCurIndex ++; + + return NS_OK; +} + +/* boolean hasMoreElements (); */ +NS_IMETHODIMP nsDocShellEnumerator::HasMoreElements(PRBool *outHasMore) +{ + NS_ENSURE_ARG_POINTER(outHasMore); + *outHasMore = PR_FALSE; + + nsresult rv = EnsureDocShellArray(); + if (NS_FAILED(rv)) return rv; + + *outHasMore = (mCurIndex < mItemArray->Count()); + return NS_OK; +} + +nsresult nsDocShellEnumerator::GetEnumerationRootItem(nsIDocShellTreeItem * *aEnumerationRootItem) +{ + NS_ENSURE_ARG_POINTER(aEnumerationRootItem); + *aEnumerationRootItem = mRootItem; + NS_IF_ADDREF(*aEnumerationRootItem); + return NS_OK; +} + +nsresult nsDocShellEnumerator::SetEnumerationRootItem(nsIDocShellTreeItem * aEnumerationRootItem) +{ + mRootItem = aEnumerationRootItem; + ClearState(); + return NS_OK; +} + +nsresult nsDocShellEnumerator::GetEnumDocShellType(PRInt32 *aEnumerationItemType) +{ + NS_ENSURE_ARG_POINTER(aEnumerationItemType); + *aEnumerationItemType = mDocShellType; + return NS_OK; +} + +nsresult nsDocShellEnumerator::SetEnumDocShellType(PRInt32 aEnumerationItemType) +{ + mDocShellType = aEnumerationItemType; + ClearState(); + return NS_OK; +} + +nsresult nsDocShellEnumerator::First() +{ + mCurIndex = 0; + return EnsureDocShellArray(); +} + +nsresult nsDocShellEnumerator::EnsureDocShellArray() +{ + if (!mItemArray) + { + mItemArray = new nsVoidArray; + if (!mItemArray) return NS_ERROR_OUT_OF_MEMORY; + + return BuildDocShellArray(*mItemArray); + } + + return NS_OK; +} + +nsresult nsDocShellEnumerator::ClearState() +{ + delete mItemArray; + mItemArray = nsnull; + + mCurIndex = 0; + return NS_OK; +} + +nsresult nsDocShellEnumerator::BuildDocShellArray(nsVoidArray& inItemArray) +{ + NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED); + inItemArray.Clear(); + return BuildArrayRecursive(mRootItem, inItemArray); +} + +nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray) +{ + nsresult rv; + nsCOMPtr itemAsNode = do_QueryInterface(inItem, &rv); + if (NS_FAILED(rv)) return rv; + + PRInt32 itemType; + // add this item to the array + if ((mDocShellType == nsIDocShellTreeItem::typeAll) || + (NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType))) + { + rv = inItemArray.AppendElement((void *)inItem); + if (NS_FAILED(rv)) return rv; + } + + PRInt32 numChildren; + rv = itemAsNode->GetChildCount(&numChildren); + if (NS_FAILED(rv)) return rv; + + for (PRInt32 i = 0; i < numChildren; ++i) + { + nsCOMPtr curChild; + rv = itemAsNode->GetChildAt(i, getter_AddRefs(curChild)); + if (NS_FAILED(rv)) return rv; + + rv = BuildArrayRecursive(curChild, inItemArray); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + + +nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray) +{ + nsresult rv; + nsCOMPtr itemAsNode = do_QueryInterface(inItem, &rv); + if (NS_FAILED(rv)) return rv; + + PRInt32 numChildren; + rv = itemAsNode->GetChildCount(&numChildren); + if (NS_FAILED(rv)) return rv; + + for (PRInt32 i = numChildren - 1; i >= 0; --i) + { + nsCOMPtr curChild; + rv = itemAsNode->GetChildAt(i, getter_AddRefs(curChild)); + if (NS_FAILED(rv)) return rv; + + rv = BuildArrayRecursive(curChild, inItemArray); + if (NS_FAILED(rv)) return rv; + } + + PRInt32 itemType; + // add this item to the array + if ((mDocShellType == nsIDocShellTreeItem::typeAll) || + (NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType))) + { + rv = inItemArray.AppendElement((void *)inItem); + if (NS_FAILED(rv)) return rv; + } + + + return NS_OK; +} + + diff --git a/mozilla/docshell/base/nsDocShellEnumerator.h b/mozilla/docshell/base/nsDocShellEnumerator.h new file mode 100644 index 00000000000..aeb0c29eb3f --- /dev/null +++ b/mozilla/docshell/base/nsDocShellEnumerator.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 1999, Mozilla. All Rights Reserved. + * + * Author: + * Simon Fraser + */ + + + +#include "nsIEnumerator.h" + +#include "nsCOMPtr.h" +#include "nsVoidArray.h" + +class nsIDocShellTreeItem; + + +/* +// {13cbc281-35ae-11d5-be5b-bde0edece43c} +#define NS_DOCSHELL_FORWARDS_ENUMERATOR_CID \ +{ 0x13cbc281, 0x35ae, 0x11d5, { 0xbe, 0x5b, 0xbd, 0xe0, 0xed, 0xec, 0xe4, 0x3c } } + +#define NS_DOCSHELL_FORWARDS_ENUMERATOR_CONTRACTID \ +"@mozilla.org/docshell/enumerator-forwards;1" + +// {13cbc282-35ae-11d5-be5b-bde0edece43c} +#define NS_DOCSHELL_BACKWARDS_ENUMERATOR_CID \ +{ 0x13cbc282, 0x35ae, 0x11d5, { 0xbe, 0x5b, 0xbd, 0xe0, 0xed, 0xec, 0xe4, 0x3c } } + +#define NS_DOCSHELL_BACKWARDS_ENUMERATOR_CONTRACTID \ +"@mozilla.org/docshell/enumerator-backwards;1" +*/ + +class nsDocShellEnumerator : public nsISimpleEnumerator +{ +protected: + + enum { + enumerateForwards, + enumerateBackwards + }; + +public: + + nsDocShellEnumerator(PRInt32 inEnumerationDirection); + virtual ~nsDocShellEnumerator(); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsISimpleEnumerator + NS_DECL_NSISIMPLEENUMERATOR + +public: + + nsresult GetEnumerationRootItem(nsIDocShellTreeItem * *aEnumerationRootItem); + nsresult SetEnumerationRootItem(nsIDocShellTreeItem * aEnumerationRootItem); + + nsresult GetEnumDocShellType(PRInt32 *aEnumerationItemType); + nsresult SetEnumDocShellType(PRInt32 aEnumerationItemType); + + nsresult First(); + +protected: + + nsresult EnsureDocShellArray(); + nsresult ClearState(); + + nsresult BuildDocShellArray(nsVoidArray& inItemArray); + virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray) = 0; + +protected: + + nsIDocShellTreeItem* mRootItem; // weak ref! + + nsVoidArray* mItemArray; // flattened list of items with matching type + PRInt32 mCurIndex; + + PRInt32 mDocShellType; // only want shells of this type + + const PRInt8 mEnumerationDirection; +}; + + +class nsDocShellForwardsEnumerator : public nsDocShellEnumerator +{ +public: + + nsDocShellForwardsEnumerator() + : nsDocShellEnumerator(enumerateForwards) + { + } + +protected: + + virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray); + +}; + +class nsDocShellBackwardsEnumerator : public nsDocShellEnumerator +{ +public: + + nsDocShellBackwardsEnumerator() + : nsDocShellEnumerator(enumerateBackwards) + { + } +protected: + + virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray); + +};