Make it possible to target non-primary content <browser>s; specifically ones

that are type="content-targetable".  Bug 326009, r=bsmedberg, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2006-02-22 03:58:48 +00:00
Родитель ec46e80305
Коммит 70a3e3a9a3
10 изменённых файлов: 319 добавлений и 99 удалений

Просмотреть файл

@ -231,6 +231,21 @@ nsFrameLoader::Destroy()
mOwnerContent = nsnull;
}
// Let the tree owner know we're gone.
if (mIsTopLevelContent) {
nsCOMPtr<nsIDocShellTreeItem> ourItem = do_QueryInterface(mDocShell);
if (ourItem) {
nsCOMPtr<nsIDocShellTreeItem> parentItem;
ourItem->GetParent(getter_AddRefs(parentItem));
nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
nsCOMPtr<nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH> owner2 =
do_QueryInterface(owner);
if (owner2) {
owner2->ContentShellRemoved(ourItem);
}
}
}
// Let our window know that we are gone
nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
if (win_private) {
@ -303,6 +318,9 @@ nsFrameLoader::EnsureDocShell()
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(parentAsWebNav));
if (parentAsNode) {
// Note: This logic duplicates a lot of logic in
// nsSubDocumentFrame::AttributeChanged. We should fix that.
nsCOMPtr<nsIDocShellTreeItem> parentAsItem =
do_QueryInterface(parentAsNode);
@ -317,23 +335,12 @@ nsFrameLoader::EnsureDocShell()
}
// we accept "content" and "content-xxx" values.
// at time of writing, we expect "xxx" to be "primary", but
// someday it might be an integer expressing priority
// at time of writing, we expect "xxx" to be "primary" or "targetable", but
// someday it might be an integer expressing priority or something else.
if (value.Length() >= 7) {
// Lowercase the value, ContentShellAdded() further down relies
// on it being lowercased.
ToLowerCase(value);
nsAutoString::const_char_iterator start, end;
value.BeginReading(start);
value.EndReading(end);
nsAutoString::const_char_iterator iter(start + 7);
isContent = Substring(start, iter).EqualsLiteral("content") &&
(iter == end || *iter == '-');
}
isContent = value.LowerCaseEqualsLiteral("content") ||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator());
if (isContent) {
// The web shell's type is content.
@ -349,16 +356,24 @@ nsFrameLoader::EnsureDocShell()
parentAsNode->AddChild(docShellAsItem);
if (isContent) {
if (parentType == nsIDocShellTreeItem::typeChrome && isContent) {
mIsTopLevelContent = PR_TRUE;
// XXXbz why is this in content code, exactly? We should handle
// this some other way.....
// this some other way..... Not sure how yet.
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
nsCOMPtr<nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH> owner2 =
do_QueryInterface(parentTreeOwner);
if (parentTreeOwner) {
PRBool is_primary = parentType == nsIDocShellTreeItem::typeChrome &&
value.EqualsLiteral("content-primary");
PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
if (owner2) {
PRBool is_targetable = is_primary ||
value.LowerCaseEqualsLiteral("content-targetable");
owner2->ContentShellAdded2(docShellAsItem, is_primary, is_targetable,
value);
} else if (parentTreeOwner) {
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
value.get());
}

Просмотреть файл

@ -51,7 +51,8 @@ class nsFrameLoader : public nsIFrameLoader
public:
nsFrameLoader(nsIContent *aOwner) :
mOwnerContent(aOwner),
mDepthTooGreat(PR_FALSE)
mDepthTooGreat(PR_FALSE),
mIsTopLevelContent(PR_FALSE)
{}
NS_DECL_ISUPPORTS
@ -67,7 +68,8 @@ private:
nsCOMPtr<nsIDocShell> mDocShell;
nsIContent *mOwnerContent; // WEAK
PRBool mDepthTooGreat;
PRPackedBool mDepthTooGreat;
PRPackedBool mIsTopLevelContent;
};
#endif

Просмотреть файл

@ -100,3 +100,43 @@ interface nsIDocShellTreeOwner : nsISupports
out boolean aPersistSize,
out boolean aPersistSizeMode);
};
/**
* Interface added to handle window targeting in tabbrowser. This is a total
* hack that's only needed to work around the fact that the tree owner api is
* really pretty useless for dealing with multiple "real" browsers in the same
* "docshell tree" and that there's no way to set up multiple treeowners in
* XUL-land right now. Gecko 1.9 will NOT be shipping this interface, and
* nsIDocShellTreeOwner will hopefully be improved significantly.
*
* @status TEMPORARY
*/
[scriptable, uuid(3c2a6927-e923-4ea8-bbda-a335c768ce4e)]
interface nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH : nsIDocShellTreeOwner
{
/**
* Called when a content shell is added to the docshell tree. This is _only_
* called for "root" content shells (that is, ones whose parent is a chrome
* shell).
*
* @param aContentShell the shell being added.
* @param aPrimary whether the shell is primary.
* @param aTargetable whether the shell can be a target for named window
* targeting.
* @param aID the "id" of the shell. What this actually means is undefined.
* Don't rely on this for anything.
*/
void contentShellAdded2(in nsIDocShellTreeItem aContentShell,
in boolean aPrimary, in boolean aTargetable,
in AString aID);
/**
* Called when a content shell is removed from the docshell tree. This is
* _only_ called for "root" content shells (that is, ones whose parent is a
* chrome shell). Note that if aContentShell was never added,
* contentShellRemoved should just do nothing.
*
* @param aContentShell the shell being removed.
*/
void contentShellRemoved(in nsIDocShellTreeItem aContentShell);
};

Просмотреть файл

@ -83,6 +83,7 @@
#include "nsAutoPtr.h"
#include "nsIDOMNSHTMLDocument.h"
#include "nsDisplayList.h"
#include "nsUnicharUtils.h"
#ifdef NS_PRINTING
#include "nsIWebBrowserPrint.h"
@ -480,6 +481,10 @@ nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType)
{
if (aNameSpaceID != kNameSpaceID_None) {
return NS_OK;
}
nsIAtom *type = mContent->Tag();
if ((type != nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::src) ||
@ -488,6 +493,8 @@ nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID,
}
// If the noResize attribute changes, dis/allow frame to be resized
else if (aAttribute == nsHTMLAtoms::noresize) {
// Note that we're not doing content type checks, but that's ok -- if
// they'd fail we will just end up with a null framesetFrame.
if (mContent->GetParent()->Tag() == nsHTMLAtoms::frameset) {
nsIFrame* parentFrame = GetParent();
@ -508,38 +515,62 @@ nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID,
if (!mFrameLoader)
return NS_OK;
nsAutoString value;
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, value);
if (!mContent->IsContentOfType(nsIContent::eXUL)) {
return NS_OK;
}
// Notify our enclosing chrome that the primary content shell
// has changed.
// Note: This logic duplicates a lot of logic in
// nsFrameLoader::EnsureDocShell. We should fix that.
// Notify our enclosing chrome that our type has changed. We only do this
// if our parent is chrome, since in all other cases we're random content
// subframes and the treeowner shouldn't worry about us.
nsCOMPtr<nsIDocShell> docShell;
mFrameLoader->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
if (!docShellAsItem) {
return NS_OK;
}
// If our container is a web-shell, inform it that it has a new
// child. If it's not a web-shell then some things will not operate
// properly.
nsCOMPtr<nsISupports> container = GetPresContext()->GetContainer();
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
nsCOMPtr<nsIDocShellTreeItem> parentItem;
docShellAsItem->GetParent(getter_AddRefs(parentItem));
if (parentAsNode) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem =
do_QueryInterface(parentAsNode);
PRInt32 parentType;
parentItem->GetItemType(&parentType);
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (parentTreeOwner) {
PRInt32 parentType;
parentAsItem->GetItemType(&parentType);
PRBool is_primary_content =
parentType == nsIDocShellTreeItem::typeChrome &&
value.LowerCaseEqualsLiteral("content-primary");
if (parentType != nsIDocShellTreeItem::typeChrome) {
return NS_OK;
}
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary_content,
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (parentTreeOwner) {
nsAutoString value;
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, value);
PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
nsCOMPtr<nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH> owner2 =
do_QueryInterface(parentTreeOwner);
if (!owner2) {
// XXXbz this adds stuff even if it's not of type content-*, but not
// much we can do about that....
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
value.get());
} else {
owner2->ContentShellRemoved(docShellAsItem);
if (value.LowerCaseEqualsLiteral("content") ||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator())) {
PRBool is_targetable = is_primary ||
value.LowerCaseEqualsLiteral("content-targetable");
owner2->ContentShellAdded2(docShellAsItem, is_primary, is_targetable,
value);
}
}
}
}

Просмотреть файл

@ -130,6 +130,7 @@ NS_IMPL_RELEASE(nsChromeTreeOwner)
NS_INTERFACE_MAP_BEGIN(nsChromeTreeOwner)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
@ -218,6 +219,8 @@ NS_IMETHODIMP nsChromeTreeOwner::FindItemWithName(const PRUnichar* aName,
}
else
{
// Note that we don't look for targetable content shells here...
// in fact, we aren't looking for content shells at all!
nsCOMPtr<nsIDocShell> shell;
xulWindow->GetDocShell(getter_AddRefs(shell));
shellAsTreeItem = do_QueryInterface(shell);
@ -250,8 +253,14 @@ NS_IMETHODIMP nsChromeTreeOwner::FindItemWithName(const PRUnichar* aName,
NS_IMETHODIMP nsChromeTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, const PRUnichar* aID)
{
mXULWindow->ContentShellAdded(aContentShell, aPrimary, aID);
return NS_OK;
NS_ENSURE_STATE(mXULWindow);
if (aID) {
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, PR_FALSE,
nsDependentString(aID));
}
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, PR_FALSE,
EmptyString());
}
NS_IMETHODIMP nsChromeTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
@ -534,6 +543,26 @@ nsChromeTreeOwner::OnSecurityChange(nsIWebProgress *aWebProgress,
return NS_OK;
}
//*****************************************************************************
// nsChromeTreeOwner::nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH
//*****************************************************************************
NS_IMETHODIMP
nsChromeTreeOwner::ContentShellAdded2(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, PRBool aTargetable,
const nsAString& aID)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, aTargetable,
aID);
}
NS_IMETHODIMP
nsChromeTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->ContentShellRemoved(aContentShell);
}
//*****************************************************************************
// nsChromeTreeOwner: Helpers
//*****************************************************************************

Просмотреть файл

@ -53,7 +53,7 @@
class nsXULWindow;
class nsChromeTreeOwner : public nsIDocShellTreeOwner,
class nsChromeTreeOwner : public nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH,
public nsIBaseWindow,
public nsIInterfaceRequestor,
public nsIWebProgressListener,
@ -68,6 +68,7 @@ public:
NS_DECL_NSIBASEWINDOW
NS_DECL_NSIDOCSHELLTREEOWNER
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIDOCSHELLTREEOWNER_MOZILLA_1_8_BRANCH
static nsresult InitGlobals();
static void FreeGlobals();

Просмотреть файл

@ -44,6 +44,7 @@
// Helper Classes
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsAutoPtr.h"
// Interfaces needed to be included
#include "nsIDOMNode.h"
@ -117,6 +118,7 @@ NS_IMPL_RELEASE(nsContentTreeOwner)
NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
@ -181,22 +183,23 @@ NS_IMETHODIMP nsContentTreeOwner::FindItemWithName(const PRUnichar* aName,
PRBool fIs_Content = PR_FALSE;
/* Special Cases */
if(!aName || !*aName)
if (!aName || !*aName)
return NS_OK;
nsDependentString name(aName);
if(name.LowerCaseEqualsLiteral("_blank"))
if (name.LowerCaseEqualsLiteral("_blank"))
return NS_OK;
// _main is an IE target which should be case-insensitive but isn't
// see bug 217886 for details
if(name.LowerCaseEqualsLiteral("_content") || name.EqualsLiteral("_main"))
{
fIs_Content = PR_TRUE;
mXULWindow->GetPrimaryContentShell(aFoundItem);
if(*aFoundItem)
return NS_OK;
}
if (name.LowerCaseEqualsLiteral("_content") ||
name.EqualsLiteral("_main")) {
mXULWindow->GetPrimaryContentShell(aFoundItem);
if(*aFoundItem)
return NS_OK;
// Fall through and keep looking...
fIs_Content = PR_TRUE;
}
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
NS_ENSURE_TRUE(windowMediator, NS_ERROR_FAILURE);
@ -208,57 +211,70 @@ NS_IMETHODIMP nsContentTreeOwner::FindItemWithName(const PRUnichar* aName,
PRBool more;
windowEnumerator->HasMoreElements(&more);
while(more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
NS_ENSURE_TRUE(xulWindow, NS_ERROR_FAILURE);
while(more) {
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
NS_ENSURE_TRUE(xulWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem;
xulWindow->GetPrimaryContentShell(getter_AddRefs(shellAsTreeItem));
if(shellAsTreeItem)
{
if(fIs_Content)
{
*aFoundItem = shellAsTreeItem;
NS_ADDREF(*aFoundItem);
}
else
{
// Get the root tree item of same type, since roots are the only
// things that call into the treeowner to look for named items.
nsCOMPtr<nsIDocShellTreeItem> root;
shellAsTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
NS_ASSERTION(root, "Must have root tree item of same type");
shellAsTreeItem = root;
if(aRequestor != shellAsTreeItem)
{
if (fIs_Content) {
xulWindow->GetPrimaryContentShell(aFoundItem);
} else {
// Get all the targetable windows from xulWindow and search them
nsRefPtr<nsXULWindow> win;
xulWindow->QueryInterface(NS_GET_IID(nsXULWindow), getter_AddRefs(win));
if (win) {
PRInt32 count = win->mTargetableShells.Count();
PRInt32 i;
for (i = 0; i < count; ++i) {
nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem =
do_QueryReferent(win->mTargetableShells[i]);
if (shellAsTreeItem) {
// Get the root tree item of same type, since roots are the only
// things that call into the treeowner to look for named items.
// XXXbz ideally we could guarantee that mTargetableShells only
// contains roots, but the current treeowner apis don't allow
// that... yet.
nsCOMPtr<nsIDocShellTreeItem> root;
shellAsTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
NS_ASSERTION(root, "Must have root tree item of same type");
shellAsTreeItem.swap(root);
if (aRequestor != shellAsTreeItem) {
// Do this so we can pass in the tree owner as the
// requestor so the child knows not to call back up.
nsCOMPtr<nsIDocShellTreeOwner> shellOwner;
shellAsTreeItem->GetTreeOwner(getter_AddRefs(shellOwner));
nsCOMPtr<nsISupports> shellOwnerSupports(do_QueryInterface(shellOwner));
nsCOMPtr<nsISupports> shellOwnerSupports =
do_QueryInterface(shellOwner);
shellAsTreeItem->FindItemWithName(aName, shellOwnerSupports,
aOriginalRequestor,
aFoundItem);
}
}
if(*aFoundItem)
return NS_OK;
}
}
}
windowEnumerator->HasMoreElements(&more);
}
}
}
if (*aFoundItem)
return NS_OK;
windowEnumerator->HasMoreElements(&more);
}
return NS_OK;
}
NS_IMETHODIMP nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, const PRUnichar* aID)
{
mXULWindow->ContentShellAdded(aContentShell, aPrimary, aID);
return NS_OK;
NS_ENSURE_STATE(mXULWindow);
if (aID) {
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, PR_FALSE,
nsDependentString(aID));
}
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, PR_FALSE,
EmptyString());
}
NS_IMETHODIMP nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
@ -795,6 +811,26 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
nsIBrowserDOMWindow::OPEN_NEW, aReturn);
}
//*****************************************************************************
// nsContentTreeOwner::nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH
//*****************************************************************************
NS_IMETHODIMP
nsContentTreeOwner::ContentShellAdded2(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, PRBool aTargetable,
const nsAString& aID)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->ContentShellAdded(aContentShell, aPrimary, aTargetable,
aID);
}
NS_IMETHODIMP
nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
{
NS_ENSURE_STATE(mXULWindow);
return mXULWindow->ContentShellRemoved(aContentShell);
}
//*****************************************************************************
// nsContentTreeOwner: Accessors
//*****************************************************************************

Просмотреть файл

@ -55,7 +55,7 @@
class nsXULWindow;
class nsSiteWindow2;
class nsContentTreeOwner : public nsIDocShellTreeOwner,
class nsContentTreeOwner : public nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH,
public nsIBaseWindow,
public nsIInterfaceRequestor,
public nsIWebBrowserChrome2,
@ -73,6 +73,7 @@ public:
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROME2
NS_DECL_NSIWINDOWPROVIDER
NS_DECL_NSIDOCSHELLTREEOWNER_MOZILLA_1_8_BRANCH
protected:
nsContentTreeOwner(PRBool fPrimary);

Просмотреть файл

@ -146,6 +146,9 @@ NS_INTERFACE_MAP_BEGIN(nsXULWindow)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
if (aIID.Equals(NS_GET_IID(nsXULWindow)))
foundInterface = NS_REINTERPRET_CAST(nsISupports*, this);
else
NS_INTERFACE_MAP_END
//*****************************************************************************
@ -1602,11 +1605,10 @@ NS_IMETHODIMP nsXULWindow::GetDOMElementById(char* aID, nsIDOMElement** aDOMElem
return NS_OK;
}
NS_IMETHODIMP nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, const PRUnichar* aID)
nsresult nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, PRBool aTargetable, const nsAString& aID)
{
nsContentShellInfo* shellInfo = nsnull;
nsDependentString newID(aID);
PRInt32 count = mContentShells.Count();
PRInt32 i;
@ -1623,7 +1625,7 @@ NS_IMETHODIMP nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
}
if (!shellInfo) {
shellInfo = new nsContentShellInfo(newID, contentShellWeak);
shellInfo = new nsContentShellInfo(aID, contentShellWeak);
mContentShells.AppendElement((void*)shellInfo);
}
@ -1640,6 +1642,50 @@ NS_IMETHODIMP nsXULWindow::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
mPrimaryContentShell = nsnull;
}
if (aTargetable) {
#ifdef DEBUG
PRInt32 debugCount = mTargetableShells.Count();
PRInt32 debugCounter;
for (debugCounter = debugCount - 1; debugCounter >= 0; --debugCounter) {
nsCOMPtr<nsIDocShellTreeItem> curItem =
do_QueryReferent(mTargetableShells[debugCounter]);
NS_ASSERTION(!SameCOMIdentity(curItem, aContentShell),
"Adding already existing item to mTargetableShells");
}
#endif
NS_ENSURE_TRUE(mTargetableShells.AppendObject(contentShellWeak),
NS_ERROR_OUT_OF_MEMORY);
}
return NS_OK;
}
nsresult nsXULWindow::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
{
if (mPrimaryContentShell == aContentShell) {
mPrimaryContentShell = nsnull;
}
PRInt32 count = mContentShells.Count();
PRInt32 i;
for (i = count - 1; i >= 0; --i) {
nsContentShellInfo* info = (nsContentShellInfo*)mContentShells.ElementAt(i);
nsCOMPtr<nsIDocShellTreeItem> curItem = do_QueryReferent(info->child);
if (!curItem || SameCOMIdentity(curItem, aContentShell)) {
mContentShells.RemoveElementAt(i);
}
}
count = mTargetableShells.Count();
for (i = count - 1; i >= 0; --i) {
nsCOMPtr<nsIDocShellTreeItem> curItem =
do_QueryReferent(mTargetableShells[i]);
if (!curItem || SameCOMIdentity(curItem, aContentShell)) {
mTargetableShells.RemoveObjectAt(i);
}
}
return NS_OK;
}

Просмотреть файл

@ -49,6 +49,7 @@
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsWeakReference.h"
#include "nsCOMArray.h"
// Interfaces needed
#include "nsIBaseWindow.h"
@ -68,6 +69,14 @@
// nsXULWindow
#define NS_XULWINDOW_IMPL_CID \
{ /* 2a38ef7e-3174-44ad-a785-b5a863cf5588 */ \
0x2a38ef7e, \
0x3174, \
0x44ad, \
{ 0xa7, 0x85, 0xb5, 0xa8, 0x63, 0xcf, 0x55, 0x88 } \
}
class nsXULWindow : public nsIBaseWindow,
public nsIInterfaceRequestor,
public nsIXULWindow,
@ -83,6 +92,8 @@ public:
NS_DECL_NSIXULWINDOW
NS_DECL_NSIBASEWINDOW
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULWINDOW_IMPL_CID)
void LockUntilChromeLoad() { mLockedUntilChromeLoad = PR_TRUE; }
PRBool IsLocked() const { return mLockedUntilChromeLoad; }
@ -116,8 +127,12 @@ protected:
NS_IMETHOD GetWindowDOMWindow(nsIDOMWindowInternal** aDOMWindow);
NS_IMETHOD GetWindowDOMElement(nsIDOMElement** aDOMElement);
NS_IMETHOD GetDOMElementById(char* aID, nsIDOMElement** aDOMElement);
NS_IMETHOD ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, const PRUnichar* aID);
// See nsIDocShellTreeOwner_MOZILLA_1_8_BRANCH for docs on next two methods
NS_HIDDEN_(nsresult) ContentShellAdded(nsIDocShellTreeItem* aContentShell,
PRBool aPrimary, PRBool aTargetable,
const nsAString& aID);
NS_HIDDEN_(nsresult) ContentShellRemoved(nsIDocShellTreeItem* aContentShell);
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, PRInt32 aCX,
PRInt32 aCY);
NS_IMETHOD ExitModalLoop(nsresult aStatus);
@ -163,8 +178,12 @@ protected:
PRUint32 mPersistentAttributesMask;
PRUint32 mChromeFlags;
nsString mTitle;
nsCOMArray<nsIWeakReference> mTargetableShells; // targetable shells only
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULWindow, NS_XULWINDOW_IMPL_CID)
// nsContentShellInfo
// Used (in an nsVoidArray) to map shell IDs to nsIDocShellTreeItems.