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 14:45:03 -07:00
Родитель 847443fc11
Коммит b468d35e89
18 изменённых файлов: 233 добавлений и 199 удалений

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

@ -100,6 +100,7 @@
#include "nsIXPConnect.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#include "nsPresShellIterator.h"
#ifdef MOZ_XUL
// 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;
// Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells();
for (PRUint32 k = 0; k < shellCount; k++) {
nsIPresShell *shell = document->GetShellAt(k);
nsPresShellIterator iter(document);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
// Reload only the chrome URL agent style sheets.
nsCOMArray<nsIStyleSheet> agentSheets;
rv = shell->GetAgentStyleSheets(agentSheets);

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

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

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

@ -49,6 +49,7 @@
#include "mozFlushType.h"
#include "nsIAtom.h"
#include "nsCompatibility.h"
#include "nsTObserverArray.h"
class nsIContent;
class nsPresContext;
@ -94,8 +95,8 @@ class mozAutoSubtreeModified;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
{ 0xb7f930df, 0x1c61, 0x410f, \
{ 0xab, 0x3c, 0xe2, 0x53, 0xca, 0x8d, 0x85, 0x49 } }
{ 0x7dd5790f, 0x110d, 0x4bf6, \
{ 0x83, 0x50, 0x4b, 0xe3, 0x5d, 0xdc, 0xe1, 0x1e } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -349,10 +350,9 @@ public:
nsStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult) = 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 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
@ -891,6 +891,7 @@ protected:
virtual void WillDispatchMutationEvent(nsINode* aTarget) = 0;
virtual void MutationEventDispatched(nsINode* aTarget) = 0;
friend class mozAutoSubtreeModified;
friend class nsPresShellIterator;
nsString mDocumentTitle;
nsCOMPtr<nsIURI> mDocumentURI;
@ -932,6 +933,8 @@ protected:
// document in it.
PRPackedBool mIsInitialDocumentInWindow;
PRPackedBool mShellsAreHidden;
// The bidi options for this document. What this bitfield means is
// defined in nsBidiUtils.h
PRUint32 mBidiOptions;
@ -949,6 +952,8 @@ protected:
// Cycle collector generation in which we're certain that this document
// won't be collected
PRUint32 mMarkedCCGeneration;
nsTObserverArray<nsIPresShell> mPresShells;
};
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 "nsIDOMNode.h"
#include "nsThreadUtils.h"
#include "nsPresShellIterator.h"
PRLogModuleInfo* gContentSinkLogModuleInfo;
@ -949,32 +950,30 @@ nsContentSink::ScrollToRef()
// http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.1
NS_ConvertUTF8toUTF16 ref(unescapedRef);
PRInt32 i, ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell* shell = mDocument->GetShellAt(i);
if (shell) {
// Check an empty string which might be caused by the UTF-8 conversion
if (!ref.IsEmpty()) {
// Note that GoToAnchor will handle flushing layout as needed.
nsPresShellIterator iter(mDocument);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
// Check an empty string which might be caused by the UTF-8 conversion
if (!ref.IsEmpty()) {
// Note that GoToAnchor will handle flushing layout as needed.
rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
} else {
rv = NS_ERROR_FAILURE;
}
// If UTF-8 URI failed then try to assume the string as a
// document's charset.
if (NS_FAILED(rv)) {
const nsACString &docCharset = mDocument->GetDocumentCharacterSet();
rv = nsContentUtils::ConvertStringFromCharset(docCharset, unescapedRef, ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty())
rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
} else {
rv = NS_ERROR_FAILURE;
}
// If UTF-8 URI failed then try to assume the string as a
// document's charset.
if (NS_FAILED(rv)) {
const nsACString &docCharset = mDocument->GetDocumentCharacterSet();
rv = nsContentUtils::ConvertStringFromCharset(docCharset, unescapedRef, ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty())
rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
}
if (NS_SUCCEEDED(rv)) {
mScrolledToRefAlready = PR_TRUE;
}
}
if (NS_SUCCEEDED(rv)) {
mScrolledToRefAlready = PR_TRUE;
}
}
}
@ -1029,46 +1028,40 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
mLayoutStarted = PR_TRUE;
mLastNotificationTime = PR_Now();
PRUint32 i;
// XXXbz Shells can get removed (or added!) as we iterate through this loop.
// We should try to use an nsTObserverArray for this.
for (i = 0; i < mDocument->GetNumberOfShells(); i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
nsPresShellIterator iter(mDocument);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
// Make sure we don't call InitialReflow() for a shell that has
// already called it. This can happen when the layout frame for
// an iframe is constructed *between* the Embed() call for the
// docshell in the iframe, and the content sink's call to OpenBody().
// (Bug 153815)
if (shell) {
// Make sure we don't call InitialReflow() for a shell that has
// already called it. This can happen when the layout frame for
// an iframe is constructed *between* the Embed() call for the
// docshell in the iframe, and the content sink's call to OpenBody().
// (Bug 153815)
PRBool didInitialReflow = PR_FALSE;
shell->GetDidInitialReflow(&didInitialReflow);
if (didInitialReflow) {
// XXX: The assumption here is that if something already
// called InitialReflow() on this shell, it also did some of
// the setup below, so we do nothing and just move on to the
// next shell in the list.
PRBool didInitialReflow = PR_FALSE;
shell->GetDidInitialReflow(&didInitialReflow);
if (didInitialReflow) {
// XXX: The assumption here is that if something already
// called InitialReflow() on this shell, it also did some of
// the setup below, so we do nothing and just move on to the
// next shell in the list.
continue;
}
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsRect r = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr<nsIPresShell> shellGrip = shell;
nsresult rv = shell->InitialReflow(r.width, r.height);
if (NS_FAILED(rv)) {
return;
}
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
continue;
}
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsRect r = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr<nsIPresShell> shellGrip = shell;
nsresult rv = shell->InitialReflow(r.width, r.height);
if (NS_FAILED(rv)) {
return;
}
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
}
// If the document we are loading has a reference or it is a

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

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

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

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

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

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

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

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

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

@ -2352,7 +2352,7 @@ nsHTMLDocument::Close()
// 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
// above about reusing frames applies.
if (GetNumberOfShells() != 0) {
if (GetPrimaryShell()) {
FlushPendingNotifications(Flush_Layout);
}

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

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

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

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

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

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

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

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

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

@ -901,9 +901,9 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster,
// |onbroadcast| event handler
nsEvent event(PR_TRUE, NS_XUL_BROADCAST);
PRInt32 j = GetNumberOfShells();
while (--j >= 0) {
nsCOMPtr<nsIPresShell> shell = GetShellAt(j);
nsPresShellIterator iter(this);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
nsCOMPtr<nsPresContext> aPresContext = shell->GetPresContext();
@ -1973,10 +1973,9 @@ nsXULDocument::StartLayout(void)
return NS_OK;
}
// XXXbz Shells can get removed (or added!) as we iterate through this
// loop. We should try to use an nsTObserverArray for this.
for (PRUint32 i = 0; i < GetNumberOfShells(); ++i) {
nsIPresShell *shell = GetShellAt(i);
nsPresShellIterator iter(this);
nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) {
// Resize-reflow this time
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 (window && doc && doc->GetNumberOfShells()) {
if (window && doc && doc->GetPrimaryShell()) {
// Not a zombie document, so we can handle the command update
window->UpdateCommands(NS_LITERAL_STRING("focus"));
mNeedUpdateCommands = PR_FALSE;
@ -283,10 +283,6 @@ nsFocusController::MoveFocus(PRBool aForward, nsIDOMElement* aElt)
// Obtain a presentation context
PRInt32 count = doc->GetNumberOfShells();
if (count == 0)
return NS_OK;
nsIPresShell *shell = doc->GetPrimaryShell();
if (!shell)
return NS_OK;

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

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

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

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