Bug 378776, Need safe way to iterate a document's presshells, r+sr=bz

This commit is contained in:
Olli.Pettay%helsinki.fi 2007-05-22 21:45:07 +00:00
Родитель 96edb88618
Коммит 6f25a6cffd
20 изменённых файлов: 237 добавлений и 467 удалений

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

@ -1,265 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Hyatt <hyatt@mozilla.org> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import "NSString+Utils.h"
#import "NSArray+Utils.h"
#import "CHBrowserView.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "CHClickListener.h"
#include "nsIDOMEventTarget.h"
#include "nsIContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMMouseEvent.h"
#include "nsEmbedAPI.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLOptionsCollection.h"
#include "nsIDOMHTMLOptGroupElement.h"
#include "nsIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIFrame.h"
@interface CHOptionSelector : NSObject
{
nsIDOMHTMLSelectElement* mSelectElt;
}
-(id)initWithSelect:(nsIDOMHTMLSelectElement*)aSel;
-(IBAction)selectOption:(id)aSender;
@end
@implementation CHOptionSelector
-(id)initWithSelect:(nsIDOMHTMLSelectElement*)aSel
{
if ( (self = [super init]) ) {
mSelectElt = aSel;
}
return self;
}
-(IBAction)selectOption:(id)aSender
{
nsIDOMHTMLOptionElement* optionElt = (nsIDOMHTMLOptionElement*)[[aSender representedObject] pointerValue];
NS_ASSERTION(optionElt, "Missing option element");
if (!optionElt) return;
optionElt->SetSelected(PR_TRUE);
// Fire a DOM event for the title change.
nsCOMPtr<nsIDOMEvent> event;
nsCOMPtr<nsIDOMDocument> domDocument;
mSelectElt->GetOwnerDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(domDocument));
docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
if (event) {
event->InitEvent(NS_LITERAL_STRING("change"), PR_TRUE, PR_TRUE);
PRBool noDefault;
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mSelectElt));
target->DispatchEvent(event, &noDefault);
}
}
@end
NS_IMPL_ISUPPORTS2(CHClickListener, nsIDOMMouseListener, nsIDOMEventListener)
CHClickListener::CHClickListener()
{
}
CHClickListener::~CHClickListener()
{
}
NS_IMETHODIMP
CHClickListener::MouseDown(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aEvent));
if (!mouseEvent) return NS_ERROR_FAILURE;
PRUint16 button;
mouseEvent->GetButton(&button);
// only show popup on left button
if (button != 0)
return NS_OK;
nsCOMPtr<nsIDOMEventTarget> target;
mouseEvent->GetTarget(getter_AddRefs(target));
if (!target)
return NS_OK;
nsCOMPtr<nsIDOMHTMLSelectElement> sel(do_QueryInterface(target));
if (!sel)
return NS_OK;
PRInt32 size = 0;
sel->GetSize(&size);
PRBool multiple = PR_FALSE;
sel->GetMultiple(&multiple);
if(size > 1 || multiple)
return NS_OK;
// the call to popUpContextMenu: is synchronous so we don't need to
// worry about retaining the menu for later.
NSMenu* menu = [[[NSMenu alloc] init] autorelease];
// We'll set the disabled state as the options are created, so disable
// auto-enabling via NSMenuValidation.
[menu setAutoenablesItems: NO];
nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
sel->GetOptions(getter_AddRefs(options));
PRUint32 count;
options->GetLength(&count);
PRInt32 selIndex = 0; // currently unused
nsCOMPtr<nsIDOMHTMLOptGroupElement> curOptGroup;
for (PRUint32 i = 0; i < count; i++) {
nsAutoString itemLabel;
nsCOMPtr<nsIDOMNode> node;
options->Item(i, getter_AddRefs(node));
nsCOMPtr<nsIDOMHTMLOptionElement> option(do_QueryInterface(node));
nsCOMPtr<nsIDOMNode> parentNode;
option->GetParentNode(getter_AddRefs(parentNode));
nsCOMPtr<nsIDOMHTMLOptGroupElement> parentOptGroup = do_QueryInterface(parentNode);
if (parentOptGroup && (parentOptGroup != curOptGroup))
{
// insert optgroup item
parentOptGroup->GetLabel(itemLabel);
NSString* title = [[NSString stringWith_nsAString: itemLabel] stringByTruncatingTo:75 at:kTruncateAtMiddle];
NSMenuItem* menuItem = [[[NSMenuItem alloc] initWithTitle: title action: NULL keyEquivalent: @""] autorelease];
[menu addItem: menuItem];
[menuItem setEnabled: NO];
curOptGroup = parentOptGroup;
}
option->GetLabel(itemLabel);
if (itemLabel.IsEmpty())
option->GetText(itemLabel);
NSString* title = [[NSString stringWith_nsAString: itemLabel] stringByTruncatingTo:75 at:kTruncateAtMiddle];
// indent items in optgroup
if (parentOptGroup)
title = [@" " stringByAppendingString:title];
NSMenuItem* menuItem = [[[NSMenuItem alloc] initWithTitle: title action: NULL keyEquivalent: @""] autorelease];
[menu addItem: menuItem];
[menuItem setRepresentedObject:[NSValue valueWithPointer:option.get()]];
PRBool selected;
option->GetSelected(&selected);
if (selected) {
[menuItem setState: NSOnState];
selIndex = i;
}
PRBool disabled;
option->GetDisabled(&disabled);
if (disabled)
[menuItem setEnabled: NO];
CHOptionSelector* optSelector = [[[CHOptionSelector alloc] initWithSelect: sel] autorelease];
[menuItem setTarget: optSelector]; // retains
if (!selected)
[menuItem setAction:@selector(selectOption:)];
}
nsCOMPtr<nsIContent> selContent = do_QueryInterface(sel);
nsCOMPtr<nsIDocument> doc = selContent->GetDocument();
NSEvent* event = [NSApp currentEvent];
NSWindow* hostWindow = [event window];
// get the frame location
nsIPresShell* presShell = doc->GetShellAt(0);
if (!presShell)
return NS_ERROR_FAILURE;
nsIFrame* selectFrame = presShell->GetPrimaryFrameFor(selContent);
if (!selectFrame)
return NS_ERROR_FAILURE;
nsIntRect selectRect = selectFrame->GetScreenRectExternal();
NSRect selectScreenRect = NSMakeRect(selectRect.x, selectRect.y, selectRect.width, selectRect.height);
NSScreen* mainScreen = [[NSScreen screens] firstObject]; // NSArray category method
if (!mainScreen)
return NS_ERROR_FAILURE;
// y-flip and subtract the control height to convert to cocoa coords
NSRect mainScreenFrame = [mainScreen frame];
selectScreenRect.origin.y = NSMaxY(mainScreenFrame) - selectScreenRect.origin.y - selectScreenRect.size.height;
// convert to window coords
NSRect selectFrameRect = selectScreenRect;
selectFrameRect.origin = [hostWindow convertScreenToBase:selectFrameRect.origin];
// we're gonna make a little view to display things with, so that the popup isn't
// shown at the top of the window when it's near the bottom of the screen.
NSView* hostView = [[NSView alloc] initWithFrame:selectFrameRect];
[[hostWindow contentView] addSubview:hostView]; // takes ownership
[hostView release];
const float kMenuWidth = 20.0; // specify something small so it sizes to fit
const float kMenuPopupHeight = 20.0; // height of a popup in aqua
NSRect bounds = NSMakeRect(0, 0, kMenuWidth, kMenuPopupHeight);
NSPopUpButtonCell* popupCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO];
[popupCell setMenu: menu];
[popupCell setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
[popupCell trackMouse:event inRect:bounds ofView:hostView untilMouseUp:YES];
[popupCell release];
[hostView removeFromSuperview]; // this releases it
return NS_OK;
}

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

@ -100,6 +100,7 @@
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsIXULAppInfo.h" #include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h" #include "nsIXULRuntime.h"
#include "nsPresShellIterator.h"
#ifdef MOZ_XUL #ifdef MOZ_XUL
// keep all the RDF stuff together, in case we can remove it in the far future // keep all the RDF stuff together, in case we can remove it in the far future
@ -923,10 +924,9 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow,
return NS_OK; return NS_OK;
// Deal with the agent sheets first. Have to do all the style sets by hand. // Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells(); nsPresShellIterator iter(document);
for (PRUint32 k = 0; k < shellCount; k++) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell *shell = document->GetShellAt(k); while ((shell = iter.GetNextShell())) {
// Reload only the chrome URL agent style sheets. // Reload only the chrome URL agent style sheets.
nsCOMArray<nsIStyleSheet> agentSheets; nsCOMArray<nsIStyleSheet> agentSheets;
rv = shell->GetAgentStyleSheets(agentSheets); rv = shell->GetAgentStyleSheets(agentSheets);

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

@ -74,6 +74,7 @@ nsCopySupport.h \
nsContentCreatorFunctions.h \ nsContentCreatorFunctions.h \
nsLineBreaker.h \ nsLineBreaker.h \
nsXMLNameSpaceMap.h \ nsXMLNameSpaceMap.h \
nsPresShellIterator.h \
$(NULL) $(NULL)
ifndef DISABLE_XFORMS_HOOKS ifndef DISABLE_XFORMS_HOOKS

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

@ -49,6 +49,7 @@
#include "mozFlushType.h" #include "mozFlushType.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsCompatibility.h" #include "nsCompatibility.h"
#include "nsTObserverArray.h"
class nsIContent; class nsIContent;
class nsPresContext; class nsPresContext;
@ -94,8 +95,8 @@ class mozAutoSubtreeModified;
// IID for the nsIDocument interface // IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \ #define NS_IDOCUMENT_IID \
{ 0xb7f930df, 0x1c61, 0x410f, \ { 0x7dd5790f, 0x110d, 0x4bf6, \
{ 0xab, 0x3c, 0xe2, 0x53, 0xca, 0x8d, 0x85, 0x49 } } { 0x83, 0x50, 0x4b, 0xe3, 0x5d, 0xdc, 0xe1, 0x1e } }
// Flag for AddStyleSheet(). // Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0) #define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -349,10 +350,9 @@ public:
nsStyleSet* aStyleSet, nsStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult) = 0; nsIPresShell** aInstancePtrResult) = 0;
virtual PRBool DeleteShell(nsIPresShell* aShell) = 0; virtual PRBool DeleteShell(nsIPresShell* aShell) = 0;
virtual PRUint32 GetNumberOfShells() const = 0;
virtual nsIPresShell *GetShellAt(PRUint32 aIndex) const = 0;
virtual nsIPresShell *GetPrimaryShell() const = 0; virtual nsIPresShell *GetPrimaryShell() const = 0;
virtual void SetShellsHidden(PRBool aHide) = 0; void SetShellsHidden(PRBool aHide) { mShellsAreHidden = aHide; }
PRBool ShellsAreHidden() const { return mShellsAreHidden; }
/** /**
* Return the parent document of this document. Will return null * Return the parent document of this document. Will return null
@ -891,6 +891,7 @@ protected:
virtual void WillDispatchMutationEvent(nsINode* aTarget) = 0; virtual void WillDispatchMutationEvent(nsINode* aTarget) = 0;
virtual void MutationEventDispatched(nsINode* aTarget) = 0; virtual void MutationEventDispatched(nsINode* aTarget) = 0;
friend class mozAutoSubtreeModified; friend class mozAutoSubtreeModified;
friend class nsPresShellIterator;
nsString mDocumentTitle; nsString mDocumentTitle;
nsCOMPtr<nsIURI> mDocumentURI; nsCOMPtr<nsIURI> mDocumentURI;
@ -932,6 +933,8 @@ protected:
// document in it. // document in it.
PRPackedBool mIsInitialDocumentInWindow; PRPackedBool mIsInitialDocumentInWindow;
PRPackedBool mShellsAreHidden;
// The bidi options for this document. What this bitfield means is // The bidi options for this document. What this bitfield means is
// defined in nsBidiUtils.h // defined in nsBidiUtils.h
PRUint32 mBidiOptions; PRUint32 mBidiOptions;
@ -949,6 +952,8 @@ protected:
// Cycle collector generation in which we're certain that this document // Cycle collector generation in which we're certain that this document
// won't be collected // won't be collected
PRUint32 mMarkedCCGeneration; PRUint32 mMarkedCCGeneration;
nsTObserverArray<nsIPresShell> mPresShells;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)

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

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Olli Pettay <Olli.Pettay@helsinki.fi> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPresShellIterato_h___
#define nsPresShellIterato_h___
#include "nsIPresShell.h"
#include "nsIDocument.h"
class nsPresShellIterator :
private nsTObserverArray<nsIPresShell>::ForwardIterator
{
public:
nsPresShellIterator(nsIDocument* aDoc)
: nsTObserverArray<nsIPresShell>::ForwardIterator(aDoc->mPresShells),
mDoc(aDoc) {}
already_AddRefed<nsIPresShell> GetNextShell()
{
nsIPresShell* shell = nsnull;
if (!mDoc->ShellsAreHidden()) {
shell = GetNext();
NS_IF_ADDREF(shell);
}
return shell;
}
private:
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
static void operator delete(void*, size_t) {}
nsCOMPtr<nsIDocument> mDoc;
};
#endif

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

@ -91,6 +91,7 @@
#include "nsNodeUtils.h" #include "nsNodeUtils.h"
#include "nsIDOMNode.h" #include "nsIDOMNode.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsPresShellIterator.h"
PRLogModuleInfo* gContentSinkLogModuleInfo; PRLogModuleInfo* gContentSinkLogModuleInfo;
@ -949,10 +950,9 @@ nsContentSink::ScrollToRef()
// http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.1 // http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.1
NS_ConvertUTF8toUTF16 ref(unescapedRef); NS_ConvertUTF8toUTF16 ref(unescapedRef);
PRInt32 i, ns = mDocument->GetNumberOfShells(); nsPresShellIterator iter(mDocument);
for (i = 0; i < ns; i++) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell* shell = mDocument->GetShellAt(i); while ((shell = iter.GetNextShell())) {
if (shell) {
// Check an empty string which might be caused by the UTF-8 conversion // Check an empty string which might be caused by the UTF-8 conversion
if (!ref.IsEmpty()) { if (!ref.IsEmpty()) {
// Note that GoToAnchor will handle flushing layout as needed. // Note that GoToAnchor will handle flushing layout as needed.
@ -976,7 +976,6 @@ nsContentSink::ScrollToRef()
mScrolledToRefAlready = PR_TRUE; mScrolledToRefAlready = PR_TRUE;
} }
} }
}
} }
nsresult nsresult
@ -1030,14 +1029,9 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
mLayoutStarted = PR_TRUE; mLayoutStarted = PR_TRUE;
mLastNotificationTime = PR_Now(); mLastNotificationTime = PR_Now();
PRUint32 i; nsPresShellIterator iter(mDocument);
nsCOMPtr<nsIPresShell> shell;
// XXXbz Shells can get removed (or added!) as we iterate through this loop. while ((shell = iter.GetNextShell())) {
// We should try to use an nsTObserverArray for this.
for (i = 0; i < mDocument->GetNumberOfShells(); i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
if (shell) {
// Make sure we don't call InitialReflow() for a shell that has // Make sure we don't call InitialReflow() for a shell that has
// already called it. This can happen when the layout frame for // already called it. This can happen when the layout frame for
// an iframe is constructed *between* the Embed() call for the // an iframe is constructed *between* the Embed() call for the
@ -1069,7 +1063,6 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
// Now trigger a refresh // Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager()); RefreshIfEnabled(shell->GetViewManager());
} }
}
// If the document we are loading has a reference or it is a // If the document we are loading has a reference or it is a
// frameset document, disable the scroll bars on the views. // frameset document, disable the scroll bars on the views.

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

@ -1294,9 +1294,10 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
PRBool applicable; PRBool applicable;
sheet->GetApplicable(applicable); sheet->GetApplicable(applicable);
if (applicable) { if (applicable) {
for (PRInt32 i = 0, i_end = GetNumberOfShells(); i < i_end; ++i) { nsPresShellIterator iter(this);
GetShellAt(i)->StyleSet()-> nsCOMPtr<nsIPresShell> shell;
RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet); while ((shell = iter.GetNextShell())) {
shell->StyleSet()->RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet);
} }
} }
@ -1315,10 +1316,10 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
nsStyleSet::sheetType attrSheetType = GetAttrSheetType(); nsStyleSet::sheetType attrSheetType = GetAttrSheetType();
if (mAttrStyleSheet) { if (mAttrStyleSheet) {
// Remove this sheet from all style sets // Remove this sheet from all style sets
PRInt32 count = GetNumberOfShells(); nsPresShellIterator iter(this);
for (indx = 0; indx < count; ++indx) { nsCOMPtr<nsIPresShell> shell;
GetShellAt(indx)->StyleSet()-> while ((shell = iter.GetNextShell())) {
RemoveStyleSheet(attrSheetType, mAttrStyleSheet); shell->StyleSet()->RemoveStyleSheet(attrSheetType, mAttrStyleSheet);
} }
rv = mAttrStyleSheet->Reset(aURI); rv = mAttrStyleSheet->Reset(aURI);
} else { } else {
@ -1332,9 +1333,10 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
if (mStyleAttrStyleSheet) { if (mStyleAttrStyleSheet) {
// Remove this sheet from all style sets // Remove this sheet from all style sets
PRInt32 count = GetNumberOfShells(); nsPresShellIterator iter(this);
for (indx = 0; indx < count; ++indx) { nsCOMPtr<nsIPresShell> shell;
GetShellAt(indx)->StyleSet()-> while ((shell = iter.GetNextShell())) {
shell->StyleSet()->
RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet); RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet);
} }
rv = mStyleAttrStyleSheet->Reset(aURI); rv = mStyleAttrStyleSheet->Reset(aURI);
@ -1349,9 +1351,10 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
mStyleAttrStyleSheet->SetOwningDocument(this); mStyleAttrStyleSheet->SetOwningDocument(this);
// Now set up our style sets // Now set up our style sets
PRInt32 count = GetNumberOfShells(); nsPresShellIterator iter(this);
for (indx = 0; indx < count; ++indx) { nsCOMPtr<nsIPresShell> shell;
FillStyleSet(GetShellAt(indx)->StyleSet()); while ((shell = iter.GetNextShell())) {
FillStyleSet(shell->StyleSet());
} }
return rv; return rv;
@ -1950,7 +1953,7 @@ nsDocument::doCreateShell(nsPresContext* aContext,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Note: we don't hold a ref to the shell (it holds a ref to us) // Note: we don't hold a ref to the shell (it holds a ref to us)
mPresShells.AppendElement(shell); NS_ENSURE_TRUE(mPresShells.AppendObserver(shell), NS_ERROR_OUT_OF_MEMORY);
shell.swap(*aInstancePtrResult); shell.swap(*aInstancePtrResult);
return NS_OK; return NS_OK;
@ -1959,33 +1962,14 @@ nsDocument::doCreateShell(nsPresContext* aContext,
PRBool PRBool
nsDocument::DeleteShell(nsIPresShell* aShell) nsDocument::DeleteShell(nsIPresShell* aShell)
{ {
return mPresShells.RemoveElement(aShell); return mPresShells.RemoveObserver(aShell);
} }
PRUint32
nsDocument::GetNumberOfShells() const
{
return mShellsAreHidden ? 0 : mPresShells.Count();
}
nsIPresShell *
nsDocument::GetShellAt(PRUint32 aIndex) const
{
return mShellsAreHidden ? nsnull :
NS_STATIC_CAST(nsIPresShell*, mPresShells.SafeElementAt(aIndex));
}
nsIPresShell * nsIPresShell *
nsDocument::GetPrimaryShell() const nsDocument::GetPrimaryShell() const
{ {
return mShellsAreHidden ? nsnull : return mShellsAreHidden ? nsnull : mPresShells.SafeObserverAt(0);
NS_STATIC_CAST(nsIPresShell*, mPresShells.SafeElementAt(0));
}
void
nsDocument::SetShellsHidden(PRBool aHide)
{
mShellsAreHidden = aHide;
} }
PR_STATIC_CALLBACK(void) PR_STATIC_CALLBACK(void)
@ -2279,10 +2263,10 @@ nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const
void void
nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet) nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet)
{ {
PRInt32 count = GetNumberOfShells(); nsPresShellIterator iter(this);
PRInt32 indx; nsCOMPtr<nsIPresShell> shell;
for (indx = 0; indx < count; ++indx) { while ((shell = iter.GetNextShell())) {
GetShellAt(indx)->StyleSet()->AddDocStyleSheet(aSheet, this); shell->StyleSet()->AddDocStyleSheet(aSheet, this);
} }
} }
@ -2306,9 +2290,11 @@ nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
void void
nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet) nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
{ {
for (PRInt32 i = 0, i_end = GetNumberOfShells(); i < i_end; ++i) nsPresShellIterator iter(this);
GetShellAt(i)->StyleSet()-> nsCOMPtr<nsIPresShell> shell;
RemoveStyleSheet(nsStyleSet::eDocSheet, aSheet); while ((shell = iter.GetNextShell())) {
shell->StyleSet()->RemoveStyleSheet(nsStyleSet::eDocSheet, aSheet);
}
} }
void void
@ -2443,9 +2429,11 @@ nsDocument::AddCatalogStyleSheet(nsIStyleSheet* aSheet)
if (applicable) { if (applicable) {
// This is like |AddStyleSheetToStyleSets|, but for an agent sheet. // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
for (PRInt32 i = 0, i_end = GetNumberOfShells(); i < i_end; ++i) nsPresShellIterator iter(this);
GetShellAt(i)->StyleSet()-> nsCOMPtr<nsIPresShell> shell;
AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet); while ((shell = iter.GetNextShell())) {
shell->StyleSet()->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet);
}
} }
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, PR_FALSE)); NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, PR_FALSE));
@ -3633,9 +3621,9 @@ nsDocument::GetTitle(nsAString& aTitle)
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::SetTitle(const nsAString& aTitle) nsDocument::SetTitle(const nsAString& aTitle)
{ {
for (PRInt32 i = GetNumberOfShells() - 1; i >= 0; --i) { nsPresShellIterator iter(this);
nsCOMPtr<nsIPresShell> shell = GetShellAt(i); nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
nsCOMPtr<nsISupports> container = shell->GetPresContext()->GetContainer(); nsCOMPtr<nsISupports> container = shell->GetPresContext()->GetContainer();
if (!container) if (!container)
continue; continue;
@ -4805,15 +4793,11 @@ nsDocument::FlushPendingNotifications(mozFlushType aType)
} }
} }
PRInt32 i, count = GetNumberOfShells(); nsPresShellIterator iter(this);
nsCOMPtr<nsIPresShell> shell;
for (i = 0; i < count; i++) { while ((shell = iter.GetNextShell())) {
nsCOMPtr<nsIPresShell> shell = GetShellAt(i);
if (shell) {
shell->FlushPendingNotifications(aType); shell->FlushPendingNotifications(aType);
} }
}
} }
void void
@ -5261,15 +5245,12 @@ PRBool
nsDocument::IsSafeToFlush() const nsDocument::IsSafeToFlush() const
{ {
PRBool isSafeToFlush = PR_TRUE; PRBool isSafeToFlush = PR_TRUE;
PRInt32 i = 0, n = GetNumberOfShells(); nsPresShellIterator iter(NS_CONST_CAST(nsIDocument*,
while (i < n && isSafeToFlush) { NS_STATIC_CAST(const nsIDocument*, this)));
nsIPresShell* shell = GetShellAt(i); nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell()) && isSafeToFlush) {
if (shell) {
shell->IsSafeToFlush(isSafeToFlush); shell->IsSafeToFlush(isSafeToFlush);
} }
++i;
}
return isSafeToFlush; return isSafeToFlush;
} }

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

@ -101,6 +101,7 @@
#include "pldhash.h" #include "pldhash.h"
#include "nsAttrAndChildArray.h" #include "nsAttrAndChildArray.h"
#include "nsDOMAttributeMap.h" #include "nsDOMAttributeMap.h"
#include "nsPresShellIterator.h"
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0) #define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1) #define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
@ -374,10 +375,7 @@ public:
nsStyleSet* aStyleSet, nsStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult); nsIPresShell** aInstancePtrResult);
virtual PRBool DeleteShell(nsIPresShell* aShell); virtual PRBool DeleteShell(nsIPresShell* aShell);
virtual PRUint32 GetNumberOfShells() const;
virtual nsIPresShell *GetShellAt(PRUint32 aIndex) const;
virtual nsIPresShell *GetPrimaryShell() const; virtual nsIPresShell *GetPrimaryShell() const;
virtual void SetShellsHidden(PRBool aHide);
virtual nsresult SetSubDocumentFor(nsIContent *aContent, virtual nsresult SetSubDocumentFor(nsIContent *aContent,
nsIDocument* aSubDoc); nsIDocument* aSubDoc);
@ -765,8 +763,6 @@ protected:
// True if the document "page" is not hidden // True if the document "page" is not hidden
PRPackedBool mVisible:1; PRPackedBool mVisible:1;
PRPackedBool mShellsAreHidden:1;
PRUint8 mXMLDeclarationBits; PRUint8 mXMLDeclarationBits;
PRUint8 mDefaultElementType; PRUint8 mDefaultElementType;
@ -807,8 +803,6 @@ private:
nsDocument(const nsDocument& aOther); nsDocument(const nsDocument& aOther);
nsDocument& operator=(const nsDocument& aOther); nsDocument& operator=(const nsDocument& aOther);
nsSmallVoidArray mPresShells;
nsCOMPtr<nsISupports> mXPathEvaluatorTearoff; nsCOMPtr<nsISupports> mXPathEvaluatorTearoff;
// The layout history state that should be used by nodes in this // The layout history state that should be used by nodes in this

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

@ -74,6 +74,7 @@
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsPresShellIterator.h"
// Concrete classes // Concrete classes
#include "nsFrameLoader.h" #include "nsFrameLoader.h"
@ -543,9 +544,9 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance)
return NS_OK; return NS_OK;
} }
PRUint32 numShells = doc->GetNumberOfShells(); nsPresShellIterator iter(doc);
for (PRUint32 i = 0; i < numShells; ++i) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell* shell = doc->GetShellAt(i); while ((shell = iter.GetNextShell())) {
shell->RecreateFramesFor(thisContent); shell->RecreateFramesFor(thisContent);
} }
@ -1175,9 +1176,9 @@ nsObjectLoadingContent::NotifyStateChanged(ObjectType aOldType,
// If our state changed, then we already recreated frames // If our state changed, then we already recreated frames
// Otherwise, need to do that here // Otherwise, need to do that here
PRUint32 numShells = doc->GetNumberOfShells(); nsPresShellIterator iter(doc);
for (PRUint32 i = 0; i < numShells; ++i) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell* shell = doc->GetShellAt(i); while ((shell = iter.GetNextShell())) {
shell->RecreateFramesFor(thisContent); shell->RecreateFramesFor(thisContent);
} }
} }

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

@ -131,6 +131,7 @@
#include "nsIProperties.h" #include "nsIProperties.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsPresShellIterator.h"
#ifdef XP_MACOSX #ifdef XP_MACOSX
#include <Events.h> #include <Events.h>
@ -1987,9 +1988,9 @@ nsEventStateManager::GetParentScrollingView(nsInputEvent *aEvent,
} }
nsIPresShell *pPresShell = nsnull; nsIPresShell *pPresShell = nsnull;
for (PRUint32 i = 0; i < parentDoc->GetNumberOfShells(); i++) { nsPresShellIterator iter(parentDoc);
nsIPresShell *tmpPresShell = parentDoc->GetShellAt(i); nsCOMPtr<nsIPresShell> tmpPresShell;
NS_ENSURE_TRUE(tmpPresShell, NS_ERROR_FAILURE); while ((tmpPresShell = iter.GetNextShell())) {
NS_ENSURE_TRUE(tmpPresShell->GetPresContext(), NS_ERROR_FAILURE); NS_ENSURE_TRUE(tmpPresShell->GetPresContext(), NS_ERROR_FAILURE);
if (tmpPresShell->GetPresContext()->Type() == aPresContext->Type()) { if (tmpPresShell->GetPresContext()->Type() == aPresContext->Type()) {
pPresShell = tmpPresShell; pPresShell = tmpPresShell;

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

@ -2352,7 +2352,7 @@ nsHTMLDocument::Close()
// it be for now, though. In any case, there's no reason to do // it be for now, though. In any case, there's no reason to do
// this if we have no presshell, since in that case none of the // this if we have no presshell, since in that case none of the
// above about reusing frames applies. // above about reusing frames applies.
if (GetNumberOfShells() != 0) { if (GetPrimaryShell()) {
FlushPendingNotifications(Flush_Layout); FlushPendingNotifications(Flush_Layout);
} }

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

@ -266,12 +266,9 @@ nsMediaDocument::CreateSyntheticDocument()
nsresult nsresult
nsMediaDocument::StartLayout() nsMediaDocument::StartLayout()
{ {
PRUint32 numberOfShells = GetNumberOfShells(); nsPresShellIterator iter(this);
// XXXbz Shells can get removed (or added!) as we iterate through this loop. nsCOMPtr<nsIPresShell> shell;
// We should try to use an nsTObserverArray for this. while ((shell = iter.GetNextShell())) {
for (PRUint32 i = 0; i < numberOfShells; i++) {
nsIPresShell *shell = GetShellAt(i);
// Make shell an observer for next time. // Make shell an observer for next time.
shell->BeginObservingDocument(); shell->BeginObservingDocument();

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

@ -74,7 +74,7 @@ nsresult
nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument) nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument)
{ {
// Check for iframe with display:none. Such iframes don't have presshells // Check for iframe with display:none. Such iframes don't have presshells
if (!aDocument->GetNumberOfShells()) { if (!aDocument->GetPrimaryShell()) {
return NS_OK; return NS_OK;
} }

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

@ -150,6 +150,7 @@
#include "nsNodeInfoManager.h" #include "nsNodeInfoManager.h"
#include "nsXBLBinding.h" #include "nsXBLBinding.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsPresShellIterator.h"
/** /**
* Three bits are used for XUL Element's lazy state. * Three bits are used for XUL Element's lazy state.
@ -1889,10 +1890,10 @@ nsXULElement::Focus()
return NS_OK; return NS_OK;
// Obtain a presentation context and then call SetFocus. // Obtain a presentation context and then call SetFocus.
if (doc->GetNumberOfShells() == 0)
return NS_OK;
nsIPresShell *shell = doc->GetPrimaryShell(); nsIPresShell *shell = doc->GetPrimaryShell();
if (!shell)
return NS_OK;
// Set focus // Set focus
nsCOMPtr<nsPresContext> context = shell->GetPresContext(); nsCOMPtr<nsPresContext> context = shell->GetPresContext();
@ -1910,10 +1911,9 @@ nsXULElement::Blur()
return NS_OK; return NS_OK;
// Obtain a presentation context and then call SetFocus. // Obtain a presentation context and then call SetFocus.
if (doc->GetNumberOfShells() == 0)
return NS_OK;
nsIPresShell *shell = doc->GetPrimaryShell(); nsIPresShell *shell = doc->GetPrimaryShell();
if (!shell)
return NS_OK;
// Set focus // Set focus
nsCOMPtr<nsPresContext> context = shell->GetPresContext(); nsCOMPtr<nsPresContext> context = shell->GetPresContext();
@ -1931,13 +1931,11 @@ nsXULElement::Click()
nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // Strong just in case nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // Strong just in case
if (doc) { if (doc) {
PRUint32 numShells = doc->GetNumberOfShells(); nsPresShellIterator iter(doc);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
// strong ref to PresContext so events don't destroy it // strong ref to PresContext so events don't destroy it
nsCOMPtr<nsPresContext> context; nsCOMPtr<nsPresContext> context = shell->GetPresContext();
for (PRUint32 i = 0; i < numShells; ++i) {
nsIPresShell *shell = doc->GetShellAt(i);
context = shell->GetPresContext();
PRBool isCallerChrome = nsContentUtils::IsCallerChrome(); PRBool isCallerChrome = nsContentUtils::IsCallerChrome();
@ -1974,13 +1972,10 @@ nsXULElement::DoCommand()
{ {
nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // strong just in case nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // strong just in case
if (doc) { if (doc) {
PRUint32 numShells = doc->GetNumberOfShells(); nsPresShellIterator iter(doc);
nsCOMPtr<nsPresContext> context; nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
for (PRUint32 i = 0; i < numShells; ++i) { nsCOMPtr<nsPresContext> context = shell->GetPresContext();
nsIPresShell *shell = doc->GetShellAt(i);
context = shell->GetPresContext();
nsEventStatus status = nsEventStatus_eIgnore; nsEventStatus status = nsEventStatus_eIgnore;
nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull); nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),

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

@ -69,6 +69,7 @@
#include "nsCRT.h" #include "nsCRT.h"
#include "nsDOMError.h" #include "nsDOMError.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsPresShellIterator.h"
#ifdef PR_LOGGING #ifdef PR_LOGGING
static PRLogModuleInfo* gLog; static PRLogModuleInfo* gLog;
@ -391,9 +392,9 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
} }
#endif #endif
PRUint32 count = document->GetNumberOfShells(); nsPresShellIterator iter(document);
for (PRUint32 i = 0; i < count; i++) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell *shell = document->GetShellAt(i); while ((shell = iter.GetNextShell())) {
// Retrieve the context in which our DOM event will fire. // Retrieve the context in which our DOM event will fire.
nsCOMPtr<nsPresContext> context = shell->GetPresContext(); nsCOMPtr<nsPresContext> context = shell->GetPresContext();

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

@ -901,9 +901,9 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster,
// |onbroadcast| event handler // |onbroadcast| event handler
nsEvent event(PR_TRUE, NS_XUL_BROADCAST); nsEvent event(PR_TRUE, NS_XUL_BROADCAST);
PRInt32 j = GetNumberOfShells(); nsPresShellIterator iter(this);
while (--j >= 0) { nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIPresShell> shell = GetShellAt(j); while ((shell = iter.GetNextShell())) {
nsCOMPtr<nsPresContext> aPresContext = shell->GetPresContext(); nsCOMPtr<nsPresContext> aPresContext = shell->GetPresContext();
@ -1973,10 +1973,9 @@ nsXULDocument::StartLayout(void)
return NS_OK; return NS_OK;
} }
// XXXbz Shells can get removed (or added!) as we iterate through this nsPresShellIterator iter(this);
// loop. We should try to use an nsTObserverArray for this. nsCOMPtr<nsIPresShell> shell;
for (PRUint32 i = 0; i < GetNumberOfShells(); ++i) { while ((shell = iter.GetNextShell())) {
nsIPresShell *shell = GetShellAt(i);
// Resize-reflow this time // Resize-reflow this time
nsPresContext *cx = shell->GetPresContext(); nsPresContext *cx = shell->GetPresContext();

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

@ -211,7 +211,7 @@ nsFocusController::UpdateCommands()
} }
// If there is no presshell, it's a zombie document which can't handle the command updates // If there is no presshell, it's a zombie document which can't handle the command updates
if (window && doc && doc->GetNumberOfShells()) { if (window && doc && doc->GetPrimaryShell()) {
// Not a zombie document, so we can handle the command update // Not a zombie document, so we can handle the command update
window->UpdateCommands(NS_LITERAL_STRING("focus")); window->UpdateCommands(NS_LITERAL_STRING("focus"));
mNeedUpdateCommands = PR_FALSE; mNeedUpdateCommands = PR_FALSE;
@ -283,10 +283,6 @@ nsFocusController::MoveFocus(PRBool aForward, nsIDOMElement* aElt)
// Obtain a presentation context // Obtain a presentation context
PRInt32 count = doc->GetNumberOfShells();
if (count == 0)
return NS_OK;
nsIPresShell *shell = doc->GetPrimaryShell(); nsIPresShell *shell = doc->GetPrimaryShell();
if (!shell) if (!shell)
return NS_OK; return NS_OK;

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

@ -101,6 +101,7 @@
#include "nsIDOMEventTarget.h" #include "nsIDOMEventTarget.h"
#include "nsIDOM3EventTarget.h" #include "nsIDOM3EventTarget.h"
#include "nsIDOMEventGroup.h" #include "nsIDOMEventGroup.h"
#include "nsPresShellIterator.h"
// Header for this class // Header for this class
#include "nsTypeAheadFind.h" #include "nsTypeAheadFind.h"
@ -554,11 +555,11 @@ nsTypeAheadFind::HandleEvent(nsIDOMEvent* aEvent)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
PRUint32 numShells = doc->GetNumberOfShells();
PRBool cancelFind = PR_FALSE; PRBool cancelFind = PR_FALSE;
for (PRUint32 count = 0; count < numShells; count ++) { nsPresShellIterator iter(doc);
nsIPresShell *shellToBeDestroyed = doc->GetShellAt(count); nsCOMPtr<nsIPresShell> shellToBeDestroyed;
while ((shellToBeDestroyed = iter.GetNextShell())) {
if (shellToBeDestroyed == focusedShell) { if (shellToBeDestroyed == focusedShell) {
cancelFind = PR_TRUE; cancelFind = PR_TRUE;
break; break;

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

@ -44,6 +44,7 @@
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsStubMutationObserver.h" #include "nsStubMutationObserver.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "nsPresShellIterator.h"
#if defined(DEBUG) && defined(SVG_DEBUG_PRINTING) #if defined(DEBUG) && defined(SVG_DEBUG_PRINTING)
#include "nsIDeviceContext.h" #include "nsIDeviceContext.h"
@ -88,9 +89,10 @@ nsSVGMutationObserver::AttributeChanged(nsIDocument *aDocument,
return; return;
} }
PRUint32 count = aDocument->GetNumberOfShells(); nsPresShellIterator iter(aDocument);
for (PRUint32 i = 0; i < count; ++i) { nsCOMPtr<nsIPresShell> shell;
nsIFrame *frame = aDocument->GetShellAt(i)->GetPrimaryFrameFor(aContent); while ((shell = iter.GetNextShell())) {
nsIFrame *frame = shell->GetPrimaryFrameFor(aContent);
if (!frame) { if (!frame) {
continue; continue;
} }

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

@ -94,6 +94,7 @@
#include "nsIJARURI.h" #include "nsIJARURI.h"
#include "nsIFileURL.h" #include "nsIFileURL.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsPresShellIterator.h"
static char kChromePrefix[] = "chrome://"; static char kChromePrefix[] = "chrome://";
nsIAtom* nsChromeRegistry::sCPrefix; // atom for "c" nsIAtom* nsChromeRegistry::sCPrefix; // atom for "c"
@ -1396,10 +1397,9 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
return NS_OK; return NS_OK;
// Deal with the agent sheets first. Have to do all the style sets by hand. // Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells(); nsPresShellIterator iter(document);
for (PRUint32 k = 0; k < shellCount; k++) { nsCOMPtr<nsIPresShell> shell;
nsIPresShell *shell = document->GetShellAt(k); while ((shell = iter.GetNextShell())) {
// Reload only the chrome URL agent style sheets. // Reload only the chrome URL agent style sheets.
nsCOMArray<nsIStyleSheet> agentSheets; nsCOMArray<nsIStyleSheet> agentSheets;
rv = shell->GetAgentStyleSheets(agentSheets); rv = shell->GetAgentStyleSheets(agentSheets);